Rust-bindings for the ReOxide decompiler plugin framework
ReOxide adds a plugin system to the Ghidra decompiler, with the larger goal of eventually improving the reverse engineering process of Rust programs in open source tools. While anyone can extend the Ghidra front end through its Java and Python API, the decompiler runs as a separate C++ program. You cannot change the decompiler rules through the Java API, but you can with ReOxide. You can define your own decompiler actions or rules and better understand the inner workings of the decompiler.
Documentation
The ReOxide homepage offers a starting point for the general documentation of the project:
- Get started by
installing the
reoxidepip package and linking it with a Ghidra installation. - Follow the documentation on how to load plugins and how to create plugins yourself.
- For documentation related to the Rust API check out the docs.rs page of the ReOxide crate.
Examples
The reoxide Rust crate offers two different things:
- Allow driving the Ghidra decompiler from Rust.
- Allow writing plugins for the Ghidra decompiler using Rust.
Both require a working ReOxide setup, make sure you can run the
reoxide command in the environment where you run your Rust builds
from.
Driving the Ghidra decompiler from Rust
The decompile example shows how to use the decompiler driver. When
you write programs by using the decompiler driver, you have to
tell the program where to find the reoxide shared library,
libreoxide.so. The build.rs build step should automatically link
the library correctly if it can run the reoxide command, but
for running the example you might have to set the LD_LIBRARY_PATH
manually:
LD_LIBRARY_PATH=
Start off by importing the driver functions:
use *;
Currently the driver needs a full Ghidra installation for the processor definition files. You need to set the path to the root folder of the Ghidra installation, for example:
initialize_decompiler.unwrap;
You can also enable or disable the ReOxide plugin system with the last parameter. Afterwards you initialize a decompiler context with the raw bytes of the program and the architecture specification string from Ghidra:
let mut ctx = from_bytes.unwrap;
Decompilation works on the function level, so you first need to define a function at the address you want to decompile:
let addr = 0x0;
ctx.define_function.unwrap;
Finally, you can decompile the function at the address:
let decomp = ctx.decompile_function?;
println!;
Here you can see the full example source code:
use env;
use Path;
use *;
const PROGRAM: & = &;
Acknowledgements
Special thanks to rust-sfml and the foreign-types library for showing how to do certain FFI related things.