C++ 从模块大小内的进程中读取所有内存 [英] C++ read all memory from process within modulesize

查看:48
本文介绍了C++ 从模块大小内的进程中读取所有内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试仅读取进程范围内的所有内存地址,(请参阅问题:C++ 只读取进程范围内的内存地址).我成功地从内存中读取,似乎我收到了正确的 baseaddress 进程.我遇到的问题是找到我认为程序会有的特定值.

I have been trying to read all memory addresses within a process range only, (see question: C++ read memory addresses within process range only). I succeeded with reading from memory and it seems like I received the correct baseaddress for the process. The problem I was having was to find specific values which I assumed the program would have.

例如,如果我玩了一个游戏并且得分为 500,我想在内存中找到 500.我遍历了所有地址,但找不到值.所以我决定阅读我自己的程序(64 位)并将值设置为 500,打印其地址并手动搜索并查看是否找到它.

For example if I played a game and had the score 500, I wanted to find 500 in the memory. I stepped through all the addresses but could not find the value. So I decided to read my own program (which is 64-bit) and set a value to 500, print its address and manually search and see if I found it.

int number = 500;
std::cout << &number;

由于某种原因,写入的地址超出了进程范围.

For some reason the address it was written to was out of bounds of the process range.

我计算地址范围:

uintptr_t moduleBase = GetModuleBaseAddress(procId, L"x.exe");
uintptr_t moduleSize = GetModuleSize(procId, L"x.exe");

// Set base and last address and print them for user
uintptr_t dynamicPtrBaseAddr = moduleBase;
uintptr_t dynamicPtrLastAddr = (moduleBase + moduleSize);

使用的方法:

uintptr_t GetModuleSize(DWORD procId, const wchar_t* modName) {
        uintptr_t modBaseSize = 0;
        HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | 0x10, procId);
        if(hSnap != INVALID_HANDLE_VALUE) {
            MODULEENTRY32 modEntry;
            modEntry.dwSize = sizeof(modEntry);
            if(Module32First(hSnap, &modEntry)) {
                do {
                    if(!_wcsicmp(modEntry.szModule, modName)) {
                        modBaseSize = (uintptr_t)modEntry.modBaseSize;
                        break;
                    }
                } while(Module32Next(hSnap, &modEntry));
            }
        }
        CloseHandle(hSnap);
        return modBaseSize;
    }

uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName) {
    uintptr_t modBaseAddr = 0;
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | 0x10, procId);
    if(hSnap != INVALID_HANDLE_VALUE) {
        MODULEENTRY32 modEntry;
        modEntry.dwSize = sizeof(modEntry);
        if(Module32First(hSnap, &modEntry)) {
            do {
                if(!_wcsicmp(modEntry.szModule, modName)) {
                    modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
                    break;
                }
            } while(Module32Next(hSnap, &modEntry));
        }
    }
    CloseHandle(hSnap);
    return modBaseAddr;
}

由于 number 的值超出范围,我认为 GetModuleSize 可能不正确.

Since the value of number is written out of bounds I assume that GetModuleSize, might be incorrect.

我的最后一个地址是:0x4F4628std::cout <<&number; 给我 0x6DFDD4

Last address for me is: 0x4F4628, std::cout << &number; gives me 0x6DFDD4

我的问题是:

  • GetModuleSize 计算最后地址的方法不正确吗?应用程序?如果是这样,我可以更正吗?
  • 通过将最后一个地址乘以 2,我能够读取该值&number.这是因为 modulesize 给了我一个 32 位的范围,还是这给了我超出进程范围的地址?
  • Is GetModuleSize an incorrect way of calculating the last address for the application? If so, can I correct it?
  • By multiplying the last address with 2, I was able to read the value of &number. Is this because modulesize gives me a 32-bit range or is this giving me addresses out of bounds for the process?

我使用:g++ main.cpp -ox -lpsapi -DUNICODE -m64 编译,并且必须将 libgcc_s_seh-1.dll 添加到我的路径中才能运行我的程序.

I compile with: g++ main.cpp -o x -lpsapi -DUNICODE -m64, and had to add libgcc_s_seh-1.dll to my path in order to run my program.

我在 github 上的整个项目:https://github.com/Darclander/memory-reading

My entire project on github: https://github.com/Darclander/memory-reading

(不知道把整个代码贴在这里对我来说是否更好).

(Not sure if it is better for me to post the entire code on here).

推荐答案

WIN32 术语中的模块"是可执行的映像文件.该图像包含代码、静态变量、堆栈展开表等内容.您尝试读取的值是一个局部变量,因此将在堆栈上分配.堆栈不是图像的一部分,因此您不会在那里找到它.

A "module" in WIN32 terms is an executable image file. This image contains things like code, static variables, stack unwind tables and more. The value you are attempting to read is a local variable and thus will be allocated on the stack. The stack is not part of the image, so you won't find it there.

您需要做的是找到堆栈的地址和大小.请参阅如何定位进程'Win32 中的全局和堆栈区域? 关于如何做到这一点.

What you need to do is find the address and size of the stack. See How can I locate a process' global and stack areas in Win32? on how to do that.

除了堆栈,您可能还想读取堆,您可以使用 GetProcessHeaps 并使用 HeapSummary.

You probably also want to read the heap in addition to the stack, you can find all open heaps by using GetProcessHeaps and get the addresses/sizes with HeapSummary.

这篇关于C++ 从模块大小内的进程中读取所有内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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