mfc HackerTools远程线程注入
在一个进程中,调用CreateThread或CreateRemoteThreadEx函数,在另一个进程内创建一个线程(因为不在同一个进程中,所以叫做远程线程)。创建的线程一般为Windows API函数LoadLibrary,来加载一个动态链接库(DLL),从而达到在另一个进程中运行自己所希望运行的代码的目的。
步骤:
- 打开目标进程
- 在目标进程中申请空间
- 将要注入的Dll路径写入刚申请的空间中
- 获取LoadLibrary函数地址
- 在目标进程中创建线程,线程回调函数就是LoadLibrary函数,回调函数参数就是要注入的Dll路径
- 等待线程结束
- 清理环境
BOOL CInject::ZwCreateThreadExInjectDll(DWORD dwProcessId, char* pszDllFileName) { HANDLE hProcess = NULL; SIZE_T dwSize = 0; LPVOID pDllAddr = NULL; FARPROC pFunProcAddr = NULL; HANDLE hRemoteThread = NULL; DWORD dwStatus = 0; //打开目标进程 获取句柄 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); if (hProcess==NULL) { m_TipMsg += L"打开进程失败\r\n"; return FALSE; } else { m_TipMsg += L"打开进程成功\r\n"; } //在注入的进程中申请内存 dwSize = strlen(pszDllFileName) + 1; pDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); if (pDllAddr==NULL) { m_TipMsg += L"申请内存失败\r\n"; return FALSE; } else { m_TipMsg += L"申请内存成功\r\n"; } //向申请的内存中写入数据 BOOL bIsSucess = WriteProcessMemory(hProcess, pDllAddr, pszDllFileName, dwSize, NULL); if (bIsSucess==FALSE) { m_TipMsg += L"写入内存失败\r\n"; return FALSE; } else { m_TipMsg += L"写入内存成功\r\n"; } //加载ntdll.dll HMODULE hNtdll = LoadLibraryA("ntdll.dll"); if (hNtdll==NULL) { m_TipMsg += L"加载ntdll失败\r\n"; return FALSE; } else { m_TipMsg += L"加载ntdll成功\r\n"; } //获取LoadLibraryA函数地址 pFunProcAddr = GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryA"); if (pFunProcAddr==NULL) { m_TipMsg += L"加载LoadLibraryA函数地址失败\r\n"; return FALSE; } else { m_TipMsg += L"加载LoadLibraryA函数地址成功\r\n"; } //获取ZwCreateThread函数地址 ZwCreateThread在64位和32位下的函数声明不一样 #ifdef _WIN64 typedef DWORD(WINAPI *typedef_ZwCreateThreadEx)( PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, LPVOID ObjectAttributes, HANDLE ProcessHandle, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, ULONG CreateThreadFlags, SIZE_T ZeroBits, SIZE_T StackSize, SIZE_T MaximumStackSize, LPVOID pUnkown); #else typedef DWORD(WINAPI *typedef_ZwCreateThreadEx)( PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, LPVOID ObjectAttributes, HANDLE ProcessHandle, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, BOOL CreateSuspended, DWORD dwStackSize, DWORD dw1, DWORD dw2, LPVOID pUnkown); #endif typedef_ZwCreateThreadEx ZwCreateThreadEx = (typedef_ZwCreateThreadEx)GetProcAddress(hNtdll, "ZwCreateThreadEx"); if (ZwCreateThreadEx==NULL) { m_TipMsg += L"加载ZwCreateThreadEx函数地址失败\r\n"; return FALSE; } else { m_TipMsg += L"加载ZwCreateThreadEx函数地址成功\r\n"; } //使用ZwCreateThreadEx函数创建远程线程 实现DLL注入 dwStatus = ZwCreateThreadEx(&hRemoteThread, THREAD_ALL_ACCESS, NULL, hProcess, (LPTHREAD_START_ROUTINE)pFunProcAddr, pDllAddr, 0, 0, 0, 0, NULL); if (hRemoteThread==NULL) { m_TipMsg += L"远程线程注入失败\r\n"; return FALSE; } else { m_TipMsg += L"远程线程注入成功\r\n"; } //关闭句柄 CloseHandle(hProcess); FreeLibrary(hNtdll); return TRUE; }
// dllmain.cpp : 定义 DLL 应用程序的入口点。 #include "header.h" BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: MessageBoxA(0,"注入成功","恭喜",0); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; } return TRUE; }