Exploit Development Toolchain
Without exploit development, binary exploitation doesn’t exist. The tools listed in this section were created to make analyzing binaries and exploiting them significantly easier. It is highly recommended that you pick one tool from each of the major categories below and learn it very well. These make developing your exploits a walk in the park - saving you a significant amount of time in the process.
My personal preferences for each category are: Binary Ninja and Ghidra for RE platforms, GDB for debuggers with Pwndbg as my preferred plugin (though I would recommend GEF as well), and lastly Pwntools for exploit development.
Reverse Engineering Platforms
Reverse engineering platforms are designed to aid the user in quickly analyzing binaries through the use of visual cues such as control flow graphs, enumerated functions, and the use of unnamed variables.

Binary Ninja is an interactive graph-based disassembler. It disassembles compiled binaries for a number of architectures and platforms and displays them in an easy-to-navigate view with features like automatic annotations, custom comments, and interactive renaming of symbols.
Third party plugins can use the same core API that Binary Ninja accesses from the GUI in their own command line scripts or interactively with the integrated python console. Binary Ninja is also architecture-agnostic.
All of the analysis occurs on its own intermediate language. This being exposed means that you can implement a new custom architecture and get the full power of Binary Ninja’s analysis or you can implement your own analysis technique and have it work on all of its supported architectures.
Binary Ninja is great at patching with a built-in compiler for replacing functions with C, easy right-click patching, and even inline assembling and editing.
All these great features aren’t free, however. With an introductory price of USD $399 for commercial use or USD $99 for students or non-commercial use, Binary Ninja is certainly not cheap.
Despite the price tag, the design and functionality won me over as I purchased the USD $99 student version roughly a year ago. I can confidently say it has helped me tremendously in learning both reverse engineering and binary exploitation. The features I use most are the Control Flow Graphs (obviously), the ability to add comments, switching between assembly and medium-level instructions, and lastly variable-renaming.

Ghidra is a free and open source reverse engineering tool developed by the National Security Agency. Ghidra’s capabilities include disassembly, assembly, decompilation, graphing and scripting, and hundreds of other features. It’s written in Java so it can be run on MacOS, Linux, and Windows. It does have a pretty awful GUI as a result, however.
Ghidra has 3 main selling points in my opinion:
Ghidra’s decompiler is a very strong competitor to IDA Pro’s Hex-Rays decompiler. It produces impressively accurate, in most circumstances, decompiled code. It’s also not $2000 like Hex-Rays which is an automatic win for anyone not using IDA professionally.
Ghidra supports a very wide variety of instruction sets and executable formats. In fact, more are getting added as community members make pull requests on Github.
Ghidra supports defining arbitrary data types. This means you can create, for instance, an arbitrary struct type and it will automagically fix the decompiled code to accurately reflect the information you put in.
For these reasons, Ghidra has become my go-to tool to quickly reverse engineer more challenging binaries.

radare2 is a complete framework for reverse-engineering and analyzing binaries; composed of a set of small utilities that can be used together or independently from the command line.
radare2 is capabale of disassembling a variety of different architectures, debugging with local native and remote debuggers (gdb, rap, webui, r2pipe, winedbg, windbg), and can run on Linux, BSD, Windows, OSX, Android, iOS, Solaris and Haiku.
Because r2 originally started as a forensics tool, it is also capable of performing filesystem forensics and data carving.
It also has bindings for Python, Javascript, Go and more!
Unfortunately, radare2 has a very steep learning curve, so it is not common for those who still want its functionality to use the GUI alternative, Cutter.

Cutter is arguably the best Binary Ninja competitor and for good reason. Cutter is built on top of the already wildly popular reverse engineering framework Radare2.
Cutter is free to use and open source (licensed under GPL 3.0), which means you can get roughly the same features as Binary Ninja in an aesthetically pleasing package for a significantly less monetary commitment.
While Cutter is based on r2, Cutter is not aimed at existing radare2 users. It instead focuses on those whose are not yet radare2 users because of the learning curve, because they don’t like CLI applications or because of the difficulty/instability of radare2. Fortunately for me, I fall into this category.
Whether you decide to fork over USD $99 for Binary Ninja or a github star for Cutter, you’re going to be getting an excellent product that will benefit you greatly in your reverse engineering and binary exploitation efforts.

Hopper is a Mac-focused disassembler, but the team behind Hopper also provides a QT 5 version for Linux.
If I were to compare it to the others, it feels like a mix between Binary Ninja and IDA Pro. Unfortunately, I have not had the chance to use it, but it certainly has some redeeming features:
With the Hopper SDK, you’ll be able to extend Hopper’s features, and even write your own file format and CPU support.
Hopper analyzes function’s prologues to extract procedural information such as basic blocks and local variables.
Once a procedure has been detected, Hopper displays a graphical representation of the control flow graph. You can even export a PDF.
Most of the Hopper features can be invoked from Python scripts, giving you the ability to transform a binary in any way you want.
Hopper can use LLDB or GDB, which lets you debug and analyze the binary in a dynamic way (Intel CPU only).
From what I’ve seen, Hoppers strongest feature is its ability to create pseudo-code of the binary.
All in all, if you’re a Mac user, I’d definitely recommend Hopper.
Debuggers
A debugger is a program that is used to test and debug other programs. These aid in dynamic analysis and greatly help you debug, develop, and test your exploits.
GDB, the GNU Project debugger, allows you to see what is going on “inside” another program while it executes - or what another program was doing at the moment it crashed. It is the standard for debugging ELF files as it is the most common debugger on Linux-based distributions.
Unfortunately, GDB is a pain to debug on and very frequently deters beginners from using it despite how valuable of a resource it is. Because of this, developers have turned to using GDB’s python bindings to enable a more feature-rich debugger. Below are a few of my recommendations for GDB plugins.
Pwndbg

Pwndbg is a GDB plugin that makes debugging with GDB easy, with a focus on features needed by low-level software developers, hardware hackers, reverse-engineers and exploit developers.
Their reason for making the plugin resonates with many in that “vanilla GDB is terrible to use for reverse engineering and exploit development, typing x/g30x $esp is not fun and does not confer much information, and GDB’s syntax is arcane and difficult to approach.”
One of Pwndbg’s strongest features is that is prints a useful summary of the current execution context every time GDB stops (e.g. breakpoint or single-step), displaying all registers, the stack, call frames, disassembly, and additionally recursively dereferencing all pointers. All memory addresses are color-coded to the type of memory they represent.

The second feature I find most useful from Pwndbg is its ability to decipher arguments on function calls. All function call sites are annotated with the arguments to those functions. This works best with debugging symbols, but also works in the most common case where an imported function (e.g. libc function via GOT or PLT) is used.
Pwndbg has many more great features such as introspection to fold jumps and only display the instructions that will be executed, heap inspection, IDA Pro integration, QEMU compatibility, process state inspection, a rop gadget finder using ROPGadget, and a telescope feature that recursively dereferences a range of memory (useful for looking at strings).
I personally use Pwndbg and highly recommend it, but there are certainly other good GDB plugins to choose from.
GEF

GEF or GDB Enhanced Features was specifically created for exploit developers and reverse engineers. If there was going to be any competition for Pwndbg, this would be it. GEF was designed with ease of use in mind as it is contained in a single GDB script.
GEF’s features include:
Entirely OS agnostic and has zero dependencies (unlike Pwndbg)
It provides more than 50 commands to drastically change your experience in GDB
Easily extendable to create other commands by providing more comprehensible layout to GDB Python API
It works consistently on both Python2 and Python3
It is built around an architecture abstraction layer, so all commands work in any GDB-supported architecture such as x86-32/x86-64, ARMv5/6/7, AARCH64, SPARC, MIPS, PowerPC, etc. (unlike PEDA)
GEF hails no dependencies, however they recommend you installing the capstone, keystone, unicorn, and Ropper python modules to “enjoy all the coolest features from some commands” as well as a gef-extras repo.
I’d say it’s largely personal preference, but both Pwndbg and GEF are good choices.
PEDA

PEDA (Python Exploit Development Assistance) is an extension for GDB to help the exploitation process on Linux and Unix systems. It can also be used as a framework for writing custom Python GDB commands.
PEDA is very similar to both GEF and Pwndbg in that it achieves similar goals for expanding the core functionality of GDB. It has a wealth of features described on their github page.
A few notable features include:
aslr- Show/set ASLR setting of GDBdumprop- Dump all ROP gadgets in specific memory rangelookup- Search for all addresses/references to addresses which belong to a memory rangepatch- Patch memory start at an address with string/hexstring/intpattern- Generate, search, or write a cyclic pattern to memoryshellcode- Generate or download common shellcodesskeleton- Generate python exploit code template
Overall, I would recommend Pwndbg or GEF over PEDA because PEDA is signifcantly less active/maintained compared to its competitors, but if you had to use PEDA or barebones GDB it would be a no-brainer to use PEDA.
Exploit Development Frameworks
Exploit development frameworks aid in writing exploits by not forcing you to reinvent the wheel. Why write all of your code by hand when you can use someone else’s boilerplate python code?
Pwntools is a CTF framework and exploit development library. Written in Python, it is designed for rapid prototyping and development, and intended to make exploit writing as simple as possible.
Pwntools is by far my favorite exploit development framework. They have a wealth of documentation at docs.pwntools.com which is an excellent reference when you want to dive into all that the library has to offer.
Pwntools enables users to effortlessly exploit remote binaries using a breathtakingly simple API. The following is an example for exploiting a very basic buffer overflow.
First, we import the pwntools library with from pwn import *. While this is bad python practice, it doesn’t really affect us on one-off python scripts.
Next we connect to our remote target binary with r = remote("ctf.hackucf.org", 9000). It should be easy to guess that this connects to the domain ctf.hackucf.org on port 9000.
After we connect to the target, we would craft our exploit. For a simple buffer overflow, specifying a large amount of input will suffice.
Lastly, we send the payload with r.sendline(payload) and transfer ourselves to an interactive session with r.interactive. This reveals the flag of flag{my_first_buffer_overflow!}.
Don’t let this simple example fool you, Pwntools is capable of doing so much more! From ADB to crafting format string exploits to generating shellcode Pwntools has it all.
angr is a platform-agnostic binary analysis framework developed by the Computer Security Lab at UC Santa Barbara and their associated CTF team, Shellphish.
Angr’s features include:
Disassembly and intermediate-representation lifting
Program instrumentation
Symbolic execution
Control-flow analysis
Data-dependency analysis
Value-set analysis (VSA)
You can find some examples on how to use angr here.
Command-Line Tools
This is a quick blurb on some commonly used command-line tools.

Strings prints the strings of printable characters in files. This is very useful in basic reverse engineering challenges (find the flag) and occasionally binary exploitation.
In the screenshot above, you should be able to discern the string “Hello, world!”. In fact, on top of the hard-coded strings present in the binary, strings will grab any printable symbols it finds. You can see this by noticing the string puts (which used to be our printf call before it was optimized) as well as the function that calls main, __libc_start_main among other random strings.
objdump is a program for displaying various information about object files on Unix-like systems. It is part of GNU Binutils which means that it is available on many Linux distributions.
We will be using a “Hello, world!” program in C to demonstrate objdump’s capabilities:
When running the following command (on an x86-64 architecture), you should get similar output:
Note: Here we just would like to see the contents of the function called
main, so we usedgrepand provided the flag-A8 main.:which translates to: output 8 lines after you find the term ‘main.:‘. Without piping the results to grep, you would have to search through the entire binary.
The flags we provided to objdump were:
--disassemble: which, as the name implies, will disassemble the binary.--disassembler-options=att: which tellsobjdumpto ouput the assembly in AT&T notation. You could change it tointelif you want.
Getting to know more about objdump will most definitely help you while reversing any small binaries (like in a CTF). The manual for objdump is a great resource for looking up its arguments and can be found with the command man objdump.
File is a simple command that determines a file’s type. In terms of binary exploitation, using the file command on a binary yields a lot of useful information.
For example, running file hello on our hello world example yields the following (on a 64-bit system):
This might seem like a lot at first, but let’s dissect the important bits.
hellois the name of the file.ELFis the type of file it is. It is an ELF (Executable and Linkable Format) binary file.64-bitis the architecture of the binary.dynamically linkedmeans that when the binary is executed it will dynamically load the required libraries (from the system) into memory. You can check these with the commandldd. If the file were to saystatically linked, it would contain all of the code necessary for it to run and not depend on any external libraries.not strippedmeans that the symbols (variables and functions) are still present. The can be removed with thestripcommand which make reverse engineering binaries slightly more difficult.
As you can see, a simple command reveals a lot of information about your target binary. It is always worth running when facing a new challenge.
Readelf displays information about ELF files. It can be used to:
Analyze if a binary’s stack is executable (compiled with
-z execstack). If it was, the flag on the second line would beRWE.
Displays the contents of the file’s relocation section, if it has one. This is useful for listing PLT functions.
Last updated