C++ Как я могу сделать процесс чтения / записи с заданным адресом из CE, который содержит float?

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

изображение адресов со смещениями

Этот адрес указывает на мою X-координату. Теперь я пытаюсь изменить свою X-координату (с плавающей точкой) с помощью процесса чтения / записи. Но что бы я ни делал, это не работает (у меня нет проблем с изменением нормальных целых). Я хочу заменить значение с плавающей точкой, которую я выбрал раньше.

Может кто-нибудь дать мне подробный пример, как я могу это сделать?

заранее спасибо

3 ответа

Решение

1) получить базовый адрес процесса - получить базовый адрес процесса, дескриптор процесса, передать туда возвращенное значение openprocess ( https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx)

2) добавить смещение 'teleport' к базовому адресу

3) записать заданное значение в память процесса

HANDLE hProcess = openProcess(processId); //you also need to pass desired mode, use read & write
DWORD dwBaseAddress = getBaseAddress(hProcess): 
DWORD dwPositionAddress = dwBaseAddress + POSITION_OFFSET; 
float newPosition = 123.5;
WriteProcessMemory(hProcess, dwPositionAddress, &newPosition, sizeof(float));

вам нужно проверять наличие ошибок, это просто псевдокод, чтобы дать вам представление о том, что вам нужно делать, а также убедиться, что вы используете трейнер как администратор и имеете доступ к памяти игры

Делать это внутренне вместо

Readprocessmemory и writeprocessmemory были бы относительно просты, но лучшим вариантом является внедрение DLL в целевой процесс для скорости и простоты. Вы можете вручную почтить с помощью *или используйте предпочтительный метод и настройте классы с подходящими размерами, чтобы вам не приходилось обрабатывать смещения одинаково. Проверьте Reclass.NET для автоматизации этого.

class unk3{
public:
    char pad_001[0x10];
    float location;
}

class unk2{
public:
    unk3* m_unk3;
}

class unk1{
public:
    char pad_001[0x78];
    unk2* m_unk2;
}

Затем объявите экземпляр с вашим статическим смещением и считывайте / записывайте в него, как будто это ваша собственная память.

unk1* p_unk1 = (unk1*)(uintptr_t*)(OFFSET);
p_unk1->m_unk2->m_unk3->location = 300f;

Использование RPM

Если вы хотите выйти на улицу, вам сначала нужно открыть дескриптор процесса.

void attach(LPCSTR WindowName) {
    HWND hWindow = FindWindowA(NULL, WindowName); 
    if (hWindow)
    {
        GetWindowThreadProcessId(hWindow, &Proc_ID); 
        hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION/*PROCESS_ALL_ACCESS*/, FALSE, Proc_ID); 
        HANDLE hModule = INVALID_HANDLE_VALUE; 
        MODULEENTRY32 ePoint; 
        hModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Proc_ID); 
        ePoint.dwSize = sizeof(MODULEENTRY32); 
        Module32First(hModule, &ePoint);
        base = (DWORD*)ePoint.modBaseAddr; 
        CloseHandle(hModule);
    }
}

Тогда я бы порекомендовал настроить шаблоны для чтения / записи для вас.

template <class T>
T read(DWORD_PTR Address){
    T buffer;
    ReadProcessMemory(this->hProcess, (LPCVOID)Address, &buffer, sizeof(buffer), NULL);
    return buffer;
}

Тогда почти такой же метод написания. Тогда исполнение будет:

DWORD_PTR p_unk1 = mem.read<DWORD_PTR>(OFFSET);
DWORD_PTR p_unk2 = mem.read<DWORD_PTR>(p_unk1 + 0x78);
DWORD_PTR p_unk3 = mem.read<DWORD_PTR>(p_unk2);
float location = mem.read<float>(p_unk3 + 0x10);

Внешне эффективность

Вместо того, чтобы просто готовить sizeof(DWORD_PTR) и читать каждый элемент в классе, лучше, если вы сделаете что-то вроде этого:

class unk3{
public:
    char pad_001[0x10];
    float location;
}

class unk2{
public:
    DWORD_PTR m_unk3;
}

class unk1{
public:
    char pad_001[0x78];
    DWORD_PTR m_unk2;
}

Заменить каждый класс * на DWORD_PTR

Затем выполните это с

unk1 p_unk1 = mem.read<unk1>(OFFSET);
unk2 p_unk2 = mem.read<unk2>(p_unk1.m_unk2);
unk3 p_unk3 = mem.read<unk3>(p_unk2.m_unk3);
float location = p_unk3.Location;

Для тех, кто задается вопросом, написание этого пути сделано:

mem.write<float>(p_unk2 + offsetof(unk3, location), value);

Заворачивать

Внутренне делать это значительно лучше, меньше хлопот. Обратите внимание на ваш вопрос, writeprocessmemory просто пихает байты, это не заботится о типе. Вы, вероятно, передаете адрес целого числа в качестве буфера для записи, когда int и float по-разному кодируются с прямым порядком байтов. Убедитесь, что вы объявили его как float, или, что еще лучше, используйте шаблон. Или даже лучше, просто напишите dll:)

Вы должны прочитать указатель и добавить, что указывает его относительные смещения, чтобы добраться до адреса телепортации.

Вы можете использовать WriteProcessMemory() для прямой записи в память процесса и ReadProcessMemory() для чтения из памяти.

Но в случае, если вы читаете двухуровневый указатель уровня, это станет громоздким подходом.

Поэтому я рекомендую использоватьGame Trainer или библиотеку для взлома памяти, чтобы легко читать / писать указатели.

Вы можете использовать GTLibc G ame T rainer libray для C / C++. GTLibc Библиотека игровых тренеров

или вы можете использовать библиотеку взлома игр Memory.dll для C#. Memory.dll

Другие вопросы по тегам