堆栈eip溢出x86 vs x86_64 easy C代码

堆栈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,

让我跳过介绍,跳到好的部分。 我正在阅读《黑客道德手册》,并尝试一些示例代码(大约在第175页)

----------------------------------------------------------------------------------------- 目标:使堆栈中的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上的结果 ----------------------------------------------------------------------------------------- 然而,如果我在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节

  • 这并不是说x86_64上没有溢出,而是表示异常的另一种方式。它不是告诉您在实际更新
    rip
    后无法执行代码0x4141,而是告诉您目标地址在更新前无效。这是x86代码和x86_64代码之间的体系结构差异,无论何时执行64位代码,都是这样处理的

  • 同样,您只会在64位代码上有不同的消息

  • 您必须将其编译为32位代码。如果要将消息编译为x86_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)