Closed mnemonikr closed 11 months ago
https://cxx.rs/binding/box.html has an example where a Rust Box
is passed to C++ and then back to Rust via a callback. Unfortunately the API for Ghidra is not so simple, as the memory object we would like to pass from Rust through C++ and back to Rust is not readily exposed anywhere in C++.
An alternative model would be to pass the "callback" directly to the C++ disassembly function via our C++ proxy and then update the stored callback pointer in C++ before performing the disassembly. The danger here is now the C++ callback pointer could fail to be updated in the event of an exception. So we would want to wrap it in some RAII object that managed the pointer...
The C++ callback implementation creates a lot of complexities for building a safe FFI layer. Ultimately we want to be able to extract pcode from memory like the following:
We don't want to require the
sleigh
object to hold a reference tomemory
as this would complicate the process of updating memory. Yet obviously it will need access to memory to decode the next instruction. However, we can't pass a buffer built from the memory object tosleigh
because we don't know ahead of time how much memory will be required to decode the instruction (thanks variable length ISAs). So unfortunately, it needs full access to the available memory.This is where things get a bit complicated. So behind the scenes, the C++
Sleigh
object has a callback object calledLoadImage
. When the pcode disassembly is requested, it calls this callback to load data from memory.Sleigh
object. This is theWeakLoader
: https://github.com/mnemonikr/pcode/blob/9694e9ba6563ce5cc328aa2d97d406a28db0516a/sla/src/sleigh.rs#L226WeakLoader
is stored in aBox
whose reference is leaked for constructing theRustLoadImage
object.RustLoadImage
object is itself stored in aBox
whose reference is leaked for constructing the C++Sleigh
object.Box
usingBox::from_raw
and stored in the RustSleigh
object so that when it is dropped, these will also be dropped.https://github.com/mnemonikr/pcode/blob/9694e9ba6563ce5cc328aa2d97d406a28db0516a/sla/src/sleigh.rs#L274-L284
However, as a result the following is simultaneously true:
&WeakLoader
reference that is held byRustLoadImage
Box<WeakLoader>
held by the RustSleigh
object.This is a problem because the
WeakLoader
is modified while the (immutable) reference is held byRustLoadImage
.