您好我正在努力了解堆溢出是如何工作的,我一直在读这篇文章,这对我来说似乎很模糊。下面是我坚持的文章页面。
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读取。解释是“used”字段是从标题部分的开头起12字节的偏移量,因此是0x41414141 + 0xc = 0x4141414d。对我来说,由于以下原因,这种解释毫无意义。
A)为什么Free_Heap()甚至会尝试读取“used”字段中的地址,当该值只告诉Free_Heap()时是否正在使用堆结构上的数据。除非“used”字段是指向正在写入的实际数据的指针(教程中没有提到),否则这对我没有任何意义。
B)假设堆结构中的used字段确实是指向可以写入的数据的指针,为什么偏移量与从哪里读取堆有关?可能是如果数据部分位于“used”指针字段之后(就像在堆栈中)那么这意味着数据应该放置在0xf的偏移而不是0xc,这样数据就不会覆盖“used”字段。
感谢您提供任何有用的输入以清除此问题。
答案 0 :(得分:1)
文章的这一部分似乎是错误的,或者写得非常糟糕。虽然它会读取 hdr->next->used
以检查后续内存对象是否正在使用,但正如您所说,其used
和size
字段将为0x41414141,所以我们不会尝试与它合并。仍然,设置很好,你将之后不久取消引用其中一个指针:当释放'line'内存对象(我们踩到它的标题的那个)时,它将尝试检查它是否{{ 1}}和next
内存块正在使用中。取消引用其中一个指针字段将崩溃或被主动利用。