launcher.hpp 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #pragma once
  2. namespace nall {
  3. //launch a new process and inject specified DLL into it
  4. auto launch(const char* applicationName, const char* libraryName, uint32 entryPoint) -> bool {
  5. //if a launcher does not send at least one message, a wait cursor will appear
  6. PostThreadMessage(GetCurrentThreadId(), WM_USER, 0, 0);
  7. MSG msg;
  8. GetMessage(&msg, 0, 0, 0);
  9. STARTUPINFOW si;
  10. PROCESS_INFORMATION pi;
  11. memset(&si, 0, sizeof(STARTUPINFOW));
  12. BOOL result = CreateProcessW(
  13. utf16_t(applicationName), GetCommandLineW(), NULL, NULL, TRUE,
  14. DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, //do not break if application creates its own processes
  15. NULL, NULL, &si, &pi
  16. );
  17. if(result == false) return false;
  18. uint8 entryData[1024], entryHook[1024] = {
  19. 0x68, 0x00, 0x00, 0x00, 0x00, //push libraryName
  20. 0xb8, 0x00, 0x00, 0x00, 0x00, //mov eax,LoadLibraryW
  21. 0xff, 0xd0, //call eax
  22. 0xcd, 0x03, //int 3
  23. };
  24. entryHook[1] = (uint8)((entryPoint + 14) >> 0);
  25. entryHook[2] = (uint8)((entryPoint + 14) >> 8);
  26. entryHook[3] = (uint8)((entryPoint + 14) >> 16);
  27. entryHook[4] = (uint8)((entryPoint + 14) >> 24);
  28. auto pLoadLibraryW = (uint32)GetProcAddress(GetModuleHandleW(L"kernel32"), "LoadLibraryW");
  29. entryHook[6] = pLoadLibraryW >> 0;
  30. entryHook[7] = pLoadLibraryW >> 8;
  31. entryHook[8] = pLoadLibraryW >> 16;
  32. entryHook[9] = pLoadLibraryW >> 24;
  33. utf16_t buffer = utf16_t(libraryName);
  34. memcpy(entryHook + 14, buffer, 2 * wcslen(buffer) + 2);
  35. while(true) {
  36. DEBUG_EVENT event;
  37. WaitForDebugEvent(&event, INFINITE);
  38. if(event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break;
  39. if(event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT) {
  40. if(event.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) {
  41. if(event.u.Exception.ExceptionRecord.ExceptionAddress == (void*)(entryPoint + 14 - 1)) {
  42. HANDLE hProcess = OpenProcess(0, FALSE, event.dwProcessId);
  43. HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, event.dwThreadId);
  44. CONTEXT context;
  45. context.ContextFlags = CONTEXT_FULL;
  46. GetThreadContext(hThread, &context);
  47. WriteProcessMemory(pi.hProcess, (void*)entryPoint, (void*)&entryData, sizeof entryData, NULL);
  48. context.Eip = entryPoint;
  49. SetThreadContext(hThread, &context);
  50. CloseHandle(hThread);
  51. CloseHandle(hProcess);
  52. }
  53. ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE);
  54. continue;
  55. }
  56. ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
  57. continue;
  58. }
  59. if(event.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) {
  60. ReadProcessMemory(pi.hProcess, (void*)entryPoint, (void*)&entryData, sizeof entryData, NULL);
  61. WriteProcessMemory(pi.hProcess, (void*)entryPoint, (void*)&entryHook, sizeof entryHook, NULL);
  62. ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE);
  63. continue;
  64. }
  65. ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE);
  66. }
  67. return true;
  68. }
  69. }