【问题标题】:how do i use a memory address from cheat engine with ReadProcessMemory?我如何使用来自作弊引擎的内存地址和 ReadProcessMemory?
【发布时间】:2015-07-09 07:25:02
【问题描述】:

我正在尝试制作一个监控 GTA 5 中角色速度的应用程序,iv 用作弊引擎找到了变量的地址:http://i.stack.imgur.com/klyYV.png

我做了一个函数来打开游戏进程的句柄:

/*returns INVALID_HANDLE_VALUE on failure*/ 
HANDLE openProcessByName(const char* name, DWORD access){
    PROCESSENTRY32 process;
    process.dwSize = sizeof(PROCESSENTRY32);

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

    if(Process32First(snapshot, &process) == FALSE){//failure
        CloseHandle(snapshot);
        return INVALID_HANDLE_VALUE;
    }

    while(Process32Next(snapshot, &process) == TRUE){//skips first but thats system anyway
        if(_stricmp(process.szExeFile, name) == 0){//found it
            HANDLE processHandle = OpenProcess(access, FALSE, process.th32ProcessID);
            CloseHandle(snapshot);
            return processHandle;
        }
    }

    CloseHandle(snapshot);
    return INVALID_HANDLE_VALUE;//reached if the process is not found and its handle not returned above
}

在 main 中,我得到句柄并尝试像这样读取内存位置:

#include <tlhelp32.h>
#include <iostream>

HANDLE openProcessByName(const char* name, DWORD access);

int main(){
    HANDLE processHandle = openProcessByName("GTA5.exe", PROCESS_VM_READ);
    if (processHandle == INVALID_HANDLE_VALUE){
        std::cout << "invalid handle value" << std::endl;
        return 0;
    }

    float speed = 0.00;
    if (ReadProcessMemory(processHandle, (LPCVOID)0x7FF65EEA3940, &speed, (DWORD)sizeof(speed), NULL) == 0){
        std::cout << "failed to read value" << std::endl;
        std::cout << GetLastError() << std::endl;//return 299
    }else{
        std::cout << speed << std::endl;
    }

    CloseHandle(processHandle);
    return 0;
}

但它失败并打印“读取值失败”。 我假设这与地址偏移有关,我一直在查找它,但我真的不明白人们在说什么。顺便说一句,内存位置不是静态的,并且在游戏重新启动时会发生变化,但我想至少在我尝试找到一种动态获取它的方法之前让它与实际内存地址一起工作。

那么我如何根据作弊引擎中显示的地址找到与 ReadProcessMemory 函数一起使用的实际内存地址。

【问题讨论】:

  • GetLastError() 返回什么?
  • ERROR_PARTIAL_COPY 299 (0x12B) 只有部分 ReadProcessMemory 或 WriteProcessMemory 请求完成。

标签: windows-applications readprocessmemory cheat-engine


【解决方案1】:

这就是我最终这样做的方式(代码已被简化且未经测试)。 该地址需要偏移游戏进程主模块的基地址。

void read() {
    MODULEENTRY32 mainModule = {0};
    HANDLE process = openProcessByName(PROCESS_NAME, PROCESS_VM_READ, &mainModule);

    float rawSpeed = 0.00f;
    ReadProcessMemory(process, (LPCVOID)(mainModule.modBaseAddr + MEMORY_ADDRESS), &rawSpeed, sizeof(rawSpeed), NULL);
}

//returns INVALID_HANDLE_VALUE on failure
HANDLE openProcessByName(const char* name, DWORD access, MODULEENTRY32* mainModule) {
    PROCESSENTRY32 process;
    process.dwSize = sizeof(PROCESSENTRY32);

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

    if (Process32First(snapshot, &process) == FALSE) {//failure
        CloseHandle(snapshot);
        return INVALID_HANDLE_VALUE;
    }

    while (Process32Next(snapshot, &process) == TRUE) {//skips first but thats system anyway
        if (_stricmp(process.szExeFile, name) == 0) {//found it

            HANDLE modSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, process.th32ProcessID);
            mainModule->dwSize = sizeof(MODULEENTRY32);
            Module32First(modSnapshot, mainModule);

            HANDLE processHandle = OpenProcess(access, FALSE, process.th32ProcessID);

            CloseHandle(modSnapshot);
            CloseHandle(snapshot);
            return processHandle;
        }
    }

    CloseHandle(snapshot);
    return INVALID_HANDLE_VALUE;//reached if the process is not found and its handle not returned above
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-12
    • 2021-01-14
    • 2016-03-31
    相关资源
    最近更新 更多