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
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ members = [
"arch/msp430",
"rust/plugin_examples/data_renderer",
"rust/plugin_examples/flowgraph_layout",
"rust/plugin_examples/primask_write_hook",
"view/minidump",
"plugins/dwarf/dwarf_import",
"plugins/dwarf/dwarf_export",
Expand Down
2 changes: 1 addition & 1 deletion arch/msp430/src/architecture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl Architecture for Msp430 {
self.max_instr_len()
}

fn associated_arch_by_addr(&self, _addr: u64) -> CoreArchitecture {
fn associated_arch_by_addr(&self, _addr: &mut u64) -> CoreArchitecture {
self.handle
}

Expand Down
2 changes: 1 addition & 1 deletion arch/riscv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ impl<D: RiscVDisassembler> Architecture for RiscVArch<D> {
self.max_instr_len()
}

fn associated_arch_by_addr(&self, _addr: u64) -> CoreArchitecture {
fn associated_arch_by_addr(&self, _addr: &mut u64) -> CoreArchitecture {
self.handle
}

Expand Down
13 changes: 13 additions & 0 deletions rust/plugin_examples/primask_write_hook/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "example_primask_write_hook"
version = "0.1.0"
edition = "2021"
license = "Apache-2.0"
publish = false

[lib]
crate-type = ["cdylib"]

[dependencies]
binaryninjacore-sys = { path = "../../binaryninjacore-sys" }
binaryninja = { path = "../.." }
13 changes: 13 additions & 0 deletions rust/plugin_examples/primask_write_hook/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# PRIMASK Write Hook Example

This example registers a Rust architecture hook on `thumb2` that appends ` ; Toggling interrupts` to the disassembly
of `msr primask` instructions.

## Building

```sh
# Build from the root directory (binaryninja-api)
cargo build -p example_primask_write_hook
# Link binary on macOS
ln -sf "$PWD/target/debug/libexample_primask_write_hook.dylib" ~/Library/Application\ Support/Binary\ Ninja/plugins/
```
25 changes: 25 additions & 0 deletions rust/plugin_examples/primask_write_hook/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
fn main() {
let link_path = std::env::var_os("DEP_BINARYNINJACORE_PATH")
.expect("DEP_BINARYNINJACORE_PATH not specified");

println!("cargo::rustc-link-lib=dylib=binaryninjacore");
println!("cargo::rustc-link-search={}", link_path.to_str().unwrap());

#[cfg(target_os = "linux")]
{
println!(
"cargo::rustc-link-arg=-Wl,-rpath,{0},-L{0}",
link_path.to_string_lossy()
);
}

#[cfg(target_os = "macos")]
{
let crate_name = std::env::var("CARGO_PKG_NAME").expect("CARGO_PKG_NAME not set");
let lib_name = crate_name.replace('-', "_");
println!(
"cargo::rustc-link-arg=-Wl,-install_name,@rpath/lib{}.dylib",
lib_name
);
}
}
58 changes: 58 additions & 0 deletions rust/plugin_examples/primask_write_hook/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//! Rust architecture hook plugin that annotates ARM/thumb writes to PRIMASK
use binaryninja::architecture::{
register_architecture_hook, Architecture, ArchitectureHook, CoreArchitecture,
};
use binaryninja::disassembly::{InstructionTextToken, InstructionTextTokenKind};
use binaryninja::logger::{bn_log, BnLogLevel};
use std::ffi::c_void;
use std::ptr::NonNull;

struct InterruptHook;

impl ArchitectureHook for InterruptHook {
fn instruction_text_with_context(
&self,
base: &CoreArchitecture,
data: &[u8],
addr: u64,
_context: Option<NonNull<c_void>>,
) -> Option<(usize, Vec<InstructionTextToken>)> {
let (length, mut tokens) = base.instruction_text(data, addr)?;
if tokens.first().is_some_and(|token| token.text == "msr")
&& tokens.get(2).is_some_and(|token| token.text == "primask")
{
tokens.push(InstructionTextToken::new(
" ; Toggling interrupts",
InstructionTextTokenKind::Annotation,
));
}
Some((length, tokens))
}
}

#[allow(non_snake_case)]
#[unsafe(no_mangle)]
pub extern "C" fn CorePluginDependencies() {
binaryninja::add_required_plugin_dependency("arch_armv7");
}

#[allow(non_snake_case)]
#[unsafe(no_mangle)]
pub extern "C" fn CorePluginInit() -> bool {
Comment thread
zznop marked this conversation as resolved.
let Some(thumb2) = CoreArchitecture::by_name("thumb2") else {
bn_log(
"interrupts_arch_hook",
BnLogLevel::ErrorLog,
"thumb2 architecture unavailable",
);
return false;
};
register_architecture_hook(thumb2, InterruptHook);
bn_log(
"interrupts_arch_hook",
BnLogLevel::InfoLog,
"Registered Rust interrupt annotation hook on thumb2",
);
true
}
Loading
Loading