进程注入有很多方式,其中有一种利用远程线程技术来实现进程的注入。
这个方式能实现主要是因为
DLL 动态加载的函数原型和线程函数的原型非常相像,所以这两个函数的指针式可以兼容的。
HMODULE LoadLibrary( LPCTSTR lpFileName);
DWORD WINAPI ThreadProc(LPVOID lpParameter);
在 调用 HANDLE CreateRemoteThread( HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); 的时候取巧,将 LoadLibrary 传给参数 pStartAddress ,在将 DLL的路径传给 lpParameter,所以当线程创建的时候自然会调用
LoadLibrary(lpParameter) 了,这样DLL 就被加载到了目标进程中了。然后 在DLLmian中就可以做一些操作了。
使用这种方法的步骤大概包括以下。
-
获取目标进程的句柄 OpenProcess(。。。)
-
给要注入的DLL在目标进程中分配空间 VirtualAllocEx(。。。。)
-
将DLL中的数据写入目标进程的地址空间中WriteProcessMemory(。。。。)
-
获取 LoadLibrary 在 Kernel32中的地址
-
使用 CreateRemoteThread(。。。)在目标进程中创建线程
DLL 测试代码
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
MessageBox(NULL,LPCWSTR("DLLMain"),LPCWSTR("DLLMain"),0);
return TRUE;
}
注入代码
BOOL Inject(LPCTSTR szModule, DWORD dwID)
{
//打开一个已存在的进程对象,并返回进程的句柄。
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwID);
if ( !hProcess ) {
return FALSE;
}
int cByte = (_tcslen(szModule)+1) * sizeof(TCHAR);
//指定进程的虚拟空间保留或提交内存区域,除非指定MEM_RESET参数,否则将该内存区域置0。
LPVOID pAddr = VirtualAllocEx(hProcess, NULL, cByte, MEM_COMMIT, PAGE_READWRITE);
// writes memory in a specified process. The entire area to be written to must be accessible, or the operation fails.
//将DLL中的 数据写入进程空间
if ( !pAddr || !WriteProcessMemory(hProcess, pAddr, szModule, cByte, NULL)) {
return FALSE;
}
//获取LoadLibraryW地址,用于线程入口点
#ifdef _UNICODE
PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryW");
#else
PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryA");
#endif
if ( !pfnStartAddr ) {
return FALSE;
}
DWORD dwThreadID = 0;
//创建线程,开始运行DLL中的代码
HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, pfnStartAddr, pAddr, 0, &dwThreadID);
if ( !hRemoteThread ) {
return FALSE;
}
CloseHandle(hRemoteThread);
CloseHandle(hProcess);
return TRUE;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
LPWSTR dir=new WCHAR[201];
GetCurrentDirectory(200,dir);
LPWSTR dir2= wcscat(dir,(wchar_t *)(_T("//..//Debug//DLLMSGBOX.dll")));
Inject(dir2, 2536);
delete[] dir;
}