2011-03-30 65 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.*/