4.5.3 其他方法

“天啊!就没有完美的办法么?”玉波绝望的说。

“我也知道这个世界,缺乏圆满~”宇强哼出林志炫的《散了吧》里的一句歌词。

“哈哈哈……”全班同学都笑了。

“学习了这么多,觉得Windows系统真有意思啊!”古风自喃道。

“操作系统是最底层、最复杂的用户软件,多亏了Bill Gates创造出Windows这种人性化的操作系统。”

老师说道,“大家越深入的学习,就会越赞叹程序设计这座美妙的大厦。这里提醒大家,我们不仅要学习系统本身,更关键的是学习微软设计系统的思想和实现系统的方法。”

“嗯,虽然没有源代码,但能感觉到他们处理问题的条理性和严谨性。”宇强认真的说。

“对!另外,大家还应体会到团队合作的必要性和管理的重要性,”老师说道,“你们想啊!这么大一个系统,浩如烟海的代码量,需要成千上万人的配合开发,如果管理协调有任何一点没到位,都不可能完成的。”

“而这方面目前在国内还很缺乏,如果大家有机会,能去微软亚洲研究院和微软工程院见识见识,近距离的向他们学习,对自己的提高是大有裨益的!”

“哦,微软研究院?想都不敢想!”大家喧哗了。

宇强听了老师的话后,顿觉得世界好大,自己好小……要学的东西很多,而一个人的时间又是这么宝贵,真的要抓紧再抓紧!努力再努力!

“老师,还有其他覆盖方法吗?”古风把宇强的思路拉了回来。

“如果对系统研究得越深,就会有越深入的见解。”老师回答说,“Matt Conover 和Oded Horovitz在BlackHat04会议上提到:我们可以构造伪造的堆块,使它释放时能算出ShellCode的地址!”

“啊?算出来?¥※……※太牛了吧!”

“这里的算出,是确切的计算出堆的地址!Matt和Oded在深入研究了Windows堆管理后指出:我们申请小于1024大小的堆块,系统会释放到Lookaside结构中,而Lookaside的地址是知道的,我们也知道会释放到哪个结点中,所以我们就可知道堆块释放后的地址是多少!”

“给大家举个例子,假设堆的基址是0x70000,Lookaside在堆基址偏移0x0688的地方,即地址是0x70688。我们申请分配922大小的堆块,释放时就会把它放在:取8对齐(922)/8=936/8=0x75的Lookaside位置中,每个Lookaside位置占据0x30的大小,所以我们的堆的地址就是 0x70688+0x75*0x30=0x71c78 !”

“哦!还可以这样啊!”

“我们的ShellCode就会在其中,这下就精确知道ShellCode的地址了!”

“这真是……不走寻常路,世界真奇妙……”大家对Matt和Oded的思维佩服得无话可说。

“在Windows下,堆的管理非常复杂,还有另外一些复杂的技术可以利用,但这里就不提了,以后有机会再说吧。”老师说道。

“其实,还有一个常用方法,就是覆盖函数或者函数的返回点,但就更需要结合具体的漏洞来分析了。”

“可以真实的学习一下吗?”

“当然可以啊!我们来看一个比较新的堆溢出漏洞——MS04-028堆溢出漏洞。”