缓冲区溢出不溢出返回地址

时间:2014-03-12 22:53:19

标签: buffer overflow

以下是C代码

#include <stdio.h>
void read_input()
{
    char input[512];
    int c = 0;
    while (read(0, input + c++,1) == 1);
}
int main ()
{
    read_input();
    printf("Done !\n");
    return 0;
}

在上面的代码中,应该有一个缓冲区溢出的数组&#39;输入&#39;。我们提供的文件中将包含600多个字符,所有2个字符(例如2222222 ...)(顺便说一下,2的ascii是32)。但是,当使用该文件执行代码时,不会抛出分段错误,这意味着程序计数器寄存器保持不变。下面是gdb中输入数组内存的截图,突出显示的是ebp(程序计数器)寄存器的地址,并且清楚表明它在写入时被跳过:

LINK

在程序计数器之后继续写入字符,这可能是为什么没有显示分段错误的原因。请解释原因,以及如何使程序计数器溢出。

1 个答案:

答案 0 :(得分:0)

这很棘手! input[]c都在堆栈中,c跟随input[]的512个字节。在阅读第513个字节之前c=0x00000201(513)。但是,自从input[]结束后,您正在阅读0x32(50)到c,在阅读后c=0x00000232(562):实际上这是小端和最不重要的字节在内存中排在第一位(如果这是一个大型的endian架构,它是c=0x32000201 - 它肯定会出现段错误。)

所以你实际上是在提前562 - 513 = 49 bytes。比有++并且它们是50.实际上你有50个字节没有被0x32覆盖(再次...... 0x3232ab64是小端。如果你将内存显示为字节而不是dwords,你将请参阅0x64 0xab 0x32 0x32)。

所以你写的是未分配的堆栈区域。它不会因为它处于合法空间(达到强制限制)而不会被删除,并且不会覆盖任何重要信息。

很好的例子,说明事情如果没有爆炸就会出现可怕的错误!这是真实的例子还是作业?

啊是的...对于第二个问题,请尝试在c之前声明input[],或将c声明为静态...以便不覆盖它。