本质上和上面的远程线程注入差别不大,差别就是远程线程注入是在进程启动之后在进程体内创建线程,而劫持进程创建注入原理是利用Windows系统中CreateProcess()
这个API创建一个进程,并将第6个参数设为CREATE_SUSPENDED
,创建一个挂起状态的进程,利用这个进程状态进行远程线程注入DLL,然后用ResumeThread()
函数恢复进程,这在一定程度上的检测。
c// Inject.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // # include <iostream> # include <Windows.h> /* lpProcessPath: 进程路径 lpDllPath : 动态链接库路径 */ BOOL Inject(LPCSTR lpProcessPath, LPCWSTR lpDllPath) { //1. 创建一个挂起的线程 STARTUPINFO si; memset(&si, 0, sizeof(STARTUPINFOW)); si.cb = sizeof(STARTUPINFOW); PROCESS_INFORMATION pi; memset(&pi, 0, sizeof(PROCESS_INFORMATION)); BOOL bRet = CreateProcess(lpProcessPath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); if (!bRet) { printf("进程创建失败!\r\n"); return FALSE; } //2. 在目标进程体内申请一段空间,需要可读可写 LPVOID pAddress = VirtualAllocEx(pi.hProcess, NULL, 0x100, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); DWORD dwWriteLength = 0; //3. 将动态链接库的路径,写入目标的体内 WriteProcessMemory(pi.hProcess, pAddress, lpDllPath, ((wcslen(lpDllPath) + 1) * 2), &dwWriteLength); //4. 创建远程线程,并且将LoadLibraryW作为回调函数,并且传入写入目标的参数地址 HANDLE hThread = CreateRemoteThread(pi.hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryW, pAddress, NULL, NULL); //5. 恢复目标进程的主线程 ResumeThread(pi.hThread); //6. 释放空间 VirtualFreeEx(pi.hProcess, pAddress, ((wcslen(lpDllPath) + 1) * 2), MEM_RELEASE); return TRUE; } int main() { Inject("F:\\work\\winmine.exe", L"F:\\work\\MsgBox.dll"); return 0; }
进阶玩法:
注入资源管理器,HOOK CreateProcess
, 然后判断第一个参数lpApplicationName
,判断包不包含我们要找的进程名,不等于NULL的情况下,就可以在HOOK的函数里进行远程线程注入,那么这个时候远程线程注入就是由资源管理器发起的。
本文作者:Na1r
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!