2011-03-30 39 views
0

我做了这个简单的类从它打开的过程和阅读记忆: 问题是,当我打电话ReadDWORD任何内存地址ReadProcessMemory失败,错误代码6:ERROR_INVALID_HANDLE, The handle is invalid。而我无法弄清楚我做错了什么。OpenProcess处理无效的ReadProcessMemory

如果我把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; 
} 
+0

什么是m_hProc值? 'Memory :: Memory'中存在OpenProcess失败的机会。另外请注意,您不能只读取远程进程的随机地址,通常正确的虚拟地址会以某种方式传递。例如通过IPC。最后,硬编码PID不是一个好主意,每当你重新测试应用程序时,你都必须改变它。 – Andrey 2011-03-30 23:08:19

+0

我检查了Memory :: Memory中的m_hProc,它并没有失败。在ReadDWORD中m_hProc与Memory :: Memory中的不同。 – sippeangelo 2011-03-30 23:16:40

回答

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

这不是在做你认为它在做的事情:它实际上并没有调用其他构造函数,而是创建了一个被丢弃的临时对象。所以你打开这个过程,但是在一个单独的临时对象中,而这个对象保持未初始化。

更安全的方法是从两个ctors调用一个单独的Initialize(偏移量)方法。 (在其他答案中的建议也很好;检查你的返回值,以及你在哪里得到一个E_INVALID_HANDLE,检查句柄是否看起来像一个句柄;或者在OpenHandle和ReadProcessMemory中设置一个断点并检查在这两个地方使用相同的值C++经常充满惊喜,并且通常无法替代仅仅通过代码来确保它按照您的想法行事)

0

要访问其他进程,你经常需要启用某些特权。想起了SeDebugPrivilege。见here。否则,请参阅Hans Passant的建议(即GetLastError)。

0

您可以使用RtlAdjustPrivilege函数获得SeDebugPrivilege。

NTSTATUS NTAPI RtlAdjustPrivilege(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN); /*This is the 
protoype of RtlAdjustPrivilege function.*/