Using GDB to inspect the Machine Stack - gdb

Is there any way to get GDB to print the last "n" values pushed on the machine's stack. For example, currently if I want to inspect the contents of the stack I do the following (assuming x86 architecture):
(gdb) # get last value pushed on stack
(gdb) p *(int *)($esp)
(gdb) # get 2nd to last value pushed on stack
(gdb) p *(int *)($esp + 4)
Is there a better way to view the machine stack? Printed nicely, maybe?

Examine 16 words on the top of stack:
x/16wx $esp
The "w" is for printing words

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.

GDB define command: print $arg1 doesn't print the correct value when in define

I want to define a new command which basically sets a breakpoint on a line, print a value of a certain variable and then continues execution. Unfortunately I am having issues. Here is the code I am using
(gdb) define print_and_continue
Type commands for definition of "print_and_continue".
End with a line saying just "end".
>break $arg0
>command $bpnum
>print $arg1
>continue
>end
>end
So I want to print the value of variable len which is defined in linked_list.h:109. And I execute the following code:
(gdb) print_and_continue linked_list.h:111 len
Breakpoint 1 at 0x388a: linked_list.h:111. (12 locations)
(gdb) r
...
Breakpoint 1, linked_list<test_struct<1>, 1>::remove_if<run_test<1, 1, 1>(std::vector<int, std::allocator<int> >&)::{lambda(test_struct<1> const&)#1}>(run_test<1, 1, 1>(std::vector<int, std::allocator<int> >&)::{lambda(test_struct<1> const&)#1}&&) (this=0x7fffffffdca0, condition=...) at linked_list.h:112
112 linked_list_node* prev = nullptr;
$1 = void
It seems like $arg1 in print function didn't get replaces by the actual argument. What am I doing wrong?
It seems like $arg1 in print function didn't get replaces by the actual argument.
I don't believe that's what is actually happening. Rather, everything following command $bpnum is attached to the newly-created breakpoint literally (without any expansion at all). You can see that happening with info break, which will show something like:
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000001136 at ...
print $arg1
continue
This is generally what you would want (deferring evaluating the argument until the time breakpoint is hit). Otherwise you would print current value of len if you use print len, when what you want is to print the value of len when the breakpoint is hit.
Of course, when the breakpoint is hit, there is no $arg1 (or $arg0) anywhere around, so you get the same output you'd get trying to print any other non-existent GDB variable.
What am I doing wrong?
You are using "quick hack of a language" (which is what the "native" GDB scripting language is), instead of using a proper programming language.
I am 99.99% certain that defining print_and_continue is possible (and probably quite easy) using embedded Python.
That said, I don't believe that print_and_continue is all that useful (in my 20+ years of using GDB, I never needed anything like that).

Buffer overflow, register wrong hex input

Trying to exploit a stack overflow. Found te offset to write to the $RSP buffer, when i write to it with normal letters like "A", it gets translated to the correct adress, same if i put the hex value such as "\x41", it gets added to $RSP buffer and used on return.
But then i try to write a memory adress in hex, it does not get translated correctly. Example when i run the code for "\xf0\xe1\xfd\xff\xff\x7f" in the position that overwrites the RSP, the RSP gets set to:
RSP: 0x7ffffffde1d8 --> 0xbfc3bdc3a1c3b0c3
Anyone have any idea what is happening?
I am doing this with bash on windows running ubuntu subsystem.
Don't have the source code, only the elf and debbuging with gdb.
Screenshot of breakpoint after the RSP has been updated
Python code used to generate input, feeded into a .txt file and the run inside gdb with the elf file.:
sys.stdout.write('\x90'*10+'\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05'+'A'*11 + "\xf0\xe1\xfd\xff\xff\x7f" + "\0"*2 + '\x90'*400)

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

How to interpret gdb disassemble output?

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.