当前位置 博文首页 > KOOKNUT的博客:浅谈MDL(叁)--实例测试(Windows内核学习笔记)

    KOOKNUT的博客:浅谈MDL(叁)--实例测试(Windows内核学习笔记)

    作者:[db:作者] 时间:2021-07-02 21:33

    在我之前写SSDTHook时候,用到过MDL的相关知识,是对内核层的虚拟地址进行MDL映射,然后修改,实现SSDTHook。
    原文链接:
    https://blog.csdn.net/qq_42253797/article/details/104352520
    接下来看一下MDL的实现过程:
    首先调用MmCreateMdl函数,对KeServiceDescriptorTable->ServiceTableBase所在地址,以系统服务函数的长度为界限,进行创建MDL。我们看到Windbg中的参数,StartVA是进行过页面对齐的大小:0x84883000,源虚拟地址为:0x8488343c,这个数据在下图有所体现。ByteOffset的值为0x43c,这印证了我们之前说过的,StartVA+ByteOffset为源虚拟地址。

    在这里插入图片描述
    在这里插入图片描述
    接下来构建一个非分页内存MmBuildMdlForNonPagedPool,免于被置换处物理内存,修改MDL属性,截至目前,所得到的MappedSystemVa都是不算数的。
    在这里插入图片描述
    接下来使用MmMapLockedPages映射非分页内存页面,返回映射之后的地址,返回值和MappedSystemVa都指向映射之后的虚拟地址。
    在这里插入图片描述
    对原本ServiceTable服务函数表的地址进行查看,和现在映射出来的地址里面的值是相同的。

    0: kd> dd 0x8488343c 
    8488343c  84a7efbf 848c6855 84a0ed47 8482a897
    8488344c  84a80895 84903112 84af10d7 84af1120
    8488345c  84a03563 84b0a9d4 84b0bc2d 849f9d3b
    8488346c  84a8aed3 84ae3da3 84a36cc7 84a068ab
    8488347c  8499c9e3 84ad5c88 849ed28c 84a2fcbc
    8488348c  84a7c191 849dd300 84a7b59e 849fadb2
    8488349c  84a8c95a 849fd435 84a8c73a 84a84e92
    848834ac  84a0f2cf 84ad0a25 84a8225f 84a8cb8c
    0: kd> dd 0xaebac43c
    aebac43c  84a7efbf 848c6855 84a0ed47 8482a897
    aebac44c  84a80895 84903112 84af10d7 84af1120
    aebac45c  84a03563 84b0a9d4 84b0bc2d 849f9d3b
    aebac46c  84a8aed3 84ae3da3 84a36cc7 84a068ab
    aebac47c  8499c9e3 84ad5c88 849ed28c 84a2fcbc
    aebac48c  84a7c191 849dd300 84a7b59e 849fadb2
    aebac49c  84a8c95a 849fd435 84a8c73a 84a84e92
    aebac4ac  84a0f2cf 84ad0a25 84a8225f 84a8cb8c
    
    

    看一下我们的挂钩函数偏移111h的地址是啥

    //因为Windbg指令后面的数字是显示多少个数据,16机制数,所以我输入112h,因为数组下标为111h的数据,应该是第112h个
    0: kd> dd 0xaebac43c l 112
    aebac43c  84a7efbf 848c6855 84a0ed47 8482a897
    aebac44c  84a80895 84903112 84af10d7 84af1120
    aebac45c  84a03563 84b0a9d4 84b0bc2d 849f9d3b
    ...................................
    aebac86c  84a5c673 84a01e50 849fe00d 84846308
    aebac87c  849dd16b 84a68007
    //进行验证果然
    0: kd> u 84a68007
    nt!NtReadFile:
    84a68007 6a4c            push    4Ch
    84a68009 68f8a38584      push    offset nt! ?? ::FNODOBFM::`string'+0x2258 (8485a3f8)
    84a6800e e82dc2e1ff      call    nt!_SEH_prolog4 (84884240)
    84a68013 33f6            xor     esi,esi
    84a68015 8975dc          mov     dword ptr [ebp-24h],esi
    84a68018 8975d0          mov     dword ptr [ebp-30h],esi
    84a6801b 8975ac          mov     dword ptr [ebp-54h],esi
    84a6801e 8975b0          mov     dword ptr [ebp-50h],esi
    

    执行挂钩,修改MDL虚拟地址中的值之后,用源SSDT表的起始地址验证,发现发生了改变:

    0: kd> dd 8488343c  l 112
    8488343c  84a7efbf 848c6855 84a0ed47 8482a897
    8488344c  84a80895 84903112 84af10d7 84af1120
    ...................
    8488386c  84a5c673 84a01e50 849fe00d 84846308
    8488387c  849dd16b 9e1bc100
    0: kd> u 9e1bc100
    SSDTHook!FakeNtReadFile [z:\ring0层代码\[3]钩子集合\ssdthook\ssdthook\ssdthook.c @ 126]:
    9e1bc100 55              push    ebp
    9e1bc101 8bec            mov     ebp,esp
    9e1bc103 6afe            push    0FFFFFFFEh
    9e1bc105 6820d31b9e      push    offset SSDTHook!__safe_se_handler_table+0x1a0 (9e1bd320)
    9e1bc10a 6880c51b9e      push    offset SSDTHook!_except_handler4 (9e1bc580)
    9e1bc10f 64a100000000    mov     eax,dword ptr fs:[00000000h]
    9e1bc115 50              push    eax
    9e1bc116 81c4d4fdffff    add     esp,0FFFFFDD4h
    
    

    证明,MDL确实修改的物理页面的东西,并且两个不同的内核虚拟地址映射到了同一个物理内存地址上。

    第二种,是Ring3的地址,在Ring0中进行映射,这里的MDL->Process就不会再是0x00000000了。我们也之前有这个例子,在内存修改器中:
    https://blog.csdn.net/qq_42253797/article/details/105399092
    来看一下调试信息:
    这是自己写的两个Ring3层的代码,简单的测试一下数据拷贝,但是通过Ring0实现拷贝。
    Windbg查看进程EPROCESS:

    PROCESS 89b1b250  SessionId: 1  Cid: 0f44    Peb: 7ffd4000  ParentCid: 09c4
        DirBase: be9b45a0  ObjectTable: a891fd60  HandleCount:   6.
        Image: SourceProcess.exe
    
    PROCESS 8967d030  SessionId: 1  Cid: 0f74    Peb: 7ffdb000  ParentCid: 09c4
        DirBase: be9b4640  ObjectTable: a88d0438  HandleCount:   6.
        Image: TargetProcess.exe
    

    驱动代码中传的参数数据:
    在这里插入图片描述
    MmInitializeMdl代码执行完毕之后,看到被初始化的部分
    在这里插入图片描述
    MmProbeAndLockPages之后:
    在这里插入图片描述
    MmMapLockedPagesSpecifyCache之后:得到映射地址
    在这里插入图片描述
    映射之后的返回地址,就用这个地址进行拷贝
    在这里插入图片描述

    2: kd> db 0xabd3aca0
    abd3aca0  48 00 65 00 6c 00 6c 00-6f 00 57 00 6f 00 72 00  H.e.l.l.o.W.o.r.
    abd3acb0  6c 00 64 00 00 00 00 00-00 00 00 00 00 00 00 00  l.d.............
    //拷贝之后的Ring3虚拟地址
    2: kd> db 0x000a9430
    000a9430  48 00 65 00 6c 00 6c 00-6f 00 57 00 6f 00 72 00  H.e.l.l.o.W.o.r.
    000a9440  6c 00 64 00 00 00 00 00-00 00 00 00 00 00 00 00  l.d.............
    
    

    先对MDL的总结告一段落,之后学习过程中,如果有什么新的发现,会再回来补充以及修正。
    “It takes courage to believe.”

    cs
    下一篇:没有了