Проблема с тренером, которую я пытаюсь создать (в образовательных целях)
Я пытаюсь создать трейнер для 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);
}
и это функция, которая должна остановить Icy Tower Clock:
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 ответа
Вы не можете передать массив такой функции. Иметь byte[]
параметр такой же, как byte *
параметр и sizeof(data)
просто даст вам размер указателя. Кроме того, вы не должны использовать &data
так как это уже указатель.
Итак, ваша функция должна выглядеть так:
void WPM(HWND hWnd,int address, byte *data, int dataSize)
{
//....
WriteProcessMemory(hProcess,(LPVOID)address,data,dataSize,NULL);
//...
}
Когда массив передается в функцию, он всегда передается по ссылке, поэтому byte[] совпадает с byte*, а вы пишете только первый sizeof(byte*)
байты вашего кода. Или 4 байта на платформах X86.
Кроме того, похоже, что вы пишете объектный код, если нет, то проигнорируйте остальную часть этого ответа.
Итак, если вы пишете в правильное место, а то, что пишете правильно, у вас все еще есть проблема - WriteProcessMemory
не гарантируется атомарность по отношению к потоку, который выполняется в целевом процессе.
Вы должны убедиться, что этот целевой поток приостановлен, а не выполняется в этой части кода. И я понятия не имею, что вы (возможно) должны сделать, чтобы очистить конвейер декодирования команд и / или кэш L1.
Изменить: Теперь, когда я подумал еще. Я думаю, что использование мьютекса для защиты этого фрагмента кода от перезаписи во время его выполнения лучше, чем приостановка потока.