我正在研究ubuntu 12.04和64位机器。我正在读一本关于缓冲区溢出的好书,在玩一个例子时发现了一个奇怪的时刻。
我有这个非常简单的 C 代码:
void getInput (void){
char array[8];
gets (array);
printf("%sn", array);
}
main() {
getInput();
return 0;
}
在文件溢出中。
我用 32 位标志编译它,因为书中的所有示例都假设是 32 位机器,我是这样做的
gcc -fno-stack-protector -g -m32 -o ./overflow ./overflow.c
在代码中,char 数组只有 8 个字节,但查看反汇编时,我发现该数组从堆栈上保存的 EBP 开始 16 个字节,所以我执行了这一行:
printf "aaaaaaaaaaaaaaaaaaaax10x10x10x20" | ./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 "aaaaaaaaaaaaaaaaaaaax10x84x04x08" | ./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
也许 0x08048410
处的代码被执行,并跳转到0xf765be1f
区域。
这个地址里有什么?我想这是一个函数(libC?),所以你可以检查它的汇编代码,看看它会做什么。
另请注意,在成功运行中,您设法超限了 EBP,而不是 EIP。EBP包含0x61616161
,即aaaa
,EIP包含0x20101010
,即nnn
。似乎腐败的EBP间接地使EIP损坏。
尝试使溢出 4 个字节更长,然后它也应该溢出返回地址。
这可能是由于现代操作系统(至少Linux确实如此,我不知道Windows)和现代libc具有不允许执行堆栈中找到的代码的机制。
缓冲区溢出正在调用未定义的行为,因此任何事情都可能发生。理论化可能发生的事情是徒劳的。