I have set about 50 breakpoints in my project. How do I figure out if a breakpoint was set in a particular function? I don't want to use
info breakpoints
as it shows all of them. I just want to confirm if there is a breakpoint on this one function.
The only approach I know for this is turning on logging, listing the breakpoints and turning it off. Then use cat and grep from within gdb to find your breakpoint by function name.
set logging file breaks.txt
set logging on
info break
set logging off
shell cat breaks.txt | grep function_name
Don't forget to delete the file when you change the breakpoint list because these commands will append logs to the existing file and you don't want that.
I know that someone can probably write a gdb script to automate this task, but this is the main idea.
Related
I am trying to do a stackoverflow for a course at university. The binary I am to exploit has a canary, however, there is a way to leak that canary to stdout. The canary of course consists of some random bytes so I can't just read them from the string that the program outputs to stdout.
For this reason I am using the python and pwntools like p.recv(timeout = 0.01).encode("hex").
(I'm using pwntools only because I don't know another way to read the output in hex format, if there is an easier way I can of course use something else)
This works more or less works as expected, I manage to write the memory area that is past the canary. However, I get a segfault, so I obviously have some problem with the stackoverflow I am causing. I need a way of debugging this, like seeing the stack after I provide the input that causes the stackoverflow.
And now without any further ado the actual question: Can I debug a process that I started with pwntools (like process("./myprog")) in GDB or some other program that can show me the content of the stack?
I already tried getting the pid in python and using gdb attach to attach to that pid, but that didn't work.
Note: The binary I am trying to exploit has the guid set. Don't know if that matters tho.
You can use the pwnlib.gdb to interface with gdb.
You can use the gdb.attach() function:
From the docs:
bash = process('bash')
# Attach the debugger
gdb.attach(bash, '''
set follow-fork-mode child
break execve
continue
''')
# Interact with the process
bash.sendline('whoami')
or you can use gdb.debug():
# Create a new process, and stop it at 'main'
io = gdb.debug('bash', '''
# Wait until we hit the main executable's entry point
break _start
continue
# Now set breakpoint on shared library routines
break malloc
break free
continue
''')
# Send a command to Bash
io.sendline("echo hello")
# Interact with the process
io.interactive()
The pwntools template contains code to get you started with debugging with gdb. You can create the pwntools template by running pwn template ./binary_name > template.py. Then you have to add the GDB arg when you run template.py to debug: ./template.py GDB.
If you get [ERROR] Could not find a terminal binary to use., you might need to set context.terminal before you use gdb.
If you're using tmux, the following will automatically open up a gdb debugging session in a new horizontally split window:
context.terminal = ["tmux", "splitw", "-h"]
And to split the screen with the new gdb session window vertically:
context.terminal = ["tmux", "splitw", "-v"]
(Note: I never got this part working, so idk if it'll work. Tell me if you get the gdb thing working).
(To use tmux, install tmux on your machine, and then just type tmux to start it. Then type python template.py GDB.
If none of the above works, then you can always just start your script, use ps aux, find the PID, and then use gdb -p PID to attach to the running process.
I am dealing with a large code base with tons of globals. Under some peculiar set of data it produces the wrong result. I wanted to automatically run few scenarios with gdb in automatic step-by-step execution and periodical dumping
of some values and recording the tracing in some file. Doing it manually will ruin my sight and my brain. I speculate that there is some globals mess-up. How to do this automatically? Use some scripting. All this is in RH linux.
Thanks in advance.
tried to do this manually using conditional breaks, but gave up after a while
I wanted to automatically run few scenarios with gdb in automatic step-by-step execution and periodical dumping of some values and recording the tracing in some file.
It may be significantly more effective to run the program under reverse debugger (such as rr), and trace the wrong result back to its source.
How to do this automatically?
You can't do automatically what you can't express as an algorithm, and you haven't described an algorithm you want to use. If it's something like "stop every 100 times foo is called and print the values of these 500 globals", than that's trivially automatable with GDB.
More complicated algorithms are possible with the use of embedded Python.
In the .gdbinit file in your home folder add
add-auto-load-safe-path /path_to_the_folder_containing_your_executable/
Now you can create another .gdbinit file in the same folder where your executable is that will be loaded when you start gdb from there (the .gdbinit file in your home that is also read - useful if you have nice stuff there such as loading pretty printers).
In this .gdbinit file, add the code below
file your_executable_name
start
# Optional
set args "<any command line parameters you program might need>"
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Add gdb commands below to set breakpoints, print variable values, etc
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
run
Gdb is very powerful and I'll list a few things that might help this automation.
You can set breakpoints with b filename.ext:line_number or b function_name
You can use commands breakpoint_number (see here) and then list commands that should be run after this breakpoint is hit. Use end to finish the commands
You know the breakpoint number, since they are created sequencially (note that the start will count as a breakpoint and thus the first one you add will be breakpoint 2)
You can use convenience variables to store useful things such as the address of an important object
The python api is very powerful
One idea is that you can save the address of the important global variables (if they are not always accessible) using convenience variables. For instance, add a breakpoint where this global variable is and then add to this breakpoint the command to save the address of this variable to a convenience variable followed by continue (with continue you will not see gdb stopping there).
set $var1 = &myglobal
continue
You might want to also delete this breakpoint with delete breakpoint_number before continue to avoid stopping at this breakpoint again.
Then as long is the object exists you can inspect it using p $var1 or p $var1->something when the program is stopped at a different breakpoint where myglobal might not be directly accessible.
In the commands that you add to be run when a breakpoint is hit you can do things such as echo message explaining where you are, p some_var to see the values of variables or even python some_complicated_python_code.
In the case you want to use python for more power it is worth reading the section about it in the manual. Let-me give you one example. Suppose one of your global variables was stored in a convenience variable called "$myvar". Then you can pass it to the python interpreter with
python myvar = gdb.parse_and_eval("$myvar")
You can also pass any variable in the current scope to parse_and_eval.
Now, suppose this global variable stores an object of a class with a "n_elem" attribute you want to check. You can print it with
python print(myvar["n_elem"])
You can also create a python file in the same folder and use
python from my_python_file import *
to import functions defined there.
With these gdb features you can pretty much automate whatever you might need.
How do I print the local variables in GDB every "next" or "step" command?
Is there a way instead of writing "info locals" every time?
If you can use GDB TUI mode, that's probably best. See this answer.
If you can't use TUI for some reason, this should also work:
# put this into ~/.gdbinit:
define hook-next
info locals
end
More info on hooking commands here.
I set a breakpoint and set its conditions and some other commands. Now I realize that I should had set it a few lines ahead. How can I change the line of the breakpoint without deleting it and losing its settings?
How can I change the line of the breakpoint without deleting it and losing its settings?
You can't.
What you can do is use save breakpoints /tmp/bp.txt command to save current settings for all breakpoints, edit the /tmp/bp.txt file to update the line info (or anything else), and finally delete to remove current breakpoints and source /tmp/bp.txt to reload them.
Considering that you will probably want to do that on many occasions, I suggest adding the following to your .gdbinit:
define loadbp
delete breakpoints
source .gdbbp
end
document loadbp
Set stored breakpoints after deleting any current breakpoints.
The breakpoints to load (set) are expected in ./.gdbbp which is the file created by savebp, but can
be edited manually.
Some breakpoints may not be set because the needed shared object hasn't been loaded yet. gdb
doesn't prompt when such breakpoint commands are not set interactively. Consequently, it may be
necessary to run this command again, once the shared object has been loaded. To account for cases
in which shared objects are loaded automatically by the dynamic loader, this command also sets a
breakpoint in main. This ensures that there is an early opportunity to call this command again to
set shared object breakpoints.
end
define savebp
save breakpoints .gdbbp
end
document savebp
Store current breakpoints in .gdbbp for retrieval using loadbp.
end
To use those commands, you need to source .gdbinit or restart gdb. Then, type savebp and hit Enter at the gdb command prompt, edit ./.gdbbp as desired, then type loadbp and hit Enter at the gdb command prompt.
Note that, as written, those commands save and load .gdbbp relative to the current directory. Usually, that's the directory from which you started gdb, but you can change it from within gdb, so pay attention to where the file is saved. (You can run the pwd command at the gdb command prompt to see what the current directory is.)
I am writing gdb command scripts to simplify the debugging. One of the problems I have
is that I am setting a breakpoint, and I want to disable it afterwards, and only enable it after another breakpoint is hit.
What I want to do is this
$my_break_number = break SomeFile.cpp:231
disable $my_break_number
but unfortunately gdb doesn't work this way. I have read the manual, but I cannot find any information on how to do this. Hopefully there is some information I have missed.
gdb will automatically set a convenience variable $bpnum with the last set breakpoint number.
You can possibly use that after setting a breakpoint to disable it (I haven't tested when a breakpoint is ambiguous and creates multiple breakpoints, I think it will work and disable all breakpoint locations created.)
see: http://sourceware.org/gdb/current/onlinedocs/gdb/Set-Breaks.html#Set-Breaks
if you need to use the breakpoint number from commands, that is probably not what you want, but it works for the question as specified.
It sounds like you may want to use the Python GDB scripting, which gives you a lot better programmatic access to breakpoints than what is possible with "regular" command scripts.
Also info breakpoints gives useful information such as:
number of breakpoint, how many time the breakpoint was hit, address in memory, what function is it in, file and line number of breakpoint