tags:

views:

93

answers:

2

Hi, I've this AA script (Cheat Engine scripting language):

[ENABLE]
alloc(newmem,2048) //2kb should be enough
label(returnhere)
label(exit)

00415e19:
jmp newmem

returnhere:
newmem:
mov [00451104],0//moves 0 to the clock variable
//nop//nops the clock increaser

exit:
jmp returnhere

[DISABLE]
dealloc(newmem)
00415e19:
mov [00451104],eax
//Alt: db A3 04 11 45 00

It's working - stopping the game clock. Now, I'm trying to convert this code to C++. Here's what I did so far:

#include <windows.h>

HWND FindIcyTower()
{
    return FindWindowA(NULL, "Icy Tower v1.4");
}

void WPM(HWND hWnd,int address, byte *data, int dataSize)
{
    DWORD proc_id;
    GetWindowThreadProcessId(hWnd, &proc_id);

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id);

    if(!hProcess) 
        return;

    WriteProcessMemory(hProcess, (LPVOID)address, data, dataSize, NULL);

    CloseHandle(hProcess); 
}

void EnableClockHack()
{
    WPM(FindIcyTower(), 0x00415E19, {0xc7, 0x05, 0x04, 0x11 ,0x45, 0x00, 0x00, 0x00, 0x00, 0x00}, 9);
}

void DisableClockHack()
{
    WPM(FindIcyTower(), 0x00415E19, {0xA3, 0x04, 0x11, 0x45, 0x00}, 4);
}

but it crashes the game, instead of stopping the clock. Any ideas?return FindWindowA(NULL, "Icy Tower v1.4");

A: 

No idea about the syntax of the AA script, but I got few points:

mov [00451104],0

Should translate as 'move the intermediate value of 0 to the location 00451104'. And your C++ code reads:

WPM(FindIcyTower(), 0x00415E19, {0xc7, 0x05, 0x04, 0x11 ,0x45, 0x00, 0x00, 0x00, 0x00, 0x00}, 9);

Why are you using the intermediate {0xc7, 0x05, 0x04, 0x11 ,0x45, 0x00, 0x00, 0x00, 0x00, 0x00} instead of 0 ( {0,0,0,0} ) ?

You may also need to read the value from the offset 0x00415E19 first (which is probably what the AA code does implicitly by prefixing the mov instruction with the name of the allocated buffer), so you can later restore the original value in the Disable... function.

arul
+3  A: 

The opcode for moving an immediate (like you are trying to do) is longer (9 bytes) than the game's original code that moves from a register (4 bytes). The extra 5 bytes are most likely overwriting an instruction or two after the original mov causing the program to crash.

Just like in Cheat Engine you'll need to allocate new memory in the target process in which to place your modification code so you don't overwrite any of the game's code. Since this memory will be used by the processor for execution it will need to have the execute bit set.

Once you have your mod code injected you can then change the game's original mov [00451104],eax to a jmp to the mod code start address. The the last instruction in the mod code would need to be a jmp back to the instruction just after your replacement jmp which would resume the game executing.

See VirtualAllocEx for allocating memory in other processes, VirtualProtectEx for setting PAGE_EXECUTE on that memory, and of course VirtualFreeEx for releasing the memory when you're done with it.

joshperry