从“.exe"读取内存+ 抵消? [英] Reading memory from ".exe" + offset?

查看:68
本文介绍了从“.exe"读取内存+ 抵消?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 WinAPI 的 ReadProcessMemory() 从游戏中读取一些隐藏"信息.

我使用 Cheat Engine 来找出静态指针,但我不知道如何读取它们.作弊引擎给了我一个这样的指针:"mygame.exe"+1C50

我是 WinAPI 的新手,如何将 "mygame.exe"+1C50 转换为我可以使用 ReadProcessMemory() 读取的地址?>

我尝试简化问题,但我想我应该首先给出完整的代码.所以我在这里使用静态地址和多级指针,但我仍然坚持获取基地址或 w/e.

这是完整的代码和我的作弊引擎地址的图片:

#include #include #include 使用命名空间标准;处理 GetProcessHandle(const char *procName);int main(){const char *procName = "prism3d.exe";处理 hProc = GetProcessHandle(procName);如果(hProc){/* 如果我使用动态地址 (f.e. 0x02C2C4DC),这有效,但是每次我重新启动游戏时它都会改变.我需要使用静态地址(prism3d.exe+A1C)来获取我的核弹"的动态地址.*/漂浮核弹;ReadProcessMemory(hProc, (void*)0x02C2C4DC, &nuke, 4, 0);cout<<核弹;}CloseHandle(hProc);返回0;}处理 GetProcessHandle(const char *procName){处理 hProc = NULL;PROCESSENTRY32 pe32;pe32.dwSize = sizeof(PROCESSENTRY32);HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (Process32First(hSnapshot, &pe32)) {做 {如果(!strcmp(pe32.szExeFile,procName)){hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);休息;}} while (Process32Next(hSnapshot, &pe32));}CloseHandle(hSnapshot);返回 hProc;}

编辑 2:这是我尝试读取核弹的值的方法,但它给了我随机数,每次重新启动游戏时都不同(有时是 0,有时是 324324324 等..):

if (hProc) [DWORD baseAddr = (DWORD)GetModuleHandle(procName) + 0xA1C50;//也用 GetModuleHandle(NULL) 试过这个DWORD 主地址;ReadProcessMemory(hProc, (void*)(baseAddr + 0x111C), &mainAddr, 4, 0);//核弹漂浮核弹;DWORD nukeAddr;ReadProcessMemory(hProc, (void*)(mainAddr + 0x48), &nukeAddr, 4, 0);ReadProcessMemory(hProc, (void*)nukeAddr, &nuke, 4, 0);cout<<核弹;}

解决方案

基本偏移量一般是模块在内存中的开始位置,你可以用 GetModuleHandle 得到这个(这个返回的地址是内存中 PE 的开始).我之所以这么说,是因为一些约定定义了相对于代码部分开头的基数,然后您需要从 PE 中读取.

您可以执行以下操作:

UINT_PTR addr = (UINT_PTR)GetModuleHandle("game.dll") + 0x1C50;ReadProcessMemory(hProc,(void*)addr,pBuffer,nSize,&BytesRead);

以上仅当您在目标进程的地址空间中运行(通过 dll 注入)时才有效,要通过远程进程(如您的示例所示)执行此操作,您需要枚举进程模块以获取您感兴趣的模块的有效句柄.

MSDN 有一个例子 here,稍微重构一下,您可以创建一个函数来检查名称并返回 HMODULE 如果匹配,转换这将为您提供模块基址.

I'm using WinAPI's ReadProcessMemory() to read some "hidden" information from a game.

I've used Cheat Engine to find out the static pointers, but I don't know how to read from them. Cheat Engine gives me a pointer to something like this: "mygame.exe"+1C50

I'm really new to WinAPI, how do I convert "mygame.exe"+1C50 to an address that I can read with ReadProcessMemory()?

EDIT: I tried simplifying the problem, but I guess I should've just given the full code in the first place. So I'm working with static addresses and multi level pointers here, but I'm still stuck with getting the base address or w/e.

Here's the full code and a picture of my cheat engine address:

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

using namespace std;

HANDLE GetProcessHandle(const char *procName);

int main()
{
    const char *procName = "prism3d.exe";
    HANDLE hProc = GetProcessHandle(procName);
    if (hProc) {

     /* This works if I use the dynamic address (f.e. 0x02C2C4DC),
        but it changes every time I restart the game.
        I need to use the static address (prism3d.exe+A1C) to get
        the dynamic address for my "nuke".
      */
        float nuke;
        ReadProcessMemory(hProc, (void*)0x02C2C4DC, &nuke, 4, 0);
        cout << nuke;

    }
    CloseHandle(hProc);
    return 0;
}

HANDLE GetProcessHandle(const char *procName)
{
    HANDLE hProc = NULL;
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (Process32First(hSnapshot, &pe32)) {
        do {
            if (!strcmp(pe32.szExeFile, procName)) {
                hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
                break;
            }
        } while (Process32Next(hSnapshot, &pe32));
    }
    CloseHandle(hSnapshot);
    return hProc;
}

Edit 2: Here's how I tried reading the value of my nuke, but it gives me random numbers, different every time I restart the game (sometimes it's 0, sometimes 324324324, etc...):

if (hProc) [

    DWORD baseAddr = (DWORD)GetModuleHandle(procName) + 0xA1C50; // also tried this with GetModuleHandle(NULL)
    DWORD mainAddr;
    ReadProcessMemory(hProc, (void*)(baseAddr + 0x111C), &mainAddr, 4, 0);

    // Nuke
    float nuke;
    DWORD nukeAddr;
    ReadProcessMemory(hProc, (void*)(mainAddr + 0x48), &nukeAddr, 4, 0);
    ReadProcessMemory(hProc, (void*)nukeAddr, &nuke, 4, 0);
    cout << nuke;
}

解决方案

The base offset is generally the start of the module in memory, you can get this with GetModuleHandle (the address this returns is the start of the PE in memory). I say generally because some conventions define the base relative to the start of the code section, which you then need to read from the PE.

you can do something such as the following:

UINT_PTR addr = (UINT_PTR)GetModuleHandle("game.dll") + 0x1C50;
ReadProcessMemory(hProc,(void*)addr,pBuffer,nSize,&BytesRead);

The above only works if you are running in the address space of the process you are targeting (via dll injection), to do this via a remote process (as your example shows) you need to enumerate to process modules to get a valid handle to the module you are interested in.

MSDN has an example of that here, refactoring it a bit, you can create a function that checks against the name and return the HMODULE if it matches, casting this will give you the module base address.

这篇关于从“.exe"读取内存+ 抵消?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆