tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

crashinject.cpp (3351B)


      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/. */
      4 
      5 /*
      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.
      9 */
     10 #include <stdio.h>
     11 #include <stdlib.h>
     12 #include <string.h>
     13 #include <windows.h>
     14 
     15 int main(int argc, char** argv) {
     16  if (argc != 2) {
     17    fprintf(stderr, "Usage: crashinject <PID>\n");
     18    return 1;
     19  }
     20 
     21  int pid = atoi(argv[1]);
     22  if (pid <= 0) {
     23    fprintf(stderr, "Usage: crashinject <PID>\n");
     24    return 1;
     25  }
     26 
     27  // find our DLL to inject
     28  wchar_t filename[_MAX_PATH];
     29  if (GetModuleFileNameW(nullptr, filename,
     30                         sizeof(filename) / sizeof(wchar_t)) == 0)
     31    return 1;
     32 
     33  wchar_t* slash = wcsrchr(filename, L'\\');
     34  if (slash == nullptr) return 1;
     35 
     36  slash++;
     37  wcscpy(slash, L"crashinjectdll.dll");
     38 
     39  // now find our target process
     40  HANDLE targetProc =
     41      OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE |
     42                      PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION,
     43                  FALSE, pid);
     44  if (targetProc == nullptr) {
     45    fprintf(stderr, "Error %lu opening target process\n", GetLastError());
     46    return 1;
     47  }
     48 
     49  /*
     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
     52   *
     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.
     58   */
     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);
     66    return 1;
     67  }
     68 
     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);
     74    return 1;
     75  }
     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);
     85    return 1;
     86  }
     87  WaitForSingleObject(hThread, INFINITE);
     88  // Cleanup, not that it's going to matter at this point
     89  CloseHandle(hThread);
     90  VirtualFreeEx(targetProc, pLibRemote, sizeof(filename), MEM_RELEASE);
     91  CloseHandle(targetProc);
     92 
     93  return 0;
     94 }