【发布时间】:2016-03-21 09:22:51
【问题描述】:
我正在尝试在不同的进程中注入代码,目前已经取得了一些成功,我可以在目标进程中注入数据和方法。我可以执行远程线程,并且只有在线程函数没有主体的情况下才会在线程完成后获得返回值。例如,如果我从 ThreadFunc 中省略 MessageBox 行,那么它将起作用,但没有 std::cout/printf/MessageBox 可以存在并且没有 Windows api 调用。所以我要么立即从该函数返回,要么做一些简单的数学运算。
编译代码
#include <windows.h>
#include <tlhelp32.h>
#include <string.h>
#include <iostream>
using namespace std;
#define cbNewProc 1600
typedef struct {
HWND hwnd;
} INJDATA, *PINJDATA;
static const char *err_str(void) {
static char buf[2048];
if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, buf,
sizeof(buf), NULL))
return buf;
return "Unknown error";
}
// entry point in remote process
static LRESULT CALLBACK ThreadFunc(LPVOID param) {
MessageBox(NULL, "I am inside remote process", "Hiiii", 0);
return 1;
}
static int inject_code(DWORD pid) {
cout << "Process found: " << pid << endl;
HANDLE hp = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid);
if (!hp) {
fprintf(stderr, "OpenProcess( %s )\n", err_str());
return 0;
}
int size = sizeof(INJDATA) + cbNewProc;
BYTE* pDataRemote = (BYTE*) VirtualAllocEx(hp, NULL, size,
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!pDataRemote) {
fprintf(stderr, "VirtualAllocEx( %s )\n", err_str());
CloseHandle(hp);
return 0;
}
SIZE_T dwNumBytesXferred;
BYTE* pNewProcRemote = pDataRemote + sizeof(INJDATA);
if (!WriteProcessMemory(hp, pNewProcRemote, (void*) &ThreadFunc,
cbNewProc, &dwNumBytesXferred)) {
fprintf(stderr, "WriteProcessMemory( %s )\n", err_str());
VirtualFreeEx(hp, pDataRemote, size, MEM_RELEASE);
CloseHandle(hp);
return 0;
}
INJDATA DataLocal;
ZeroMemory(&DataLocal, sizeof(INJDATA));
if (!WriteProcessMemory(hp, pDataRemote, &DataLocal, sizeof(INJDATA),
&dwNumBytesXferred)) {
fprintf(stderr, "WriteProcessMemory( %s )\n", err_str());
VirtualFreeEx(hp, pDataRemote, size, MEM_RELEASE);
CloseHandle(hp);
return 0;
}
printf("pDataRemote=%ld\n", pDataRemote);
printf("pNewProcRemote1=%ld\n", pNewProcRemote);
printf("pNewProcRemote2=%ld\n", pNewProcRemote + cbNewProc);
int nSuccess = 0;
DWORD dwThreadId;
HANDLE hThread = CreateRemoteThread(hp, NULL, 0,
(LPTHREAD_START_ROUTINE) pNewProcRemote, pDataRemote, 0,
&dwThreadId);
if (hThread == 0) {
cout << "CreateRemoteThread failed" << endl;
return 0;
}
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, (PDWORD) &nSuccess);
VirtualFreeEx(hp, pDataRemote, size, MEM_RELEASE);
cout << "nSuccess=" << nSuccess << ", size=" << size << endl;
CloseHandle(hp);
return 1;
}
int main() {
cout << "Remote Thread" << endl;
HANDLE h;
PROCESSENTRY32 p;
h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (h == INVALID_HANDLE_VALUE) {
fprintf(stderr, "CreateToolHelp32Snapshot( %s )\n", err_str());
return 0;
}
p.dwSize = sizeof(p);
if (!Process32First(h, &p)) {
fprintf(stderr, "Process32First( %s )\n", err_str());
goto out_close;
}
do {
if (strcasecmp(p.szExeFile, "dllexp.exe"))
continue;
inject_code(p.th32ProcessID);
} while (Process32Next(h, &p));
out_close: CloseHandle(h);
return 0;
}
通常目标进程会因页面错误或无效读取位置错误而崩溃。
【问题讨论】: