今天调试程序的时候,对windows对R3的保护机制很感兴趣,为什么rdata段只可读,为什么data可读写,为什么text段不可写入,只可执行,正好今天没事干,这里就做了个测试,首先查看程序断到入口点后,它的物理页的情况
kd> !dd 1db69000 #1db69000 120a5025 80000000 1e642025 00000000 #1db69010 03481025 80000000 1e85e225 80000000 #1db69020 1db96025 80000000 00000000 00000000 物理地址1db69000-1db69020,分别对应虚拟地址400000-404000
通过上面的值,这里做下总结:
虚拟地址400000对应的PTE是 80000000~120a5025:禁止执行,不可写入的user页面,bit9为0 PE文件头
虚拟地址401000对应的PTE是 00000000~1e642025:可以执行,不可写入的user页面,bit9为0 text段
虚拟地址402000对应的PTE是 80000000~03481025:禁止执行,不可写入的user页面,bit9为0 rdata段
虚拟地址403000对应的PTE是 80000000~1e85e225:禁止执行,不可写入的user页面,bit9为1 data段
虚拟地址404000对应的PTE是 80000000~1db96025:禁止执行,不可写入的user页面,bit9为0 rsrc段
首先看下data段,它与其它段(除了text段)的唯一区别就是bit9为1,那么先测试下data,看看它在分页和分段的共同作用下,结果是怎样的
PAGE.Write SEGMENT.W 结果 00 00 NO 01 00 NO 01 01 YES 00 01 YES 可以看到在物理页禁止写入,数据段可以写入的情况下,仍然可以写入
那么再测试下rdata段,它与data段的唯一区别就是bit9为0,那么这里测试下它,看看结果是怎样的
PAGE.Write SEGMENT.W 结果 00 00 NO 01 00 NO 01 01 YES 00 01 NO可以看到在物理页禁止写入,数据段可以写入的情况下,不能写入数据了
为什么会出现这种结果,毕竟402000和403000对应的PTE就只有Bit9不同,那么是不是windows用PTE的bit9来区分程序中的data段呢,如果Bit9为1,那么在数据段可以写入的情况下,就算物理页不让写入数据,那么数据仍然能被写入物理页呢,那么我们修改下402000对应的PTE的bit9为1,然后物理页禁止写入,数据段允许写入,这里做了两次测试
测试一: kd> !ed 1db69010 03481225 修改后,402000可以被写入数据
测算二: kd> !ed 1db69010 03481025 修改后,402000不能再被写入数据了
根据这种情况来看,是不是所有的程序段对应的PTE的bit9为1,就可以写入数据了呢,这里测试下text段
可以看到,不可访问,并且出现了异常,为什么会出现这种情况呢,看下text对应的PTE,除了bit9不同外,它的bit63也不同,bit63是执行禁止位,其他的都为1,禁止执行,说明不是个代码段,而text对应的PTE的bit63为0,说明这是个代码段,那么把text对应的PTE的bit9置1和bit63置1后,可不可以写入了呢,为了省点事,这里修改所有的物理页
kd> !dd 1db69000 #1db69000 120a5225 80000000 1e642225 80000000 #1db69010 03481225 80000000 1e85e225 80000000 #1db69020 1db96225 80000000 00000000 00000000
OD运行,看看结果如何
通过测试,400000-404000的所有地址都可以写入了
总结:windows通过bit9区分data段,对bit63区分text段,如果bit9为1,bit63为1,那么windows这逗逼就只会认为它是data段了