首页
社区
课程
招聘
[原创]Win10 DiSPATCH_LEVEL下读取物理内存
发表于: 2020-4-3 02:28 15619

[原创]Win10 DiSPATCH_LEVEL下读取物理内存

2020-4-3 02:28
15619
收藏
免费 1
支持
分享
最新回复 (32)
雪    币: 919
活跃值: (1340)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
26

请教一个问题哈~
1. MmMapIoSpace,将物理地址映射成虚拟地址 和MDL的区别是什么呀?我记得MDL也是将物理地址重新映射映射一下(不是走原型PTE的那一套..是直接搞一个虚拟地址挂上同一个PTE)然后从虚拟地址去读?
2. 你这个测试 hello Wold是放在静态数据段的,也就是说在申请内存的时候时候,挂上PTE了,但是大多数下申请内存的时候,最多都是保留状态,访问的时候才会挂上
不知道自己想的对不对? 感觉就是方法挺好的,但是局限性同样很大

最后于 2021-2-5 09:29 被丿一叶知秋编辑 ,原因:
2021-2-5 09:27
0
雪    币: 2674
活跃值: (2304)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
27
hhkqqs 代码有漏洞,在配置高容量内存条的机子上,MmAllocateContinguousMemory申请的页可能处于2M大分页或1G大分页中,此时的PTE要么清零要么根本不存在,楼上说的概率蓝屏应该指的就是 ...

的确!有处于大分页中的页PTE清0的情况。
0: kd> lmDvmnt
Browse full module list
start             end                 module name
fffff800`5eebc000 fffff800`5f92c000   nt         (pdb symbols)          c:\symbols\ntkrnlmp.pdb\45C12C294F739481AC5E8E014C068FB61\ntkrnlmp.pdb
    Loaded symbol image file: ntkrnlmp.exe
    Image path: ntkrnlmp.exe
    Image name: ntkrnlmp.exe
    Browse all global symbols  functions  data
    Image was built with /Brepro flag.
    Timestamp:        2E8B5A19 (This is a reproducible build file hash, not a timestamp)
    CheckSum:         0093F426
    ImageSize:        00A70000
    Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4
    Information from resource tables
0: kd> !pte fffff800`5eebc000 ;查看ntkrnlmp.exe模块基址所在页的PTE
                                           VA fffff8005eebc000
PXE at FFFFB2592C964F80    PPE at FFFFB2592C9F0008    PDE at FFFFB2593E0017B8    PTE at FFFFB27C002F75E0
contains 0000000002808063  contains 0000000002809063  contains 0000000002C008E3  contains 0000000000000000
pfn 2808      ---DA--KWEV  pfn 2809      ---DA--KWEV  pfn 2c00      --LDA--KWEV  LARGE PAGE pfn 2cbc        
(1)PTE清0了
0: kd> db FFFFB27C002F75E0  ;PTE
ffffb27c`002f75e0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
ffffb27c`002f75f0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
ffffb27c`002f7600  05 04 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
ffffb27c`002f7610  00 00 00 00 00 00 00 00-10 00 00 00 00 00 00 00  ................
ffffb27c`002f7620  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
ffffb27c`002f7630  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
ffffb27c`002f7640  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
ffffb27c`002f7650  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

(2)PDE有效:
0: kd> db FFFFB2593E0017B8 ;PDE
ffffb259`3e0017b8  e3 08 c0 02 00 00 00 00-e3 08 e0 02 00 00 00 00  ................
ffffb259`3e0017c8  e3 08 00 03 00 00 00 00-e3 08 20 03 00 00 00 00  .......... .....
ffffb259`3e0017d8  e3 08 40 03 00 00 00 00-e3 08 60 03 00 00 00 00  ..@.......`.....
ffffb259`3e0017e8  63 50 81 02 00 00 00 00-63 60 81 02 00 00 00 00  cP......c`......
ffffb259`3e0017f8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
ffffb259`3e001808  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
ffffb259`3e001818  63 90 81 02 00 00 00 00-63 a0 81 02 00 00 00 00  c.......c.......
ffffb259`3e001828  00 00 00 00 00 00 00 00-63 c0 91 02 00 00 00 00  ........c.......

(3)模块ntkrnlmp.exe:
VA=0xfffff8005eebc000
*PDE=0x02c008e3
物理地址:
PHY_ADDR=((*PDE)&0xFFFFFFE00000)+(VA&0x1FFFFF)
=(0x02c008e3&0xFFFFFFE00000)+(0xfffff8005eebc000&0x1FFFFF)
=0x2c00000+0xbc000
=0x2cbc000
1)VA=0xfffff8005eebc000的内容为:
0: kd> db fffff800`5eebc000 ;ntkrnlmp.exe起始VA
fffff800`5eebc000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
fffff800`5eebc010  b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00  ........@.......
fffff800`5eebc020  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fffff800`5eebc030  00 00 00 00 00 00 00 00-00 00 00 00 00 01 00 00  ................
fffff800`5eebc040  0e 1f ba 0e 00 b4 09 cd-21 b8 01 4c cd 21 54 68  ........!..L.!Th
fffff800`5eebc050  69 73 20 70 72 6f 67 72-61 6d 20 63 61 6e 6e 6f  is program canno
fffff800`5eebc060  74 20 62 65 20 72 75 6e-20 69 6e 20 44 4f 53 20  t be run in DOS 
fffff800`5eebc070  6d 6f 64 65 2e 0d 0d 0a-24 00 00 00 00 00 00 00  mode....$.......

2)PHY_ADDR=0x2cbc000处内容:
0: kd> !db 2cbc000 ; ;ntkrnlmp.exe起始物理地址
# 2cbc000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............
# 2cbc010 b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00 ........@.......
# 2cbc020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
# 2cbc030 00 00 00 00 00 00 00 00-00 00 00 00 00 01 00 00 ................
# 2cbc040 0e 1f ba 0e 00 b4 09 cd-21 b8 01 4c cd 21 54 68 ........!..L.!Th
# 2cbc050 69 73 20 70 72 6f 67 72-61 6d 20 63 61 6e 6e 6f is program canno
# 2cbc060 74 20 62 65 20 72 75 6e-20 69 6e 20 44 4f 53 20 t be run in DOS 
# 2cbc070 6d 6f 64 65 2e 0d 0d 0a-24 00 00 00 00 00 00 00 mode....$.......
内容完全吻合。说明我所调试的系统上ntkrnlmp.exe的基址fffff800`5eebc000位于PDE所描述的大分页中。

最后于 2021-2-5 13:06 被低调putchar编辑 ,原因:
2021-2-5 12:47
0
雪    币: 2428
活跃值: (2597)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
28
pte挂上物理地址后,在读之前可以把pfn->SharedCount+=1,读完再减回去,这样就不会中途换出了。
不过这个方法似乎也没法解决已经缺页的,已经缺页了就必须读(probe)一次让pf把物理页读回内存,但这样在dispatch_level下肯定就蓝了。mdl也就是这个问题,它第一步就是ProbeAndLock,如果是dispatch_level遇到缺页就会蓝。不过ProbeAndLock成功的话,后续就不会蓝了,因为Lock之后就不会换出了
所以我觉得你这种方法本质上和mdl没有多大区别啊。现在没有缺页的话,两种方法都可以的。但一旦缺页了,你这种方法一样也是不行的。
2021-2-5 13:15
0
雪    币: 919
活跃值: (1340)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
29
dearfuture pte挂上物理地址后,在读之前可以把pfn->SharedCount+=1,读完再减回去,这样就不会中途换出了。 不过这个方法似乎也没法解决已经缺页的,已经缺页了就必须读(probe)一次让p ...
大哥说的,不就是我想问的嘛
2021-2-5 13:58
0
雪    币: 2428
活跃值: (2597)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
30
丿一叶知秋 大哥说的,不就是我想问的嘛
哦,没看你的回复,我说的主要是缺页问题
2021-2-5 14:15
0
雪    币: 7116
活跃值: (3176)
能力值: ( LV4,RANK:52 )
在线值:
发帖
回帖
粉丝
31
dearfuture pte挂上物理地址后,在读之前可以把pfn->SharedCount+=1,读完再减回去,这样就不会中途换出了。 不过这个方法似乎也没法解决已经缺页的,已经缺页了就必须读(probe)一次让p ...
这个方法主要是针对标题的内容“DISPATCH_LEVEL下读取物理内存”,当初的想法是用的API比较干净不会被HOOK所拦截,由于不太懂内核的知识,所以也没有从头开始一级一级增加到PTE的描述,而是直接调用MmAllocateContiguousMemory,让系统构造好一个映射链,通过PTE_BASE计算地址替换PTE最后指向的物理地址,原理不是很复杂,至于缺页蓝屏应该不会出现,但是前提是得保证MmAllocateContiguousMemory这个函数分配的是4KB页面,否则寻址还得改变。

至于MDL,这个东西我不太了解,有时间我去了解一下,感谢回复
2021-2-5 14:34
0
雪    币: 2428
活跃值: (2597)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
32
不对 这个方法主要是针对标题的内容“DISPATCH_LEVEL下读取物理内存”,当初的想法是用的API比较干净不会被HOOK所拦截,由于不太懂内核的知识,所以也没有从头开始一级一级增加到PTE的描述,而是 ...
你说的那些我觉得倒只是细节,无论MmAllocateContiguousMemory还是nonpagedpool(避免大页)都只是为了借用pte而已。最关键的步骤还是拿到目标地址的物理页号填进pte吧。如果目标地址正好缺页了,那就拿不到物理页号了。除非你先读一次目标地址,让缺页处理函数把目标页换进内存,然后你才能拿物理页号,不过就是这一步在dispatch_level下会蓝屏。
2021-2-5 14:49
0
雪    币: 7116
活跃值: (3176)
能力值: ( LV4,RANK:52 )
在线值:
发帖
回帖
粉丝
33
dearfuture 你说的那些我觉得倒只是细节,无论MmAllocateContiguousMemory还是nonpagedpool(避免大页)都只是为了借用pte而已。最关键的步骤还是拿到目标地址的物理页号填进pte吧 ...
我明白您的意思了,可能是我没有表述清楚,目前解决的问题是读取 "物理地址" 而不是 映射后的 "虚拟地址",虚拟地址可能随时会被系统换出,所以,目前只能读取没有被换出物理页以及没有被内容覆盖的物理页。

换句话说,只是提供了一个MmIoSpace的替换的可行思路,感谢您的回复
2021-2-5 14:57
0
游客
登录 | 注册 方可回帖
返回
//