-
-
[原创]详解Windows写时复制机制
-
2021-3-29 16:14
13766
-
看雪上关于写时拷贝的文章,又是各种MDL又是各种函数调用?觉得讲得挺复杂的。明明挺简单的一个事搞得那么复杂,所以才想写这么一篇文章
废话不多说,直接进入主题。
当一个应用层程序试图往一个内存页面写入数据时,CPU操作系统会走如下流程:
第0步:检查PTE被写入内存页的PTE属性,如果页面的PTE属性的U/S位为0,触发页保护异常,写入失败返回0XC00000005错误码;否则进入下一步.
第1步:检查PTE的Write/Read位,如果为1表示检查通过则直接写入数据到内存,写入成功!如果为0,表示此PTE描述的内存页面为只读页,继续检查PTE的第9位,如果此位为0,触发页保护异常;
第2步:进入页保护异常后就完全将控制权交给操作系统,操作系统会先检查被写入页面的进程VAD属性,如果为不存在写拷贝属性,写入失败,返回0xc00000005错误码;如果存在写拷贝属性,进入下一步;
第3步:如果存在写拷贝属性,操作系统会在将被写入页面的PTE的第9位置1,将CPU的EIP设置为之前程序往内存写入数据的那条指令的地址,进入下一步;
第4步:继续执行写入数据到内存的那条指令,注意此时PTE属性的write/Read仍然为0,仍然会再次触发页保护异常,返回第0步,接着走第2步,此时操作系统会发现PTE的第9位被置1了,如果PTE属性的第9位为1,则分配一个新的物理内存页面,将原来的数据复制到新的内存页面,修改PTE并且将PTE的write/Read位置1,页保护异常返回到程序之前写入数据到内存的那条指令,再次执行这条指令因为PTE的Write/Read位为1,会直接写入成功!
可以做以下实验来验证以上流程:
修改PTE属性
修改之后程序写入数据到内存之后的PTE
如果你看懂了以上流程,无论是突破写拷贝还是把自己指定的内存加上写拷贝属性应该都能做到了。
TIP: 看完上面的流程,我们应该时刻记住以下两件事:
1.Windows操作系统的写拷贝机制是依赖于页保护(#GP)异常的;
1.一个物理内存的页面的属性是由PTE属性和VAD属性两部分组成的,PTE属性层面的保护由CPU实现,VAD属性的层面的保护则由操作系统控制;
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界