3 unstable releases

0.2.0 Jan 21, 2025
0.1.3 Jan 20, 2025
0.1.0 Jan 16, 2025

#250 in Debugging

Download history 147/week @ 2025-01-14 157/week @ 2025-01-21

304 downloads per month

Apache-2.0

4.5MB
105K SLoC

C++ 100K SLoC // 0.2% comments Happy 3.5K SLoC Rust 1.5K SLoC // 0.0% comments Lex 607 SLoC // 0.0% comments

Overview

This crate provides Rust bindings to the Sleigh library libsla found in NSA's Ghidra, which disassembles processor instructions into p-code. This enables binary analysis programs to analyze arbitrary programs by targeting p-code instead of specific instruction set architectures.

Requirements

A Sleigh instance requires a compiled sleigh specification (.sla) and a processor specification (.pspec).

Sleigh Specification (.sla)

The relevant .slaspec file must be compiled using the Sleigh compiler to generate the appropriate .sla file for the target architecture. Existing .slaspec files can be found in the Ghidra processors repository.

Sleigh Compiler

The sleigh compiler must be built from the Ghidra decompiler source using make sleigh_opt.

Processor Specification (.pspec)

Processor specification files can be found in Ghidra processors repository. These are responsible for filling in context data defined in sla files. For example, addrsize is variable context defined in the x86 sla file. The x86-64 pspec defines this as 2 for 64-bit addressing while the x86 pspec defines this as 1 for 32-bit addressing. Note the sla file is responsible for interpreting the meaning of these values.

Example

This gives an overview of the general structure for disassembling code into p-code. For a working example using x86-64 see the sleigh unit tests.

// Compiled from x86-64.slaspec in Ghidra repository
let slaspec = std::fs::read_to_string("x86-64.sla");

// Located in Ghidra repository. No compilation necessary.
let pspec = std::fs::read_to_string("x86-64.pspec");

// Construct new sleigh instance
let sleigh = GhidraSleigh::builder()
    .sleigh_spec(&slaspec)?
    .processor_spec(&pspec)?
    .build()?;

// The instruction reader is defined by the user and implements the LoadImage trait.
let instruction_reader = InstructionReader::new();

// Instruction to decode from the reader.
let instruction_offset = 0x800000;
let address_space = sleigh.default_code_space();
let instruction_address = Address::new(instruction_offset, address_space);

// Disassemble!
let pcode_disassembly = sleigh.disassemble_pcode(&instruction_reader, instruction_address).expect("disassembly failed");

Dependencies