How to interpret gdb disassemble output? - gdb

I am trying to match the gdb disassemble output (disas [address]) against the source code. I know that such mapping can be done using (gdb) info line *address to find the matching line. However I do not quite understand the format of the output of disassemble. Specifically, what do the following numbers, +4722, and +4281, mean ?
0x00002ad61e45bd02 <+4722>: jmpq 0x2ad61e45bb49 <MsgManager::ForwardMsg(boost::shared_ptr<Channel>, boost::shared_ptr<Msg>, boost::shared_ptr<Context>)+4281>
I am using GNU gdb (GDB) 7.4.1.

Specifically, what do the following numbers, +4722, and +4281, mean
The instruction at address 0x00002ad61e45bd02, which is 4722 bytes from the start of current function (most likely MsgManager::ForwardMsg()) is a jump to address 0x2ad61e45bb49, which is 4281 bytes from the start of MsgManager::ForwardMsg().
You may also find (gdb) disas/m command handy.

Related

Why do the first digits of disassembled instructions in gdb not match the value in rip? Can anyone provide background?

First time disassembling a program in a few months using GDB and on a new linux VM. Last time, when I disassembled a program, set a breakpoint, and ran, the value returned by "i r rip" would EXACTLY match the address of one of the program instructions.
This time, the value returned by "i r rip" == 0x5...54699 <main+15" while the assembly address shown for <+15> == "0x0...0699".
Is GDB now using relative addressing and zeroing the more significant (irrelevant?) address bits similar to what Wireshark does for sequence numbers?
This is my screen dump:
Disassembled code and rip query
You are looking at position-independent executable (PIE).
This executable is linked to load at address 0, and is relocated to 0x54... address on execution.
If you disas main before first running the binary, GDB will show the original linked-at addresses. If you do the same command after first run, GDB will show relocated (actual) addresses.
You can also link non-PIE binary with gcc t.c -no-pie. That binary will exhibit the behavior you expect: the output of disas main will not change between before and after first run, and the disassembly will match the actual value of rip at runtime.

What is GDB's "here"?

I am trying to troubleshoot a bus error with some inline SSE2 assembly. The source code has a macro that uses 5 pointers, and I suspect one of them is not aligned.
I set a breakpoint on the source line. But when I perform a disass, it disassembles from the top of the function, and not where the debugger is stopped. There are hundreds of lines of assembly, so its not really helpful to me. Pressing ENTER 30 to 40 times in response to "Press ENTER to continue" got old very quickly.
I tried a disass $pc, but it dsassembled from the top of the function. I also tried a disass . (with the dot meaning "here"), but that resulted in:
A syntax error in expression, near `.'.
What does GDB use to denote "here"?
You were correct with the use of $pc to represent the current location. The reason that this did not do what you expected when used with the disassemble command is that the disassemble command tries by default to disassemble the function containing the given address which is what you are seeing.
There are alternative forms that can be given to disassemble, for example start,end where start and end are addresses, or start,+length where start is an address and length is a number of bytes.
Try help disassemble at the gdb prompt for more information.
As an alternative you can also use the x (examine) command to display instructions, without the smart find the beginning of the function behaviour, so x/10i $pc will display 10 instructions starting from $pc. This can be helpful if you only want the instructions disassembled, however you don't have access to the /m or /r modifiers that are available on the disassemble command. These modifiers display interleaved source and assembler (for /m) or the raw instruction bytes (for /r).
Also, if the whole press ENTER to continue thing is getting old then you can try set height 0 to turn off the pager, do make sure that you have enough scroll back in your terminal though :)

GDB: How to check current line number during debug

How do I check the current line number that I'm stopped in when debugging with GDB? I would have thought this would be obvious (and maybe it is) but I don't see it on the GDB Cheat Sheet.
Some digging around revealed the following methods:
frame: This command was exactly what I was looking for. Output looked as follows:
(gdb) frame
#0 MyDialog::on_saveButton_clicked (this=0x72bf9e0) at src/ui/dialog/MyDialog.cxx:86
86 _item->save();
(gdb)
where or bt (same effect): This prints out the call stack, ending on the current line.
list *$pc: This doesn't tell you the exact line but it prints out the surrounding lines with the current line in the center.
x/i $eip
eip(rip) points to the next instruction

GDB Patching results in "Cannot access memory at address 0x

I have a program that I need to patch using GDB. The issue is there is a line of code that makes a "less than or equal test" and fails causing the program to end with a Segmentation fault. The program is already compiled and I do not have the source so I cannot change the source code obviously. However, using GDB, I was able to locate where the <= test is done and then I was able to locate the memory address which you can see below.
(gdb) x/100i $pc
... removed extra lines ...
0x7ffff7acb377: jle 0x7ffff7acb3b1
....
All I need to do is change the test to a 'greater than or equal to' test and then the program should run fine. The opcode for jle is 0x7e and I need to change it to 0x7d. My assignment gives instructions on how to do this as follows:
$ gdb -write -q programtomodify
(gdb) set {unsigned char} 0x8040856f = 0x7d
(gdb) quit
So I try it and get...
$ gdb -write -q player
(gdb) set {unsigned char} 0x7ffff7acb377 = 0x7d
Cannot access memory at address 0x7ffff7acb377
I have tried various other memory addresses and no matter what I try I get the same response. That is my only problem, I don't care if it's the wrong address or wrong opcode instruction at this point, I just want to be able to modify the memory.
I am running Linux Mint 14 via VMware Player
Thank
Cannot access memory at address 0x7ffff7acb377
You are trying to write to an address where some shared library resides. You can find out which library that is with info sym 0x7ffff7acb377.
At the time when you are trying to perform the patch, the said shared library has not been loaded yet, which explains the message you get.
Run the program to main. Then you should be able to write to the address. However, you'll need to have write permission on the library to make your write "stick".

GDB question - how do I go through disassembled code line by line?

I'd like to go through a binary file my teacher gave me line by line to check addresses on the stack and the contents of different registers, but I'm not extremely familiar with using gdb. Although I have the C code, we're supposed to work entirely from a binary file. Here are the commands I've used so far:
(gdb) file SomeCode
Which gives me this message:
Reading symbols from ../overflow/SomeCode ...(no debugging symbols found)...done.
Then I use :
(gdb) disas main
which gives me all of the assembly. I wanted to set up a break point and use the "next" command, but none of the commands I tried work. Does anyone know the syntax I would use?
try using ni which is nexti. equivalent is si which is step instruction
nexti if you want to jump over function calls.
stepi if you want to enter a function call.
The following documentation is very helpful; it has a list of all the important commands you could use on gdb.
X86-64: http://csapp.cs.cmu.edu/public/docs/gdbnotes-x86-64.pdf
IA32: http://csapp.cs.cmu.edu/public/docs/gdbnotes-ia32.pdf