如何在远程线程中创建新的线程
对待这个问题,首先要考虑一个重要因素。即远程线程已经不是原先进程中的线程,由其创建的线程,必然存在于远程线程所在的进程当中。所以应该按照对待创建远程线程这个问题一样处理。也就是说,也要为这个线程在远程进程中开辟一段内存空间。
首先,定义一个结构体,其中包含与远程线程和远程线程要创建的线程的相关项目:
typedef struct _RemoteParam{
FARPROC LoadLibrary;
FARPROC GetProcAddress;
FARPROC CreateThread;
LPVOID Injection;
char lpszLibFileName[16];
char lpszMessageBox[64];
char lpszTextThread1[8];
char lpszTextThread2[8];
}REMOTEPARAM,*PREMOTEPARAM;
而后,将相应API进行映射,写入相应得参数:
REMOTEPARAM RemoteParam;
ZeroMemory(&RemoteParam,sizeof(REMOTEPARAM));
hModule =LoadLibrary("kernel32.dll");
RemoteParam.LoadLibrary
= GetProcAddress(hModule,"LoadLibraryA");
RemoteParam.GetProcAddress
= GetProcAddress(hModule,"GetProcAddress");
RemoteParam.CreateThread
= GetProcAddress(hModule,"CreateThread");
strcpy(RemoteParam.lpszLibFileName,"user32.dll");
strcpy(RemoteParam.lpszMessageBox,"MessageBoxA");
strcpy(RemoteParam.lpszTextThread1,"Test1");
strcpy(RemoteParam.lpszTextThread2,"Test2");
然后,将远程线程要创建之线程的线程函数的地址写入该结构体:
RemoteParam.Injection = (LPVOID)VirtualAllocEx(hProcess,
0,
4*1024,
MEM_COMMIT|MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess,
RemoteParam.Injection,
&Injection,
4*1024,
0);
然后再按照创建远程线程的步骤,创建第一个远程线程:
PREMOTEPARAM pRemoteParam
=
(PREMOTEPARAM)VirtualAllocEx( hProcess,
0,
sizeof(REMOTEPARAM),
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess,
pRemoteParam,
&RemoteParam,
sizeof(REMOTEPARAM),
0)
PVOID pRemoteThread =VirtualAllocEx(hProcess,
0,
(SIZE_T)RemoteThreadProc/1024,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess,
pRemoteThread,
&RemoteThreadProc,
(SIZE_T)RemoteThreadProc/1024,
0)
CreateRemoteThread(hProcess ,
NULL,
0,
(LPTHREAD_START_ROUTINE)pRemoteThread,
pRemoteParam,
0,
&dwThreadID);
在远程线程中则需要进行如下几个步骤,以创建新的线程,其中MessageBox仅仅是起到提示作用并不影响线程创建:
DWORD __stdcall RemoteThreadProc(PREMOTEPARAM lpParam)
{
typedef HMODULE (WINAPI *PLoadLibraryA)(LPCTSTR);
typedef FARPROC
(WINAPI *PGetProcAddress)(HMODULE,LPCSTR);
typedef int (WINAPI *PMessageBoxA)
(HWND hWnd,LPCTSTR,LPCTSTR,UINT);
typedef HANDLE (WINAPI *PCreateThread)
(LPSECURITY_ATTRIBUTES,
SIZE_T,
LPTHREAD_START_ROUTINE,
LPVOID,
DWORD,
LPDWORD);
HMODULE hUser = NULL;
PLoadLibraryA pLoadLibraryA;
PGetProcAddress pGetProcAddress;
PCreateThread pCreateThread;
PMessageBoxA pMessageBoxA;
pLoadLibraryA = (PLoadLibraryA)lpParam->LoadLibrary;
pGetProcAddress = (PGetProcAddress)lpParam->GetProcAddress;
pCreateThread = (PCreateThread)lpParam->CreateThread;
hUser = pLoadLibraryA(lpParam->lpszLibFileName);
pMessageBoxA = (PMessageBoxA)pGetProcAddress(hUser,lpParam->lpszMessageBox);
pMessageBoxA(NULL,
lpParam->lpszTextThread1,
lpParam->lpszTextThread1,
MB_OK);
pCreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)lpParam->Injection,
lpParam,
0,
NULL);
return 0;
}
新的线程函数Injection则可以如此编写:
void Injection(PREMOTEPARAM lpParam)
{
typedef HMODULE (WINAPI *PLoadLibraryA)(LPCTSTR);
typedef FARPROC
(WINAPI *PGetProcAddress)(HMODULE,LPCSTR);
typedef int (WINAPI *PMessageBoxA)
(HWND hWnd,LPCTSTR,LPCTSTR,UINT);
HMODULE hModule = NULL;
PLoadLibraryA pLoadLibraryA;
PGetProcAddress pGetProcAddress;
PMessageBoxA pMessageBoxA;
pLoadLibraryA = (PLoadLibraryA)lpParam->LoadLibrary;
pGetProcAddress = (PGetProcAddress)lpParam->GetProcAddress;
hModule = pLoadLibraryA(lpParam->lpszLibFileName);
pMessageBoxA = (PMessageBoxA)pGetProcAddress(hModule,lpParam->lpszMessageBox);
pMessageBoxA(NULL,
lpParam->lpszTextThread2,
lpParam->lpszTextThread2,
MB_OK);
}
(由于这些片断都是从我的程序摘抄下来并且修改过的,所以没有进过测试)
程序很简单,构思也不是很复杂,希望能跟朋友们一起分享我的这一点点经验。其他API的调用我想,也不外乎是使用类似的方法。本人水平有限,希望广大编程爱好者多加指正!