缓冲区溢出是引发程序崩溃的常见原因之一,也常常被黑客利用来发起攻击。缓冲区溢出引发的bug常常难以定位。那么缓冲区溢出问题有什么现象呢?如何找出蛛丝马迹从而何定位缓冲区溢出问题呢?
原文:小宇的博客
什么是缓冲区?缓冲区就是在程序中开辟的一块区域。这块区域可以在堆上也可以在栈上。
int function()
{
char buffer1[256]; // 在栈上的缓冲区
char *buffer2 = (char *)malloc(sizeof(char)*256); //在堆上的缓冲区
}
一般来说,用malloc分配的内存区域在堆上;直接声明的缓冲区数组是在栈上。堆上的缓冲区溢出和栈上的缓冲区后果是不一样的。在堆上的缓冲区溢出的后果一般,可能覆盖了临近的内存,当然如果临近的内存中有函数指针,也可能照成程序运行到错误的地址。在栈上的缓冲区溢出的后果往往更严重,因为可能破坏了程序的返回地址。下面我们分别对这两种情况进行讨论。
栈上的缓冲区溢出
我们有个程序运行中崩溃,生成core文件,用gdb查看堆栈如下:
(gdb) bt
#0 0x00000000004004f7 in f () at main.c:11
Cannot access memory at address 0x646c726f77206f74
堆栈显示在函数f()
函数处崩溃,崩溃的指令地址是0x4004f7
,崩溃的原因是不能访问内存0x646c726f77206f74
区域。同时我们找不到f的调用者。
我们通过汇编,进一步分析问题:
(gdb) disas f
Dump of assembler code for function f:
0x0