blob: b44bfc916406548aac846fdb45782f5008e16380 [file] [log] [blame]
#include <stdint.h>
#include <windows.h>
#include <limits.h>
#include <shellapi.h>
#include "dbg.h"
#include "fsatrace.h"
void injectProcess(HANDLE proc) {
HANDLE tid;
BOOL is32;
FARPROC addr;
LPVOID arg;
char dll[PATH_MAX];
int ndll;
DWORD rc;
static unsigned nesting = 0;
extern IMAGE_DOS_HEADER __ImageBase;
ASSERT(proc);
ASSERT(0 == nesting++);
if (nesting > 1) return;
memset(dll, 0, sizeof(dll));
CHK(ndll = GetModuleFileNameA((HMODULE)&__ImageBase, dll, sizeof(dll)));
// dll is one of mypath\fsatrace.exe, mypath\fsatrace64.dll or mypath\fsatrace32.dll
CHK(IsWow64Process(proc, &is32));
if (strcasecmp(&dll[ndll-4], ".exe") == 0)
ndll -= 4; // .exe
else
ndll -= 6; // 32.dll or 64.dll
memcpy(&dll[ndll], is32 ? "32.dll" : "64.dll", 6);
CHK(0 != (arg = VirtualAllocEx(proc, 0, strlen(dll) + 1,
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)));
if (is32 && !IS32) {
STARTUPINFO si;
PROCESS_INFORMATION pi;
const char * helpername = "fsatracehelper.exe";
char helper[PATH_MAX];
char * p;
si.cb = sizeof(si);
strcpy(helper, dll);
p = strrchr(helper, '\\');
strcpy(p+1, helpername);
CHK(CreateProcessA(0, helper, 0, 0, 0, 0, 0, 0, &si, &pi));
CHK(WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, INFINITE));
CHK(GetExitCodeProcess(pi.hProcess, &rc));
CHK(CloseHandle(pi.hProcess));
CHK(CloseHandle(pi.hThread));
addr = (FARPROC)(uintptr_t)rc;
}
else
addr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
CHK(addr);
CHK(WriteProcessMemory(proc, arg, dll, strlen(dll) + 1, NULL));
CHK(0 != (tid = CreateRemoteThread(proc, 0, 0,
(LPTHREAD_START_ROUTINE)addr, arg, 0, 0)));
CHK(-1 != ResumeThread(tid));
CHK(WAIT_OBJECT_0 == WaitForSingleObject(tid, INFINITE));
CHK(CloseHandle(tid));
CHK(VirtualFreeEx(proc, arg, 0, MEM_RELEASE));
ASSERT(0 == --nesting);
}
void injectPID(DWORD pid) {
HANDLE h;
CHK(0 != (h = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid)));
injectProcess(h);
CHK(CloseHandle(h));
}