2
votes

Context

When issuing the command info frame on my machine (with break point on main), the output is as follows:

(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

As I understand from this answer, eip and ebp registers (not present in my output), have the following meaning:

eip is the register for next instruction to execute (also called program counter)

"ebp" is the register usually considered as the starting address of the locals of this stack frame, which use "offset" to address

From this other answer, I understand that

[RIP is] the instruction pointer

[...]

Some of these registers were envisioned to be used for specific use, and commonly are. The most critical ones are the RSP and RBP.

Finally, info registers gives me the following output:

(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.: tried with info all-registers as well. Much longer output, still no eip/epb -- which I was expecting, since according to documentation, these are vector/FPU registers.)

Based on all this, I suppose that:

  • on my machine there are no epb/eip registers
  • instead of eip, rip is always used on my machine
  • instead of ebp, rbp is always used on my machine

Questions

  1. Is the above understanding correct? (Theory B: there are these registers on my machine as well, but gcc compiled the program in such a way, that it uses rip instead of eip and rbp instead of ebp. Theory C: since I broke at the beginning of a function, not inside it, eip and ebp are not yet used; rip and rbp serve some other purpose in this case.)
  2. (Assuming my main theory is correct): is it the case that newer machines have eip/ebp instead of rbp/rip, or do newer machines have both sets of registers, and older ones only rbp/rip?
  3. If info registers in gdb does not show a register, does that mean that that register does not exist on the machine, or that it might exist, but is not used in the context of the debugged program? (Based on GDB documentation, I would suppose the former.)

Background

I am trying to do this exercise, whose main point is:

Stack4 takes a look at overwriting saved EIP and standard buffer overflows.

So the main question would be: should I go for rip instead of eip in this case? (However, besides answering this point, I would like to have a better understanding of the background in general, therefore the above, more detailed questions.)

1
try print $ebp and print $pc you'll get registers unlisted but working. But it doesn't work for eipJean-François Fabre
EBP is the low half of RBP. -fomit-frame-pointer is the default, so don't expect to see stack-frame stuff. See the x86 tag wiki for some what's-new-in-x86-64 links, and register diagrams showing what's a subset of what. Or build 32-bit executables, so you can follow the 32-bit tutorial.Peter Cordes

1 Answers

8
votes

The exercise was written, I imagine, for the i386 architecture, which is the older 32-bit x86 variant. The %ebp, %eip registers are the 32-bit versions of these registers.

You are running, I imagine, on x86-64, the 64-bit x86 variant. For this version of the architecture these registers are extended to 64-bits, and have new names %rbp and %rip.

When compiling on x86-64 it's often possible to compile code for the 32-bit x86 ABI, if you're using gcc then add the -m32 flag at compile time. If you do this then GDB will show you the %ebp and %eip registers.

In general you should consider %rip as just a 64-bit version of %eip, and %rbp as a 64-bit version of %ebp.