注入dll.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // RemoteThread.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. // 提升进程特权,否则某些操作会失败
  5. BOOL EnablePrivilege(BOOL enable)
  6. {
  7. // 得到令牌句柄
  8. HANDLE hToken = NULL;
  9. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ, &hToken))
  10. return FALSE;
  11. // 得到特权值
  12. LUID luid;
  13. if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
  14. return FALSE;
  15. // 提升令牌句柄权限
  16. TOKEN_PRIVILEGES tp = {};
  17. tp.PrivilegeCount = 1;
  18. tp.Privileges[0].Luid = luid;
  19. tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
  20. if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
  21. return FALSE;
  22. // 关闭令牌句柄
  23. CloseHandle(hToken);
  24. return TRUE;
  25. }
  26. // 注入DLL,返回模块句柄(64位程序只能返回低32位)
  27. HMODULE InjectDll(HANDLE process, LPCTSTR dllPath)
  28. {
  29. DWORD dllPathSize = ((DWORD)_tcslen(dllPath) + 1) * sizeof(TCHAR);
  30. // 申请内存用来存放DLL路径
  31. void* remoteMemory = VirtualAllocEx(process, NULL, dllPathSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  32. if (remoteMemory == NULL)
  33. {
  34. printf("申请内存失败,错误代码:%u\n", GetLastError());
  35. return 0;
  36. }
  37. // 写入DLL路径
  38. if (!WriteProcessMemory(process, remoteMemory, dllPath, dllPathSize, NULL))
  39. {
  40. printf("写入内存失败,错误代码:%u\n", GetLastError());
  41. return 0;
  42. }
  43. // 创建远线程调用LoadLibrary
  44. HANDLE remoteThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, remoteMemory, 0, NULL);
  45. if (remoteThread == NULL)
  46. {
  47. printf("创建远线程失败,错误代码:%u\n", GetLastError());
  48. return NULL;
  49. }
  50. // 等待远线程结束
  51. WaitForSingleObject(remoteThread, INFINITE);
  52. // 取DLL在目标进程的句柄
  53. DWORD remoteModule;
  54. GetExitCodeThread(remoteThread, &remoteModule);
  55. // 释放
  56. CloseHandle(remoteThread);
  57. VirtualFreeEx(process, remoteMemory, dllPathSize, MEM_DECOMMIT);
  58. return (HMODULE)remoteModule;
  59. }
  60. // 程序运行时注入DLL,返回模块句柄(64位程序只能返回低32位)
  61. HMODULE InjectDll(LPTSTR commandLine, LPCTSTR dllPath, DWORD* pid, HANDLE* process)
  62. {
  63. TCHAR* commandLineCopy = new TCHAR[32768]; // CreateProcess可能修改这个
  64. _tcscpy_s(commandLineCopy, 32768, commandLine);
  65. int cdSize = _tcsrchr(commandLine, _T('\\')) - commandLine + 1;
  66. TCHAR* cd = new TCHAR[cdSize];
  67. _tcsnccpy_s(cd, cdSize, commandLine, cdSize - 1);
  68. // 创建进程并暂停
  69. STARTUPINFO startInfo = {};
  70. PROCESS_INFORMATION processInfo = {};
  71. if (!CreateProcess(NULL, commandLineCopy, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, cd, &startInfo, &processInfo))
  72. {
  73. delete commandLineCopy;
  74. delete cd;
  75. return 0;
  76. }
  77. delete commandLineCopy;
  78. delete cd;
  79. *pid = processInfo.dwProcessId;
  80. *process = processInfo.hProcess;
  81. DWORD dllPathSize = ((DWORD)_tcslen(dllPath) + 1) * sizeof(TCHAR);
  82. // 申请内存用来存放DLL路径
  83. void* remoteMemory = VirtualAllocEx(processInfo.hProcess, NULL, dllPathSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  84. if (remoteMemory == NULL)
  85. {
  86. printf("申请内存失败,错误代码:%u\n", GetLastError());
  87. return 0;
  88. }
  89. // 写入DLL路径
  90. if (!WriteProcessMemory(processInfo.hProcess, remoteMemory, dllPath, dllPathSize, NULL))
  91. {
  92. printf("写入内存失败,错误代码:%u\n", GetLastError());
  93. return 0;
  94. }
  95. // 创建远线程调用LoadLibrary
  96. HANDLE remoteThread = CreateRemoteThread(processInfo.hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, remoteMemory, 0, NULL);
  97. if (remoteThread == NULL)
  98. {
  99. printf("创建远线程失败,错误代码:%u\n", GetLastError());
  100. return NULL;
  101. }
  102. // 等待远线程结束
  103. WaitForSingleObject(remoteThread, INFINITE);
  104. // 取DLL在目标进程的句柄
  105. DWORD remoteModule;
  106. GetExitCodeThread(remoteThread, &remoteModule);
  107. // 恢复线程
  108. ResumeThread(processInfo.hThread);
  109. // 释放
  110. CloseHandle(remoteThread);
  111. VirtualFreeEx(processInfo.hProcess, remoteMemory, dllPathSize, MEM_DECOMMIT);
  112. return (HMODULE)remoteModule;
  113. }
  114. // 卸载DLL
  115. BOOL FreeRemoteDll(HANDLE process, HMODULE remoteModule)
  116. {
  117. // 创建远线程调用FreeLibrary
  118. HANDLE remoteThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, (LPVOID)remoteModule, 0, NULL);
  119. if (remoteThread == NULL)
  120. {
  121. printf("创建远线程失败,错误代码:%u\n", GetLastError());
  122. return FALSE;
  123. }
  124. // 等待远线程结束
  125. WaitForSingleObject(remoteThread, INFINITE);
  126. // 取返回值
  127. DWORD result;
  128. GetExitCodeThread(remoteThread, &result);
  129. // 释放
  130. CloseHandle(remoteThread);
  131. return result != 0;
  132. }
  133. #ifdef _WIN64
  134. #include <tlhelp32.h>
  135. HMODULE GetRemoteModuleHandle(DWORD pid, LPCTSTR moduleName)
  136. {
  137. HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);
  138. MODULEENTRY32 moduleentry;
  139. moduleentry.dwSize = sizeof(moduleentry);
  140. BOOL hasNext = Module32First(snapshot, &moduleentry);
  141. HMODULE handle = NULL;
  142. do
  143. {
  144. if (_tcsicmp(moduleentry.szModule, moduleName) == 0)
  145. {
  146. handle = moduleentry.hModule;
  147. break;
  148. }
  149. hasNext = Module32Next(snapshot, &moduleentry);
  150. } while (hasNext);
  151. CloseHandle(snapshot);
  152. return handle;
  153. }
  154. #endif
  155. int _tmain(int argc, _TCHAR* argv[])
  156. {
  157. // 提升权限
  158. EnablePrivilege(TRUE);
  159. // 打开进程
  160. HWND hwnd = FindWindow(NULL, _T("任务管理器"));
  161. DWORD pid;
  162. GetWindowThreadProcessId(hwnd, &pid);
  163. HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
  164. if (process == NULL)
  165. {
  166. printf("打开进程失败,错误代码:%u\n", GetLastError());
  167. return 1;
  168. }
  169. // 要将RemoteThreadDll.dll放在本程序当前目录下
  170. TCHAR dllPath[MAX_PATH]; // 要用绝对路径
  171. GetCurrentDirectory(_countof(dllPath), dllPath);
  172. _tcscat_s(dllPath, _T("\\RemoteThreadDll.dll"));
  173. // 注入DLL
  174. HMODULE remoteModule = InjectDll(process, dllPath);
  175. //HMODULE remoteModule = InjectDll(_T("C:\\Windows\\System32\\Taskmgr.exe"), dllPath, &pid, &process);
  176. if (remoteModule == NULL)
  177. {
  178. CloseHandle(process);
  179. return 2;
  180. }
  181. #ifdef _WIN64
  182. remoteModule = GetRemoteModuleHandle(pid, _T("RemoteThreadDll.dll"));
  183. printf("模块句柄:0x%08X%08X\n", *((DWORD*)&remoteModule + 1), (DWORD)remoteModule);
  184. #else
  185. printf("模块句柄:0x%08X\n", (DWORD)remoteModule);
  186. #endif
  187. // 暂停
  188. printf("按回车卸载DLL\n");
  189. getchar();
  190. // 卸载DLL
  191. if (!FreeRemoteDll(process, remoteModule))
  192. {
  193. CloseHandle(process);
  194. return 3;
  195. }
  196. // 关闭进程
  197. CloseHandle(process);
  198. return 0;
  199. }