【发布时间】:2016-10-30 07:59:17
【问题描述】:
上下文
在我的机器上发出命令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 answer、eip 和 ebp 寄存器(不在我的输出中)具有以下含义:
eip 是下一条要执行的指令的寄存器(也称为程序计数器)
“ebp”是寄存器,通常被认为是这个栈帧的locals的起始地址,使用“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
(注意:也尝试使用 info all-registers。输出更长,仍然没有 eip/epb ——这是我所期待的,因为根据文档,这些是向量/FPU 寄存器。)
基于这一切,我认为:
- 在我的机器上没有 epb/eip 寄存器
- 我的机器上总是使用 rip 而不是 eip
- 我的机器上总是使用 rbp 而不是 ebp
问题
- 上述理解正确吗? (理论 B:我的机器上也有有这些寄存器,但是 gcc 以这样的方式编译程序,它使用 rip 而不是 eip 和 rbp 而不是 ebp . 理论 C:由于我在函数的开头而不是在函数内部中断,因此尚未使用 eip 和 ebp;在这种情况下,rip 和 rbp 有其他用途。)
- (假设我的主要理论是正确的):是新机器有 eip/ebp 而不是 rbp/rip,还是新机器有两组寄存器,而旧机器只有 rbp/rip?
- 如果 gdb 中的
info registers没有显示寄存器,这是否意味着该寄存器在机器上不存在,或者它可能存在,但没有在被调试程序的上下文中使用? (基于GDB documentation,我猜是前者。)
背景
我正在尝试做this exercise,其要点是:
Stack4 看看覆盖已保存的 EIP 和标准缓冲区 溢出。
所以主要问题是:在这种情况下我应该选择 rip 而不是 eip? (但是,除了回答这一点,我想对背景有一个更好的了解,因此上面的问题更详细。)
【问题讨论】:
-
尝试
print $ebp和print $pc你会得到未列出但工作的寄存器。但它不适用于eip -
EBP 是 RBP 的下半部分。
-fomit-frame-pointer是默认值,所以不要期望看到堆栈帧的东西。请参阅x86 tag wiki 了解 x86-64 中的一些新功能链接,以及显示什么是什么的子集的注册图表。或者build 32-bit executables,这样你就可以跟着32位教程学习了。
标签: c x86 gdb buffer-overflow