#include "StdAfx.h"
#include <windows.h>
#include <tlhelp32.h>
// #pragma comment(lib,"kernel32")
//
// #pragma comment(lib,"user32")
//
// #pragma comment(linker, "/subsystem:windows")
//
// #pragma comment(linker, "/entry:main")
typedef int (WINAPI *PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD);
struct RemoteParam {
DWORD dwMessageBox; // MessageBox 函数的入口地址
CHAR szText[32]; // MessageBox 函数的内容
CHAR szCaption[32]; // MessageBox 函数的标题
};
DWORD GetProcessId(LPCSTR lpszProcessName);
DWORD WINAPI RemoteFunction(LPVOID lParam);
// 获取进程标识符
DWORD GetProcessId(LPCSTR lpszProcessName)
{
// 创建进程快照句柄
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
DWORD dwPid = NULL;
PROCESSENTRY32 ProcessEntry;
// 查找第一个进程
ProcessEntry.dwSize = sizeof(PROCESSENTRY32);
Process32First(hProcessSnap, &ProcessEntry);
// 遍历进程获取 PID
do
{
if(!stricmp(ProcessEntry.szExeFile, lpszProcessName))
{
dwPid = ProcessEntry.th32ProcessID;
break;
}
}
while(Process32Next(hProcessSnap, &ProcessEntry));
// 清理现场
if(!dwPid)
{
return false;
}
CloseHandle(hProcessSnap);
return dwPid;
}
// 程序入口函数
int main()
{
// 线程栈大小
const DWORD dwThreadSize = 4096;
// 获取指定映像的 PID
DWORD dwProcessId = false;
dwProcessId = GetProcessId("calc.exe");
if (!dwProcessId){
MessageBox(NULL, "Get remote process ID failed !", "Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
// 定义远程进程句柄并打开该进程
HANDLE hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (!hRemoteProcess){
MessageBox(NULL, "Open remote process failed !", "Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
// 在宿主进程中为线程体开辟一块存储区域
// 在这里需要注意 MEM_COMMIT | MEM_RESERVE 内存非配类型
// 以及 PAGE_EXECUTE_READWRITE 内存保护类型
// 其具体含义请参考 MSDN 中关于 VirtualAllocEx 函数的说明
LPVOID pRemoteThread = VirtualAllocEx(hRemoteProcess, NULL, dwThreadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!pRemoteThread)
{
MessageBox(NULL, "Alloc memory in remote process failed !", "Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
// 将线程体拷贝到宿主进程
if (!WriteProcessMemory(hRemoteProcess, pRemoteThread, &RemoteFunction, dwThreadSize, 0)){
MessageBox(NULL, "Write data to remote process failed !", "Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
// 定义线程参数结构体变量
RemoteParam RemoteData;
ZeroMemory(&RemoteData, sizeof(RemoteParam));
// 填充结构体变量中的成员
HINSTANCE hUser32 = LoadLibrary("USER32.DLL");
RemoteData.dwMessageBox = (DWORD)GetProcAddress(hUser32, "MessageBoxA");
strcpy(RemoteData.szText, "szText");
strcpy(RemoteData.szCaption, "szCaption");
// 为线程参数在宿主进程中开辟存储区域
RemoteParam* pRemoteParam = (RemoteParam*)VirtualAllocEx(hRemoteProcess , 0, sizeof(RemoteParam), MEM_COMMIT, PAGE_READWRITE);
if (!pRemoteParam) {
MessageBox(NULL, "Alloc memory failed !", "Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
// 将线程参数拷贝到宿主进程地址空间中
if (!WriteProcessMemory(hRemoteProcess, pRemoteParam, &RemoteData, sizeof(RemoteData), 0)) {
MessageBox(NULL, "Write data to target process failed !", "Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
// 在宿主进程中创建线程
HANDLE hRemoteThread = CreateRemoteThread(hRemoteProcess, NULL, 0, (DWORD(WINAPI*)(LPVOID))pRemoteThread, pRemoteParam, 0, NULL);
if (!hRemoteThread)
{
MessageBox(NULL, "Create remote thread failed !", "Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
// 等待线程返回
WaitForSingleObject(hRemoteThread, INFINITE);
// 释放进程空间中的内存
VirtualFreeEx(pRemoteParam, pRemoteParam, 0, MEM_RELEASE);
VirtualFreeEx(hRemoteThread, pRemoteThread, 0, MEM_RELEASE);
// 关闭远程句柄
CloseHandle(hRemoteThread);
CloseHandle(hRemoteProcess);
return 0;
}
// 远程执行函数
DWORD WINAPI RemoteFunction(LPVOID lParam)
{
RemoteParam* PRP = (RemoteParam*)lParam;
PFN_MESSAGEBOX PFN_MessageBox;
PFN_MessageBox = (PFN_MESSAGEBOX)PRP->dwMessageBox;
PFN_MessageBox(NULL, PRP->szText, PRP->szCaption, MB_ICONINFORMATION);
return 0;
}
ooo