Don't like ads? PRO users don't see any ads ;-)
0
Guest

VAC decryptans!

By: hlsdk on Jul 16th, 2010  |  syntax: None  |  size: 3.38 KB  |  hits: 31  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /*
  2. ** VAC decrypter
  3. **
  4. ** Special thanks to wav for some infos.
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <windows.h>
  9. #include <conio.h>
  10. #include <Tlhelp32.h>
  11. #include "Detours.h"
  12.  
  13.  
  14. // Pointer to the decryption function, as of July 16th 2010.
  15. UINT32 decryptCall = 0x27EE;
  16.  
  17. // Offsets to encrypted code blocks. We loop through these in main().
  18. UINT32 encryptedCodeBlocks[14] = {
  19.                 0x29CE, 0x35A4, 0x7018, 0x14C7,
  20.                 0x1E4F, 0x218F, 0x7331,
  21.  
  22.  
  23.  
  24. };
  25.  
  26.  
  27. // A struct for vac_encrypted_func.
  28. typedef struct {
  29.                 UINT8    fcn_number; // Number of the encrypted block (unused?)
  30.                 UINT32   fcn_size;   // Size of the block
  31.                 UINT32   fcn_passes; // Passes during decryption (thanks, wav)
  32.                 UINT32   fcn_crc32;  // CRC32 of the function
  33. } vac_encrypted_func;
  34.  
  35.  
  36. /*
  37. ** Here is the VAC decryption function.
  38. ** The encryption key is 32 bit and can be brute-forced within a day.
  39. **
  40. ** The arguments somePointer and something in the function don't seem to be used by anything during
  41. ** decryption. These arguments seem to be left over from older versions.
  42. **
  43. ** somePointer - random block of memory
  44. ** something   - Always 0x2000, maximum size of encrypted code block.
  45. **               This value is checked in the comparison anyways.
  46. **
  47. ** Likely prototype is:
  48. ** BOOL __cdecl VacDecryptCode( vac_encrypted_func* dwFunction, UINT32* key, UINT8* c, UINT32 d);
  49. */
  50.  
  51. BOOL (__cdecl *VacDecryptCode)(UINT8* dwDestAddress, UINT32* key, UINT8* somePointer, UINT32 something);
  52.  
  53.  
  54. // The decryption key. To get this, hook VacDecryptCode and log the second argument.
  55. UINT32 key[5];
  56.  
  57. // Something to satisfy the third argument to the function with. I have no idea what this is.
  58. UINT32 more_buffer[0x10000];
  59.  
  60. // The last CRC32 hash calculated. This is done within the decryption routine,
  61. // so we detour at the end of the function and grab the checksum there.
  62. UINT32 last_crc = 0;
  63.  
  64.  
  65. // A jump inserted at the end of the CRC32 routine lands us here
  66. // We monitor CRC32's coming off of CRC32_ProcessBuffer
  67. void __declspec(naked) Crc32Hook() {
  68.                 __asm {
  69.                         pop esi
  70.                         mov last_crc, eax
  71.                         mov [edi], eax
  72.                         pop ebx
  73.                         retn
  74.                 }
  75. }
  76.  
  77.  
  78. int main( int argc, char** argv ) {
  79.  
  80.                 HMODULE hVac = LoadLibraryA("SourceInit.dat");
  81.  
  82.                 if (!hVac) {
  83.                                 printf("Can't load VAC client\n");
  84.                                 return 1;
  85.                 }
  86.  
  87.                 UINT8* callPtr = (UINT8*)hVac + 0x27ee;
  88.                 UINT8* decode_addr = (UINT8*)hVac + 0x35a4;
  89.  
  90.                 printf("hVac %p, Callptr %p\n", hVac, callPtr);
  91.                 printf("decoding at %p\n", decode_addr);
  92.  
  93.                 VacDecryptCode = (BOOL (__cdecl *)(UINT8 *,UINT32 *,UINT8 *,UINT32))callPtr;
  94.  
  95.                 UINT8* patchPtr = (UINT8*)hVac + 0x10e67;
  96.                 void (*origCrc32)() = (void(*)())patchPtr;
  97.  
  98.                 // hookens
  99.  
  100.                 DetourTransactionBegin();
  101.                 DetourUpdateThread( GetCurrentThread() );
  102.  
  103.                 DetourAttach( (PVOID*)&origCrc32, Crc32Hook);
  104.                 DetourTransactionCommit();
  105.                
  106.  
  107.                 printf("Decrypting...\n");
  108.  
  109.                 more_buffer[0] = 325235235;
  110.  
  111.  
  112.                 key[0] = 0x61DFBEEA;
  113.                 key[1] = 0x1177B262;
  114.                 //key[2] = 0x78434FDA;
  115.                 //key[3] = 0x5A3957F4;
  116.  
  117.                 printf("Key is %p%p\n", key[1], key[0]);
  118.  
  119.                 // This is pretty much what the real VAC does.
  120.                 BOOL result = VacDecryptCode( decode_addr, key, (UINT8*)more_buffer, 0x2000);
  121.                
  122.                
  123.  
  124.                 if (result)
  125.                         printf("Decrypt successful! key %p%p\n",  key[1], key[0]);
  126.                 else
  127.                         printf("Decrypt failed. Key was %p, more_buffer was %p,\noutput CRC32 was %p\n",
  128.                                                 key[0], more_buffer[0], last_crc);
  129.  
  130.                 return 0;
  131. }