【问题标题】:Fill allocated memory with data from another process用来自另一个进程的数据填充分配的内存
【发布时间】:2021-02-15 16:52:13
【问题描述】:

好吧,这个问题不正常,而且可能很愚蠢,因为我不熟悉 c++ 中的指针和链接:

所以我在另一个进程 (http://prntscr.com/zmfb4p) 的内存中有一些数据,大约 1200-1600 字节。 我有一个驱动程序,它可以对需要的进程进行内核读写。 我有一个用户模式应用程序,它与驱动程序的通信方式如下:

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

它适用于小数据类型,但我不明白如何获取“大量”字节并存储它:

分配内存来存储数据:

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?

它可以编译并且可以工作,但是当我尝试访问 *test 时出现错误:

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

Mysoftware.exe 中 0x00007FF6D1DD1671 处未处理的异常:0xC0000005:访问冲突写入位置 0x00000000C21C833C。

知道我在这里缺少什么吗?

【问题讨论】:

  • 违规写入位置 0x00000000C21C833C 您的操作系统说您尝试写入数据。我不确定错误是否来自显示的行。
  • 分配内存然后读取一个块并返回一些内容并将其放入char 是没有意义的。 ReadVirtualMemory 到底是做什么的?为什么不给它一个缓冲区来复制数据呢?
  • 是的,也许我很困惑,因为 *test_buf = driver. 在我运行解决方案时由 VS 完成。
  • 这个函数没有意义,因为它返回一个 int? Int 是 4 个字节,所以如果我让函数读取 5 个字节会发生什么,它如何返回额外的字节?
  • cout &lt;&lt; "buf: " &lt;&lt; *test_buf 中,*test_buf 很可能不是以空字符结尾的字符串。虽然我希望Access violation reading location 而不是Access violation writing location

标签: c++ memory-management read-write


【解决方案1】:

所以基本函数 readVirtualMemory 是这样做的(我想我上面的解释太短了,但现在是 nvm):

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

KERNEL_READ_REQUEST 是:

   typedef struct _KERNEL_READ_REQUEST
{
    ULONG64 ProcessId;
    ULONG64 Address;
    PVOID64 pBuff;
    ULONG64 Size;

} KERNEL_READ_REQUEST, * PKERNEL_READ_REQUEST;

所以问题在于原始函数和函数结构中的必要类型定义。下一个解决方案解决了问题:添加一个新的 kernel_read 函数,没有类型声明,带有指向缓冲区的指针,该缓冲区需要被读取数据填充。 (感谢@SamiKuhmonen 的想法):

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

在那之后我的缓冲区

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

充满了所需的数据。

对于一些对这个问题感到恼火的人来说,这是我第一次尝试提出问题和 stackoverflow。

【讨论】:

    猜你喜欢
    • 2021-12-25
    • 2013-04-25
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 1970-01-01
    • 2018-04-20
    • 1970-01-01
    相关资源
    最近更新 更多