简体   繁体   中英

OpenProcess handle invalid for ReadProcessMemory

I've made this simple class to open a process and read memory from it: The problem is when I call ReadDWORD with any memory address ReadProcessMemory fails with error code 6: ERROR_INVALID_HANDLE, The handle is invalid . And I can't figure out what I'm doing wrong.

If I put the OpenProcess part in the ReadDWORD function it works fine. Is there something wrong with how I store the handle? Why does it become invalid before I use it?

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);
}

This isn't doing what you think its doing: it's not actually calling the other constructor, instead it's creating a temporary that gets discarded. So you are opening the process, but in a separate temporary object, while this object remains uninitialized.

Safer approach is to have a separate Initialize(offset) method that you call from both ctors.

(The advice in the other answers is also good; check your return values, and where you get a E_INVALID_HANDLE, check that the handle is something that looks like a handle. Or set a breakpoint at the OpenHandle and ReadProcessMemory and check that the same value is being used in both places. C++ is often full of surprises, and there's often no substitute for just stepping through the code to make sure it's doing what you think it's doing.)

You can use RtlAdjustPrivilege function to get SeDebugPrivilege.

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

To access other processes, you often need to enable certain privileges. SeDebugPrivilege comes to mind. See here . Otherwise see the suggestion from Hans Passant (ie GetLastError ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM