fork(5) download
  1. #pragma comment(lib, "Kernel32.lib")
  2.  
  3. #define USAGE \
  4.   "本ツールは実行中のプロセスにDLLを注入(ロード)します。\n" \
  5. "使い方: dllinj EXEファイル名 DLLファイル名\n" \
  6. "\tEXEファイル名: 注入先となるプロセスのEXEファイル名\n" \
  7. "\tDLLファイル名: 注入するDLLファイル名\n" \
  8. "※同じEXEファイル名のプロセスが複数ある場合には、\n" \
  9. " 最初に見つけたものに注入します。\n"
  10.  
  11. #include <windows.h>
  12. #include <tlhelp32.h>
  13.  
  14. #include <cstdio>
  15. #include <memory>
  16. #include <string>
  17.  
  18. using namespace std;
  19.  
  20. class Handle {
  21. public:
  22. Handle(HANDLE value);
  23. virtual ~Handle();
  24. virtual operator bool() const;
  25. virtual void close();
  26. HANDLE get();
  27. protected:
  28. HANDLE value;
  29. };
  30.  
  31. class VirtualMemory {
  32. public:
  33. static VirtualMemory* allocate(const HANDLE& processHandle, const DWORD& size);
  34. virtual ~VirtualMemory();
  35. LPVOID getAddress();
  36. protected:
  37. VirtualMemory(const HANDLE& processHandle, LPVOID address);
  38. LPVOID address;
  39. HANDLE processHandle;
  40. };
  41.  
  42. int main(int argc, char** argv) {
  43. if (argc != 3) {
  44. fprintf(stderr, USAGE);
  45. return 1;
  46. }
  47. string exeName = string(argv[1]);
  48. string dllName = string(argv[2]);
  49. Handle processSnapHandle(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
  50. if (!processSnapHandle) {
  51. fprintf(stderr, "エラー: 予期せぬエラーが発生しました。(%s:%d)\n", "CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS)", GetLastError());
  52. return 1;
  53. }
  54. PROCESSENTRY32 pe32;
  55. pe32.dwSize = sizeof(PROCESSENTRY32);
  56. if (!Process32First(processSnapHandle.get(), &pe32)) {
  57. fprintf(stderr, "エラー: 予期せぬエラーが発生しました。(%s:%d)\n", "Process32First", GetLastError());
  58. return 1;
  59. }
  60. for (;;) {
  61. if (string(pe32.szExeFile) == exeName) {
  62. break;
  63. }
  64. if (!Process32Next(processSnapHandle.get(), &pe32)) {
  65. fprintf(stderr, "エラー: プロセスが見つかりませんでした。(%s)\n", exeName.c_str());
  66. return 1;
  67. }
  68. }
  69. Handle processHandle(OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID));
  70. if (!processHandle) {
  71. fprintf(stderr, "エラー: 予期せぬエラーが発生しました。(%s:%d)\n", "OpenProcess", GetLastError());
  72. return 1;
  73. }
  74. char dllFullPath[MAX_PATH];
  75. DWORD dllFullPathLength = GetFullPathName(dllName.c_str(), MAX_PATH, dllFullPath, nullptr);
  76. if (dllFullPathLength == 0) {
  77. fprintf(stderr, "エラー: DLLファイルが見つかりませんでした。(%s)\n", dllName.c_str());
  78. return 1;
  79. }
  80. shared_ptr<VirtualMemory> dllNameMemory(VirtualMemory::allocate(processHandle.get(), dllName.length() + 1));
  81. if (!dllNameMemory.get()) {
  82. return 1;
  83. }
  84. SIZE_T written;
  85. if (!WriteProcessMemory(processHandle.get(), dllNameMemory->getAddress(), dllFullPath, dllFullPathLength + 1, &written)) {
  86. fprintf(stderr, "エラー: 予期せぬエラーが発生しました。(%s:%d)\n", "WriteProcessMemory", GetLastError());
  87. return 1;
  88. }
  89. LPTHREAD_START_ROUTINE procAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32.dll"), "LoadLibraryA");
  90. Handle threadHandle(CreateRemoteThread(processHandle.get(), nullptr, 0, procAddress, dllNameMemory->getAddress(), 0, nullptr));
  91. if (!threadHandle) {
  92. fprintf(stderr, "エラー: 予期せぬエラーが発生しました。(%s:%d)\n", "CreateRemoteThread", GetLastError());
  93. return 1;
  94. }
  95. if (WaitForSingleObject(threadHandle.get(), INFINITE) != WAIT_OBJECT_0) {
  96. fprintf(stderr, "エラー: 予期せぬエラーが発生しました。(%s:%d)\n", "WaitForSingleObject", GetLastError());
  97. return 1;
  98. }
  99. HMODULE module;
  100. if (!GetExitCodeThread(threadHandle.get(), (DWORD*)&module)) {
  101. fprintf(stderr, "エラー: 予期せぬエラーが発生しました。(%s:%d)\n", "GetExitCodeThread", GetLastError());
  102. return 1;
  103. }
  104. if (module == nullptr) {
  105. fprintf(stderr, "エラー: 予期せぬエラーが発生しました。(%s)\n", "LoadLibraryA");
  106. return 1;
  107. }
  108. printf("注入しました。(0x%08X)\n", module);
  109. return 0;
  110. }
  111.  
  112. Handle::Handle(HANDLE value) : value(value) {}
  113.  
  114. Handle::~Handle() {
  115. close();
  116. }
  117.  
  118. Handle::operator bool() const {
  119. return value != nullptr && value != INVALID_HANDLE_VALUE;
  120. }
  121.  
  122. void Handle::close() {
  123. if (operator bool()) {
  124. CloseHandle(value);
  125. value = nullptr;
  126. }
  127. }
  128.  
  129. HANDLE Handle::get() {
  130. return value;
  131. }
  132.  
  133. VirtualMemory* VirtualMemory::allocate(const HANDLE& processHandle, const DWORD& size) {
  134. LPVOID address = VirtualAllocEx(processHandle, nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  135. if (address == nullptr) {
  136. fprintf(stderr, "エラー: 予期せぬエラーが発生しました。(%s)\n", "VirtualAllocEx");
  137. return nullptr;
  138. }
  139. return new VirtualMemory(processHandle, address);
  140. }
  141.  
  142. VirtualMemory::~VirtualMemory() {
  143. VirtualFreeEx(processHandle, address, 0, MEM_RELEASE);
  144. }
  145.  
  146. LPVOID VirtualMemory::getAddress() {
  147. return address;
  148. }
  149.  
  150. VirtualMemory::VirtualMemory(const HANDLE& processHandle, LPVOID address) :
  151. processHandle(processHandle), address(address) {}
  152.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty