Неверный дескриптор OpenProcess для ReadProcessMemory - PullRequest
0 голосов
/ 31 марта 2011

Я сделал этот простой класс, чтобы открыть процесс и прочитать из него память: Проблема в том, что когда я вызываю 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;
}

Ответы [ 3 ]

2 голосов
/ 31 марта 2011
Memory::Memory()
{
    Memory(0);
}

Это не делает то, что вы думаете, что делает: на самом деле это не вызов другого конструктора, а создание временного объекта, который отбрасывается.Таким образом, вы открываете процесс, но в отдельном временном объекте, в то время как этот объект остается неинициализированным.

Более безопасный подход - использовать отдельный метод Initialize (offset), который вы вызываете из обоих ctors.

(Совет в других ответах также хорош; проверьте ваши возвращаемые значения, и где вы получите E_INVALID_HANDLE, проверьте, что дескриптор выглядит как дескриптор. Или установите точку останова в OpenHandle и ReadProcessMemory и проверьте, что то же самоеЗначение используется в обоих местах. C ++ часто полон сюрпризов, и часто нет замены простому пошаговому выполнению кода, чтобы убедиться, что он делает то, что, как вы думаете, он делает.)

0 голосов
/ 30 марта 2013

Вы можете использовать функцию RtlAdjustPrivilege, чтобы получить SeDebugPrivilege.

NTSTATUS NTAPI RtlAdjustPrivilege(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN); /*This is the
protoype of RtlAdjustPrivilege function.*/
0 голосов
/ 31 марта 2011

Чтобы получить доступ к другим процессам, вам часто необходимо включить определенные привилегии. SeDebugPrivilege приходит на ум. Смотрите здесь . В противном случае см. Предложение Ханса Пассанта (т. Е. GetLastError).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...