【发布时间】:2012-01-16 00:14:51
【问题描述】:
让我跳过介绍并跳到好的部分。 我正在阅读“道德黑客手册”并尝试一些示例代码(大约 p175)。
----------------------------------------------- ------------------------------------------
目标:溢出堆栈中的 EIP
示例代码:
##> cat overflow.c
main(){
char str1[10]; // declare a 10byte string
// next, copy 35 bytes of 'A' to 'str1'
strcpy(str1,"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
}
----------------------------------------------- ------------------------------------------
如果我在我的 x86 笔记本电脑上编译并运行它,那么结果符合预期。
在 X86 上使用 openSuse 12.1 的结果
##> uname -a
Linux linux-tzxm.site 3.1.0-1.2-desktop #1 SMP PREEMPT
Thu Nov 3 14:45:45 UTC 2011 (187dde0) i686 i686 i386 GNU/Linux
##> cat /proc/sys/kernel/randomize_va_space
1
##> gcc version 4.6.2 (SUSE Linux)
##> GNU gdb (GDB) SUSE (7.3-41.1.2)
##> gdb -q overflow
Reading symbols from /home/administrator/Programming/C/testProgs/overflow...done.
(gdb) run
Starting program: /home/administrator/Programming/C/testProgs/overflow
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) info reg eip
eip 0x41414141 0x41414141
----------------------------------------------- ------------------------------------------
但是,如果我在我的 x86_64 笔记本电脑上做同样的事情,那么结果会有所不同并且不像预期的那样(从我的小知识的角度来看)
在 x86_64 上使用 openSuse 11.3 的结果
##> uname -a
Linux linux-2mna.site 2.6.34.10-0.4-desktop #1 SMP PREEMPT 2011-10-19 22:16:41 +0200 x86_64 x86_64 x86_64 GNU/Linux
##> cat /proc/sys/kernel/randomize_va_space
1
##> gcc version 4.5.0 20100604
##> GNU gdb (GDB) SUSE (7.1-3.12)
##> gdb -q overflow2
Reading symbols from /home/jojojorn/Documents/Personal/HACKING/C_Prog/Tests/testProgs/overflow2...done.
(gdb) run
Starting program: /home/jojojorn/Documents/Personal/HACKING/C_Prog/Tests/testProgs/overflow2
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400553 in main () at overflow.c:11
11 }
(gdb) info reg eip
Invalid register `eip'
(gdb)
----------------------------------------------- ------------------------------------------
所以这是我的问题:
1) 为什么我的 x86_64 堆栈上的 EIP 不能溢出? x86_64 和 x86 的堆栈行为有区别吗?
2) 当我在我的 x86_64 上运行 x86 编译的二进制文件并使用 gdb 检查时,结果再次符合预期。 所以我假设差异是使用 gcc 32 位和 gcc 64 位?对于这个简单的代码,有什么区别,为什么有区别?
3) 如果我希望我在 x86_64 上的代码的行为与在 x86 上编译时一样,是否在编译时设置 gcc 参数?
4) 我问这个问题,这意味着我还没有足够的知识来问更好的问题。我应该问你的天才头脑中是否有一些额外的东西(你会回答)?
真诚的
【问题讨论】:
-
我认为 x86_64 使用 %rip,gcc 还向堆栈添加了填充以防止这种情况,请尝试使用 -fno-stack-protector。
-
eip/rip 没有溢出。寄存器具有固定大小,您无法将任何内容复制到 eip/rip,因此您无法“溢出”它。溢出的是内存
标签: c assembly x86 stack x86-64