课后解惑

Q:对于各个Windows版本,堆的处理过程都一样么?

A:堆管理和回收是个很大的主题。微软也一直在试验与改进,希望在效率和资源占用方面取得一个合理的折衷。所以堆管理器采用的分配算法,在不同的Windows版本上是不同的,但微软的改进毕竟是逐步的,所以讲的方法基本对各种版本研究都有效。

Q:堆溢出的利用有很大的实际意义么?

A:当然!堆溢出的危害还不像堆栈溢出那样被人认识得很清楚。无论是实际的利用,还是深入的研究方法,都很有意义。有本书讲解防止缓冲区溢出的方法时,居然建议不使用数组,使用动态分配这一项。

Q:为什么一再要求不要在VC里调试和运行堆溢出相关程序呢?

A:Windows为堆管理提供了两套API,一套用于正常管理分配,另一套用于调试。使用VC这类ring3调试器调试时,Windows会创建调试堆,并使用调试那套函数,这样就和正常运行时的堆处理不同。所以一再要求在正常模式下运行相关程序。如果要对正常的堆分配进行跟踪,最好使用ring0调试器(如SoftICE)。

Q:DEBUG版本和RELEASE版本的还有些什么不同呢?

A:DEBUG版和RELEASE版由于编译选项不同,所以编译器对它们的链接处理和生成的程序也不同。DEBUG版多了很多东西,比如调试信息;RELEASE版还会进行优化。所以调试版本会比发布版大很多。

Q:我写了一些程序,在DEBUG版时可以正常运行;但做成RELEASE版却报错,马上就要发布了,天啊!这是怎么回事啊?

A:不要轻易将问题归结为DEBUG/RELEASE问题,先确保有没有其他原因。如果是DEBUG/RELEASE的问题,最大的可能性是变量初始化的问题。在DEBUG下,编译器会自动把变量初始化;而RELEASE版则不会。 另外,预处理的不同、资源文件的改变,都有可能带来问题。

Q:堆溢出利用的ShellCode为什么会有这么多要求呢?怎么解决呢?

A:API函数执行会使用到进程的堆块。我们把堆覆盖了,那么函数执行时就会发生异常。

可按如下方法解决:

我们可以使用系统中另外存在的一个堆替换掉PEB中系统默认的堆,比如:

mov eax,fs:[0x00000018] 〈---------PEB地址
mov eax,[eax+0x30]
lea eax,[eax+0x18] 〈--------获得进程默认HEAP BASE地址??????
mov ebx,0x170000??
mov [eax],ebx 〈-----------换成0X170000

我们也可恢复HEAP FREE LIST结构,由于被破坏的主要是释放堆连表的结构,我们可以取出链表进行分析,恢复成一个正常的释放堆链表。

具体实现我们将在ShellCode的高级编程中讲到。

Q:为什么覆盖 Call [esi+4c] 指令的地址就会引发异常,从而进入异常处理点?而为什么在JPEG漏洞中可以覆盖0x7830B1DC处的函数,又不会出错呢?

A:这涉及到PE文件的的分段了。 Call [esi+4c] 的指令是在text段,就是代码段中。text段是不可写的,所以往它附近写入时就会出错,从而进入异常处理;而JPEG漏洞利用时,覆盖函数的地址是在data段中,而data段是可以写的,所以不会引发异常。

Q:还有哪些堆溢出利用的实际例子呢?

A:有很多哦,建议再看看RPC堆溢出漏洞的分析和利用,对增加堆的利用经验有很大帮助!