gdb" info frame"

时间:2016-10-30 07:59:17

标签: 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

据我所知this answereipebp个寄存器(我的输出中没有),具有以下含义:

  

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

     

" EBP"寄存器通常被认为是该堆栈帧的本地的起始地址,它使用" offset"解决

来自this other answer,我理解

  

[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

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

基于这一切,我想:

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

问题

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

    我正在尝试this exercise,其主要观点是:

      

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

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

1 个答案:

答案 0 :(得分:4)

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

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

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

通常,您应将%rip视为64位版本的%eip,将%rbp视为64位版本的%ebp