1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 * Given a PID, this program attempts to inject a DLL into the process
7 * with that PID. The DLL it attempts to inject, "crashinjectdll.dll",
8 * must exist alongside this exe. The DLL will then crash the process.
15 int main(int argc
, char** argv
) {
17 fprintf(stderr
, "Usage: crashinject <PID>\n");
21 int pid
= atoi(argv
[1]);
23 fprintf(stderr
, "Usage: crashinject <PID>\n");
27 // find our DLL to inject
28 wchar_t filename
[_MAX_PATH
];
29 if (GetModuleFileNameW(nullptr, filename
,
30 sizeof(filename
) / sizeof(wchar_t)) == 0)
33 wchar_t* slash
= wcsrchr(filename
, L
'\\');
34 if (slash
== nullptr) return 1;
37 wcscpy(slash
, L
"crashinjectdll.dll");
39 // now find our target process
41 OpenProcess(PROCESS_VM_OPERATION
| PROCESS_VM_WRITE
|
42 PROCESS_CREATE_THREAD
| PROCESS_QUERY_INFORMATION
,
44 if (targetProc
== nullptr) {
45 fprintf(stderr
, "Error %lu opening target process\n", GetLastError());
50 * This is sort of insane, but we're implementing a technique described here:
51 * http://www.codeproject.com/KB/threads/winspy.aspx#section_2
53 * The gist is to use CreateRemoteThread to create a thread in the other
54 * process, but cheat and make the thread function kernel32!LoadLibrary,
55 * so that the only remote data we have to pass to the other process
56 * is the path to the library we want to load. The library we're loading
57 * will then do its dirty work inside the other process.
59 HMODULE hKernel32
= GetModuleHandleW(L
"Kernel32");
60 // allocate some memory to hold the path in the remote process
61 void* pLibRemote
= VirtualAllocEx(targetProc
, nullptr, sizeof(filename
),
62 MEM_COMMIT
, PAGE_READWRITE
);
63 if (pLibRemote
== nullptr) {
64 fprintf(stderr
, "Error %lu in VirtualAllocEx\n", GetLastError());
65 CloseHandle(targetProc
);
69 if (!WriteProcessMemory(targetProc
, pLibRemote
, (void*)filename
,
70 sizeof(filename
), nullptr)) {
71 fprintf(stderr
, "Error %lu in WriteProcessMemory\n", GetLastError());
72 VirtualFreeEx(targetProc
, pLibRemote
, sizeof(filename
), MEM_RELEASE
);
73 CloseHandle(targetProc
);
76 // Now create a thread in the target process that will load our DLL
77 HANDLE hThread
= CreateRemoteThread(
78 targetProc
, nullptr, 0,
79 (LPTHREAD_START_ROUTINE
)GetProcAddress(hKernel32
, "LoadLibraryW"),
80 pLibRemote
, 0, nullptr);
81 if (hThread
== nullptr) {
82 fprintf(stderr
, "Error %lu in CreateRemoteThread\n", GetLastError());
83 VirtualFreeEx(targetProc
, pLibRemote
, sizeof(filename
), MEM_RELEASE
);
84 CloseHandle(targetProc
);
87 WaitForSingleObject(hThread
, INFINITE
);
88 // Cleanup, not that it's going to matter at this point
90 VirtualFreeEx(targetProc
, pLibRemote
, sizeof(filename
), MEM_RELEASE
);
91 CloseHandle(targetProc
);