summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorBrandon Miller <brandon@vector35.com>2025-09-16 09:21:46 -0400
committerBrandon Miller <brandon@vector35.com>2025-09-29 07:07:41 -0400
commit63e37dfb1185552135e397a786e92cd8669880a8 (patch)
tree0b7e8a0859ba26d0c57f47d95e40ef7a17f0cf4a /rust
parent87975c6620347671352c65b7fa518635180809c6 (diff)
Rust binding for LLVM MC disassembler
Diffstat (limited to 'rust')
-rw-r--r--rust/src/llvm.rs30
1 files changed, 21 insertions, 9 deletions
diff --git a/rust/src/llvm.rs b/rust/src/llvm.rs
index f74d00e3..1296db65 100644
--- a/rust/src/llvm.rs
+++ b/rust/src/llvm.rs
@@ -1,21 +1,33 @@
use binaryninjacore_sys::BNLlvmServicesDisasmInstruction;
-use std::ffi::CStr;
+use std::ffi::{CStr, CString};
+use std::os::raw::{c_char, c_int};
pub fn disas_instruction(triplet: &str, data: &[u8], address64: u64) -> Option<(usize, String)> {
unsafe {
- let mut buf = vec![0; 256];
+ let triplet = CString::new(triplet).ok()?;
+ let mut src = data.to_vec();
+ let mut buf = vec![0u8; 256];
let instr_len = BNLlvmServicesDisasmInstruction(
- triplet.as_ptr() as *const i8,
- data.as_ptr() as *mut u8,
- data.len() as i32,
+ triplet.as_ptr(),
+ src.as_mut_ptr(),
+ src.len() as c_int,
address64,
- buf.as_mut_ptr() as *mut i8,
+ buf.as_mut_ptr() as *mut c_char,
buf.len(),
);
+
if instr_len > 0 {
- let cstr = CStr::from_ptr(buf.as_ptr() as *const i8);
- let string = cstr.to_str().unwrap().to_string();
- Some((instr_len as usize, string))
+ // Convert buf (u8) → &CStr by finding the first NUL
+ if let Some(z) = buf.iter().position(|&b| b == 0) {
+ let s = CStr::from_bytes_with_nul(&buf[..=z])
+ .unwrap()
+ .to_string_lossy()
+ .into_owned();
+ Some((instr_len as usize, s))
+ } else {
+ // Callee didn't NULL terminate, return an empty string
+ Some((instr_len as usize, String::new()))
+ }
} else {
None
}