以下是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(程序计数器)寄存器的地址,并且清楚表明它在写入时被跳过:
在程序计数器之后继续写入字符,这可能是为什么没有显示分段错误的原因。请解释原因,以及如何使程序计数器溢出。
答案 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
声明为静态...以便不覆盖它。