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)
当我从了解这个答案,eip和ebp寄存器(在我的输出不存在),具有以下含义:
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 寄存器。)
基于这一切,我认为:
info registers在 gdb 中没有显示寄存器,这是否意味着该寄存器在机器上不存在,或者它可能存在,但未在调试程序的上下文中使用?(基于GDB 文档,我认为是前者。)我正在尝试做这个练习,其主要观点是:
Stack4 查看覆盖保存的 EIP 和标准缓冲区溢出。
所以主要问题是:在这种情况下,我应该选择 rip 而不是 eip吗?(不过,除了回答这一点之外,我还想对背景有一个更好的了解,因此上面的问题更详细。)
我想这个练习是为 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。