5

本质上,我正在寻找一个可以为内核模式做的功能,就像VirtualProtect为用户模式做的一样。

我使用以下简化代码示例的逻辑分配内存。

    PMDL mdl = MmAllocatePagesForMdl    
    (
        LowAddress,
        HighAddress,
        SkipAddress,
        size
    );

    ULONG flags = NormalPagePriority | MdlMappingNoExecute | MdlMappingNoWrite;
    PVOID ptr = MmGetSystemAddressForMdlSafe
    (
        mdl, 
        flags
    );

和标志仅对 Win8+ 有效 MdlMappingNoExecute。此外,仅使用我不能为内存区域分配例如保护。MdlMappingNoWrite
MmGetSystemAddressForMdlSafeNoAccess

我可以使用任何其他或替代的 API 来修改分配内存的页面保护吗?
黑客也可以这样做,因为目前此功能不会在生产代码中使用。

4

2 回答 2

2
C:\Windows\System32>dumpbin /exports ntdll.dll | find "Protect"
        391  17E 0004C030 NtProtectVirtualMemory
       1077  42C 000CE8F0 RtlProtectHeap
       1638  65D 0004C030 ZwProtectVirtualMemory

我认为您可以Zw从内核模式调用函数,并且args通常与相应Nt函数相同。虽然ZwProtectVirtualMemory没有记录,但有一个记录在案的ZwAllocateVirtualMemory接受保护标志。

另一种方法可能是在用户模式下分配和保护虚拟内存,将缓冲区向下传递给驱动程序,然后在那里创建相应的 MDL。

于 2016-08-01T17:11:04.567 回答
1

我目前最终使用的代码如下。
所有使用的 API 都是官方的。 在这里,我为分配的内存的子范围
创建了另一个mdl ,并更改了该子范围的保护。

如果您使用下面的这种方法保护了内存,那么:

  • IRQL < DISPATCH_LEVEL您将遇到PAGE_FAULT_IN_NONPAGED_AREA错误(引用了无效的系统内存。这不能由 try-except 保护,它必须由 Probe 保护。通常地址只是简单的错误或者它指向已释放的内存。)
  • IRQL == DISPATCH_LEVEL您将遇到 DRIVER_IRQL_NOT_LESS_OR_EQUAL错误(尝试以过高的中断请求级别 (IRQL) 访问可分页(或完全无效)地址。这通常是由驱动程序使用不正确的地址引起的。)

请注意,如果子范围大页面分配的一部分,则更改保护可能会失败。那么status就有可能STATUS_NOT_SUPPORTED。 如果最初分配的内存区域的大小和对齐方式(取决于问题中的变量)合适并且满足了一些我不熟悉的附加先决条件(可能从某些操作系统版本开始),则可能会发生
大页面分配。SkipAddress

        PMDL guard_mdl = IoAllocateMdl
        (
            NULL, 
            PAGE_SIZE * guardPageCount, 
            FALSE,           
            FALSE,  
            NULL        
        );

        if (guard_mdl)
        {
            IoBuildPartialMdl
            (
                mdl,    
                guard_mdl,  
                (PVOID)(0),  // **offset** from the beginning of allocated memory ptr
                PAGE_SIZE * guardPageCount
            );

            status = MmProtectMdlSystemAddress
            (
                guard_mdl,
                PAGE_NOACCESS
            );
        }
于 2016-08-02T19:51:18.503 回答