0

嗨,我想了解堆溢出是如何工作的,我一直在阅读这篇文章,这对我来说似乎很模糊。下面是我卡住的文章的页面。

http://www.h-online.com/security/features/A-Heap-of-Risk-747224.html

在链接的第 4 页后半部分之后,我的理解停止了。他们在第 2 页实现了自己的堆管理器,这也可能有用。下图表示字符串复制到图像数据后的堆数据结构(希望这是对的)。

  Root = Hdr                        Free Memory
 _________________                 ________________
|*Next = 0xF      |----------->0xF|*Next = "AAAA"  |
-------------------               ------------------
|*Previous = NULL |               |*Previous="AAAA"|
-------------------               ------------------
|Size = 0         |               |Size = "AAAA"   |
-------------------               ------------------
|Used = 0         |               |Used = "AAAA"   |
-------------------               ------------------
                                  |Free Mem Data   |

(让 Root 从 0x0 开始。每个字段也是 32 位,因此是 4 个字节宽。“AAAA”代表字符串“AAAA”,其中每个“A”是一个字符,因此是一个字节的内存。)

从教程中他们说,当内存被释放时,函数 Free_Heap() 将要从地址“AAAA”= 0x4141414d 读取。有解释是“使用”字段是从标题部分开始的 12 个字节的偏移量,因此 0x41414141 + 0xc = 0x4141414d。对我来说,这种解释没有意义,原因如下。

A) 为什么 Free_Heap() 甚至会尝试从“已使用”字段中的地址读取,而该值仅告诉 Free_Heap() 是否正在使用堆结构上的数据。除非“使用”字段是指向正在写入的实际数据的指针(教程中没有提到),否则这对我来说没有任何意义。

B)假设堆结构中的已使用字段确实是指向可能写入的数据的指针,为什么偏移量与应该从哪里读取堆有关?可能是如果数据部分位于“已使用”指针字段之后(例如在堆栈中),那么这意味着数据应放置在 0xf 而不是 0xc 的偏移量处,以便数据不会覆盖“已使用”场地。

感谢您提供任何有用的信息来解决这个问题。

4

1 回答 1

1

文章的那部分似乎是错误的,或者只是写得很糟糕。虽然它会读取 hdr->next->used以检查后续内存对象是否正在使用,但正如您所说,它的usedsize字段将为0x41414141,因此我们不会尝试与其合并。尽管如此,设置还是不错的,不久之后您取消引用其中一个指针:当释放“line”内存对象(我们踩到其标题的那个)时,它将尝试检查其nextprev内存块是否正在使用中。取消引用这些指针字段中的任何一个都会崩溃或被积极利用。

于 2012-04-18T12:02:53.843 回答