Calling Functions Directly with GDB

Calling Functions Directly with GDB

I recently came across a CTF style challenge where the attacker had to guess a few passwords before getting to the function where the flag is reassembled from an encoded format. Or what if there was a CTF challenge with a function that is never called throughout the execution of the program.  At the time I felt it would be easy enough to just figure out the passwords by reversing the encoding function and getting the flag that way.  However, I felt as though there should be a way to get GDB to just jump straight to the function in question.  In order to spin up a quick Proof-Of-Concept, without having to reveal the answer to any CTFs, I created a quick C program that in the main function will ask the user to read in a string, and will simply print it back out to the screen.  There are two functions I have included as well a foo and two function.  You should notice that the foo function is a void function.  Meaning it does not take any arguments, and it does not return a value.  On the other hand the two function does take in two arguments, and will return and int.

First thing we can do is load the program into gdb using the command gdb ./a.out. The file name a.out can be whatever you named the compiled program after using gcc.  Now that the program is loaded we can break main in order to pause at the main function.  It should be noted that if the binary you are debugging has had the symbols stripped then there might not be a main function defined. If so you will need to find the entry point.  Which is another blog post all together.

You can use the command inside of gdb info functions to print every function that has been loaded up to this point of execution.  Additionally you can use info functions regexp to look for specific functions. GDB uses a built-in less style paging system.  You can hit the return key to move down page by page, q to quit out of the paging system, and c to simply print the remainder of the information to screen.  

Scrolling all the way to the bottom you can find Non-debugging symbols.  

When running the binary by itself you can see that it merely asks for a value, writes that value to the screen, and then exits normally.  We know there are other functions within this program, and we want to know how to access them.

In order to do that I read through the gdb documentation and found that calling functions with no debug info.  You can simply use the syntax:

print (<return type> <function name> (<parameters>)

As you can see in the screenshot below I have called the function foo without any return or parameters, and the string gets called.  

Following along with the syntax stated above, if I wanted to call a function that required parameters and has a return type I would use the command shown in the screenshot below.  Also, the p command is gdb's shorthand for the commands provided.  In this example the p relates to the print command.  I wanted to make sure I showed both ways of doing it.

This has been another short blog post while in quarantine.  Hopefully everyone is staying safe! Until next time, keep on hacking.

Ryan Villarreal

About Ryan Villarreal