堆栈eip溢出x86 vs x86_64 easy C代码
让我跳过介绍,跳到好的部分。 我正在阅读《黑客道德手册》,并尝试一些示例代码(大约在第175页) ----------------------------------------------------------------------------------------- 目标:使堆栈中的EIP溢出 示例代码:堆栈eip溢出x86 vs x86_64 easy C代码,c,assembly,x86,stack,x86-64,C,Assembly,X86,Stack,X86 64,让我跳过介绍,跳到好的部分。 我正在阅读《黑客道德手册》,并尝试一些示例代码(大约在第175页) ----------------------------------------------------------------------------------------- 目标:使堆栈中的EIP溢出 示例代码: ##> cat overflow.c main(){ char str1[10]; // declare a 10byte string // next,
##> 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上的结果
-----------------------------------------------------------------------------------------
然而,如果我在x86_64笔记本电脑上也这样做,那么结果就不同了,也不像预期的那样(从我所知不多的角度来看)
使用openSuse 11.3在x86_64上的结果
-----------------------------------------------------------------------------------------
下面是我的问题:
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
。。。因此,如果使用64位可执行文件查询gdb
中的EIP
寄存器,则不会得到任何值,因为这不是有效的64位寄存器。如果希望在本机64位平台上将可执行文件保持为32位,则在编译时传递gcc
标记-m32
如果您想了解x86_64 Unix堆栈与x86 Unix堆栈相比的性能,那么我建议您阅读第3.2节和第3.4节
rip
后无法执行代码0x4141,而是告诉您目标地址在更新前无效。这是x86代码和x86_64代码之间的体系结构差异,无论何时执行64位代码,都是这样处理的rip
指向的位置和其他寄存器的值,实际上不难注意到这种差异我认为x86_64使用了%rip,gcc也在堆栈中添加了填充以防止出现这种情况,请尝试使用-fno stack protector。eip/rip上没有溢出。寄存器的大小是固定的,您无法将任何内容复制到eip/rip,因此无法“溢出”它。溢出的是内存如果要将其编译为32位,则需要安装
libc6-dev-i386
。否则您将得到致命错误:sys/cdefs.h:没有这样的文件或目录
##> 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
##> 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)