20-读写空指针

有不少人看到这个标题会说,博主疯了,走吧走吧,不看了。学过 C 语言的人都知道,0 地址是不可能被读写的。

为了能够狡辩,我不得不提前把实验结果贴在下面。


这里写图片描述
图1 读写空指针

请原谅我,无论你在自己的 VC6.0 执行多少次,你都不会成功,但是我成功了。我确实做了手脚。难道你不想知道吗?聪明的你也许根本不需要继续往下读,就能完成这个功能(如果你真的搞定了前面的分页知识的话)。

0 地址分析

动手能力强的你,第一件事情是应该按照前面的方法去分析 0x00000000这个线性地址转换后的物理页是多少。不妨我们打开图1的程序,来看看。

  • 在第一行下断点,让程序停下


这里写图片描述
图2 在这里下断

  • 中断到 WinDbg,输入命令 !process 0 0,找到你的程序,一般是最后一个。我这里是 demo6.exe。


这里写图片描述
图3 中断到 WinDbg

  • 将线性地址 0 转换为物理地址,发现 PTE 的值是 0,所以这是一个无效线性地址。还记得PDE和PTE属性吗?P位为1才能说明物理页有效。


    这里写图片描述
    图4 发现 0 地址是一个无效地址

  • 转换过程可以用下面的图来表示。我们发一同,PTT 中的第一个页表项PTE是个空的。


    这里写图片描述
    图5 转换过程

给 0 号页表的 PTE 挂上物理页

既然已经找到问题的“症状”,何不对症下药?我们把PTT中的第一个面表项手动补上,在这里安放一个物理页的索引号,一切不就搞定了吗?

可是,我怎么知道哪个物理页可以用?为了不破坏操作系统,我们可以使用当前程序堆栈所在的物理页。

  • 查看堆栈所在物理页

可以在 WinDbg 中输入命令 g,让虚拟机中的 xp 恢复运行。


这里写图片描述
图6 查看寄存器

  • 查看 esp 中的值,为 0x0012ff30


    这里写图片描述
    图7 查看ESP

  • 找到 0x0012ff30 所以的物理页


    这里写图片描述
    图8 查看 0012FF30 线性地址所在的物理页

  • 使用 ed 命令,修改 PTT 的第一项


    这里写图片描述
    图9 给 PTT 的第一个页表项安装上物理页 0x05b40

  • 修改后的页目录、页表全貌


    这里写图片描述
    图10 修改 PTT 中的第一个 PTE

最终,我们让 0 地址指向的物理页和堆栈指针 ESP 指向相同的物理页。从图10清晰的就可以看到。

修改完成后,回到虚拟机,让你的程序 go on 吧,记得在 return 0 位置下个断点,不然程序就跑飞啦。

总结

这个实验本身并不难,重点在于你从这个实验学到了什么?malloc 在干什么?操作系统又在干什么?线性地址是什么?物理页是什么?

其实到了这里,很多事情,你在心里已经有了自己 的答案。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值