Keep GDB prompt interactive while reading from stdin? - gdb

I automate my gdb script like this
gdb -q --args the_program <<EOL
# breakpoints etc.
run
EOL
Works fine, however when interrupting the running process with Ctrl+C, the entire process falsely exits:
Quit anyway? (y or n) [answered Y; input not from terminal]
, meaning gdb is not interactive anymore. How do I prevent this?
For some reason, the interrupt signal works fine when using an external commands file like gdb ... -x the_commands_file. But this question is about the stdin-way. Is there a possibility to send the desired commands via stdin but still be able to keep interaction possible afterwards?

Related

Debugging multiprocess project with GDB

I'd like to to debug a multiprocess C++ project with GDB, specifically I'd like to know if there is a way to achieve the following
Attach multiple processes to a single instance of GDB while letting all the processes run
Setting up a breakpoint in the source code of one of the processes stops all the attached processes
The ideal solution would be something similar to what is offered by the Visual Studio debugger as described here.
At the moment I'm able to attach multiple processes to a GDB instance but then only the current selected inferior is executed while the others are stopped and waiting for a continue command.
In order to be able to run inferiors in the background, one needs to issue this gdb command
set target-async on
after start up and before running anything. With this option in effect, one ca issue
continue&
(or just c&) and this will send the inferior to the background, giving an opportunity to switch to run another one.
Stopping all inferiors at once is a bit more difficult. There is no built-in command for that. Fortunately gdb is scriptable and it is possible to attach a script to a breakpoint. Once the breakpoint is hit, the commands are executed. Put inferior n and interrupt commands in the script for each inferior. It is probably more convenient to do that from a Python script, something like
(gdb) python
>inf = gdb.inferiors()
>for i in inf:
> gdb.execute("inferior %d" % i.num)
> gdb.execute("interrupt")

Debugging a program that is opened by pwntools

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.

How do I attach gdbserver to a process at startup?

I am using gdbserver to debug a remote process. I am able to attach gdbserver to the process after it has launched and is waiting for input.
However, I want to attach gdbserver to the process while it is being launched. The process is launched via a shell script and I cannot change how this process is being launched i.e. I cannot modify the shell script to launch the process via a call to gdbserver.
How do I attach gdbserver to this process as soon as it launches?
Edit: I am able to create a wait loop at the start of main(). For example a loop which waits till it finds a file at a predetermined location :
#include <unistd.h>
int main() {
while( access("/home/username/CONTINUE", F_OK) == -1)
sleep(1);
/*
...all the rest of main()
*/
return 0;
}
We can attach gdbserver while the process is busy with this loop, set breakpoints as required and say touch /home/username/CONTINUE to exit the loop. But this requires us to be able to access the source code, compile the binary and place it on the target machine. I am looking for a better, easier way than this.
But this requires us to be able to access the source code1, compile the binary and place it on the target machine. I am looking for a better, easier way than this.
It looks like you are working on a linux / unix like remote operating system.
If you have admin access to the remote system, the simplest way I could think of is to rename the original executable, and replace that with a shell script named like the original executable, that starts the now renamed under control of gdbserver.
Something like (assumed executable /usr/bin/foo) at the target machine:
root:# cd /usr/bin
root:# mv foo foo_
root:# echo "#!/bin/sh\ngdbserver /dev/com1 foo_ foo.txt" > foo
root:# chmod a+x foo
As it says in the gdbserver man(1) page:
This tells gdbserver to debug foo_ with an argument of foo.txt, and
to communicate with GDB via /dev/com1. gdbserver now waits patiently
for the host GDB to communicate with it.
Another way I could think of without modifying the original process at all, could be a little program that monitors changes in the /dev/proc directory(ies), and attaches gdbserver at such event with the associated pid.
Though it's kind of luck then, if gdbserver is attached, before that process already schedules to main().
1You should have acces to the source code anyways for reasonable debugging with gdb. Though there are cases where you can just get with the (dis-)assembly code as well.

gdb attach to a process without stop

Everytime I attach to a process using gdb, it will stop the target program, and I need to type 'cont' to let it go. Is there a way to attach to a process without stopping it? This makes things easier if the process will behave differently if it stops for a while.
I know there is already a fine answer for this, but I prefer not using an additional file.
Here is another answer:
gdb attach $(pidof process_name) -ex cont
You can't make it not stop. You can however instantly continue... Create a simple batch script which will attach to a specific process and instantly continuing execution after attaching:
gdb attach $1 -x <(echo "cont")
./attach PID
For when you don't know the PID of the process...
gdb attach $(pgrep -f myApp) -ex cont

How do I stop execution in GDB without a breakpoint?

How do I stop a GDB execution without a breakpoint?
Just use a regular interrupt Ctrl-c will work just fine. GDB just forwards the SIGINT to the debugging process which then dies. GDB will catch the non-standard exit and break the process there, so you can still examine all the threads, their stacks and current values of variables. This works fine, though you would be better off using break points. The only time I find myself doing this is, if I think I've gotten into some sort of infinite loop.
GUI applications don't react to ^C and ^Break the way console applications do. Since these days most non-trivial projects tend to be GUI applications or libraries primarily used in GUI applications, you have two options:
Send SIGSTOP to the application from a separate terminal. This is cumbersome.
If you press ^C or ^Break on the GDB prompt, GDB will terminate but the application will remain running. You can then run GDB again to attach to it using the -p command-line switch. This loses debugger state.
In both cases, you might find this helpful: tasklist | grepProcessName| sed -e 's/ProcessName*\([0-9]*\).*/gdbModuleName-pid=\1/' > rungdb.sh You can modify this for use in shell scripts, makefiles or to send a signal instead of attaching GDB.
info threads will help you figure out which thread you want to look at. Then use threadThreadNumber to switch to it.
Start a shell, find the process ID using ps and send it SIGSTOP or SIGINT by using the kill command (e.g. kill -INT pid).
Just type BREAK without any arguments.
Break, when called without any arguments, break sets a breakpoint at the next instruction to be executed in the selected stack frame
Ctrl + Z seems to work for me (but only in some cases - I'm not sure why).