Как написать процесс памяти с многоуровневым указателем с C ++? - PullRequest
0 голосов
/ 10 мая 2019

Я пытаюсь сделать чит для RE2. Я нашел память с сканированием указателя с чит-движком. Мой код не работает: (

image

#include <iostream>
#include <windows.h>

using namespace std;

int main() {
    int newValue = 10 ;
    HWND hwnd = FindWindowA(NULL, "RESIDENT EVIL 2");
    if ( hwnd == NULL )
    {
        cout << endl << "Process handle not found !" << endl;
        return 0 ;
    } else {
        DWORD pId;
        GetWindowThreadProcessId(hwnd, &pId);
        HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId);
        if(!hProc) {
            cerr << "Cannot open process !" << endl ;
        } else {

            int c = WriteProcessMemory(hProc, (LPVOID)0x707B6D0 + 0x80 + 0x78 + 0x98 + 0x50 + 0x18, &newValue, (DWORD)sizeof(newValue), NULL);
            if (c>0) {
                clog << "yes" << endl ;
            } else {
                clog << "no" << endl ;
            }
            CloseHandle(hProc);
        }
    }
    return 0;
}

Ответы [ 2 ]

1 голос
/ 11 мая 2019

Вы неверно истолковываете то, что Cheat Engine показывает вам.

В вашем коде 0x707B6D0 + 0x80 + 0x78 + 0x98 + 0x50 + 0x18 равно 0x707B8C8, что НИКОГДА даже близко к значению 0x0EC1A3F0, которого вы пытаетесь достичь.

Вместо этого вам нужно сделать следующее:

  • Сначала прочитайте указатель, который хранится по базовому адресу 0x707B6D0 (значение чтения 0x128BFBB0).

  • Затем добавьте 0x18 к этому указателю (0x128BFBB0 + 0x18 = 0x128BFBC8) и прочитайте новый указатель по этому адресу (значение считано 0x128564D0).

  • Затем добавьте 0x50 к этому указателю (0x128564D0 + 0x50 = 0x12856520) и прочитайте новый указатель по этому адресу (считанное значение 0x0F2EC940).

  • Затем добавьте 0x98 к этому указателю (0x0F2EC940 + 0x98 = 0x0F2EC9D8) и прочитайте новый указатель по этому адресу (считанное значение 0x0F2EB2B0).

  • Затем добавьте 0x78 к этому указателю (0x0F2EB2B0 + 0x78 = 0x0F2EB328) и считайте новый указатель по этому адресу (считываемое значение 0x0EC1A370).

  • Затем добавьте 0x80 к этому указателю (0x0EC1A370 + 0x80 = 0x0EC1A3F0) и запишите свои данные по этому адресу.

Попробуйте что-то вроде этого:

#include <iostream>
#include <stdexcept>
#include <memory>
#include <windows.h>

DWORD_PTR readPointerFromProc(HANDLE hProc, DWORD_PTR baseAddr)
{
    DWORD ptr;

    if (!ReadProcessMemory(hProc, reinterpret_cast<LPVOID>(baseAddr), &ptr, sizeof(ptr), NULL);
        throw std::runtime_error("Cannot read from process !");

    return ptr;
}

void WriteIntToProc(HANDLE hProc, DWORD_PTR baseAddr, int value)
{
    if (!WriteProcessMemory(hProc, reinterpret_cast<LPVOID>(baseAddr), &value, sizeof(value), NULL);
        throw std::runtime_error("Cannot write to process !");
}

struct HandleDeleter
{
    typedef HANDLE pointer;
    void operator()(HANDLE handle) const { CloseHandle(handle); }
};

int main()
{
    int newValue = 10;

    try
    {
        HWND hwnd = FindWindowA(NULL, "RESIDENT EVIL 2");
        if (!hwnd)
           throw std::runtime_error("Process window not found !");

        DWORD pId = 0;
        GetWindowThreadProcessId(hwnd, &pId);

        HANDLE hProc = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pId);
        if (!hProc)
            throw std::runtime_error("Cannot open process !");

        std::unique_ptr<HANDLE, HandleDeleter> hProc_deleter(hProc);

        DWORD_PTR ptr = readPointerFromProc(hProc, 0x707B6D0);
        ptr = readPointerFromProc(hProc, ptr + 0x18);
        ptr = readPointerFromProc(hProc, ptr + 0x50);
        ptr = readPointerFromProc(hProc, ptr + 0x98);
        ptr = readPointerFromProc(hProc, ptr + 0x78);
        writeIntToProc(hProc, ptr + 0x80, newValue);
    }
    catch (const std::exception &e)
    {
        std::cerr << e.what() << std::endl;
        return 0;
    }

    std::cout << "Success !" << std::endl;
    return 0;
}
0 голосов
/ 25 мая 2019

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

Вот функция, которая делает это за вас, имейте в виду, что нет проверки ошибок:

uintptr_t FindDMAAddy(HANDLE hProc, uintptr_t ptr, std::vector<unsigned int> offsets)
{
    uintptr_t addr = ptr;
    for (unsigned int i = 0; i < offsets.size(); ++i)
    {
        ReadProcessMemory(hProc, (BYTE*)addr, &addr, sizeof(addr), 0);
        addr += offsets[i];
    }
    return addr;
}

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

uintptr_t ammoAddr = FindDMAAddy(hProcess, dynamicPtrBaseAddr, { 0x374, 0x14, 0x0 });

Он не отменяет ссылку на последнее смещение, что является идеальным.

После этого вызовите WriteProcessMemory, используя возврат из этой функции в качестве аргумента lpBaseAddress.

...