我制作了这个简单的类来打开进程并从中读取内存:
问题是当我用任何内存地址ReadDWORD调用ReadProcessMemory时失败,错误代码为6:ERROR_INVALID_HANDLE, The handle is invalid。而且我不知道我在做什么错。

如果我将OpenProcess部分放在ReadDWORD函数中,则可以正常工作。我存放手柄的方式有问题吗?为什么在使用前无效?

Memory.h

#ifndef MEMORY_H
#define MEMORY_H

#include <windows.h>
#include <psapi.h>
#pragma comment(lib, "psapi.lib")
#include <iostream>

class Memory
{
public:
    Memory();
    Memory(DWORD offset);
    ~Memory();

    DWORD ReadDWORD(DWORD addr);
private:
    HANDLE m_hProc;
    DWORD m_Offset;

};

#endif

Memory.cpp
#include "Memory.h"

Memory::Memory()
{
    Memory(0);
}

Memory::Memory(DWORD offset)
{
    m_hProc = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, 5444); // 5444 is the PID of a process I'm testing this with
    m_Offset = offset;
}

Memory::~Memory()
{
    CloseHandle(m_hProc);
}

DWORD Memory::ReadDWORD(DWORD addr)
{
    // Optional memory offset
    addr += m_Offset;

    DWORD value = -1;
    int result = ReadProcessMemory(m_hProc, (LPVOID)addr, &value, sizeof(DWORD), NULL);
    if (result == 0)
        std::cout << "ReadProcessMemory error: " << GetLastError() << std::endl;

    return value;
}

最佳答案

Memory::Memory()
{
    Memory(0);
}

这并没有做您想做的事情:实际上并没有在调用另一个构造函数,而是创建了一个被丢弃的临时对象。因此,您正在打开进程,但在一个单独的临时对象中,而此对象仍未初始化。

比较安全的方法是有一个从两个ctor调用的单独的Initialize(offset)方法。

(其他答案中的建议也很好;请检查您的返回值,并在获取E_INVALID_HANDLE的位置上,检查该句柄看起来像一个句柄。或者在OpenHandle和ReadProcessMemory处设置断点,并检查相同的值C++经常充满惊喜,并且通常没有什么可替代的,只能单步执行代码以确保它在执行您认为正在执行的操作。)

关于c++ - OpenProcess句柄对ReadProcessMemory无效,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5493395/

10-13 07:00