首页
社区
课程
招聘
[讨论]win7与xp pte页属性的问题
发表于: 2017-1-1 13:23 4193

[讨论]win7与xp pte页属性的问题

2017-1-1 13:23
4193
这是xp32位系统关于pte改变页属性的步骤(我直接从其他的地方复制过来的)

4.DEP在内核中到底是如何实现的?
这个问题我曾经费不了少时间去找答案,从内存操作的API上来看,
有标准内存管理API,虚拟内存管理API,堆管理API,内存映射文件API
从内存管理的结构上来看,有VAD,有PFN,有PTE,PDE,有段
一开始我认为windows可能会在任何一个层面上做文章,可能是VAD,也可能是PFN,也可能是PTE
并且我认为VAD的可能性比较大,因为PTE没有相关的bit位表示此页有没有可执行属性。PFN也没有。
VAD倒是有相关的位表示页的可执行属性。
经过一点点的测试和排除,发现VAD与此并没有关系,用VirtualProtect()改变页的属性时,此页对应
的VAD的flag位竟然毫无变化。
那么只剩下PFN和PTE了,发现这个API调用前后,PFN的restore pte这个字段有变化,PTE的低双字却
没有一点变化,高双字我时候我没有关心,我一直认为高双字是用于寻址4G以外的物理内存地址的。
然后我手动把PFN的restore pte改变成上面提到的API改成的值,但是结果却让人失望,我拷入shellcode
的页还是不可执行。
尽管这时,我还是没有意识到PTE的高双字发生的变化,并为此付出了代价,那就是二夜一天的对VirtualProtect()
相关API的反汇编。
VirtualProtect()调用了VirtualProtectEx()
VirtualProtectEx()调用了ZwProtectVirtualMemory()
ZwProtectVirtualMemory()通过sysenter进入内核,EAX中存放的服务号是0x89,对应的服务是NtProtecVirtualMemory()
NtProtectVirtualMemory()又调用了MiProtectVirtualMemory()
在MiProtectVirtualMemory()内部,计算出要改变其属性的内存页的PTE的地址,新的属性,然后调用
MiFlushTbAndCapture()改变PTE的属性,但是我当时也只是看到把PTE的属性从067变成了027,和可执行属性还是
没有关系,然后我再深入到MiFlushTbAndCapture()中,发现它主要又是调用KeFlushSingleTb()来改变指定PTE
的属性的,深入到KeFlushSingleTb()内部,它主要是调用KeInterlockedSwapPte()来改变指定PTE的属性。
而KeInterlockedSwapPte()的内部是比较简单的,来看看它的反汇编代码:

nt!KeInterlockedSwapPte:
80541c08 53 push ebx
80541c09 56 push esi
80541c0a 8b5c2410 mov ebx,dword ptr [esp+10h] ;ebx=新的PTE值所在变量的地址
80541c0e 8b74240c mov esi,dword ptr [esp+0Ch] ;esi=PTE地址
80541c12 8b4b04 mov ecx,dword ptr [ebx+4] ;ecx=新PTE值高双字
80541c15 8b1b mov ebx,dword ptr [ebx] ;ebx=新PTE值低双字
80541c17 8b5604 mov edx,dword ptr [esi+4] ;edx=旧PTE值高双字
80541c1a 8b06 mov eax,dword ptr [esi] ;eax=旧PTE值低双字
80541c1c 0fc70e cmpxchg8b qword ptr [esi]

看到关键点了吧,就是一个cmpxch8b指令,这个指令是干什么的呢?
执行的操作:edx,eax与DST相比较
如果 (edx,eax)=(dst)
则 ZF=1,(dst)<-(ecx,ebx)
否则 ZF=0,(edx,eax)<-dst
很简单,如果新的PTE属性和旧的不等,把PTE属性设置为新的属性。如果相等,则实际上等于不进行操作。
从这里我才发现,他把PTE的高双字设置为0了,以前的值是0x80000000.
所以,DEP是通过PTE的高双字的最高bit即bit63来实现的,这个位置位了,表示此页不可执行。没有置位,
表示此页可以执行。而win2k下面的页目录和页表项只有32个bit,所以不可能提供DEP的这个保护位,因此
DEP只有在64bit的PTE上才能实现。而只有cr4的bit5即PAE启用的时候,PTE才为64bit。
所以,可以这么说吧,intel的奔腾CPU是早就有PAE属性位的,可以支持64位的页表项,而windows系统
只有win2k的某个版本,winxp和win2003的某个server pack版本的内核才支持64的页表项。
不管怎样,PTE的第63位控制着页的可执行属性,我后来查了IA,在IA的修正说明中,才提到这一点,并
把这个位叫做EXB,却对此位的作用一字为提。
但是我们是不能在ring3下操作PTE的,所以,绕过DEP还是得用return-to-lib的经典方式返回到VirtualProtect()
来改变当前栈的属性。

其中【KeInterlockedSwapPte】函数是关键函数
那么win7的呢?win7改变页属性是流程是什么,我用ida看了很多次,都没找到关键的地方,大神们可以的话讲解一下吧

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 2347
活跃值: (58)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
楼主分析了好多 受用很多 感谢
2017-1-1 13:44
0
雪    币: 346
活跃值: (25)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
佩服楼主!
2017-1-1 14:12
0
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
win7改变页属性也是调用NtProtecVirtualMemory
ntos拖到IDA里面配合符号文件看看就知道了
2017-1-1 14:39
0
雪    币: 46
活跃值: (1785)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我知道,但是和xp变了好多
2017-1-1 18:27
0
游客
登录 | 注册 方可回帖
返回