Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## Unreleased

Nothing here yet
### Fixed

* `AddressSpace` from another Sleigh instance is now properly recognized.

## [v1.0.0](https://github.com/mnemonikr/libsla/tree/v1.0.0)

Expand Down
28 changes: 12 additions & 16 deletions src/sleigh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,25 +640,21 @@ impl GhidraSleigh {
/// Convert an address to a system address. Returns `None` if the provided address space cannot
/// be mapped to a system address space.
fn sys_address(&self, address: &Address) -> Option<UniquePtr<sys::Address>> {
let sys_addr_space = self.sys_address_space(&address.address_space)?;

// SAFETY: The provided address space has been verified to be safe
Some(unsafe {
sys::new_address(
self.sys_address_space(address.address_space.id)?,
address.offset,
)
})
Some(unsafe { sys::new_address(sys_addr_space, address.offset) })
}

/// Creates address space using the given address space id. Returns `None` if the provided id
/// cannot be mapped to a system address space.
fn sys_address_space(&self, space_id: AddressSpaceId) -> Option<*mut sys::AddrSpace> {
let num_spaces = self.sleigh.num_spaces();
for i in 0..num_spaces {
let addr_space = self.sleigh.address_space(i);
/// Converts an address space to a system address space. Returns `None` if the provided address
/// space cannot be mapped to a system address space.
fn sys_address_space(&self, address_space: &AddressSpace) -> Option<*mut sys::AddrSpace> {
for i in 0..self.sleigh.num_spaces() {
let sys_addr_space = self.sleigh.address_space(i);

// SAFETY: The address space returned here is safe to dereference
if AddressSpaceId::from(unsafe { &*addr_space }) == space_id {
return Some(addr_space);
// SAFETY: The address space is safe to dereference
if unsafe { (&*sys_addr_space).name() } == address_space.name.as_ref() {
return Some(sys_addr_space);
}
}

Expand All @@ -685,7 +681,7 @@ impl Sleigh for GhidraSleigh {
/// Get the register name for a varnode targeting a register. This will return `None` if the
/// target is not a valid register.
fn register_name(&self, target: &VarnodeData) -> Option<String> {
let base = self.sys_address_space(target.address.address_space.id)?;
let base = self.sys_address_space(&target.address.address_space)?;

// If offset + size overflows then Ghidra can accidentally match a register
//
Expand Down
18 changes: 18 additions & 0 deletions src/tests/sleigh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,24 @@ fn all_register_names() -> Result<()> {
Ok(())
}

#[test]
fn multiple_sleigh_data_sharing() -> Result<()> {
let sleigh1 = GhidraSleigh::builder()
.processor_spec(PROCESSOR_SPEC)?
.build(SLEIGH_SPEC)?;
let sleigh2 = GhidraSleigh::builder()
.processor_spec(PROCESSOR_SPEC)?
.build(SLEIGH_SPEC)?;
for (reg, name) in &sleigh1.register_name_map() {
// Sanity check to ensure sleigh1 correctly identifies this as a register
assert_eq!(name, &sleigh1.register_name(reg).unwrap());

// Even though the reg varnode is from sleigh1, it should still be recognized by sleigh2
assert_eq!(name, &sleigh2.register_name(reg).unwrap());
}
Ok(())
}

fn verify_sleigh(sleigh: GhidraSleigh) {
// 0x55 = PUSH RBP
let loader = LoadImageImpl(vec![0x55]);
Expand Down