Search code examples
c++memory-managementread-write

Fill allocated memory with data from another process


Okay, this question is not regular, and maybe stupid, cause im not familiar with pointers and links in c++:

So i have some data in memory of another process (http://prntscr.com/zmfb4p), it's about 1200-1600 bytes. I have a driver, which can do kernel read-write to needed process. I have a user-mode application, which one communicate with driver like that:

int reading_data = driver.readvirtualmemory<int>(<processId>, <adress to read>, <size to read>);

It works as intended with small data types, but i can't understand, how to get "large" amount of bytes and store it:

Allocating memory to store data:

char* test_buf = new char[size_matricies_buffer];    // allocating memory and creating a pointer to it ~1200-1600 depends on situation
*test_buf = driver.ReadVirtualMemory<char>(<process>, <address>, static_cast<uint32_t>(size_matricies_buffer));  // filling allocated memory with data?

It compiles, and works, but when im trying to get access to *test i get an error:

cout << "buf: " << *test_buf << " | " << &test_buf << endl;

Unhandled exception at 0x00007FF6D1DD1671 in Mysoftware.exe: 0xC0000005: Access violation writing location 0x00000000C21C833C.

Any idea what im missing here?


Solution

  • So basic function readVirtualMemory doin this(i guess i presented too short explanation above, but nvm now):

    template <typename type>
    type ReadVirtualMemory(ULONG64 ProcessId, ULONG64 ReadAddress, SIZE_T Size)
    {
        type Buffer;
    
        KERNEL_READ_REQUEST ReadRequest;
    
        ReadRequest.ProcessId = ProcessId;
        ReadRequest.Address = ReadAddress;
        ReadRequest.pBuff = &Buffer;
        ReadRequest.Size = Size;
    
        if (DeviceIoControl(hDriver, IO_READ_REQUEST, &ReadRequest, sizeof(ReadRequest), &ReadRequest, sizeof(ReadRequest), 0, 0))
        {
            return Buffer;
        }
    
        return Buffer;
    }
    

    And KERNEL_READ_REQUEST is:

       typedef struct _KERNEL_READ_REQUEST
    {
        ULONG64 ProcessId;
        ULONG64 Address;
        PVOID64 pBuff;
        ULONG64 Size;
    
    } KERNEL_READ_REQUEST, * PKERNEL_READ_REQUEST;
    

    So the problem was with necessary type definition in original function and structure of function. Problem was solved with next solution: adding a new kernel_read function, without type declaration, with pointer to buffer which needs to be filled by read data. (thanks to @SamiKuhmonen for idea):

        bool ReadBuffer(ULONG64 ProcessId, void* buffer, ULONG64 ReadAddress, SIZE_T Size, bool secondary = false)
    {
        KERNEL_READ_REQUEST ReadRequest;
    
        ReadRequest.ProcessId = ProcessId;
        ReadRequest.Address = ReadAddress;
        ReadRequest.pBuff = buffer;
        ReadRequest.Size = Size;
    
        if (DeviceIoControl(hDriver, IO_READ_REQUEST, &ReadRequest, sizeof(ReadRequest), &ReadRequest, sizeof(ReadRequest), 0, 0))
        {
            return true;
        }
    
        return false;
    }
    

    After that my buffer

    char* matricies_buf_buf = new char[size_matricies_buffer];
    driver.ReadBuffer(pid, matricies_buf_buf, transform_data[0], size_matricies_buffer);
    

    was filled with needed data.

    sry for some ppl, who was annoyed with that question, it's my first time when i trying to ask a question and stackoverflow.