通过CreateRemoteThread注入代码的步骤
1.通过FindWindow、GetWindowThreadProcessId、OpenProcess打开目标进程
2.通过VirtualAllocEx函数在目标进程中分配内存
3.使用WriteProcessMemory将代码和变量写入到目标进程
4.使用CreateRemoteThread启动远程线程,运行注入的代码
定义自定义函数
//自定义函数
static DWORD myFuncStart(void *arg){
int aa = 0;
aa = *(int*)arg * 2;
//MessageBox(NULL,NULL,L"",MB_OK);
//printf("a");
return aa;
}
//定义个静态变量,便于计算代码大小
static int ga;
计算代码大小
分配代码内存空间
void *pCodeRemote = VirtualAllocEx( hProcess, 0, dwCodeSize, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE );
注入代码
分配变量内存
void *pDataRemote = VirtualAllocEx( hProcess, 0, sizeof(iArg), MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
写入参数值到目标程序内存
建立远程线程执行代码
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pCodeRemote, pDataRemote, 0 , NULL);

完整代码
#include <iostream>
#include <windows.h>
using namespace std;
static DWORD myFuncStart(void *arg){
int aa = 0;
aa = *(int*)arg * 2;
//MessageBox(NULL,NULL,L"",MB_OK);
//printf("a");
return aa;
}
static int ga;
int main()
{
//获取目标程序窗体句柄 查找”随机数生成器“程序
HWND hwnd = FindWindow(NULL,L"随机数生成器");
//获取目标程序线程pid
DWORD pId;
GetWindowThreadProcessId(hwnd,&pId);
//打开目标进程
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pId);
//函数参数
int iArg = 999;
//在目标程序中分配变量内存
void *pDataRemote = VirtualAllocEx( hProcess, 0, sizeof(iArg), MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
if(GetLastError()){
cout<<"1error!!"<<GetLastError()<<endl;
}
//写入参数值到目标程序的内存
WriteProcessMemory( hProcess, pDataRemote, (void*)&iArg, sizeof(iArg),NULL);
if(GetLastError()){
cout<<"2error!!"<<GetLastError()<<endl;
}
//计算注入的代码大小
DWORD dwCodeSize = (DWORD)&ga - (DWORD)myFuncStart;
cout<<"inject code size:"<<dwCodeSize<<endl;
//分配代码地址空间
void *pCodeRemote = VirtualAllocEx( hProcess, 0, dwCodeSize, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE );
if(GetLastError()){
cout<<"3error!!"<<GetLastError()<<endl;
}
//注入代码
WriteProcessMemory( hProcess, pCodeRemote, (LPCVOID)myFuncStart, dwCodeSize, NULL);
if(GetLastError()){
cout<<"4error!!"<<GetLastError()<<endl;
}
//建立远程线程,执行目标程序注入的代码
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pCodeRemote, pDataRemote, 0 , NULL);
if(GetLastError()){
cout<<"5error!!"<<GetLastError()<<endl;
}
if (hThread)
{
//等待线程执行结束
WaitForSingleObject( hThread, INFINITE );
//获取线程函数返回值
DWORD remoteRet;
GetExitCodeThread( hThread, &remoteRet );
cout<<"函数返回值:"<<remoteRet<<endl;
//关闭线程
CloseHandle( hThread );
//释放目标程序中分配的内存
VirtualFreeEx(hProcess, pDataRemote, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
}
system("pause");
return 0;
}
在自定义函数代码中如果调用printf、MessageBox等函数,会导致宿主程序崩溃,猜测是调用的函数也是代表程序地址,如果是在本地程序编译将这些函数编译进程序并且确定了函数地址,而宿主程序中明显是没有这类函数地址的,因此执行会导致程序崩溃
另外,32位程序不可将代码注入64位程序,会导致CreateRemoteThread函数返回错误5,拒绝访问