c - 堆栈 eip 溢出 x86 与 x86_64 简单的 C 代码

标签 c assembly x86 stack x86-64

让我跳过介绍,直接跳到精彩部分。 我正在阅读“道德黑客手册”并尝试一些示例代码(大约 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 中查询 EIP 寄存器 对于 64 位可执行文件,您不会获得任何值,因为它不是有效的 64 位寄存器。如果您想在 native 64 位平台上将可执行文件保留为 32 位,请在编译时将 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/

相关文章:

x86 - :offset addressing scheme work?段如何

c - 在 C 中初始化指针的不同方法

c - 关于 BYTE 类型的 strlen() 的警告

c - 对 `printf' 的 undefined reference

assembly - 用汇编语言画线

assembly - 常量乘法 - imul 或 shl-add-combination

c - 程序集 MMX 点积段错误

c - 将指向结构的指针作为参数传递给线程取消清理处理程序

在 Swift 中创建一个字符串缓冲区供 C 稍后使用和释放

c - 如何用C软件中断正在运行的函数?