Home > Back-end >  Exception: STATUS_ACCESS_VIOLATION when trying to read value of pointer from another program
Exception: STATUS_ACCESS_VIOLATION when trying to read value of pointer from another program

Time:07-13

I am practicing the use of ReadProcessMemory and one task I have is to read the value of a pointer, and then read the value of the address stored in that pointer.

I can get up to the part of reading the value of the pointer, but every time I try to access the value stored in the address in that pointer, I get Exception: STATUS_ACCESS_VIOLATION, and I don't know why. I have tried to initialize it via = new int; but the error still persists.

Here is the program run: enter image description here

Here is my code:

dummy.cpp

#include <iostream>
#include <Windows.h>
#include <string>


// Dummy program
int main()
{
    // Variables
    int varInt = 123456;
    std::string varString = "DefaultString";
    char arrChar[128] = "Long char array right there ->";

    // Pointers
    int* ptr2int = &varInt;
    int** ptr2ptr = &ptr2int;
    int*** ptr2ptr2 = &ptr2ptr;

    // Infinite loop of process
    while (true)
    {
        // Print current process ID
        std::cout << "Process ID: " << GetCurrentProcessId() << std::endl;
        
        // Print varInt's address and value
        std::cout << "varInt " << "(0x" << &varInt << ")" << " = " << varInt << std::endl;
        // Print varStrings's address and value
        std::cout << "varString " << "(0x" << &varString << ")" << " = " << varString << std::endl;
        // Print arrChar's address and value
        std::cout << "arrChar " << "(0x" << &arrChar << ")" << " = " << arrChar << std::endl;
        
        // Same thing as above but for the 3 pointers now
        std::cout << "ptr2int " << "(0x" << &ptr2int << ")" << " = " << ptr2int << std::endl;
        std::cout << "ptr2ptr " << "(0x" << &ptr2ptr << ")" << " = " << ptr2ptr << std::endl;
        std::cout << "ptr2ptr2 " << "(0x" << &ptr2ptr2 << ")" << " = " << ptr2ptr2 << std::endl;

        std::cout << "Press ENTER to print again." << std::endl;
        getchar(); // To pause
        std::cout << "-------------------------------------" << std::endl;
    }

}

reader.cpp

#include <iostream>
#include <Windows.h>

// Program that reads memory from our dummy program
int main()
{
    int* intRead = new int;

    // Get handle
    HANDLE wHandle = OpenProcess(PROCESS_ALL_ACCESS, false, 16564);

    // Error checking
    if (wHandle == NULL)
    {
        std::cout << "ERROR! OpenProcess failed: " << GetLastError() << std::endl;
        return 1;
    }

    // Read process memory
    ReadProcessMemory(wHandle, (LPCVOID)0x00F3F990, &intRead, sizeof(int), NULL);

    // Output new value we read
    std::cout << "New value of intRead buffer is: " << *intRead << std::endl; // Throws exception when dereferencing

    // Close the open process
    CloseHandle(wHandle);

    return 0;
}

And the CORE file it generates:

[main] reader 1000 (0) exception: trapped!
[main] reader 1000 (0) exception: code 0xC0000005 at 0x401114
[main] reader 1000 (0) exception: ax 0xF3FA48 bx 0x246FF10 cx 0x8EE00000 dx 0x0
[main] reader 1000 (0) exception: si 0x0 di 0x401000 bp 0x246FEF4 sp 0x246FEE0
[main] reader 1000 (0) exception: exception is: STATUS_ACCESS_VIOLATION
[main] reader 1000 (0) stack: Stack trace:
[main] reader 1000 (0) stack: frame 0: sp = 0x246F2A8, pc = 0x6100A2C3
[main] reader 1000 (0) stack: frame 1: sp = 0x246F2E4, pc = 0x77DC8FB2
[main] reader 1000 (0) stack: frame 2: sp = 0x246F308, pc = 0x77DC8F84
[main] reader 1000 (0) stack: frame 3: sp = 0x246F3D0, pc = 0x77DA71E6
[main] reader 1000 (0) stack: frame 4: sp = 0x246FEF4, pc = 0x61004402
[main] reader 1000 (0) stack: frame 5: sp = 0x246FF3C, pc = 0x61004420
[main] reader 1000 (0) stack: frame 6: sp = 0x246FF48, pc = 0x4131EE
[main] reader 1000 (0) stack: frame 7: sp = 0x246FF58, pc = 0x40103A
[main] reader 1000 (0) stack: frame 8: sp = 0x246FF74, pc = 0x76736739
[main] reader 1000 (0) stack: frame 9: sp = 0x246FF84, pc = 0x77D98FEF
[main] reader 1000 (0) stack: frame 10: sp = 0x246FFDC, pc = 0x77D98FBD
[main] reader 1000 (0) stack: frame 11: sp = 0x246FFEC, pc = 0x0
[main] reader 1000 (0) stack: End of stack trace

Compiled using MinGW.

CodePudding user response:

You can't just retrieve a pointer with ReadProcessMemory() and then dereference it normally, like you would with pointers in your own process. You have to use ReadProcessMemory() for each value you want to read from the remote process.

0x00F3F990 is the address of ptr2int in the remote process. You are reading the value of ptr2int at that address. That value is the address of varInt in the remote process. To then read the value of varInt, you need to call ReadProcessMemory() again with the address that is in ptr2int, eg:

#include <iostream>
#include <Windows.h>

// Program that reads memory from our dummy program
int main()
{
    int varInt;
    int* ptr2int;

    // Get handle
    HANDLE wHandle = OpenProcess(PROCESS_VM_READ, false, 16564);

    // Error checking
    if (wHandle == NULL)
    {
        std::cout << "ERROR! OpenProcess failed: " << GetLastError() << std::endl;
        return 1;
    }

    // Read process memory
    ReadProcessMemory(wHandle, (LPCVOID)0x00F3F990, &ptr2int, sizeof(int*), NULL);

    // Output new value we read
    std::cout << "New value of ptr2int is: " << ptr2int << std::endl;

    // Read process memory
    ReadProcessMemory(wHandle, (LPCVOID)ptr2int, &varInt, sizeof(int), NULL);

    // Output new value we read
    std::cout << "New value of varInt is: " << varInt << std::endl;

    // Close the open process
    CloseHandle(wHandle);

    return 0;
}

CodePudding user response:

The line

ReadProcessMemory(wHandle, (LPCVOID)0x00F3F990, &intRead, sizeof(int), NULL);

is telling the API to write what it read to the pointer variable, breaking the pointer.

Change the line to

ReadProcessMemory(wHandle, (LPCVOID)0x00F3F990, intRead, sizeof(int), NULL);

(remove the & before intRead)

to have the API write to the allocated buffer.

  • Related