# GEF: a single-file GDB extension for exploit developers and reverse engineers

> GEF adds architecture-agnostic debugging commands to stock GDB through the Python API. It installs in one command, but it assumes GDB 10.0 or higher with Python 3.10+ bindings, and that constraint decides most of the adoption questions.

**hugsy/gef** — GEF (GDB Enhanced Features) - a modern experience for GDB with advanced debugging capabilities for exploit devs & reverse engineers on Linux

- Repository: https://github.com/hugsy/gef
- Website: https://hugsy.github.io/gef
- Stars: 8,381 · Forks: 833
- Language: Python
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/hugsy-gef

## What GEF adds to a plain GDB session

Stock GDB prints registers, disassembly and memory one command at a time. GEF is a set of commands layered on top, written against the GDB Python API, aimed at exploit developers and reverse engineers working on Linux. The README describes it as assisting "during the process of dynamic analysis and exploit development" and notes that application developers benefit too, because it hides part of GDB's command surface and surfaces runtime information that would otherwise take several commands to assemble. Architectures covered are x86/64, ARM, MIPS, PowerPC and SPARC, with the README stating that commands work in any GDB-supported architecture through an architecture abstraction layer. The project also lists CTF work alongside real-life application debugging as a target use, so it is not positioned as a CTF-only tool. If you are choosing between GEF and pwndbg, the practical difference is packaging: GEF ships as one GDB script with no dependencies, while pwndbg is a larger plugin with its own install path. Both extend the same debugger, so the choice is about what you want loaded into GDB, not about which debugger you use.

## One file, one source line, and an architecture abstraction layer

The mechanism is deliberately small. The repository's top level contains gef.py, and the README calls GEF "One single GDB script". Installation means GDB sources that Python file at startup. Inside, commands are built around an architecture abstraction layer so that a command written once behaves the same whether the target is AARCH64, MIPS or x86-64. That layer is the reason the README can claim architecture agnosticism without shipping per-architecture command sets. The trade-off is that anything the abstraction layer does not model has to be handled per architecture anyway, and the README does not enumerate those gaps. Extension happens through the same Python API: the project documents an API page for writing additional commands, and community commands live in a separate repository, GEF-Extras, rather than in the core file. Keeping extras out of gef.py is what keeps the single-file install credible. Python 2 support was dropped in the 2020.03 release, and the README points to a separate gef-legacy repository for anyone still on that path.

## Installing GEF and running a first command

The prerequisite is stated plainly: GDB 10.0 or higher, compiled with Python 3.10+ bindings. The README gives an install script over curl or wget, and a manual route that downloads the Python file and appends a source line to ~/.gdbinit. The script form is the shortest path.

```bash
bash -c "$(curl -fsSL https://gef.blah.cat/sh)"
```

If you prefer not to pipe a remote script into a shell, the manual route writes the same file and edits your GDB startup file. Note that the echo appends to ~/.gdbinit, so an existing configuration in that file is preserved but grows by one line.

```bash
wget -O ~/.gdbinit-gef.py -q https://gef.blah.cat/py
echo source ~/.gdbinit-gef.py >> ~/.gdbinit
```

The README also documents loading GEF from inside a running GDB session, which is useful when you cannot write to the home directory. It downloads the file to a temporary location and sources it in one command.

```bash
gdb -q
(gdb) pi import urllib.request as u, tempfile as t; g=t.NamedTemporaryFile(suffix='-gef.py'); open(g.name, 'wb+').write(u.urlopen('https://tinyurl.com/gef-main').read()); gdb.execute('source %s' % g.name)
```

After that, launching GDB should show the GEF context display instead of the bare prompt. The README points to a screenshot of that view and to an online demo with the credentials user gef and password gef-demo if you want to see the output before installing anything locally.

## Where GEF is the wrong tool

The GDB version floor is the first real constraint. GDB 10.0 with Python 3.10+ bindings is not what ships on older distributions, and a GDB built without Python bindings cannot load GEF at all, since the whole project is a Python script sourced by GDB. If you are debugging a vendor toolchain that pins an older GDB, or working on a system where you cannot rebuild GDB, GEF is not the right layer to add. The second limitation is scope: GEF extends GDB, so it inherits every GDB limitation for the target, including whatever the debugger cannot attach to. The README does not document rollback or an uninstall procedure, so removing GEF means undoing the source line in ~/.gdbinit and deleting the downloaded file yourself. The documentation does maintain an FAQ page for installation problems, and the README directs users there before the Discord channel or the issue tracker, which suggests installation friction is a known and recurring category rather than an edge case.

## GEF against pwndbg, and where GEF-Extras fits

The most common comparison is with pwndbg, and the difference is in how much gets loaded into the debugger. GEF is one file sourced by GDB, with no dependency list in the README and an explicit claim of being dependency-free. pwndbg is a separate plugin with its own installation and its own command set. If you want to audit exactly what runs inside your debugger, a single Python file you can read end to end is easier to review than a plugin tree, and it is easier to pin to a specific download. If you want a broader built-in command surface without adding anything, pwndbg's approach may fit better. GEF's answer to extra functionality is GEF-Extras, a separate repository of community commands, which keeps the core file small but means the feature you want may live outside the thing you installed. That split is a design decision with a cost: you have two places to check when a command is missing.

## Maintenance, releases and the MIT licence

The last push to the main branch was on 2026-08-20, roughly a month before this writing, so the repository is not stale. Releases are not frequent: 2026.01 in February 2026, 2025.01 in January 2025, and 2024.06 in June 2024. Between releases, fixes land on main, so if you install from the script you are tracking the branch rather than a tagged version. For a debugging tool that is usually acceptable, but it means an upgrade can change behaviour without a version number to point at. GEF is MIT licensed, which permits commercial and closed-source use and modification, but the README does not state a support commitment, so the licence tells you what you may do with the code, not what you can expect from maintainers. If you need a fixed artifact, download the Python file once and keep your own copy instead of re-running the install script. Sponsorship is mentioned in the README as a way to support the project; it does not change the licence terms.

## Conclusion

Adopt GEF if you debug on Linux and want richer GDB output without a dependency tree; skip it if your toolchain is pinned to an older GDB or a GDB built without Python 3.10+ bindings. Before installing, run gdb --version and confirm the version and Python bindings, and if you already have a .gdbinit, read it first because the install script appends a source line to that file.

## FAQ

### How do I install GEF?

The README gives an install script that can be run with curl or wget, and a manual route that downloads the Python file to ~/.gdbinit-gef.py and appends a source line to ~/.gdbinit. GEF can also be loaded from inside a running GDB session with a single pi command. GDB 10.0 or higher with Python 3.10+ bindings is required either way.

### What are the requirements for running GEF?

The README states that GDB 10.0 or higher must be compiled with Python 3.10+ bindings. GEF itself is a single Python script with no other dependencies listed.

### Which architectures does GEF support?

The README lists x86/64, ARM, MIPS, PowerPC and SPARC, and states that commands work across any GDB-supported architecture through an architecture abstraction layer.

### How do I uninstall GEF?

The README does not document an uninstall procedure. Installation adds a source line to ~/.gdbinit and downloads a Python file, so removing GEF means undoing those two steps yourself.

### What is the difference between GEF and pwndbg?

GEF is distributed as one GDB script with no dependencies, while pwndbg is a separate plugin with its own installation and command set. Both extend GDB, so the choice is about what gets loaded into the debugger rather than which debugger you run.

## Sources

- [hugsy/gef on GitHub](https://github.com/hugsy/gef)
- [License: MIT](https://github.com/hugsy/gef/blob/main/LICENSE)
- [Project website](https://hugsy.github.io/gef)
- [README](https://github.com/hugsy/gef/blob/main/README.md)
- [Releases](https://github.com/hugsy/gef/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/hugsy-gef
