Место чтения нарушения прав доступа ... это меня сбило с толку - PullRequest
0 голосов
/ 28 мая 2020

Я хочу прочитать переменную другой программы в памяти, указатель указывает на int. Я хочу это int. Но я получил ошибку.
Адрес указателя - 0x420CEFFC40, его значение - 0x420CEFFC30, буфер должен быть 123456, но доступ нарушен.

#include <Windows.h>
#include <iostream>
using namespace std;
int main()
{
    DWORD pid;
    cout<<"INPUT PID:";
    cin>>pid;
    HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,pid);
    if(hProcess==NULL)
    {
        cout<<"OpenProcess failed.Error code:"<<GetLastError()<<endl;
        system("pause");
        return EXIT_FAILURE;
    }
    uintptr_t memaddress;
    uintptr_t buffer;
    cout<<"Target memory address:";
    cin>>hex>>memaddress;
    if (!ReadProcessMemory(hProcess,(LPCVOID)&(*(uintptr_t*)memaddress),(LPVOID)&buffer,sizeof(int),NULL))
    {
        cout<<"ReadProcessMemory failed.Error code:"<<GetLastError()<<endl;
        return EXIT_FAILURE;
    }
    cout<<"buffer:"<<*(uintptr_t*)buffer<<endl;
    system("pause");
    return 0;
}

screenshot1

screenshot2

code screenshot

Я получил 'Местоположение чтения нарушения прав доступа 0x000000000CEFFC30. ' Но почему?

1 Ответ

1 голос
/ 28 мая 2020

В современных операционных системах каждый процесс имеет собственную карту памяти. Каждый процесс с одним и тем же адресом может иметь разные участки памяти или даже ничего.

Вот почему вы должны использовать системный API ReadProcessMemory , чтобы иметь возможность читать память другого процесса.

Теперь, когда вы читаете некоторую память из другого процесса (значение ptr2int), он не определяет, является ли считанное значение указателем, с точки зрения текущего процесса адрес в этой ячейке не имеет существенного значения. Этот адрес действителен в другом процессе, но в текущем процессе указывает на недопустимое местоположение.

Таким образом, в основном эта строка имеет неопределенное поведение:

cout<<"buffer:"<<*(uintptr_t*)buffer<<endl;

Это должно быть:

cout << "buffer:" << buffer << endl;

Если вам нужно прочитать, что указывает на ptr2int, вы должны снова вызвать ReadProcessMemory с соответствующими аргументами.

...