hlsdk

VAC key dumper, codecave style

Jul 25th, 2010
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.76 KB | None | 0 0
  1. /*
  2. ** Simple utility to dump VAC encryption keys
  3. ** (c) 2010 TEAM METALSLAVE RAGE CO. All Rights Reserved.
  4. **
  5. ** HOW TO USE
  6. ** 1. Inject into Steam.exe
  7. ** 2. Start game
  8. ** 3. Join secure server
  9. ** 4. Wait for keys to dump; there are 14 in total
  10. **
  11. ** WARNING
  12. ** Some obfuscation is included but this code is mostly out in the open.
  13. ** This is likely to translate into bans. Use at your own risk.
  14. */
  15.  
  16. #include <stdio.h>
  17. #include <conio.h>
  18. #include <Windows.h>
  19. #include <Tlhelp32.h>
  20.  
  21. #define SCAN_TABLE_BASE 0x7275
  22.  
  23. HANDLE hCurProc = NULL;
  24. BOOL bIsJumpTableHooked = FALSE;
  25. UINT8* bIsScanRunning = NULL;
  26. UINT32* pJumpTablePtr = NULL;
  27. UINT32 origJumpTable[14];
  28. UINT8 haveKeys[14];
  29.  
  30.  
  31. void Unhook();
  32.  
  33. void SetRunningThreadsStatus(int shouldSuspend) {
  34. HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
  35.  
  36. THREADENTRY32 te;
  37.  
  38. te.dwSize = sizeof(THREADENTRY32);
  39.  
  40. BOOL hasEntry = Thread32First( snapshot, &te );
  41. while ( hasEntry ) {
  42. if (te.th32OwnerProcessID == GetCurrentProcessId()
  43. &&
  44. te.th32ThreadID != GetCurrentThreadId()
  45. ) {
  46. HANDLE hThread = OpenThread( THREAD_ALL_ACCESS, FALSE, te.th32ThreadID );
  47.  
  48. if (hThread) {
  49. if (shouldSuspend) SuspendThread(hThread);
  50. else ResumeThread (hThread);
  51. } else cprintf("WARNING: Can't suspend thread %d\n", te.th32ThreadID);
  52. }
  53. hasEntry = Thread32Next( snapshot, &te );
  54. }
  55. }
  56.  
  57. const char* strfmt = "Got Key %p%p for Fcn %d\n";
  58.  
  59.  
  60. void __declspec(naked) MarkFunctionRead() {
  61. __asm {
  62. mov haveKeys[eax], 1h
  63. retn
  64. };
  65. }
  66.  
  67. //
  68. // HookCallEncryption: Code cave for the function jumptable.
  69. // This will print out keys as we get them, then unhook from
  70. // VAC so scans can run.
  71. //
  72.  
  73. void __stdcall HookMsgHandler( UINT32 fcnId, UINT32* keys ) {
  74.  
  75. cprintf("Key dumped for FCN #%d: 0x%p%p\n", fcnId, keys[1], keys[0]);
  76. Unhook();
  77. }
  78.  
  79. void __declspec(naked) HookCallEncryption() {
  80. UINT32 fcn_number;
  81.  
  82. __asm {
  83. pushad
  84.  
  85. push [ebp + 0xC]
  86. push eax
  87. call HookMsgHandler
  88.  
  89. popad
  90. jmp origJumpTable[eax * 4]
  91. };
  92. }
  93.  
  94. void Hook() {
  95. // Freeze other threads
  96. SetRunningThreadsStatus(1);
  97.  
  98. MEMORY_BASIC_INFORMATION buf;
  99.  
  100. VirtualQueryEx( hCurProc, (LPCVOID)pJumpTablePtr, &buf, sizeof(MEMORY_BASIC_INFORMATION));
  101.  
  102. DWORD oldProtect;
  103.  
  104.  
  105.  
  106. if (
  107. VirtualProtectEx( hCurProc,(LPVOID)buf.BaseAddress, buf.RegionSize, PAGE_EXECUTE_READWRITE, &oldProtect )
  108. == FALSE ) {
  109. cprintf("FATAL ERROR: Jumptable hook failed.\nBaseAddress %p, RegionSize %p, LastError = %d\n", buf.BaseAddress, buf.RegionSize, GetLastError());
  110. cprintf("Program locked. Hit Ctrl+C to exit.\n");
  111. while(1) Sleep(1);
  112. }
  113.  
  114. // Copy over the pointer to our code cave, while saving the original pointers
  115.  
  116. if ( bIsJumpTableHooked == FALSE ) {
  117.  
  118. for (int i = 0; i < 14; i++) {
  119. origJumpTable[i] = pJumpTablePtr[i];
  120. pJumpTablePtr[i] = (UINT32) HookCallEncryption;
  121. }
  122.  
  123. bIsJumpTableHooked = TRUE;
  124.  
  125. } else
  126. cprintf("WARNING! Jump table was already hooked!\n");
  127.  
  128.  
  129. // Restore original protection
  130. VirtualProtectEx( hCurProc, (LPVOID)buf.BaseAddress, buf.RegionSize, PAGE_EXECUTE_READ, &oldProtect );
  131.  
  132. // Unfreeze threads
  133. SetRunningThreadsStatus(0);
  134. }
  135.  
  136.  
  137. void Unhook() {
  138. // Freeze other threads
  139. SetRunningThreadsStatus(1);
  140.  
  141. DWORD oldProtect;
  142. MEMORY_BASIC_INFORMATION buf;
  143. VirtualQueryEx( hCurProc, (LPCVOID)pJumpTablePtr, &buf, sizeof(MEMORY_BASIC_INFORMATION));
  144.  
  145. if (
  146. VirtualProtectEx( hCurProc,(LPVOID)buf.BaseAddress, buf.RegionSize, PAGE_EXECUTE_READWRITE, &oldProtect )
  147. == FALSE ) {
  148. cprintf("FATAL ERROR: Jumptable hook failed.\nBaseAddress %p, RegionSize %p, LastError = %d\n", buf.BaseAddress, buf.RegionSize, GetLastError());
  149. cprintf("Program locked. Hit Ctrl+C to exit.\n");
  150. while(1) Sleep(1);
  151. }
  152.  
  153. // Restore the original values
  154. if (bIsJumpTableHooked == TRUE) {
  155. for (int i = 0; i < 14; i++) {
  156. pJumpTablePtr[i] = origJumpTable[i];
  157. }
  158. bIsJumpTableHooked = FALSE;
  159. } else
  160. cprintf("WARNING! Jump table was already unhooked!\n");
  161.  
  162. // Restore original protection
  163. VirtualProtectEx( hCurProc, (LPVOID)buf.BaseAddress, buf.RegionSize, PAGE_EXECUTE_READ, &oldProtect );
  164.  
  165. // Unfreeze threads
  166. SetRunningThreadsStatus(0);
  167. }
  168.  
  169.  
  170. void ExecutionThread() {
  171.  
  172. AllocConsole();
  173. cprintf("Grabbing VAC pointers...\n");
  174.  
  175. MODULEENTRY32 module;
  176. HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
  177. if (!snapshot) {
  178. cprintf("Snapshot couldn't be taken.\n");
  179. return;
  180. }
  181.  
  182. module.dwSize = sizeof( MODULEENTRY32 );
  183.  
  184. // Grab the first module
  185. BOOL moduleFound = Module32First( snapshot, &module );
  186.  
  187. while ( moduleFound ) {
  188. if ( strstr(module.szModule, ".tmp") ) {
  189. cprintf("VAC found in module list as %s\n", module.szModule);
  190.  
  191. // Initialize pointers
  192. bIsScanRunning = (UINT8*)module.hModule + 0x2D1AD;
  193. pJumpTablePtr = (UINT32*)((UINT8*)module.hModule + 0x7275);
  194. }
  195.  
  196. moduleFound = Module32Next( snapshot, &module );
  197. }
  198.  
  199. hCurProc = OpenProcess( PROCESS_ALL_ACCESS | PROCESS_VM_OPERATION, FALSE, GetCurrentProcessId() );
  200.  
  201. cprintf("bIsScanRunning %p\n", bIsScanRunning);
  202. cprintf("pJumpTablePtr %p\n", pJumpTablePtr );
  203.  
  204. // Run this loop for the rest of the time
  205. while ( 1 ) {
  206. if ( *bIsScanRunning == 0 && !bIsJumpTableHooked ) {
  207. Hook();
  208. } else {
  209. // If the scan's running it likely means we've intercepted it already
  210. }
  211.  
  212.  
  213. // Output a message around every 10 seconds
  214.  
  215. Sleep(1);
  216. }
  217. }
  218.  
  219. BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) {
  220.  
  221. if ( fdwReason == DLL_PROCESS_ATTACH )
  222. CreateThread(NULL, 1000000, (LPTHREAD_START_ROUTINE)ExecutionThread,NULL,NULL,NULL);
  223.  
  224. return TRUE;
  225.  
  226. }
Add Comment
Please, Sign In to add comment