Randomize code hashes

Posts 114 of 14 · Page 1 of 1
Randomize code hashes
[PHP]#define RANDOMIZE_BLOCK __asm _emit 0x55 \
__asm _emit 0xAA \
__asm _emit 0xBB \
__asm _emit 0xCC \
__asm _emit 0xAB \
__asm _emit 0xCD \
__asm _emit 0xEF \
__asm _emit 0xFE \
__asm _emit 0xDC \
__asm _emit 0xBA \
__asm _emit 0x90 \
__asm _emit 0xC3 \
__asm _emit 0xC3 \
__asm _emit 0xC3 \
__asm _emit 0xC3 \
__asm _emit 0xC3 \


void FunctionToRandomize(...)
{
goto LABEL;

RANDOMIZE_BLOCK

LABEL:
RunCode();
}

void OverseerFunction(...)
{
srand(GetTickCount());

DWORD oldProtect = 0;
VirtualProtect(FunctionToRandomize + offset, 16, PAGE_READWRITE, &oldProtect);

for (int i = 0; i < 16; i+=4)
{
*(FunctionToRandomize + offset +i) = rand()&0xFFFFFFFF;
}

VirtualProtect(FunctionToRandomize + offset, 16, oldProtect, &oldProtect);
}[/PHP]

Alternatively, you could potentially have __declspec naked functions and just write over them with nonsense as long as you don't call them. The advantage of the approach I posted above is that you can randomize these functions at runtime and still be able to call them. (it'd be safe to ensure they are not executing first).

You also need to determine offset. You could search at runtime or just disassemble so you don't overwrite the jump statement.

Credits: MSDN for the _emit.
Sweet ! Thanks for this(:

It'll probably become useful for me, and many others at some point
Nice release, someone who knows C++, especially a leecher. Good Job Dude!
thanks man, ill get the offsets and post them in a bit.
The offset depends on compiler/linker and optimization settings.

This would serve as an alternative to what has been done before -- take a detected cheat and compress it, which changes it enough to apparently evade detection.

This may also be useful if you are distributing a cheat around. I may/may not make a better version (global class you can set up). Since jumps can be relative, I should be able to emit the right ASM to jump over the junkcode instead of using a C goto statement.

...but I don't like the intel manuals _THAT_ much :-/

Using relative jumps, the function becomes:
Code:
.text:004113F0 ; =============== S U B R O U T I N E =======================================
.text:004113F0
.text:004113F0 ; Attributes: bp-based frame
.text:004113F0
.text:004113F0 FunctionToRandomize proc near           ; CODE XREF: .text:loc_411195j
.text:004113F0
.text:004113F0 var_C0          = byte ptr -0C0h
.text:004113F0
.text:004113F0                 push    ebp
.text:004113F1                 mov     ebp, esp
.text:004113F3                 sub     esp, 0C0h
.text:004113F9                 push    ebx
.text:004113FA                 push    esi
.text:004113FB                 push    edi
.text:004113FC                 lea     edi, [ebp+var_C0]
.text:00411402                 mov     ecx, 30h
.text:00411407                 mov     eax, 0CCCCCCCCh
.text:0041140C                 rep stosd
.text:0041140E                 jmp     short loc_411420
.text:0041140E ; ---------------------------------------------------------------------------
.text:00411410                 dd 0CCBBAA55h, 0FEEFCDABh, 0C390BADCh, 0C3C3C3C3h
.text:00411420 ; ---------------------------------------------------------------------------
.text:00411420
.text:00411420 loc_411420:                             ; CODE XREF: FunctionToRandomize+1Ej
.text:00411420                 mov     esi, esp
.text:00411422                 push    offset Format   ; "OK\n"
.text:00411427                 call    ds:__imp__printf
.text:0041142D                 add     esp, 4
.text:00411430                 cmp     esi, esp
.text:00411432                 call    j__RTC_CheckEsp
.text:00411437                 pop     edi
.text:00411438                 pop     esi
.text:00411439                 pop     ebx
.text:0041143A                 add     esp, 0C0h
.text:00411440                 cmp     ebp, esp
.text:00411442                 call    j__RTC_CheckEsp
.text:00411447                 mov     esp, ebp
.text:00411449                 pop     ebp
.text:0041144A                 retn
.text:0041144A FunctionToRandomize endp
You will see the "offset" is something like 0x1E. That will be unnecessary. If I work on this again, I'll search for the beginning of a code pattern and overwrite there.

In the end, I intend the interface to be
...code...
RANDOMIZE_BLOCK
...code...

and then in the global class: g_whateverClass.AddFunction(function_pointer);

Without some code wizardry, I can not make there be an arbitrary block length. That would require runtime code editing and I don't feel like that. It would be cool though....

This doesn't work in cases where the compiler encloses your functions in jump statements. This can be turned off (and usually is in release mode).
I do believe this is english...right?
Quote Originally Posted by sassycatman View Post
I do believe this is english...right?
Yep, completely understandable, high-level English.
Thank you for the great share ^^
Thanks for the information
Look kids, someone that knows what there doing
I don't understand, wouldn't this just mess up your function?
Code:
void OverseerFunction(...)
{
    srand(GetTickCount());

    DWORD oldProtect = 0;
    VirtualProtect(FunctionToRandomize + offset, 16, PAGE_READWRITE, &oldProtect);

    for (int i = 0; i < 16; i+=4)
    {
        *(FunctionToRandomize + offset +i) = rand()&0xFFFFFFFF;
    }

    VirtualProtect(FunctionToRandomize + offset, 16, oldProtect, &oldProtect);
}
Maybe it has something to do with the RANDOMIZEBLOCK why it doesn't. Idk I've never heard of _emit guess I'll look it up. The _emit Pseudoinstruction (C++) Oh hey that's a neat trick!

Also I never have understood why some groups of coders are really fond of the whole (...) ellipsis thing. Why not explicitly state your arguments. Maybe that might be useful when creating a function pointer, but I honestly could never see the point behind just not listing the variables and having done with it? No offense that's just a personal opinion of mine.

It seems like a very nice way to keep code undetected.
Quote Originally Posted by why06 View Post
I don't understand, wouldn't this just mess up your function?
Code:
void OverseerFunction(...)
{
    srand(GetTickCount());

    DWORD oldProtect = 0;
    VirtualProtect(FunctionToRandomize + offset, 16, PAGE_READWRITE, &oldProtect);

    for (int i = 0; i < 16; i+=4)
    {
        *(FunctionToRandomize + offset +i) = rand()&0xFFFFFFFF;
    }

    VirtualProtect(FunctionToRandomize + offset, 16, oldProtect, &oldProtect);
}
Maybe it has something to do with the RANDOMIZEBLOCK why it doesn't. Idk I've never heard of _emit guess I'll look it up. The _emit Pseudoinstruction (C++) Oh hey that's a neat trick!

Also I never have understood why some groups of coders are really fond of the whole (...) ellipsis thing. Why not explicitly state your arguments. Maybe that might be useful when creating a function pointer, but I honestly could never see the point behind just not listing the variables and having done with it? No offense that's just a personal opinion of mine.

It seems like a very nice way to keep code undetected.
Lazy person's heaven.
Quote Originally Posted by why06 View Post
Also I never have understood why some groups of coders are really fond of the whole (...) ellipsis thing. Why not explicitly state your arguments.
I didn't feel like typing, also it is kind of silly to do things in that fashion.

Fun fact: Oreans' Themida does a similar thing, taking advantage of certain code blocks that will work when registers are switched.

e.g.

mov edx &g_pClass
mov eax [edx] //????
mov edx [eax] //???
mov eax [edx + 0x04] //????

Can be changed to

mov ebx &g_pClass
mov edx [ebx]
mov eax [edx]
mov ebx [eax + 0x04]

Within constraints. Different bytes, same result. (IDK any compiler that would generate the nonsense I just wrote. Just an example.) I should get back to work :-/
OK, I'd call this one a prelim:

Randomizer.h
[php]#pragma once

#include <Windows.h>
#include "UTIL_Memory.h"

#define RANDOMIZE_BLOCK __asm _emit 0xEB \
__asm _emit 0x10 \
__asm _emit 0xAA \
__asm _emit 0xAB \
__asm _emit 0xBB \
__asm _emit 0xCB \
__asm _emit 0xDB \
__asm _emit 0xEB \
__asm _emit 0xFB \
__asm _emit 0xFB \
__asm _emit 0xEB \
__asm _emit 0xDB \
__asm _emit 0xCB \
__asm _emit 0xBB \
__asm _emit 0xAB \
__asm _emit 0x9B \
__asm _emit 0x8B \
__asm _emit 0x7B

class CRandomizer
{
public:
CRandomizer(void)
{
}

void AddFn(LPVOID function)
{
PDWORD addr = (PDWORD)Util::Memory::FindPattern((BYTE*)"\xAA\xAB \xBB\xCB\xDB\xEB\xFB\xFB\xEB\xDB\xCB\xBB\xAB\x9b\x 8b\x7b","xxxxxxxxxxxxxxxx",
(unsigned long)function, 0x30);

if (!addr)
return;

DWORD oldProtect = 0;
VirtualProtect(addr, 0x10, PAGE_EXECUTE_READWRITE, &oldProtect);

srand(GetTickCount());
memset(addr, rand(), 0x10);

VirtualProtect(addr, 0x10, oldProtect, &oldProtect);
}
};
[/php]

I'm sure you have your own findpattern equivalents.

Usage:
[php]CRandomizer g_Randomizer;

void FunctionToRandomize();

int _tmain(int argc, _TCHAR* argv[])
{
g_Randomizer.AddFn(FunctionToRandomize);
FunctionToRandomize();

getchar();
return 0;
}

void FunctionToRandomize()
{
RANDOMIZE_BLOCK

printf("OK\n");
}
[/php]
Output is "OK".
Verified in IDA that it does write over those bytes. There are problems with some debug builds that use jumps to go into your functions. This code will not follow those jumps. You can only use one RANDOMIZE_BLOCK per function and it should be at the beginning of that function.

Adding more RANDOMIZE_BLOCKs won't hurt, it'll just be kind of silly.
/
Posts 114 of 14 · Page 1 of 1
This thread is closed for replies.

Similar Threads

Tags for this Thread

None

Need help?