Working POC Decrypt/Encrypt gate menu

User Tag List

Results 1 to 2 of 2
  1. #1
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Working POC Decrypt/Encrypt gate

    As promised a while back, here's a working encrypt/decrypt call gate. The encryption is just XOR'ing against a rotating key, but it's fast and it will pretty much break Warden's hashing entirely.

    The idea is that an external cryptor will:

    • Pause the target (WoW, presumably)
    • Get the data extent (base, size) of the code to be encrypted
    • Redirect the calls into the code to be encrypted, to calls in a "jump gate" structure
    • Inject the encryptor/decryptor code
    • Hash the code to be encrypted once (so it starts encrypted)
    • Resume the target process


    The weakness of this implementation is that since you need to know the number of params for the target method (the function that you're encrypting, which may just be a hook from something else), you create a minor coupling between the encryption gate injector and the code to be encrypted. I'm still working on better ways to do this so that your hack code doesn't need to be coupled to the cryptor.

    But for now, it works. My main() includes some basic tests to show it in action.

    Note: this isn't platform-agnostic; it will fail -- badly -- on x64 native apps (sorry, Cypher). I know the code is messy -- I wrote it in about 30 minutes today so I haven't had time to prettify it Finally, this is POC. The real code would virtualalloc a code cave in the target and inject a real jumpgate and cryptor. I just wanted to show how it works in theory.

    Code:
    #include <stdio.h>
    #include <windows.h>
    
    static CRITICAL_SECTION csHashLock; // we need this to be thread-safe
    static int buffer[256] = { 0 }; // this is our make-believe hack functions which the decrypt gate will be hashing
    static int dwordCount = sizeof(buffer) >> 2; // convert bytes to dwords; to do this correctly we should round up
    static int dwHashInit = GetTickCount(); // we can generate any pseudo-random seed 
    
    // ultimately, implement in raw ASM and VirtualAlloc by the injector.  For now, POC.
    __declspec(noinline)
    void __stdcall HashPE()
    {
    	int dwHash = dwHashInit;
    	for (int i = 0; i < dwordCount; ++i)
    	{
    		buffer[i] ^= dwHash; // xor "encryption"
    		__asm rol dwHash, 1 // keep rotating the key so we can't use a simple fixed-key brute force (rotation is obviously not complex, but it's beyond a simple Warden hash)
    	}
    }
    
    // a function to call "hooked" and "unhooked", shows some data, looks at the "encrypted" stuff, returns something
    int __stdcall TestFunction_Original(int value)
    {
    	printf("Hi there!  I'm in TestFunction!  You passed: %d (buffer[0] == 0x%08x\n", value, buffer[0]);
    	return value * 2;
    }
    
    // for ease of "hooking"
    typedef int (__stdcall *TestFunction_ptr)(int);
    TestFunction_ptr TestFunction = TestFunction_Original;
    
    __declspec(naked)
    __declspec(noinline)
    void __stdcall DecryptGate(int argCount, DWORD targetHook)
    {
    	printf("Entering DecryptGate!\n");
    
    	__asm
    	{
    		push ebp
    		mov ebp, esp
    		mov eax, [ebp + 0x4] // ebp+4 is the address of the first function to the decrypt gate (param count)
    		add eax, 3 // compensate for target addr and original return addr
    		cmp eax, 3
    		jbe StackCopyComplete
    StackCopyLoop:
    		mov ebx, [ebp + eax * 4]
    		push ebx
    		sub eax, 1
    		cmp eax, 3
    		jg StackCopyLoop
    StackCopyComplete:
    		push OFFSET csHashLock
    		call dword ptr [EnterCriticalSection]
    		call HashPE
    		call [ebp + 0x8] // [ebp + 0x8] contains the target fn addx	
    		push eax
    		call HashPE
    		push OFFSET csHashLock
    		call dword ptr [LeaveCriticalSection]
    		pop eax
    		pop ebp
    		add esp, 0x8
    		ret
    	}
    }
    
    // in a real app, this jump table would be dynamically allocated and filled in with correct values
    // one weakness of this approach is that we need to know the number of parameters, thus the cryptor
    // is coupled with the hack code (!)
    __declspec(naked)
    __declspec(noinline)
    void __stdcall JumpTable()
    {
    	__asm
    	{
    		push TestFunction_Original
    		push 1
    		jmp DecryptGate
    	}
    }
    
    
    
    int main(int argc, char *argv[])
    {
    	printf("Entering main...\n");
    	InitializeCriticalSection(&csHashLock);
    
    	int result = 0;
    	
    	printf("About to call original (unhooked) function...\n");
    	TestFunction_ptr TestFunction = TestFunction_Original;
    	result = TestFunction(3);
    	printf("Back from (unhooked) TestFunction, result: %d\n", result);
    		
    	// first, "encrypt" the "PE"
    	HashPE();
    
    	// store a random value to show that we're not trashing the stack
    	int x = 0xfeedbeef;
    	printf("About to call hooked function (buffer[0] == 0x%08x)...\n", buffer[0]);
    	TestFunction = (TestFunction_ptr)JumpTable;
    	result = TestFunction(4);
    	// show the stored stack value for verification
    	printf("Back from (hooked) TestFunction... result: %d (x == %08x, buffer[0] == 0x%08x)\n", result, x, buffer[0]);
    
    	printf("Press RETURN to exit...\n");
    	fgetc(stdin);
    }
    Last edited by amadmonk; 06-11-2009 at 03:38 AM.
    Don't believe everything you think.

    Working POC Decrypt/Encrypt gate
  2. #2
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    (Edit2: The more I think about this, the less concerned I am about the coupling; unless you guess at stack size and unless your hack functions are somehow "known," you have to tell the cryptor about the hack functions in some way.

    I'm fleshing this out now, with the "last one out shuts off the lights" thread block, and looking into correctly doing a VirtualQuery/VirtualProtect call so that we don't have to set the code block as RWE.

    I'll try to put up a working out-of-process example within a few days.)
    Last edited by amadmonk; 06-11-2009 at 12:32 PM.
    Don't believe everything you think.

Similar Threads

  1. ESO Packet Decrypt/Encrypt. Close, but cannot determine key
    By jarjar1 in forum Elder Scrolls Online General
    Replies: 3
    Last Post: 10-06-2013, 12:19 PM
  2. Gates of Andaron BOT - 100% working
    By scabbz in forum Gaming Chat
    Replies: 9
    Last Post: 12-12-2009, 01:45 PM
  3. [Working] 3.0.3 LIVE Alterac Valley Early Start Behind Gates Exploit
    By Glovek77 in forum World of Warcraft Exploits
    Replies: 7
    Last Post: 11-07-2008, 02:05 AM
  4. Working Doors / Gates?
    By ollan1 in forum World of Warcraft General
    Replies: 0
    Last Post: 12-31-2007, 01:58 PM
  5. [H Warlock] Get outside of AV Gate/Camp GY early! [Still Working]
    By Memphiz in forum World of Warcraft Exploits
    Replies: 6
    Last Post: 12-14-2007, 09:03 PM
All times are GMT -5. The time now is 03:37 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search