首页 > 解决方案 > Windows 内核:为什么我的内存映射不起作用?

问题描述

MmAllocateContiguousMemorySpecifyCache我有一个 kmdf,它使用并获取它的 mdl分配一个缓冲区:

auto ptr = MmAllocateContiguousMemorySpecifyCache(
    BUFFER_SIZE,
    lowestAcceptible,
    highestAcceptible,
    lowestAcceptible,
    MmCached);

PQUEUE_CONTEXT queueContext = QueueGetContext(queue);
if (ptr)
{
    RtlZeroMemory(ptr, BUFFER_SIZE);
    queueContext->stage_buffer_ptr = ptr;
    queueContext->stage_buffer_byte_size = BUFFER_SIZE;
    queueContext->stage_buffer_bus_address = MmGetPhysicalAddress(ptr).QuadPart;
    queueContext->mdl = IoAllocateMdl(
        ptr,
        static_cast<ULONG>(queueContext->stage_buffer_byte_size),
        false,
        false,
        nullptr
    );

一旦分配了该缓冲区,驱动程序就会处理一个 ioctl(两个方法都没有),它将预分配的缓冲区映射到请求的进程地址空间,使用MmMapLockedPagesSpecifyCache

auto queueContext = QueueGetContext(Queue);

auto user_ptr = MmMapLockedPagesSpecifyCache(
     queueContext->mdl,
     UserMode,
     MmCached,
     nullptr,
     false,
     MM_PAGE_PRIORITY::HighPagePriority
);

几行之后,我用测试值填充内存:

auto vals = (int*)queueContext->stage_buffer_ptr; // kernel virtual address
for (auto i = 0; i < 10; ++i)
{
    vals[i] = i;
}

但是当用户在其映射地址上循环时,它会得到垃圾值。
我尝试使用 WinDbg 调试此问题,当我在循环后中断时,我看到以下内容:

内核虚拟地址:

1: kd> dc 0xffffb901`c6f5d000 (ok)

ffffb901`c6f5d000  00000000 00000001 00000002 00000003  ................
ffffb901`c6f5d010  00000004 00000005 00000006 00000007  ................
ffffb901`c6f5d020  00000008 00000009 00000000 00000000  ................
ffffb901`c6f5d030  00000000 00000000 00000000 00000000

用户虚拟地址:(显示垃圾)

1: kd> dc 0x00000174`423f0000

00000174`423f0000  332c3000 ffffcc05 bc823afb 01d40a37  .0,3.....:..7...
00000174`423f0010  5e784ab3 01d5da99 5e784ab3 01d5da99  .Jx^.....Jx^....
00000174`423f0020  b1de413c 01d5db3f 00002000 00000000  <A..?.... ......
00000174`423f0030  00002000 00000000 00000010 00000000  . ..............

那么为什么我没有通过接收到的指针看到相同的值MmMapLockedPagesSpecifyCache呢?

标签: windowsdriverkmdfwdmwdf

解决方案


推荐阅读