Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- ** VAC decrypter
- **
- ** Special thanks to wav for some infos.
- */
- #include <stdio.h>
- #include <windows.h>
- #include <conio.h>
- #include <Tlhelp32.h>
- // The VAC module!
- HMODULE hVac = NULL;
- // Pointer to the decryption function, as of July 16th 2010.
- // VAC hasn't been updated in ages so this should still work.
- UINT32 decryptCall = 0x27EE;
- // Offsets to encrypted code blocks. This uses the 64-bit encryption
- // algorithm. These are arranged in order of the jump table.
- UINT32 encryptedCodeBlocks[14] = {
- // Functions in the scan request jump table
- 0x24B5, // Function 0 - Undumped
- // Function 1 - Unused
- // Function 2 - Unused
- 0x7018, // Function 3 - Undumped
- 0x14C7, // Function 4 - Undumped
- 0x1E4F, // Function 5 - Undumped
- 0x218F, // Function 6 - Undumped
- 0x7331, // Function 7 - Module check of some sort
- 0x4564, // Function 8 - Process / Module enumeration
- 0x35A4, // Function 9 - Compute MD5 of all modules
- 0x29CE, // Function 10 -
- 0x5879, // Function 11 -
- 0x662F, // Function 12 -
- // Encrypted functions referenced within the encrypted blocks
- 0x7DBF,
- 0x89F0, // Utility functions. Used by Function 7
- 0xF5FD,
- };
- // Offsets to encrypted string blocks. This uses a far more simple
- // algorithm, which we handle in here.
- UINT32 encryptedStringBlocks[8] = {
- 0x22FC8,
- 0x22FD8,
- 0x23090,
- 0x230A8,
- 0x230C4,
- 0x230D8,
- 0x230F8,
- 0x2310C,
- };
- //
- // Here are the 64-bit encryption keys used by VAC to decrypt its code.
- // Keys are sent over whenever VAC wants a function to run.
- // To dump these, hook some code slightly before the scans run. The key
- // will be stored in a pointer at [ebp + 0xC].
- //
- #define MAX_KEYS 7
- UINT8 keys[MAX_KEYS][8] = {
- { 0x6c, 0xa3, 0xda, 0x1a, 0x35, 0x13, 0xc3, 0xc1 }, // Key A - Shared between 2 functions
- { 0xa9, 0x5c, 0x1a, 0x9b, 0x98, 0x37, 0x76, 0x05 }, // Key B
- { 0xea, 0xbe, 0xdf, 0x61, 0x62, 0xb2, 0x77, 0x11 }, // Key C
- { 0x0b, 0x16, 0xd5, 0xe4, 0x76, 0x5b, 0xdf, 0xf3 }, // Key D: Fcn 11.
- { 0xd0, 0xe6, 0xa5, 0x35, 0x1c, 0x93, 0x5a, 0xe5 }, // Key E: Fcn 10. Seems to be popular for MW2
- // Keys in VAC, probably for client/server communications.
- // These might just be one big 128-bit key.
- { 0x34, 0xb2, 0xa2, 0x48, 0x7f, 0xd6, 0x8f, 0xd1 },
- { 0xec, 0x08, 0xa1, 0xb4, 0xf3, 0xc6, 0xd2, 0x35 },
- };
- // A struct for vac_encrypted_func.
- typedef struct {
- UINT8 fcn_number; // Number of the encrypted block (unused?)
- UINT32 fcn_size; // Size of the block
- UINT32 fcn_passes; // Passes during decryption (thanks, wav)
- UINT32 fcn_crc32; // CRC32 of the function
- } vac_encrypted_func;
- /*
- ** Here is the VAC decryption function.
- **
- ** A more accurate prototype is:
- ** BOOL __cdecl VacDecryptCode( vac_encrypted_func* pFunction, UINT32* pKey, UINT8* pWorkspace, UINT32 dwMaxCodeSize);
- */
- BOOL (__cdecl *VacDecryptCode)(UINT8* dwDestAddress, UINT32* key, UINT8* somePointer, UINT32 something);
- // Something to satisfy the third argument to the function with. I have no idea what this is.
- UINT32 more_buffer[0x10000];
- void DecodeCodeBlocks() {
- }
- // String block decoding
- // This is a bit buggy...
- void DecodeStringBlocks() {
- DWORD oldProtect;
- for (int i = 0; i < 8; i++) {
- UINT32* base = (UINT32*)((UINT8*)hVac + encryptedStringBlocks[i]);
- cprintf("Working on string block at %p\n", base);
- for (int x = 0; base[x] != 0; x++) {
- UINT8* encryptedstring = (UINT8*)base[x];
- UINT8 xor_key = 0x55;
- UINT8 size = encryptedstring[0] ^ xor_key;
- VirtualProtect( (LPVOID)encryptedstring, 0x10000, PAGE_EXECUTE_READWRITE, &oldProtect );
- encryptedstring++;
- UINT8 buffer[ 256 ];
- memset(buffer, 0, 256);
- for (int y = 0; encryptedstring[y] != 0; y++) {
- UINT8 decoded = encryptedstring[y] ^ xor_key;
- xor_key = encryptedstring[y];
- buffer[y] = decoded;
- // zero-terminate the string
- //if (encryptedstring[y+1] == 0) encryptedstring[y] = 0;
- }
- printf("Decrypted string %s\n", buffer);
- //encryptedstring[size - 1] = 0;
- //memcpy( encryptedstring - 1, buffer, size);
- }
- }
- }
- int main( int argc, char** argv ) {
- hVac = LoadLibraryA("SourceInit.dat");
- if (!hVac) {
- printf("Can't load VAC client\n");
- return 1;
- }
- UINT8* callPtr = (UINT8*)hVac + 0x27ee;
- // Pointer
- printf("hVac %p, Callptr %p\n", hVac, callPtr);
- //printf("decoding at %p\n", decode_addr);
- VacDecryptCode = (BOOL (__cdecl *)(UINT8 *,UINT32 *,UINT8 *,UINT32))callPtr;
- printf("Decrypting...\n");
- UINT32 decoded_funcs = 0;
- for (int i = 0; i < 14; i++ ) {
- UINT8* decode_addr = (UINT8*)hVac + encryptedCodeBlocks[i];
- for (int x = 0; x < MAX_KEYS; x++) {
- BOOL result = VacDecryptCode( decode_addr, (UINT32*)keys[x], (UINT8*)more_buffer, 0x2000);
- if (result) {
- decoded_funcs++;
- UINT32* key = (UINT32*)keys[i];
- printf("Key #%d decrypted block #%d at 0x%p OK\n",
- x, i, encryptedCodeBlocks[i]);
- // break from this loop
- break;
- }
- }
- }
- printf("Decoded %d of 14 functions\n", decoded_funcs);
- printf("Decoding encrypted strings...\n");
- DecodeStringBlocks();
- FILE * f = fopen("VacDecoded.bin","wb");
- if (f) {
- fwrite(hVac, 0x31000, 1, f);
- fclose(f);
- printf("Wrote decoded DLL to VacDecoded.bin\n");
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement