Skip to content

Quokka: A Fast and Accurate Binary Exporter

Introduction

Quokka is a binary exporter: from the disassembly of a program, it generates an export file that can be used without the disassembler. It currently supports IDA Pro and Ghidra as disassembly backends.

The main objective of Quokka is to enable to completely manipulate the binary without ever opening a disassembler after the initial export. Moreover, it abstracts the disassembler's API to expose a clean interface to the users.

Quokka is heavily inspired by BinExport, the binary exporter used by BinDiff.

Architecture

     IDA Pro                Ghidra
        |                      |
IDA Plugin (C++)    Ghidra Plugin (Java)
        |                      |
        +--- quokka.proto -----+
          (protobuf schema)
                   |
             .quokka files
                   |
   Python bindings (quokka.Program)
   +-- Capstone backend (primary)
   +-- Pypcode backend (optional)

Installation

Python library

$ pip install quokka-project

Disassembler plugins

The IDA and Ghidra plugins are only needed to generate .quokka files. Reading them requires only the Python library above.

  • IDA Plugin -- pre-built libraries available in Releases. Get the file named quokka_plugin**.so.
  • Ghidra Extension -- see the Ghidra extension README for build and install instructions.

For more details see Installation.

Quick Start

Loading an export file

Program.from_binary() invokes a disassembler to export and load the binary in one step. It requires the appropriate environment variable to locate the disassembler:

  • IDA: set IDA_PATH to the IDA installation directory
  • Ghidra: set GHIDRA_INSTALL_DIR to the Ghidra installation directory
import quokka
from quokka.types import Disassembler

# Directly from the binary (auto-detects available backend)
prog = quokka.Program.from_binary("/bin/ls")

# Explicitly choose a backend
prog = quokka.Program.from_binary("/bin/ls", disassembler=Disassembler.GHIDRA)
prog = quokka.Program.from_binary("/bin/ls", disassembler=Disassembler.IDA)

# From an already-exported file
prog = quokka.Program("ls.quokka",  # the exported file
                      "/bin/ls")    # the original binary

Exploring the binary

# Functions
func = prog.get_function("main")
print(func.name, hex(func.start), len(func), "blocks")

# Basic blocks and instructions
for block in func.values():
    for addr, inst in block.items():
        print(f"  0x{addr:x}: {inst.mnemonic}")

# Cross-references
for callee in func.callees:
    print(f"  calls {callee.name}")

# Strings
for s in func.strings:
    print(repr(s))

Editing and adding types

# Add new types from C declarations
prog.add_type("struct context { int id; char name[64]; };")
prog.add_type("enum status { OK=0, ERROR=1 };")

# Save the .quokka file
prog.write()

# Or apply changes (including new types) back to the IDA database
prog.commit(database_file="ls.i64", overwrite=True)

See the full editing documentation for details on renaming functions, setting prototypes, and more.

Building

See the Installation page for full build instructions for both the IDA plugin and Ghidra extension.