我正在使用ubuntu 12.04和64位机器。我正在阅读一本关于缓冲区溢出的好书,在玩一个例子的时候发现了一个奇怪的时刻。
我有这个非常简单的C代码:
void getInput (void){
char array[8];
gets (array);
printf("%s\n", array);
}
main() {
getInput();
return 0;
}
文件overflow.c中的
我用32位标志编译它导致书中假设32位机器的所有例子,我这样做
gcc -fno-stack-protector -g -m32 -o ./overflow ./overflow.c
在代码中,char数组只有8个字节,但是看看反汇编我发现该数组从堆栈上保存的EBP开始16个字节,所以我执行了这一行:
printf "aaaaaaaaaaaaaaaaaaaa\x10\x10\x10\x20" | ./overflow
得到了:
aaaaaaaaaaaaaaaaaaaa
Segmentation fault (core dumped)
然后我打开了核心文件:
gdb ./overflow core
#0 0x20101010 in ?? ()
(gdb) info registers
eax 0x19 25
ecx 0xffffffff -1
edx 0xf77118b8 -143583048
ebx 0xf770fff4 -143589388
esp 0xffef6370 0xffef6370
ebp 0x61616161 0x61616161
esi 0x0 0
edi 0x0 0
eip 0x20101010 0x20101010
正如您所见,EIP实际上获得了我想要的新价值。但是,当我想放一些有用的值,如0x08048410
printf "aaaaaaaaaaaaaaaaaaaa\x10\x84\x04\x08" | ./overflow
程序像往常一样崩溃但是当我试图观察EIP寄存器中的值时发生了一些奇怪的事情:
#0 0xf765be1f in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) info registers
eax 0x61616151 1633771857
ecx 0xf77828c4 -143120188
edx 0x1 1
ebx 0xf7780ff4 -143126540
esp 0xff92dffc 0xff92dffc
ebp 0x61616161 0x61616161
esi 0x0 0
edi 0x0 0
eip 0xf765be1f 0xf765be1f
突然EIP开始看起来像这个0xf765be1f,它看起来不像0x08048410。实际上我注意到,从0开始放置任何十六进制值就足以得到这个崩溃的EIP值。你知道为什么会这样吗?是因为我在64位机器上吗?
UPD
评论中的好人要求提供更多信息,这里是getInput函数的反汇编:
(gdb) disas getInput
Dump of assembler code for function getInput:
0x08048404 <+0>: push %ebp
0x08048405 <+1>: mov %esp,%ebp
0x08048407 <+3>: sub $0x28,%esp
0x0804840a <+6>: lea -0x10(%ebp),%eax
0x0804840d <+9>: mov %eax,(%esp)
0x08048410 <+12>: call 0x8048310 <gets@plt>
0x08048415 <+17>: lea -0x10(%ebp),%eax
0x08048418 <+20>: mov %eax,(%esp)
0x0804841b <+23>: call 0x8048320 <puts@plt>
0x08048420 <+28>: leave
0x08048421 <+29>: ret
答案 0 :(得分:3)
也许0x08048410
处的代码已执行,并跳转到0xf765be1f
区域。
这个地址是什么?我想这是一个函数(libC?),所以你可以检查它的汇编代码,看看它会做什么。
另请注意,在成功运行中,您设法超出了EBP,而不是EIP。 EBP包含0x61616161
,aaaa
,EIP包含0x20101010
,\n\n\n
。似乎腐败的EBP间接导致EIP腐败
尝试使溢出4个字节更长,然后它也应该超出返回地址。
答案 1 :(得分:1)
这可能是因为现代操作系统(Linux至少,我不知道Windows)和现代libc have mechanisms不允许执行堆栈中的代码执行。
答案 2 :(得分:0)
缓冲区溢出正在调用未定义的行为,因此任何事情都可能发生。理论化可能发生的事情是徒劳的。