c++ - 如何扫描另一个进程内存中的 INT 值

标签 c++ windows virtual-memory

我一直在尝试找到一种好方法来扫描另一个程序内存中的特定值(int)。我现在所拥有的确实有效,但我确信还有更好的方法和更快的方法。

DWORD pid;
DWORD Money = 0x04661128; //Address of money in-game
int MyMoney;
int MyMoneyReal;

int main()
{
    HWND hWnd = FindWindowA(0, ("Euro Truck Simulator 2"));
    GetWindowThreadProcessId(hWnd, &pid);
    HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    cout << "Please input your exact current money value!" << pid << endl;
    cin >> MyMoneyReal;
    for (int i = 0; i < 0x7FFFFFFF; i++) {
        ReadProcessMemory(pHandle, (LPVOID)i, &MyMoney, sizeof(MyMoney), 0);
        if (MyMoney == MyMoneyReal) {
            cout << "Found a match: " << MyMoney << MyMoneyReal << " With HEX value: " << hex << i << endl;
        }
    }
    cout << "Processing...";
}

如您所见,我创建了一个 int MyMoney 和 MyMoneyReal。然后我继续从程序存储器中的 0 到 0x7FFFFFFF 进行扫描,以查找包含 MyMoneyReal 的所有地址。 这需要很长时间才能完成,我确信有更好的方法,但我不知道如何实现。

我应该补充一点:我对 C++ 很陌生,所以任何额外的帮助总是很好:)

最佳答案

您的循环调用了 ReadProcessMemory 2147483647 次。

每次调用它时,它都必须验证内存是否可读,然后将 sizeof(int) 字节复制到缓冲区中。它有它的成本...

您可以读取例如 1MB 的内存块,从而减少对 ReadProcessMemory 的调用。然后您可以像现在一样在本地处理每个 block 。简化版:

constexpr unsigned CHUNK_SIZE = 0x100000;
constexpr unsigned MAX_ADDRESS = 0x7FFFFFFF;
//remember to make sure stack is big enough or allocate it on heap
char buffer[CHUNK_SIZE];

for (unsigned i = 0; i < MAX_ADDRESS; i += CHUNK_SIZE) {
    if (ReadProcessMemory(hProcess, (LPVOID)i, buffer, sizeof(buffer), nullptr)) {
        for (int j = 0; j <= CHUNK_SIZE - sizeof(int); ++j) {
            int something;
            memcpy(&something, buffer + j, sizeof(int));
            //...
        }
    }
}

正如您在内部 for 中看到的,我们一直读取到 CHUNK_SIZE - sizeof(int) 因为我们不想读取超过缓冲区末尾的内容。然而,我的示例中的外循环无法正确处理它,我们跳过了一些字节。这很容易修复,我把它留给你。

当然,您的缓冲区可以更大/更小。您必须尝试并衡量。

注意:这仍然是很多操作。我们只是限制对可能昂贵的 ReadProcessMemory 的调用次数。您应该尝试限制您的地址范围。我很确定大多数对 ReadProcessMemory 的调用都会失败。正如评论中所建议的,一种是使用 VirtualQueryEx

关于c++ - 如何扫描另一个进程内存中的 INT 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42464068/

相关文章:

c - 将虚拟地址映射回物理地址

Linux:如何检测进程是否抖动过多?

c++ - 复制构造函数不起作用?

c++ - 参数包参数消耗

c# - 以编程方式对开始菜单进行排序

c++ - 什么会导致页面缓冲池增加?

ios - 如何找到 EXC_BAD_ACCESS 异常的地址?

c++ - SQL Server 的批量复制 (C API) 和 ODBC 驱动程序

c++ - 如何捕获从 MFC web 浏览器 c++ 发出的 GET/POST 请求

windows - 将 IPython 配置为使用 powershell 而不是 cmd