DEV Community

Cover image for Decompiling and Debugging with Ghidra
G.L Solaria
G.L Solaria

Posted on

Decompiling and Debugging with Ghidra

Ghidra is an open source tool developed by the U.S. National Security Agency (NSA) for reverse engineering binaries when you don't have access to the source code. It can be used to assist in capture the flag cyber security challenges. Among its many features is that it can convert binaries into C code. Ghidra can run headless or through a Java GUI. This post will focus on using the GUI to decompile and debug a C program given just the binary.

Installation

This installation guide assumes you are installing to a Debian based Linux distribution.

Install JDK

Ghidra requires the Java Development Kit (currently uses JDK 21) to run. Eclipse Termurin is a free, open-source JDK provided by the Eclipse Adoptium project. It is a build of OpenJDK that is widely used as an alternative to Oracle JDK. Depending on the Linux distribution, you may be able to install the JDK using the following command:

$ sudo apt install temurin-21-jdk
Enter fullscreen mode Exit fullscreen mode

If your distribution doesn't distribute a Temurin JDK, then you can download the version for your hardware architecture from Adoptium. Follow the installation instructions for archives.

Install GBD

Run the following command to install GDB (the GNU debugger) if you want to be able to use Ghidra's debugging features:

$ sudo apt install gdb
Enter fullscreen mode Exit fullscreen mode

You will need gdb compiled with Python version of at least 3.7. Verify the version of Python supported by GDB by running the following:

$ gdb
(gdb) python import sys
(gdb) python print(sys.version)
(gdb) quit
Enter fullscreen mode Exit fullscreen mode

Make sure the version is 3.7 or higher.

Install psutil and protobuf Python Modules

To use the GDB debugger in Ghidra, you need the psutil and protobuf Python modules to be installed:

$ sudo apt install python3-psutil python3-protobuf
Enter fullscreen mode Exit fullscreen mode

Install Ghidra

Download the appropriate zip file from the GitHub repo. Unzip it to a directory then find the "ghidraRun" script and run it.

Create a Sample C Program

You can skip this step if you already have a binary you want to decompile but when learning I think it is best to start with something where you already know the code being decompiled. This code comes from the leetcode solution for the simple two sum problem. Create a main.c file:

#include <stdlib.h>
#include <stdio.h>

int* twoSum(int* nums, int numsSize, int target, int* returnSize) 
{
    for (int i = 0; i < numsSize; i++) {
        for (int j = i + 1; j < numsSize; j++) {
            if (nums[j] == target - nums[i]) {
                int* result = malloc(sizeof(int) * 2);
                result[0] = i;
                result[1] = j;
                *returnSize = 2;
                return result;
            }
        }
    }

    *returnSize = 0;
    return malloc(sizeof(int) * 0);
}

int main() {
    int nums[5] = { 7, 3, 5, 10, 22 };
    int returnSize = 0;

    int* twoSumResult = twoSum(nums, sizeof(nums) / sizeof(nums[0]), 32, &returnSize);

    if (returnSize > 0){
        for (int i = 0; i < returnSize; ++i){
            printf("twoSumResult[%d]: %d\n", i, twoSumResult[i]);
        }
        free(twoSumResult);
    }
    else{
        printf("No result\n");
    }
}
Enter fullscreen mode Exit fullscreen mode

Compile an executable by running:

$ gcc -o main main.c
Enter fullscreen mode Exit fullscreen mode

Note you may have to install the gcc compiler if you haven't already done so.

Creating a Project in Ghidra

  • Go to "File" then "New Project" and select "Non-shared Project".
  • Select the directory and give the project a name (in our case TwoSum).
  • Drag and drop the main executable from a file explorer window to the newly created project pane.
  • A pop-up should appear. Have a look around at the options and languages then click "OK" and then "OK" again when the next popup appears.

Browsing the Code

  • Select "main" in the Active Project pane and drag it to the dragon button (i.e. Code browser) in the Tool Chest set of buttons.
  • Click "Yes" on the analyze popup then click "Analyze" on the next popup keeping all options set to the defaults.

Finding the TwoSum Function

  • Select "Search" then "Program Text" from the menu.
  • Select the "All Fields" button then click "Search All".
  • A popup should appear. Select "twoSum" and the listing window should auto navigate to the disassembly listing.
    Image description

  • Next select "Window" then "Decompiler" from the menu. A pane should appear with the decompiled code.
    Image description

You can see that the decompiled code differs from the original code we wrote. This is because Ghidra reverse engineers C code from the compiler generated instructions in the binary file.

Debugging the Code

  • Close the Code Browser window and return to the Ghidra project window.
  • Select "main" and drag it to the button with a bug on it (the debugger tool).
  • Click "Yes" to analyze then click "Analyze".
  • From the "Debugger" menu item click "Configure and Launch main using...".
  • Then select "gdb" then click "Launch" on the popup keeping the defaults selected.
  • The launch of GDB should be successful and you should see a message in the GDB pane:
Connected to Ghidra 11.2.1 at 127.0.0.1:36921
Enter fullscreen mode Exit fullscreen mode
  • Next click on "Window" then "Decompile: main" from the menu. You should see a pane that now shows the decompiled main code.

Setting a Breakpoint

  • In the decompiled code pane, right click on the line you want to break at and select "Toggle Breakpoint".
  • Leave the defaults as selected (specifically ensure "SW_EXECUTE" is selected) and click "OK".
  • Click on the the green arrow button on the main debugger window to start debugging.
  • You should see the debugger stop at the breakpoint.
  • You can then step using the arrow buttons on the debugger menu: Image description

Note you can see the values of various variables as you step by hovering over them.

Conclusion

This was a brief introduction to installing and using Ghidra. It has many more features to explore so take your time. Or you could join a capture the flag challenge and see how you go using it on unfamiliar code. There are also lots of YouTube videos showing how it can be used in capture the flag challenges too.

Top comments (0)