一. 概述挂起进程注入是指在创建进程的时候把运行状态设置为挂起,然后创建一个远程线程,来注入。挂起进程注入作为远线程注入的一个补充,可以在进程创建的时候就注入,从而注入时间较早,不宜被拦截。易知挂起进程注入的局限性也就是如果进程已经启动,那么这种注入方式就不行了。 二. 用到的Windows API函数比远线程注入多了一个调用的API函数,原型如下所示: BOOL WINAPI CreateProcess( _In_opt_ LPCTSTR lpApplicationName,//NULL _Inout_opt_ LPTSTR lpCommandLine,//”calc.exe” _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,//NULL _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,//NULL _In_ BOOL bInheritHandles,//FALSE _In_ DWORD dwCreationFlags,//CREATE_SUSPEND _In_opt_ LPVOID lpEnvironment,//NULL _In_opt_ LPCTSTR lpCurrentDirectory,//NULL _In_ LPSTARTUPINFO lpStartupInfo,//&stStartupInfo _Out_ LPPROCESS_INFORMATION lpProcessInformation//&stProcessInfo ); 在创建目标进程时把dwCreateFlags设置为CREATE_SUSPEND,就可以创建挂起的进程。 接下来,创建远程线程,创建的时候也要设置为挂起状态。最后恢复目标进程执行,调用函数ResumeThread函数,DWORD WINAPI ResumeThread( _In_ HANDLE hThread//要恢复执行的线程句柄 ) 首先恢复目标进程的主线程,然后恢复远程线程。 三.代码实现第一步,创建目标进程,设置为挂起状态;第二步,创建远程线程也设置为挂起状态;第三步,恢复线程执行。详细过程见附件代码所示。关键代码如下所示。 void SuspendProcessInject(char* pTargetProcName, char* pDllName) { STARTUPINFO stStartupInfo = { 0 }; stStartupInfo.cb = sizeof (stStartupInfo); stStartupInfo.dwFlags = STARTF_USESHOWWINDOW; stStartupInfo.wShowWindow = SW_SHOW; PROCESS_INFORMATION stProcessInfo = { 0 }; BYTE* pbyDllNameBuf = NULL; HANDLE hRemoteThread = NULL;
do { BOOL bRet = CreateProcessA(NULL, pTargetProcName, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, (LPSTARTUPINFOA)&stStartupInfo, &stProcessInfo);//第一步创建目标进程 if (!bRet) { printf("[SuspendProcessInject] CreateProcessA fails\n"); }
DWORD dwDllNameStrLen = strlen(pDllName) + 2; pbyDllNameBuf = (BYTE*)VirtualAllocEx(stProcessInfo.hProcess, NULL, dwDllNameStrLen, MEM_COMMIT, PAGE_READWRITE); if (!pbyDllNameBuf) { printf("[SuspendProcessInject]VirtualAllocEx Fails\n"); CloseHandle(stProcessInfo.hProcess); break; }
if (!WriteProcessMemory(stProcessInfo.hProcess, pbyDllNameBuf, pDllName, dwDllNameStrLen, NULL)) { printf("[SuspendProcessInject]WriteProcessMemory Fails\n"); VirtualFreeEx(stProcessInfo.hProcess, (PVOID)pbyDllNameBuf, 0, MEM_RELEASE); break; }
PTHREAD_START_ROUTINE pfnRemoteThreadProc = NULL; pfnRemoteThreadProc = (PTHREAD_START_ROUTINE)GetProcAddress((HMODULE)LoadLibraryA("kernel32.dll"), "LoadLibraryA"); if (!pfnRemoteThreadProc) { printf("[SuspendProcessInject]GetProcAddress Fails\n"); break; }
hRemoteThread = CreateRemoteThread(stProcessInfo.hProcess, NULL, 0, pfnRemoteThreadProc, (PVOID)pbyDllNameBuf, CREATE_SUSPENDED, NULL);//第二步,创建挂起的远程线程 if (!hRemoteThread) { printf("[SuspendProcessInject]CreateRemoteThread Fails\n"); break; }
} while (0);
ResumeThread(stProcessInfo.hThread);//第三步,恢复线程执行 ResumeThread(hRemoteThread);
CloseHandle(hRemoteThread); } |
Demo的运行结果如下图所示。 
四.习题 在Demo的基础上,参试HOOK进程创建函数,向目标进程注入dll。
*转载请注明来自游戏安全实验室(GSLAB.QQ.COM)
|
最新评论
发表评论