Я делаю хак для игры под названием AssaultCube, и базовый адрес игрока - 0x0050F4F4
, а адрес «здоровья» - 0x0050F4F4 + 0xF8
, проблема в том, что я не могу писать по этому адресу даже с полным доступом.
Мой код:
#include <Windows.h>
#include <iostream>
using namespace std;
int main() {
HWND window = FindWindowA(NULL,"AssaultCube");
int value = 888;
if (window == NULL) {
cout << "Can't find window!";
exit(-1);
}
DWORD pid;
GetWindowThreadProcessId(window,&pid);
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
while(true) {
WriteProcessMemory(handle,reinterpret_cast<LPVOID>(0x0050F4F4 + 0xF8),&value,sizeof(value),0);
Sleep(750);
}
}
Теперь в инструменте, который я использую для просмотра адресов памяти, Cheat Engine, я могу изменить значение, но в моей программе я не могу.
Любая помощь будет оценена по достоинству.
@JesperJuhl Во-первых, как Cheat Engine может изменять физическую память, а моя программа не может? Во-вторых, почему так прямолинейно?
Помните, что адрес должен каждый раз меняться из-за ASLR. en.wikipedia.org/wiki/…
@drescherjm Но это адрес статической памяти.
Почему вы не проверяете ошибки?
Я не получаю ошибок при запуске, и GetLastError тоже ничего не возвращает.
Ваш код не вызывает GetLastError. Также не проверяйте возвращаемое значение WriteProcessMemory.
@jes: Как отладчик установит программную точку останова в ОС, которая соответствует вашему определению для "здравомыслящий"?
@Jesper Вы явно не знаете, что делает WriteProcessMemory
@DavidHeffernan Возвращаемое значение моей WriteProcessMemory - 1, поэтому ошибки нет.
в данном случае на 0x0050F4F4 + 0xF8
хранится не то, что вы ожидаете. или изменить только эти данные недостаточно. но это уже связано с реверс-инжинирингом конкретной программы, но не с C++ или winapi
Вам нужно сначала получить фактический базовый адрес игрового процесса, затем добавить к нему смещение игрока, а затем добавить к нему смещение здоровья. Очень маловероятно, что игрок находится по одному и тому же адресу каждый раз при запуске игры.
@pau: Это не форум. Это сайт вопросов и ответов. Пожалуйста, возьмите тур.
В комментариях вы указываете, что WriteProcessMemory
возвращает 1. В этом случае, вопреки вашим убеждениям, значение было успешно записано.
Возможно, вы пишете не по адресу, или программа перезаписывает значение. Но когда функция возвращает ненулевое значение, это означает, что она прошла успешно.
Кстати, я настоятельно рекомендую вам в будущем начать включать код проверки ошибок. Если бы вы сделали это, вы бы поняли, что вызов функции выполнен успешно.
@DavidHefferman Тогда почему он не работает, в Cheat Engine он показывает, что программа не перезаписывает значение, которое я отправляю. Но волшебным образом Cheat Engine может записывать в память, а мой - нет. Ошибок нет, попробовал GetLastError () и ничего не показал, программа буквально идеальна, но ничего работать не будет. Меня это так бесит.
@elitexjj - прикрепите отладчик к вашему Cheat Engine и установите bp на NtWriteVirtualMemory
Если функция возвращает ненулевое значение, значит, она успешна.
Ваша логика неверна.
0x0050F4F4 - указатель на объект локального плеера.
0xF8 - смещение здоровья относительно локального объекта игрока.
Вы складываете их вместе, думая, что это адрес переменной здоровья, а это не так. Вам нужно ReadProcessMemory на 0x0050F4F4, что даст вам адрес локального объекта плеера в целевом буфере. Затем вы добавляете к нему 0xF8, это дает адрес локальной переменной здоровья игрока. Затем вы вызываете WriteProcessMemory по этому адресу и перезаписываете его.
@JesperJuhl Так что мне делать?