CreateRemoteThread - 创建一个运行在其他进程的虚拟内存空间。
需要一个地址,这个地址在其他进程的虚拟地址空间;参数是个指针,也需要在那个进程的虚拟地址空间。
这里包含两个例子:
1 用远程线程在uedit32.exe 中加载一个dll
1.1 LoadLibraryA 在进程中地址一样,所以直接传LoadLibraryA就可以
1.2 在uedit32.exe虚拟内存开辟空间,把路径复制过去即可
2 用远程线程在uedit32.exe 中执行本程序的一个函数
1.1 把 MessageBoxA 复制到开辟的虚拟内存空间
1.2 把要打印字符串复制过去
1.3 把程序(汇编写的)复制到开辟的虚拟内存空间(uedit32.exe)
// remoteThread.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include <TlHelp32.h>
void InjectDll(PROCESSENTRY32 & pe)
{
const char * processName = "uedit32.EXE";
char dllName[256] = {0};
HANDLE hProcess = NULL;
LPVOID remoteAddress = NULL;
DWORD loadLibraryAddr = (DWORD)LoadLibrary;
DWORD dwWrite = 0;
BOOL bFlag = FALSE;
DWORD codeLen = sizeof(dllName);
PVOID codeBuffer = NULL;
HANDLE remoteThread = NULL;
strcpy(dllName,"D:\\ronggf\\develop\\cpp\\remoteThread\\Release\\injectedDll.dll");
do
{
if(stricmp(pe.szExeFile,processName) != 0)
{
break;
}
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
if(hProcess == NULL) { break; }
remoteAddress = VirtualAllocEx(hProcess,NULL,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(remoteAddress == NULL) { break; }
bFlag = WriteProcessMemory(hProcess,(BYTE *)remoteAddress,&dllName,sizeof(dllName),&dwWrite);
LPTHREAD_START_ROUTINE a = (LPTHREAD_START_ROUTINE)(loadLibraryAddr);
remoteThread = CreateRemoteThread(hProcess,NULL,0,a,remoteAddress,0,&dwWrite);
if(remoteThread != NULL) {
WaitForSingleObject(remoteThread,INFINITE);
}
if(loadLibraryAddr != 0)
{
break;
}
}while (FALSE);
if(remoteAddress != NULL)
{
VirtualFreeEx(hProcess,remoteAddress,0,MEM_RELEASE);
}
if(hProcess != NULL)
{
CloseHandle(hProcess);
}
return ;
}
void InjectToProcess(PROCESSENTRY32 & pe)
{
const char * processName = "uedit32.EXE";
char szMessage[40] = {0};
HANDLE hProcess = NULL;
LPVOID remoteAddress = NULL;
DWORD dwMessageBoxA = (DWORD)MessageBoxA;
DWORD dwWrite = 0;
BOOL bFlag = FALSE;
DWORD codeLen = 0;
PVOID codeBuffer = NULL;
HANDLE remoteThread = NULL;
strcpy(szMessage,"message from remote thread!");
do
{
if(stricmp(pe.szExeFile,processName) != 0)
{
break;
}
//
//
//
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
if(hProcess == NULL) { break; }
remoteAddress = VirtualAllocEx(hProcess,NULL,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(remoteAddress == NULL) { break; }
//
// 获取代码的地址和长度
//
_asm
{
LEA EAX,_End
PUSH EAX
POP codeBuffer
SUB EAX,OFFSET _Begin
MOV codeLen,EAX
MOV EAX,_Begin
MOV codeBuffer,EAX
}
bFlag = WriteProcessMemory(hProcess,remoteAddress,&dwMessageBoxA,4,&dwWrite);
bFlag = WriteProcessMemory(hProcess,(BYTE *)remoteAddress + 4,&szMessage,40,&dwWrite);
bFlag = WriteProcessMemory(hProcess,(BYTE *)remoteAddress + 44,codeBuffer,codeLen,&dwWrite);
LPTHREAD_START_ROUTINE a = (LPTHREAD_START_ROUTINE)((BYTE *)remoteAddress + 44);
remoteThread = CreateRemoteThread(hProcess,NULL,0,a,remoteAddress,0,&dwWrite);
if(remoteThread != NULL) {
WaitForSingleObject(remoteThread,INFINITE);
}
if(dwMessageBoxA != 0)
{
break;
}
}while (FALSE);
if(remoteAddress != NULL)
{
VirtualFreeEx(hProcess,remoteAddress,0,MEM_RELEASE);
}
if(hProcess != NULL)
{
CloseHandle(hProcess);
}
return ;
__asm {
_Begin:
//
// 参数 [ebp+0x8]
// myParam 0-4 是messageBox
// myParam+4 L40h 是打印的消息
// myParam+4+40h 是执行的程序二进制代码
//
push ebp
mov ebp,esp
push ecx
mov eax,[ebp+0x08]
mov edx,[eax]
lea ecx,[eax+4]
push 0
push 0
push ecx
push 0
call edx
pop ecx
pop ebp
ret
_End:
}
}
int _tmain(int argc, _TCHAR* argv[])
{
PROCESSENTRY32 pe;
pe.th32ProcessID = 7760;
strcpy(pe.szExeFile,"uedit32.exe");
InjectDll(pe);
InjectToProcess(pe);
return 0;
}