gdb“信息框架”中没有 epb/eip 寄存器

Att*_*lio 2 c x86 gdb buffer-overflow

语境

info frame在我的机器上发出命令时(断点打开main),输出如下:

(gdb) info frame
Stack level 0, frame at 0x7fffffffdbd0:
 rip = 0x4005b1 in main; saved rip = 0x7ffff7a53b05
 Arglist at 0x7fffffffdbc0, args: 
 Locals at 0x7fffffffdbc0, Previous frame's sp is 0x7fffffffdbd0
 Saved registers:
  rbp at 0x7fffffffdbc0, rip at 0x7fffffffdbc8
Run Code Online (Sandbox Code Playgroud)

当我从了解这个答案eipebp寄存器(在我的输出不存在),具有以下含义:

eip 是执行下一条指令的寄存器(也称为程序计数器)

“ebp”是通常被认为是这个栈帧的locals的起始地址的寄存器,它使用“offset”来寻址

另一个答案中,我明白

【RIP是】指令指针

[...]

其中一些寄存器被设想用于特定用途,并且通常如此。最关键的是 RSP 和 RBP。

最后,info registers给我以下输出:

(gdb) info registers
rax            0x4005ad 4195757
rbx            0x0      0
rcx            0x0      0
rdx            0x7fffffffdcc0   140737488346304
rsi            0x7fffffffdca8   140737488346280
rdi            0x2      2
rbp            0x7fffffffdbc0   0x7fffffffdbc0
rsp            0x7fffffffdbc0   0x7fffffffdbc0
r8             0x7ffff7dd7c60   140737351875680
r9             0x7ffff7dead10   140737351953680
r10            0x7fffffffda50   140737488345680
r11            0x7ffff7a53a10   140737348188688
r12            0x4004b0 4195504
r13            0x7fffffffdca0   140737488346272
r14            0x0      0
r15            0x0      0
rip            0x4005b1 0x4005b1 <main+4>
eflags         0x246    [ PF ZF IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
Run Code Online (Sandbox Code Playgroud)

(注意:也尝试过info all-registers。更长的输出,仍然没有 eip/epb——这是我所期待的,因为根据文档,这些是向量/FPU 寄存器。)

基于这一切,我认为:

  • 在我的机器上没有 epb/eip 寄存器
  • 我的机器上总是使用 rip 而不是 eip
  • 我的机器上总是使用 rbp 而不是 ebp

问题

  1. 以上理解是否正确?(理论 B:我的机器上也这些寄存器,但是 gcc 以这样一种方式编译程序,即它使用 rip 而不是 eip 和 rbp 而不是 ebp。理论 C:因为我在函数的开头中断了,不在其中,eip 和 ebp 尚未使用;在这种情况下,rip 和 rbp 有其他用途。)
  2. (假设我的主要理论是正确的):是新机器有 eip/ebp 而不是 rbp/rip,还是新机器有两组寄存器,而旧机器只有 rbp/rip?
  3. 如果info registers在 gdb 中没有显示寄存器,这是否意味着该寄存器在机器上不存在,或者它可能存在,但未在调试程序的上下文中使用?(基于GDB 文档,我认为是前者。)

背景

我正在尝试做这个练习,其主要观点是:

Stack4 查看覆盖保存的 EIP 和标准缓冲区溢出。

所以主要问题是:在这种情况下,我应该选择 rip 而不是 eip吗?(不过,除了回答这一点之外,我还想对背景有一个更好的了解,因此上面的问题更详细。)

And*_*rew 8

我想这个练习是为 i386 架构编写的,它是较旧的 32 位 x86 变体。的%ebp%eip寄存器是这些寄存器的32位版本。

我想,您正在 x86-64 上运行 64 位 x86 变体。对于此版本的架构,这些寄存器扩展到 64 位,并具有新名称%rbp%rip.

在 x86-64 上编译时,通常可以为 32 位 x86 ABI 编译代码,如果您正在使用,gcc-m32在编译时添加标志。如果您这样做,那么 GDB 将向您显示%ebp%eip寄存器。

一般来说,你应该考虑%rip的只是一个64位版本%eip,并%rbp为64位版本%ebp