Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
6.3 KiB

  1. #include <windows.h>
  2. #include "inject.h"
  3. #include "profiler.h"
  4. BOOL g_bIsWin9X = FALSE;
  5. CHAR g_fnFinalizeInjection[MAX_PATH];
  6. HINSTANCE g_hProfileDLL = 0;
  7. HANDLE
  8. InjectDLL(DWORD dwEntryPoint,
  9. HANDLE hProcess,
  10. LPSTR pszDLLName)
  11. {
  12. CHAR szTempPath[MAX_PATH];
  13. HMODULE hKernel32;
  14. BOOL bResult = FALSE;
  15. INJECTIONSTUB injStub;
  16. DWORD dwLoadLibrary;
  17. DWORD dwGetProcAddress;
  18. DWORD dwBytesWritten;
  19. DWORD dwBytesRead;
  20. DWORD dwOldProtect;
  21. DWORD dwOldProtect2;
  22. PBYTE pSharedMem = 0;
  23. HANDLE hFileMap = 0;
  24. hKernel32 = GetModuleHandle("KERNEL32.DLL");
  25. dwLoadLibrary = (DWORD)GetProcAddress(hKernel32,
  26. "LoadLibraryA");
  27. if (0 == dwLoadLibrary) {
  28. bResult = FALSE;
  29. goto handleerror;
  30. }
  31. dwGetProcAddress = (DWORD)GetProcAddress(hKernel32,
  32. "GetProcAddress");
  33. if (0 == dwGetProcAddress) {
  34. bResult = FALSE;
  35. goto handleerror;
  36. }
  37. //
  38. // Initialize the asm for the stub
  39. //
  40. injStub.pCode[0] = 0x90; // int 3 or nop
  41. injStub.pCode[1] = 0x60; // pushad
  42. injStub.pCode[2] = 0x8d; // lea eax, [xxxxxxxx]
  43. injStub.pCode[3] = 0x05;
  44. *(DWORD *)(&(injStub.pCode[4])) = dwEntryPoint + (DWORD)&(injStub.szDLLName) - (DWORD)&injStub;
  45. injStub.pCode[8] = 0x50; // push eax
  46. injStub.pCode[9] = 0xff; // call dword ptr [xxxxxxxx] - LoadLibraryA
  47. injStub.pCode[10] = 0x15;
  48. *(DWORD *)(&(injStub.pCode[11])) = dwEntryPoint + 50;
  49. injStub.pCode[15] = 0x50; // push eax
  50. injStub.pCode[16] = 0x5b; // pop ebx
  51. injStub.pCode[17] = 0x8d; // lea eax, [xxxxxxxx]
  52. injStub.pCode[18] = 0x05;
  53. *(DWORD *)(&(injStub.pCode[19])) = dwEntryPoint + (DWORD)&(injStub.szEntryPoint) - (DWORD)&injStub;
  54. injStub.pCode[23] = 0x50; // push eax // module base
  55. injStub.pCode[24] = 0x53; // push ebx // function name
  56. injStub.pCode[25] = 0xff; // call dword ptr [xxxxxxxx] - GetProcAddress
  57. injStub.pCode[26] = 0x15;
  58. *(DWORD *)(&(injStub.pCode[27])) = dwEntryPoint + 54;
  59. injStub.pCode[31] = 0xff;
  60. injStub.pCode[32] = 0xd0;
  61. *(DWORD *)(&(injStub.pCode[50])) = dwLoadLibrary;
  62. *(DWORD *)(&(injStub.pCode[54])) = dwGetProcAddress;
  63. //
  64. // Create the file mapping object from the paging file
  65. //
  66. hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE,
  67. NULL,
  68. PAGE_READWRITE,
  69. 0,
  70. sizeof(INJECTIONSTUB),
  71. "ProfilerSharedMem");
  72. if (0 == hFileMap) {
  73. bResult = FALSE;
  74. goto handleerror;
  75. }
  76. pSharedMem = (PBYTE)MapViewOfFile(hFileMap,
  77. FILE_MAP_ALL_ACCESS,
  78. 0,
  79. 0,
  80. sizeof(INJECTIONSTUB));
  81. if (0 == pSharedMem) {
  82. bResult = FALSE;
  83. goto handleerror;
  84. }
  85. //
  86. // Initialize injection stub
  87. //
  88. strcpy(injStub.szDLLName, pszDLLName);
  89. strcpy(injStub.szEntryPoint, DEFAULT_ENTRY_POINT);
  90. bResult = ReadProcessMemory(hProcess,
  91. (LPVOID)dwEntryPoint,
  92. (PVOID)pSharedMem,
  93. sizeof(INJECTIONSTUB),
  94. &dwBytesRead);
  95. if (FALSE == bResult) {
  96. bResult = FALSE;
  97. goto handleerror;
  98. }
  99. //
  100. // Write the stub code into the entry point
  101. //
  102. bResult = WriteProcessMemory(hProcess,
  103. (LPVOID)dwEntryPoint,
  104. (PVOID)&injStub,
  105. sizeof(INJECTIONSTUB),
  106. &dwBytesWritten);
  107. if (FALSE == bResult) {
  108. bResult = FALSE;
  109. goto handleerror;
  110. }
  111. handleerror:
  112. return hFileMap;
  113. }
  114. VOID
  115. RestoreImageFromInjection(VOID)
  116. {
  117. PIMAGE_NT_HEADERS pHeaders = 0;
  118. BOOL bResult;
  119. BOOL bError = FALSE;
  120. PVOID pBase = 0;
  121. DWORD dwEntryPoint;
  122. DWORD dwBytesRead;
  123. DWORD dwBytesWritten;
  124. PINJECTIONSTUB pInjStub;
  125. HANDLE hFileMap = 0;
  126. PBYTE pSharedMem = 0;
  127. OSVERSIONINFO verInfo;
  128. //
  129. // Get the entry point from the headers
  130. //
  131. pBase = (PVOID)GetModuleHandle(0);
  132. if (0 == pBase) {
  133. bError = TRUE;
  134. goto handleerror;
  135. }
  136. //
  137. // Dig out the PE information
  138. //
  139. pHeaders = ImageNtHeader2(pBase);
  140. if (0 == pHeaders) {
  141. bError = TRUE;
  142. goto handleerror;
  143. }
  144. dwEntryPoint = pHeaders->OptionalHeader.ImageBase + pHeaders->OptionalHeader.AddressOfEntryPoint;
  145. pInjStub = (PINJECTIONSTUB)dwEntryPoint;
  146. //
  147. // Open the memory mapped file and get the bits
  148. //
  149. hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS,
  150. FALSE,
  151. "ProfilerSharedMem");
  152. if (0 == hFileMap) {
  153. bError = TRUE;
  154. goto handleerror;
  155. }
  156. pSharedMem = (PBYTE)MapViewOfFile(hFileMap,
  157. FILE_MAP_ALL_ACCESS,
  158. 0,
  159. 0,
  160. 0);
  161. if (0 == pSharedMem) {
  162. bError = TRUE;
  163. goto handleerror;
  164. }
  165. //
  166. // Replace the bits
  167. //
  168. bResult = WriteProcessMemory(GetCurrentProcess(),
  169. (PVOID)dwEntryPoint,
  170. (PVOID)pSharedMem,
  171. sizeof(INJECTIONSTUB),
  172. &dwBytesWritten);
  173. if (FALSE == bResult) {
  174. bError = TRUE;
  175. goto handleerror;
  176. }
  177. //
  178. // Set the OS information
  179. //
  180. ZeroMemory(&verInfo, sizeof(OSVERSIONINFO));
  181. verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  182. bResult = GetVersionExA(&verInfo);
  183. if (FALSE == bResult) {
  184. bError = TRUE;
  185. goto handleerror;
  186. }
  187. if (VER_PLATFORM_WIN32_NT == verInfo.dwPlatformId) {
  188. g_bIsWin9X = FALSE;
  189. }
  190. else if (VER_PLATFORM_WIN32_WINDOWS == verInfo.dwPlatformId) {
  191. g_bIsWin9X = TRUE;
  192. }
  193. else {
  194. //
  195. // Unsupported platform
  196. //
  197. ExitProcess(-1);
  198. }
  199. //
  200. // Finish profiler initializations
  201. //
  202. bResult = InitializeProfiler();
  203. if (FALSE == bResult) {
  204. bError = TRUE;
  205. goto handleerror;
  206. }
  207. handleerror:
  208. if (TRUE == bError) {
  209. ExitProcess(-1);
  210. }
  211. return;
  212. }