Memory management 如何设置内存区域';Windows 7下内核模式下的s保护

Memory management 如何设置内存区域';Windows 7下内核模式下的s保护,memory-management,windows-kernel,Memory Management,Windows Kernel,本质上,我正在寻找一个函数,它可以为内核模式做VirtualProtect为用户模式做的事情 我使用以下简化代码举例说明的逻辑分配内存 PMDL mdl = MmAllocatePagesForMdl ( LowAddress, HighAddress, SkipAddress, size ); ULONG flags = NormalPagePriority | MdlMappingNoE

本质上,我正在寻找一个函数,它可以为内核模式做
VirtualProtect
为用户模式做的事情

我使用以下简化代码举例说明的逻辑分配内存

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

    ULONG flags = NormalPagePriority | MdlMappingNoExecute | MdlMappingNoWrite;
    PVOID ptr = MmGetSystemAddressForMdlSafe
    (
        mdl, 
        flags
    );
MdlMappingNoExecute
MdlMappingNoWrite
标志仅对Win8+有效。
此外,仅使用
MmGetSystemAddressForMdlSafe
我无法为内存区域分配例如
NoAccess
保护

我是否可以使用任何附加或替代API-s,以便修改分配内存的页面保护?
黑客也可以,因为目前这个功能不会在生产代码中使用

C:\Windows\System32>dumpbin /exports ntdll.dll | find "Protect"
        391  17E 0004C030 NtProtectVirtualMemory
       1077  42C 000CE8F0 RtlProtectHeap
       1638  65D 0004C030 ZwProtectVirtualMemory
我认为您可以从内核模式调用
Zw
函数,参数通常与相应的
Nt
函数相同。虽然
ZwProtectVirtualMemory
没有文档记录,但有一个文档记录了接受保护标志的方法


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

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

如果使用以下方法保护内存,则:

  • IRQL
    中,您将在\u非分页\u区域中获得
    PAGE\u FAULT\u故障(引用了无效的系统内存。这无法通过try进行保护,除非,
    它必须受到探测的保护。通常,地址是完全错误的,或者是错误的
    指向已释放的内存。)
  • IRQL==DISPATCH\u级别
    您将获得
    DRIVER_IRQL_NOT_LESS_或_EQUAL
    故障(试图访问某个位置的可分页(或完全无效)地址) 中断请求级别(IRQL)太高。这通常是 由使用不正确地址的驱动程序引起。)
请注意,如果子范围是大页面分配的一部分,则更改保护可能会失败。然后,
状态
很可能是不受支持的
状态

如果最初分配的内存区域的大小和对齐方式(取决于问题中的
SkipAddress
变量)合适,并且满足了一些我不熟悉的附加先决条件(可能从某个OS版本开始),则可能会发生大页面分配


谢谢您是否知道,这些API-s也可以应用于非分页和系统(不与进程相关)内存?
ZwAllocateVirtualMemory
例程在指定进程的用户模式虚拟地址空间内保留、提交或同时提交一个页面区域,而您的答案仍然有用,目前的问题有点含蓄地要求解决非分页内存问题,因为
MmAllocatePagesForMdl
生成非分页内存分配-了解未记录的
ZwProtectVirtualMemory
API是否能够处理非分页内存以及它与
MmProtectMdlSystemAddress
?我想我知道
NtProtectVirtualMemory
是用于用户模式内存的,并且会在参数指向系统内存范围时失败。
Zw
Mm
API之间的区别很有趣,因为在互联网上可以找到各种各样的黑客来调用
ZwProtectVirtualMemory
API。如果不是为了某些好处。。。那么我想这些黑客不会被制造出来?
        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
            );
        }