1

I developing online game. I have full sources for server, but game client I am using is closed-source so I need to do some reverse engineering there. So for 2 weeks I am trying to properly call draw_rectangle function. In the image below you can see screenshot from OLLY. There are functions:

DRAW_BLACK_BAR(black frame for health bar),

DRAW_COLORED_BAR(The health inside),

DRAW_NICK(already hooked)

enter image description here

the CALL DWORD PTR DS:[EDX+14] always points to 0x4EB2F0

So the addres contains that function in debugger:

enter image description here

As you can see there are parameters on the stack such as: Surface_id, position, size, color, pointer to creature.

So theres my hook:

superHook(dwHandle, 0x4C8C28, (unsigned int)newFunc); //instead of call print rectangle func for colored bar
 
void superHook(HANDLE dwHandle, int adr, unsigned int targetFunction)
{
    //its not normal CALL ADDR which takes 5 bytes (E8 + 4x bytes for address)
    //It is CALL DWORD PTR DS:[EDX+14] which takes 3bytes, so we will take more space
    //and we will rebuild the function
     
     
    // jmp to address +2x nop
    BYTE bytes[7] = { 0xE9, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x90};
    DWORD targetAddr = targetFunction - adr - 5;
    *(DWORD*)(bytes + 1) = targetAddr;
    WriteProcessMemory(dwHandle, (void *)adr, bytes, 7, NULL);
}
 
void newFunc()
{
    //Rebuild the function (Earsed commands to be able to put JMP address)
    __asm {
            MOV ECX, DWORD PTR SS : [EBP - 0x18]
            PUSH ESI
    }
 
    //Here I can access all the registers and stack before CALL will be executed
     
 
    //call draw rectangle
    __asm {
            CALL DWORD PTR DS : [EDX + 0x14]//always call 0x4EB2F0?
    }
 
 
    //go back
    __asm {
        PUSH 0x4C8C2F
            RET
    }
 
}

And it works fine, I can acces the params on stack and modify them (CHange color,size, location etc). BUt I would like to be able to create another rectangle, for example next one with another color and position. I tried a lot of combinations of setting up the new stack with params calling the func and then calling it again with original ones but I always end up with client crash.

Heres an one of example of my attempt to create new call + restoring old one https://pastebin.com/RUmaPGya (pastebin to not make this post too long)

Help plz :)

5
  • First of all please use PUSHAD and POPAD to store/restore the registers and not to do it one by one. – EWD-0- Dec 4 '17 at 9:36
  • Had no idea about that command. Thanks, gonna definitely check them out as soon Im home – Piodo Dec 4 '17 at 10:24
  • To note, PUSHAD/POPAD are x86-only (which will work fine in your case since you're clearly dealing with a 32-bit binary). General purpose registers must be individually preserved/restored in x64. That aside, have you tried placing a breakpoint and stepping through your code to see exactly where the crash happens? That should elaborate on register/stack states for you to identify key problem areas. – dsasmblr Dec 5 '17 at 19:01
  • I wish I can do it, but I go some weird anti-bot block that does not let me login into the game with attached debugger. Its okay to attach when the game is running and the player is already logged in, but in that case the game crashes after login and Im not able to check out how the parameters went there. – Piodo Dec 5 '17 at 20:34
  • Your first priority should be to bypass the anti-RE mitigations the application uses, so future reverse engineering can be easier to perform. – NirIzr Dec 5 '17 at 21:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.