让我跳过介绍,直接跳到精彩部分。 我正在阅读“道德黑客手册”并尝试一些示例代码(大约 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 笔记本电脑上编译并运行它,那么结果是符合预期的。
使用 openSuse 12.1 在 X86 上的结果
##> 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
,而不是 EIP
... 因此,如果您在 gdb 中查询
对于 64 位可执行文件,您不会获得任何值,因为它不是有效的 64 位寄存器。如果您想在 native 64 位平台上将可执行文件保留为 32 位,请在编译时将 EIP
寄存器gcc
传递给 -m32
标志。
如果您想了解 x86_64 Unix 堆栈与 x86 Unix 堆栈相比的行为方式,那么我建议阅读 x86_64 Unix ABI , 第 3.2 和 3.4 节。
关于c - 堆栈 eip 溢出 x86 与 x86_64 简单的 C 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8433036/