Проблема с тренером, которую я пытаюсь создать (в образовательных целях) - PullRequest
1 голос
/ 16 января 2010

Я пытаюсь создать тренажер для Icy Tower 1.4 для образовательных целей.

Я написал функцию, которая сокращает функцию WriteProcessMemory следующим образом:

void WPM(HWND hWnd,int address,byte data[])
{
    DWORD proc_id;
    GetWindowThreadProcessId(hWnd, &proc_id);
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id);

    if(!hProcess)
        return;

    DWORD dataSize = sizeof(data);
    WriteProcessMemory(hProcess,(LPVOID)address,&data,dataSize,NULL);
    CloseHandle(hProcess);
}

и это функция, которая должна остановить Часы ледяной башни:

void ClockHack(int status)
{
    if(status==1)//enable
    {
        //crashes the game
        byte data[]={0xc7,0x05,0x04,0x11,0x45,0x00,0x00,0x00,0x00,0x00};
        WPM(FindIcyTower(),0x00415E19,data);
    }
    else if(status==0)//disable
    {
            byte data[]={0xA3,0x04,0x11,0x45,0x00};
    }
}

в операторе else есть оригинальный AOB кода операции. Когда я вызываю функцию ClockHack с параметром состояния, установленным в 1, игра вылетает.

В Cheat Engine я написал для этого скрипт, который точно не записывает по тому же адресу, потому что я сделал Code Cave, и он прекрасно работает.

Кто-то знает почему? Спасибо.

Кстати: только для образовательных целей .

Ответы [ 2 ]

2 голосов
/ 16 января 2010

когда массив передается в функцию, он всегда передается по ссылке, поэтому byte [] совпадает с byte *, и вы пишете только первые sizeof(byte*) байты вашего кода.Или 4 байта на платформах X86.

Кроме того, похоже, что вы пишете объектный код, если нет, то проигнорируйте остальную часть этого ответа.

Что ж, если вы пишетев правильное местоположение, и то, что вы пишете правильно, у вас все еще есть проблема - WriteProcessMemory не гарантированно будет атомарным по отношению к потоку, который выполняется в целевом процессе.

Необходимо убедиться, что этот целевой поток находится в состоянии Suspended и не выполняется в этой части кода.И я понятия не имею, что вы (возможно) должны сделать, чтобы очистить конвейер декодирования команд и / или кэш L1.

Редактировать: Теперь, когда я подумал еще.Я думаю, что использование мьютекса для защиты этого фрагмента кода от перезаписи во время его выполнения лучше, чем приостановка потока.

2 голосов
/ 16 января 2010

Вы не можете передать массив такой функции.Параметр byte[] совпадает с параметром byte *, а sizeof(data) даст вам размер указателя.Кроме того, вы не должны использовать &data, поскольку это уже указатель.

Таким образом, ваша функция должна выглядеть следующим образом:

void WPM(HWND hWnd,int address, byte *data, int dataSize)
{
    //....
    WriteProcessMemory(hProcess,(LPVOID)address,data,dataSize,NULL);
    //...
}
...