3 unstable releases
new 0.2.0 | Jan 21, 2025 |
---|---|
0.1.3 | Jan 20, 2025 |
0.1.0 | Jan 16, 2025 |
#245 in Debugging
104 downloads per month
4.5MB
105K
SLoC
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.
// Construct new sleigh instance
let mut sleigh = GhidraSleigh::new();
// 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");
// Initialize sleigh. Required before decoding can be performed.
sleigh.initialize(&slaspec, &pspec).expect("failed to initialize sleigh");
// 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");