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.
Latest Changes
See change log for latest changes.
Configuration
Building a Sleigh instance requires a compiled sleigh specification (.sla) and a processor specification (.pspec). These can be obtained from the sleigh-config crate.
Processor specification files 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.
Custom Sleigh Specification
Custom sleigh specification files can be compiled from Rust using the
sleigh-compiler crate. Alternatively the original
compiler can be built from the
Ghidra decompiler source
using make sleigh_opt.
Example
Disassemble bytes into native assembly instructions.
let sleigh = builder
.processor_spec?
.build?;
// PUSH RBP instruction is the byte 0x55.
let instructions = new;
// InstructionBytes is a simple byte loader that does not model multiple address spaces.
// However an address space is required, so for simplicity use the default code space.
let address_space = sleigh.default_code_space;
// Start disassembly from the first byte (index 0)
let instruction_address = new;
// Confirming this is indeed PUSH RBP.
let native_disassembly = sleigh.disassemble_native?;
assert_eq!;
assert_eq!;
Disassemble bytes into pcode instructions. Pcode instructions can be used for program modeling.
let sleigh = builder
.processor_spec?
.build?;
// PUSH RBP
let instructions = new;
let instruction_address = new;
let pcode_disassembly = sleigh.disassemble_pcode?;
let pcode_instructions = pcode_disassembly.instructions;
assert_eq!;
// Copy RBP into a temporary
let copy_destination = pcode_instructions.output.as_ref.unwrap;
assert_eq!;
assert_eq!;
// Subtract 8 bytes from RSP
assert_eq!;
assert_eq!;
assert_eq!;
// Store temporary (RBP) into memory address pointed to by RSP
assert_eq!;
assert_eq!;
assert_eq!;