Hooking

03/24/2020 17:00 MrSn0w#1
So I recently got started with Hooking and Detouring. Now I'm playing

a bit around with it to get a better understanding.

I wanted to hook the ammo decrement function in Assult Cube to get Inf. Ammo. It works kinda fine but instead of incrementing the ammo it's just freezing so there has to be something wrong in my Asm code.

I'm also trying to understand what the brackets mean. Because when I use

inc esi it works fine but I thought I need to dereference it to get the actual value of the address so I thought inc [esi] was right. But then the game is crashing. Maybe you could help me out or give me some advises. I'll post the

code below.

Code:
//Includes
#include <Windows.h>


//Prototypes
bool Hook(void* toHook, void* ourFunct, int len);
DWORD WINAPI MainThread(LPVOID param);
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved);


//Vars
DWORD jmpBackAddy;


bool Hook(void* toHook, void* ourFunct, int len) {
    if (len < 5) {
        return false;
    }

    //Get access to mem page
    DWORD curProtection;
    VirtualProtect(toHook, len, PAGE_EXECUTE_READWRITE, &curProtection);

    //Nop all 6 bytes to
    memset(toHook, 0x90, len);

    DWORD relativeAddress = ((DWORD)ourFunct - (DWORD)toHook) - 5;

    *(BYTE*)toHook = 0xE9; //Set jmp instruction
    *(DWORD*)((DWORD)toHook + 1) = relativeAddress; //Address for the jump to our func we redirect

    //Restore old access
    DWORD temp;
    VirtualProtect(toHook, len, curProtection, &temp);

    return true;
}

void __declspec(naked) ourFunct() {
    __asm {
        mov esi, [esi+14]
        inc esi //Ammo ist not incrementing
       //inc [esi] crashes
        jmp[jmpBackAddy]
    }
}

DWORD WINAPI MainThread(LPVOID param) 
{
   int hookLength = 5;
   DWORD mBase = (DWORD)GetModuleHandle(L"ac_client.exe");
   //eip instrcution pointer
   DWORD hookAddress = mBase + 0x637E6; //Addr to the hook function

    jmpBackAddy = hookAddress + hookLength;

    Hook((void*)hookAddress, ourFunct, hookLength);

    while (!(GetAsyncKeyState(VK_ESCAPE) & 1)) 
    {
        
        Sleep(50);
    }

    //Exit
    FreeLibraryAndExitThread((HMODULE)param, 0);
    return 0;
}

BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) {
    switch (dwReason) {
    case DLL_PROCESS_ATTACH:
        CreateThread(0, 0, MainThread, hModule, 0, 0);
        break;
    }

    return TRUE;
}
03/25/2020 01:10 elmarcia#2
Quote:
Originally Posted by MrSn0w View Post
So I recently got started with Hooking and Detouring. Now I'm playing

a bit around with it to get a better understanding.

I wanted to hook the ammo decrement function in Assult Cube to get Inf. Ammo. It works kinda fine but instead of incrementing the ammo it's just freezing so there has to be something wrong in my Asm code.

I'm also trying to understand what the brackets mean. Because when I use

inc esi it works fine but I thought I need to dereference it to get the actual value of the address so I thought inc [esi] was right. But then the game is crashing. Maybe you could help me out or give me some advises. I'll post the

code below.

Code:
//Includes
#include <Windows.h>


//Prototypes
bool Hook(void* toHook, void* ourFunct, int len);
DWORD WINAPI MainThread(LPVOID param);
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved);


//Vars
DWORD jmpBackAddy;


bool Hook(void* toHook, void* ourFunct, int len) {
    if (len < 5) {
        return false;
    }

    //Get access to mem page
    DWORD curProtection;
    VirtualProtect(toHook, len, PAGE_EXECUTE_READWRITE, &curProtection);

    //Nop all 6 bytes to
    memset(toHook, 0x90, len);

    DWORD relativeAddress = ((DWORD)ourFunct - (DWORD)toHook) - 5;

    *(BYTE*)toHook = 0xE9; //Set jmp instruction
    *(DWORD*)((DWORD)toHook + 1) = relativeAddress; //Address for the jump to our func we redirect

    //Restore old access
    DWORD temp;
    VirtualProtect(toHook, len, curProtection, &temp);

    return true;
}

void __declspec(naked) ourFunct() {
    __asm {
        mov esi, [esi+14]
        inc esi //Ammo ist not incrementing
       //inc [esi] crashes
        jmp[jmpBackAddy]
    }
}

DWORD WINAPI MainThread(LPVOID param) 
{
   int hookLength = 5;
   DWORD mBase = (DWORD)GetModuleHandle(L"ac_client.exe");
   //eip instrcution pointer
   DWORD hookAddress = mBase + 0x637E6; //Addr to the hook function

    jmpBackAddy = hookAddress + hookLength;

    Hook((void*)hookAddress, ourFunct, hookLength);

    while (!(GetAsyncKeyState(VK_ESCAPE) & 1)) 
    {
        
        Sleep(50);
    }

    //Exit
    FreeLibraryAndExitThread((HMODULE)param, 0);
    return 0;
}

BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) {
    switch (dwReason) {
    case DLL_PROCESS_ATTACH:
        CreateThread(0, 0, MainThread, hModule, 0, 0);
        break;
    }

    return TRUE;
}
I will explain what [] means so you can get a hint of what is going wrong.

In assembly you use registers to perform operations most of the time, the [] means go to the address location that is inside brackets and get the value,
So lets say we have a base address like 0x400000 and offseting that address with a value we get our ammo.
We get something like this:
offset is 0x5 (5 dec)
[0x400000] = AA BB CC DD EE | 00 00 00 0A | 11 22 33 44
that means that our ammo is offset 5 bytes, so value
00 00 00 0A (4 byte value) is our current ammo value

can be expressed as [0x400000 + 0x5] = 00 00 00 0A (10 dec)

in your assembly you get:
mov esi, [esi+14]

where [esi + 14] obtains the value at that address location and it stores in esi register with the mov opcode.

Following previous example if our current ammo is 10, then after executing this: mov esi,[esi+14], now esi contains value 0A then
we execute inc esi, now esi contains 0B but since is a copy of the previous address it doesn't affect your current ammo.
inc [esi] crash because it is trying to modify a non accesible memory address
which is equal to your current ammo
[0xA] - this address isn't accessible so it crash.

In order to make it work you have to:
-store your current base address in a register or do it all the way,
whatever works best for you

//option 1
inc [esi + 14]
mov esi,[esi + 14] //if your hook needs to set esi to current ammo value
jmp[jmpBackAddy]

//option 2
inc [esi + 14] //if not needed to set esi to current ammo value
jmp[jmpBackAddy]

Now lets talk about some register ops, sometimes you can't work with the same register, so you need to use another register to store some temp value

For example what if we want to add 5 bullets every time we shoot:

Our hook code will look like this:

mov eax,[esi +14]
add eax,05
mov [esi],eax

but because it is a hook and we are editing a register it may crash, so we need to save the edited register state before changing it and return its original state after edit. We can do this with the stack... now the code will look like this:

push eax //push current eax value to the stack
mov eax,[esi +14] //store current ammo value
add eax,05 // add 5 to current ammo value
mov [esi+14],eax // set current ammo value in memory to new value
pop eax // restore previous eax value
jmp[jmpBackAddy]
03/25/2020 15:52 MrSn0w#3
Quote:
Originally Posted by elmarcia View Post
I will explain what [] means so you can get a hint of what is going wrong.

In assembly you use registers to perform operations most of the time, the [] means go to the address location that is inside brackets and get the value,
So lets say we have a base address like 0x400000 and offseting that address with a value we get our ammo.
We get something like this:
offset is 0x5 (5 dec)
[0x400000] = AA BB CC DD EE | 00 00 00 0A | 11 22 33 44
that means that our ammo is offset 5 bytes, so value
00 00 00 0A (4 byte value) is our current ammo value

can be expressed as [0x400000 + 0x5] = 00 00 00 0A (10 dec)

in your assembly you get:
mov esi, [esi+14]

where [esi + 14] obtains the value at that address location and it stores in esi register with the mov opcode.

Following previous example if our current ammo is 10, then after executing this: mov esi,[esi+14], now esi contains value 0A then
we execute inc esi, now esi contains 0B but since is a copy of the previous address it doesn't affect your current ammo.
inc [esi] crash because it is trying to modify a non accesible memory address
which is equal to your current ammo
[0xA] - this address isn't accessible so it crash.

In order to make it work you have to:
-store your current base address in a register or do it all the way,
whatever works best for you

//option 1
inc [esi + 14]
mov esi,[esi + 14] //if your hook needs to set esi to current ammo value
jmp[jmpBackAddy]

//option 2
inc [esi + 14] //if not needed to set esi to current ammo value
jmp[jmpBackAddy]

Now lets talk about some register ops, sometimes you can't work with the same register, so you need to use another register to store some temp value

For example what if we want to add 5 bullets every time we shoot:

Our hook code will look like this:

mov eax,[esi +14]
add eax,05
mov [esi],eax

but because it is a hook and we are editing a register it may crash, so we need to save the edited register state before changing it and return its original state after edit. We can do this with the stack... now the code will look like this:

push eax //push current eax value to the stack
mov eax,[esi +14] //store current ammo value
add eax,05 // add 5 to current ammo value
mov [esi+14],eax // set current ammo value in memory to new value
pop eax // restore previous eax value
jmp[jmpBackAddy]
Thank you very much!
I still need to get used with assembly but you helped me to get
a better understanding of it especially with the dereferencing.