4

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.)

2
  • try print $ebp and print $pc you'll get registers unlisted but working. But it doesn't work for eip Commented Oct 30, 2016 at 8:08
  • 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. Commented Oct 30, 2016 at 9:01

1 Answer 1

12

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.

Sign up to request clarification or add additional context in comments.

2 Comments

No imagination needed. Seeing rip = 0x4005b1 in the output is absolute confirmation that this is x86-64.
Thanks for the answer, Andrew. Although not directly stated, I can infer the answers to my original questions from your answer. (1. Kind of correct: while the registers do not exist with this name, 64-bit versions with the same name exist. 2. Not correct, it is the other way round :) 3. Kind of correct, but it is possible to "emulate" the 32 bit versions of the registers, by using -m32 flag)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.