c++ - OpenProcess 句柄对 ReadProcessMemory 无效

标签 c++ winapi error-handling

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

如果我将 OpenProcess 部分放在 ReadDWORD 函数中,它就可以正常工作。我存放 handle 的方式有问题吗?为什么还没用就失效了?

内存.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

内存.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);
}

这并没有像您想象的那样做:它实际上并没有调用另一个构造函数,而是创建了一个被丢弃的临时对象。所以你正在打开进程,但是在一个单独的临时对象中,而这个对象保持未初始化。

更安全的方法是从两个 ctors 调用一个单独的 Initialize(offset) 方法。

(其他答案中的建议也很好;检查您的返回值,并在获得 E_INVALID_HANDLE 的位置检查句柄是否看起来像句柄。或者在 OpenHandle 和 ReadProcessMemory 处设置断点并检查两个地方都使用了相同的值。C++ 常常充满惊喜,而且通常没有什么可以替代的,只能单步执行代码以确保它按照您认为的方式执行。)

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

相关文章:

delphi - 标准用户(XP/Server 2003及以下)如何获取所有正在运行的进程的镜像路径?

reactjs - ×对象作为React子对象无效(找到: object with keys {author, quote}). If you meant to render a collection of children, use an array

c++ - 如何在 cvCvColor 之后获取对 YUV 组件的引用?

C++ STL set_union 获取错误 vector 迭代器+偏移量超出范围

c++ - KeyboardProc 返回 TRUE 会导致性能下降

c++ - 为什么 Windows 拒绝访问某些进程的名称?

node.js - 如何按照存储库模式从 nodeJS 应用程序中的服务和存储库中抛出错误

使用 Hpricot 进行 Ruby Web API 抓取/错误处理

c++ - 如何在 QGraphicsItem 上设置不透明度

c++ - 在光线追踪器中实现软阴影