0x00 前言

  • 方式:CreateRemoteThread
  • 需要:visual studio 2015
  • 需要:进程模块查看器,如【PCHunter】【ProcessHacker】等。
  • 需要:创建一个用于实验注入的【MFC项目】窗体。
  • 需要:创建一个用于有痕注入的【Dll项目】模块。
  • 需要:创建一个用于无痕注入的【Dll项目】模块。

0x01 实验窗体

  • 在【VS2015】中,创建一个名为【MFC】的【MFC项目】,打开【MFC.rc】的【IDD_MFC_DIALOG】:
  • 然后在【IDD_MFC_DIALOG】放入以下三个【Button】:
  • 弹窗的ID设置为【IDOK】,无痕注入的ID设置为【IDC_BUTTON1】,有痕注入的ID设置为【IDC_BUTTON2】:
  • 在【MFCDlg.cpp】贴入以下代码:
#include "stdafx.h"
#include "MFC.h"
#include "MFCDlg.h"
#include "afxdialogex.h"
#include <windows.h>#ifdef _DEBUG
#define new DEBUG_NEW
#endif//1.获取进程句柄
HANDLE GetThePidOfTargetProcess(HWND hwnd)
{DWORD pid;GetWindowThreadProcessId(hwnd, &pid);HANDLE hProcee = ::OpenProcess(PROCESS_ALL_ACCESS | PROCESS_CREATE_THREAD, 0, pid);return hProcee;
}
//2.提升权限
void Up()
{HANDLE hToken;LUID luid;TOKEN_PRIVILEGES tp;OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);tp.PrivilegeCount = 1;tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;tp.Privileges[0].Luid = luid;AdjustTokenPrivileges(hToken, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
}
//3.进程注入
BOOL DoInjection(char *DllPath, HANDLE hProcess)
{DWORD BufSize = strlen(DllPath) + 1;LPVOID AllocAddr = VirtualAllocEx(hProcess, NULL, BufSize, MEM_COMMIT, PAGE_READWRITE);WriteProcessMemory(hProcess, AllocAddr, DllPath, BufSize, NULL);PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryA");HANDLE hRemoteThread;hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, pfnStartAddr, AllocAddr, 0, NULL);if (hRemoteThread){MessageBox(NULL, TEXT("注入成功"), TEXT("提示"), MB_OK);return true;}else{MessageBox(NULL, TEXT("注入失败"), TEXT("提示"), MB_OK);return false;}
}class CAboutDlg : public CDialogEx
{public:CAboutDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_ABOUTBOX };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现
protected:DECLARE_MESSAGE_MAP()
};CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{}void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()CMFCDlg::CMFCDlg(CWnd* pParent /*=NULL*/): CDialogEx(IDD_MFC_DIALOG, pParent)
{m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CMFCDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CMFCDlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDOK, &CMFCDlg::OnBnClickedOk)ON_BN_CLICKED(IDC_BUTTON1, &CMFCDlg::OnBnClickedButton1)ON_BN_CLICKED(IDCANCEL, &CMFCDlg::OnBnClickedCancel)ON_BN_CLICKED(IDC_BUTTON2, &CMFCDlg::OnBnClickedButton2)
END_MESSAGE_MAP()BOOL CMFCDlg::OnInitDialog()
{CDialogEx::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){BOOL bNameValid;CString strAboutMenu;bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动//  执行此操作SetIcon(m_hIcon, TRUE);           // 设置大图标SetIcon(m_hIcon, FALSE);        // 设置小图标// TODO: 在此添加额外的初始化代码return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}void CMFCDlg::OnSysCommand(UINT nID, LPARAM lParam)
{if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialogEx::OnSysCommand(nID, lParam);}
}void CMFCDlg::OnPaint()
{if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CDialogEx::OnPaint();}
}HCURSOR CMFCDlg::OnQueryDragIcon()
{return static_cast<HCURSOR>(m_hIcon);
}void CMFCDlg::OnBnClickedOk()
{//MessageBox(_T("你好,世界!!!"), _T("提示:"), MB_OK);
}void CMFCDlg::OnBnClickedButton1()//无痕
{//HWND hwnd = FindWindowExA(NULL, NULL, NULL, "MFC");//Up();//HANDLE hP = GetThePidOfTargetProcess(hwnd);//DoInjection("C:UsersHHZDesktopHideDllReleaseHideDll.dll", hP);
}void CMFCDlg::OnBnClickedButton2()//有痕
{//HWND hwnd = FindWindowExA(NULL, NULL, NULL, "MFC");//Up();//HANDLE hP = GetThePidOfTargetProcess(hwnd);//DoInjection("C:UsersHHZDesktopShowDllReleaseShowDll.dll", hP);
}void CMFCDlg::OnBnClickedCancel()
{// TODO: 在此添加控件通知处理程序代码CDialogEx::OnCancel();
}

  • 在【MFCDlg.cpp】中,重点是三个跟进程注入有关的函数:
  • 1.获取进程句柄【HANDLE GetThePidOfTargetProcess(HWND hwnd)】
  • 2.提升权限【void Up()】
  • 3.进程注入【BOOL DoInjection(char *DllPath, HANDLE hProcess)】
  • 然后选择【Release】以及【x86】,然后运行:
  • 现在【实验窗体】创建完毕:

0x02 有痕注入

  • 在【VS2015】中,创建一个名为【ShowDll】的【Win32项目】,详细界面选择【Dll】:
  • 打开【dllmain.cpp】:
  • 在【dllmain.cpp】内贴入以下代码:
/***************************************************************************************************************************/
//
#include "stdafx.h"
//
DWORD oldProtect;
BYTE  JmpBtye[5];
DWORD oldAddr;
DWORD WINAPI HookMessageBox(LPVOID notUse);
void UnHook();
//
using pMessageBoxW = int (WINAPI*)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType);
pMessageBoxW ToMessageBox;
//或
//typedef int (WINAPI *pMessageBoxW)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType);
//pMessageBoxW ToMessageBox;
/***************************************************************************************************************************//***************************************************************************************************************************/
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{//switch (ul_reason_for_call){case DLL_PROCESS_ATTACH://HookMessageBox(NULL);//break;case DLL_PROCESS_DETACH://UnHook();//break;}//return TRUE;
}int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{//lpText = L"有痕Hook成功!!!";//return ToMessageBox(hWnd, lpText, lpCaption, uType);
}DWORD WINAPI HookMessageBox(LPVOID notUse)
{//HMODULE hModule = LoadLibraryA("user32.dll");DWORD   mAddr = (DWORD)GetProcAddress(hModule, "MessageBoxW");ToMessageBox = (pMessageBoxW)(mAddr + 2);oldAddr = mAddr;//DWORD addr = mAddr - 5;VirtualProtect((void *)addr, 15, PAGE_EXECUTE_READWRITE, &oldProtect);JmpBtye[0] = 0xE9;//*(DWORD *)&JmpBtye[1] = (DWORD)((long long)MyMessageBoxW - (long long)addr - 5);memcpy((void *)addr, JmpBtye, 5);//__asm{mov bx, 0xF9EBmov eax, mAddrmov[eax], bx}
}void UnHook()
{__asm{mov bx, 0xFF8Bmov eax, oldAddrmov[eax], bx}
}
/***************************************************************************************************************************/

  • 简单讲解一下代码逻辑:
  • 首先,当【ShowDll.dll】模块被注入到【某进程】中,【某进程】将自动调用其【DllMain】接口函数。
  • 其次,【DllMain】的第二个形参【ul_reason_for_call】,【某进程】传参为【DLL_PROCESS_ATTACH】,触发【HookMessageBox(NULL)】。
  • 然后,【HookMessageBox(NULL)】将【MessageBox】首地址指向我们自定义的【MyMessageBoxW】从而Hook【MessageBox】。
  • 最后,在【MyMessageBoxW】中,我们将本来要传给【MessageBox】的【lpText】篡改成【“有痕Hook成功!!!”】,之后再通过【ToMessageBox(hWnd, lpText, lpCaption, uType)】传给了真正的【MessageBox】,这样就达成了一次完整的Hook。
  • 当要卸载【ShowDll.dll】时,进程则调用此Dll的【DllMain】,且第二个形参【ul_reason_for_call】传参为【DLL_PROCESS_DETACH】,则可触发【UnHook()】,恢复【MessageBox】的首地址。
  • 接下来选择【Release】以及【x86】,然后生成【ShowDll.dll】:
  • 现在,在【MFC项目】的【MFCDlg.cpp】中设置好【ShowDll.dll】的路径,然后运行【MFC】:
  • 在【MFC】窗口中点击【弹窗】:
  • 然后再点击【有痕注入】,显示【注入成功】:
  • 再次点击【弹窗】,则显示在【ShowDll项目】中的【dllmain.cpp】的第40行设置好的【“有痕Hook成功!!!”】:
  • 然后我们使用【进程模块查看器】,这里使用【ProcessHacker】可以查看到【ShowDll.dll】模块:
  • 这就是【注入模块】可被遍历到的【有痕注入】。

0x03 无痕注入

  • 0x02一样,在【VS2015】中,创建一个名为【HideDll】的【Win32项目】,然后在【dllmain.cpp】内贴入以下代码:
/***************************************************************************************************************************/
//
#include "stdafx.h"
//
DWORD oldProtect;
BYTE  JmpBtye[5];
DWORD oldAddr;
DWORD HideModule(HMODULE hModule);
DWORD WINAPI HookMessageBox(LPVOID notUse);
//
using pMessageBoxW = int (WINAPI*)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType);
pMessageBoxW ToMessageBox;
/***************************************************************************************************************************/
BOOL APIENTRY DllMain(HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{//switch (ul_reason_for_call){case DLL_PROCESS_ATTACH://DWORD newModule = HideModule(hModule);//if (newModule){LPTHREAD_START_ROUTINE  hook = (LPTHREAD_START_ROUTINE)(newModule + ((DWORD)HookMessageBox - (DWORD)hModule));hook(NULL);//CreateThread(0, 0, hook, 0, 0, 0);}//break;}//return FALSE;
}DWORD HideModule(HMODULE hModule)
{//PIMAGE_DOS_HEADER  pDos = (PIMAGE_DOS_HEADER)hModule;//DOS 头PIMAGE_NT_HEADERS  pNt = (PIMAGE_NT_HEADERS)((DWORD)hModule + pDos->e_lfanew);//NT 头//PBYTE mem = (PBYTE)VirtualAlloc(0, pNt->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE);if (NULL == mem){//MessageBox(NULL, TEXT("申请空间失败。"), NULL, MB_ICONINFORMATION | MB_YESNO);//return NULL;}//memcpy(mem, (void *)hModule, pNt->OptionalHeader.SizeOfImage);//PIMAGE_BASE_RELOCATION  rBase = (PIMAGE_BASE_RELOCATION)((DWORD)mem + pNt->OptionalHeader.DataDirectory[5].VirtualAddress);DWORD n = 0;DWORD Base = (DWORD)mem;DWORD offset = (DWORD)mem - (DWORD)hModule;if (offset == 0)(DWORD)mem;//typedef struct RELOCATIONITEM{WORD value : 12;WORD attr : 4;} *PRELOCATIONITEM;//PRELOCATIONITEM   rItem;DWORD *item;//while (true){if (rBase->SizeOfBlock == 0)break;rItem = (PRELOCATIONITEM)((PBYTE)rBase + 8);n = (rBase->SizeOfBlock - 8) / 2;for (int i = 0; i < (int)n; ++i){if (3 == rItem[i].attr){item = (DWORD *)(Base + rBase->VirtualAddress + rItem[i].value);*item = (*item + offset);}}rBase = (PIMAGE_BASE_RELOCATION)((PBYTE)rBase + rBase->SizeOfBlock);}//return (DWORD)mem;
}int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{//lpText = L" 无痕Hook成功!!!";//return ToMessageBox(hWnd, lpText, lpCaption, uType);
}DWORD WINAPI HookMessageBox(LPVOID notUse)
{//HMODULE hModule = LoadLibraryA("user32.dll");DWORD   mAddr = (DWORD)GetProcAddress(hModule, "MessageBoxW");ToMessageBox = (pMessageBoxW)(mAddr + 2);oldAddr = mAddr;//DWORD addr = mAddr - 5;VirtualProtect((void *)addr, 15, PAGE_EXECUTE_READWRITE, &oldProtect);JmpBtye[0] = 0xE9;//*(DWORD *)&JmpBtye[1] = (DWORD)((long long)MyMessageBoxW - (long long)addr - 5);memcpy((void *)addr, JmpBtye, 5);//__asm{mov bx, 0xF9EBmov eax, mAddrmov[eax], bx}
}void UnHook()
{__asm{mov bx, 0xFF8Bmov eax, oldAddrmov[eax], bx}
}

  • 简单讲解一下代码逻辑:
  • 大体与【有痕注入】一样,不同点在于当【某进程】传入【DLL_PROCESS_ATTACH】时,【HideModule(hModule)】将【HideDll.dll】拷贝到了新开辟的内存空间,然后通过【(LPTHREAD_START_ROUTINE)(newModule + ((DWORD)HookMessageBox - (DWORD)hModule))】计算出在新位置的【HideDll.dll】的【HookMessageBox】的首地址,将这个首地址存储在【hook】这个指针里,然后通过【hook(NULL)】调用新位置的【HookMessageBox】。
  • 最后【break】出【switch】后,再【return FALSE】,【DllMain】返回【FALSE】会导致刚刚注入到【某进程】的【HideDll.dll】被卸载,而被拷贝到了新开辟的内存空间的【HideDll.dll】则悄咪咪的运行了起来,此时再通过【进程模块查看器】查看,发现以及没有了【HideDll.dll】的踪迹,此为【无痕注入】。
  • 接下来选择【Release】以及【x86】,然后生成【HideDll.dll】,之后在【MFC项目】的【MFCDlg.cpp】中设置好【HideDll.dll】的路径,然后运行【MFC】:
  • 在【MFC】窗口中点击【弹窗】:
  • 然后再点击【无痕注入】,显示【注入成功】:
  • 再次点击【弹窗】,则显示在【HideDll项目】中的【dllmain.cpp】的第95行设置好的【“无痕Hook成功!!!”】:
  • 然后我们使用【进程模块查看器】,这里使用【ProcessHacker】查找是否有【HideDll.dll】模块:
advapi32.dll
bcryptprimitives.dll
cfgmgr32.dll
combase.dll
comctl32.dll
CoreMessaging.dll
CoreUIComponents.dll
crypt32.dll
cryptbase.dll
cryptsp.dll
dwmapi.dll
gdi32.dll
gdi32full.dll
imm32.dll
kernel.appcore.dll
kernel32.dll
KernelBase.dll
locale.nls
MFC.exe
mfc140chs.dll
mfc140u.dll
msasn1.dll
msctf.dll
msvcp_win.dll
msvcrt.dll
ntdll.dll
ntdll.dll
ntmarta.dll
ole32.dll
oleaut32.dll
powrprof.dll
profapi.dll
rpcrt4.dll
sechost.dll
SHCore.dll
shell32.dll
shlwapi.dll
SortDefault.nls
sspicli.dll
StaticCache.dat
TextInputFramework.dll
ucrtbase.dll
user32.dll
user32.dll.mui
uxtheme.dll
vcruntime140.dll
win32u.dll
windows.storage.dll
WinTypes.dll
wow64.dll
wow64cpu.dll
wow64win.dll

  • 经过查找,并没有发现【HideDll.dll】模块,【无痕注入】成功。

  • 如有谬误,欢迎指教。

ce变速注入dll失败_[LAB]一种无痕Dll模块注入方式相关推荐

  1. 无痕注入dll_[LAB]一种无痕Dll模块注入方式

    #include "stdafx.h"#include "MFC.h"#include "MFCDlg.h"#include "a ...

  2. 无法启动此程序因为计算机丢失dtlui,电脑缺少dll文件_电脑开机总是出来DLL文件丢失,...

    最佳答案 如果您的电脑开机出现"加载C:/WIND/SYSTEM32.UKWIEG96.DLL时出错"之类的加载dll文件出错或提示dll文件丢失,但又可以正常进入系统,那么这篇文 ...

  3. jsp给前端注入值失败_基于 qiankun 的微前端最佳实践(图文并茂) 应用间通信篇...

    引言 大家好~ 本文是基于 qiankun 的微前端最佳实践系列文章之 应用间通信篇,本文将分享在 qiankun 中如何进行应用间通信. 在开始介绍 qiankun 的应用通信之前,我们需要先了解微 ...

  4. python replace函数 成功 失败_请教下调用python string模块的replace方法出错的原因

    直接调用没有问题 def test1(): test_str="028-123456" print test_str.replace(old="-",new=& ...

  5. 依赖注入通俗解释_我如何向团队解释依赖注入

    依赖注入通俗解释 最近,我们公司开始开发一个新的基于Java的Web应用程序,经过一些评估过程,我们决定使用Spring. 但是许多团队成员并不了解Spring和Dependency Injectio ...

  6. java jna调用dll文件_关于java jna调用dll的问题

    public interface User32 extends StdCallLibrary { User32 INSTANCE = (User32)Native.loadLibrary(" ...

  7. 计算机中丢失cg,【计算机中丢失dll文件】计算机丢失dll文件_计算机中丢失cg dll-win7之家...

    2017-05-16 00:00:00 浏览量:489 wpcap.dll是一个高层的强大捕获程序库,与Unix下的libpcap兼容.它独立于下层的网络硬件和操作系统文件下载,解决找不到wpcap. ...

  8. stlink 升级固件以后失败_介绍几种ST-Link差异 固件升级的方法和应用

    本文目的在于让更多朋友知道如何选择ST-Link.如何升级和使用. 1写在前面 今天就写点关于ST-LINK的内容,可能很多朋友对ST-Link都不陌生,但是很多人却对一些相关内容不清楚. 本文主要包 ...

  9. SQL Server 装载 msxmlsql.dll 失败的解决办法

    错误信息:装载 msxmlsql.dll 失败(Failed to load Msxmlsql.dll). 环境:ASP.NET2.0  SQL Server 2000(SP4). 出错原因:存储过程 ...

最新文章

  1. python 新运算符定义_【干货系列之萌新知识点】python与变量和运算符
  2. Ecshop购物流程结算步骤 显示商品缩略图
  3. SpringBoot原理
  4. Windows环境下IOCP和SELECT模型性能比较
  5. sitecore系列教程之如何以编程方式将访客数据关联到联系人卡片
  6. 一行代码取出HTML页面某个按钮的css属性,比如margin
  7. jenkins 远程启动tomcat报错:Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
  8. c语言 指针6行7列矩阵的转置,指针第一次练习
  9. 【英语学习】【WOTD】sleuth 释义/词源/示例
  10. android之AlarmManager 全局定时器
  11. 2009年十大Java技术解决方案
  12. 几何平均数和调和平均数是什么?有什么作用?详细资料讨论
  13. taobao.trades.sold.get-查询卖家已卖出的交易数据API接口,店铺交易API接口,店铺订单交易API接口,订单详情API接口,r2接口,淘宝oAuth2.0接口
  14. 2022-2027年中国家用清洁产品行业发展监测及投资战略研究报告
  15. C++ Templates中文版 p61页的一个问题
  16. 跟着项目学设计模式(六):三层架构
  17. mac下hadoop 2.6.0编译native library
  18. sqlplus导数_GitHub - Erik-Yim/blog: Everything about database,bussiness.(Most for PostgreSQL).
  19. 自己动手实现fft.m函数
  20. vue 组件封装 确认弹框带可以自定义titile ,内容,和取消,确定按钮的弹窗 slot插槽

热门文章

  1. 彻底解决python打印结果省略号的问题显示宽度
  2. python中使用指定GPU
  3. LeetCode简单题之设计 Goal 解析器
  4. 王道考研 计算机网络笔记 第一章:概述计算机网络体系结构
  5. 4D毫米波雷达Radar
  6. 队列:实用程序服务和数据结构
  7. 2021年大数据常用语言Scala(二十八):scala面向对象 MAVEN依赖和类
  8. git clean和git reset结合用法
  9. [JS]请给Array本地对象增加一个原型方法,它用于删除数组条目中重复的条目(可能有多个),返回值是一个包含被删除的重复条目的新数组。
  10. Ubuntu 系统通过终端打开AndroidStudio工具