summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorKyleMiles <krm504@nyu.edu>2023-09-20 14:40:22 -0400
committerKyleMiles <krm504@nyu.edu>2023-09-20 15:06:35 -0400
commit052a8d2adb0c7899ae875c03da4edf80b2fa1a81 (patch)
tree51fef92c717c7cc3af22446e97aed1bb1fd0bedb /rust
parentaf2e0455c082239b21bceffbaa1684f795cb1452 (diff)
Rust API : FFI Fix, was leaking some non-null-terminated strings to the core..fix passing a nullptr to `load`
Diffstat (limited to 'rust')
-rw-r--r--rust/examples/dwarf/shared/src/lib.rs4
-rw-r--r--rust/src/architecture.rs52
-rw-r--r--rust/src/downloadprovider.rs2
-rw-r--r--rust/src/headless.rs7
-rw-r--r--rust/src/interaction.rs79
-rw-r--r--rust/src/lib.rs7
-rw-r--r--rust/src/metadata.rs4
7 files changed, 81 insertions, 74 deletions
diff --git a/rust/examples/dwarf/shared/src/lib.rs b/rust/examples/dwarf/shared/src/lib.rs
index 0bf11771..29ca02a4 100644
--- a/rust/examples/dwarf/shared/src/lib.rs
+++ b/rust/examples/dwarf/shared/src/lib.rs
@@ -95,7 +95,6 @@ pub fn create_section_reader<'a, Endian: 'a + Endianity>(
let data = view.read_vec(data_var.address, data_type.width() as usize);
let element_type = data_type.element_type().unwrap().contents;
- // TODO : broke af?
if let Some(current_section_header) = data
.chunks(element_type.width() as usize)
.find(|section_header| {
@@ -104,11 +103,10 @@ pub fn create_section_reader<'a, Endian: 'a + Endianity>(
{
if (endian.read_u64(&current_section_header[8..16]) & 2048) != 0 {
// Get section, trim header, decompress, return
- let offset = section.start() + 24; // TODO : Super broke AF
+ let offset = section.start() + 24;
let len = section.len() - 24;
if let Ok(buffer) = view.read_buffer(offset, len) {
- // Incredibly broke as fuck
use std::ptr;
let transform_name =
CString::new("Zlib").unwrap().into_bytes_with_nul();
diff --git a/rust/src/architecture.rs b/rust/src/architecture.rs
index 348e8e06..1bf22423 100644
--- a/rust/src/architecture.rs
+++ b/rust/src/architecture.rs
@@ -18,26 +18,27 @@
// RegisterInfo purge
use binaryninjacore_sys::*;
-use std::borrow::{Borrow, Cow};
-use std::collections::HashMap;
-use std::ffi::{CStr, CString};
-use std::hash::Hash;
-use std::mem::zeroed;
-use std::ops;
-use std::ops::Drop;
-use std::ptr;
-use std::slice;
+use std::{
+ borrow::{Borrow, Cow},
+ collections::HashMap,
+ ffi::CStr,
+ hash::Hash,
+ mem::zeroed,
+ ops, ptr, slice,
+};
-use crate::callingconvention::CallingConvention;
-use crate::disassembly::InstructionTextToken;
-use crate::platform::Platform;
-use crate::{BranchType, Endianness};
-
-use crate::llil::{get_default_flag_cond_llil, get_default_flag_write_llil};
-use crate::llil::{FlagWriteOp, LiftedExpr, Lifter};
-
-use crate::rc::*;
-use crate::string::*;
+use crate::{
+ callingconvention::CallingConvention,
+ disassembly::InstructionTextToken,
+ llil::{
+ get_default_flag_cond_llil, get_default_flag_write_llil, FlagWriteOp, LiftedExpr, Lifter,
+ },
+ platform::Platform,
+ rc::*,
+ string::BnStrCompatible,
+ string::*,
+ {BranchType, Endianness},
+};
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum BranchInfo {
@@ -673,13 +674,8 @@ impl CoreArchitecture {
CoreArchitectureList(archs, count)
}
- pub fn by_name<N: Into<Vec<u8>>>(name: N) -> Option<Self> {
- let name = match CString::new(name) {
- Ok(s) => s,
- _ => return None,
- };
-
- let res = unsafe { BNGetArchitectureByName(name.as_ptr()) };
+ pub fn by_name(name: &str) -> Option<Self> {
+ let res = unsafe { BNGetArchitectureByName(name.into_bytes_with_nul().as_ptr() as *mut _) };
match res.is_null() {
false => Some(CoreArchitecture(res)),
@@ -2032,9 +2028,7 @@ where
A: 'static + Architecture<Handle = Self> + Send + Sync,
{
fn clone(&self) -> Self {
- Self {
- handle: self.handle,
- }
+ *self
}
}
diff --git a/rust/src/downloadprovider.rs b/rust/src/downloadprovider.rs
index 441714b6..4ba07dbe 100644
--- a/rust/src/downloadprovider.rs
+++ b/rust/src/downloadprovider.rs
@@ -157,7 +157,7 @@ impl DownloadInstance {
};
// Drop it
- unsafe { Box::from_raw(callbacks) };
+ unsafe { drop(Box::from_raw(callbacks)) };
if result < 0 {
Err(self.get_error())
} else {
diff --git a/rust/src/headless.rs b/rust/src/headless.rs
index 0ce24cb3..c5e14eb0 100644
--- a/rust/src/headless.rs
+++ b/rust/src/headless.rs
@@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+use crate::string::BnStrCompatible;
+
use std::env;
-use std::ffi::CString;
use std::path::PathBuf;
#[cfg(not(target_os = "windows"))]
@@ -72,9 +73,9 @@ use binaryninjacore_sys::{BNInitPlugins, BNInitRepoPlugins, BNSetBundledPluginDi
pub fn init() {
unsafe {
let path = binja_path().join("plugins").into_os_string();
- let path = CString::new(path.into_string().unwrap()).unwrap();
+ let path = path.into_string().unwrap();
- BNSetBundledPluginDirectory(path.as_ptr());
+ BNSetBundledPluginDirectory(path.as_str().into_bytes_with_nul().as_ptr() as *mut _);
BNInitPlugins(true);
BNInitRepoPlugins();
}
diff --git a/rust/src/interaction.rs b/rust/src/interaction.rs
index 557dfdf3..b3f9fddd 100644
--- a/rust/src/interaction.rs
+++ b/rust/src/interaction.rs
@@ -16,20 +16,23 @@
use binaryninjacore_sys::*;
-use std::ffi::CString;
use std::os::raw::c_void;
use std::path::PathBuf;
use crate::binaryview::BinaryView;
use crate::rc::Ref;
-use crate::string::{BnStr, BnString, BnStrCompatible};
+use crate::string::{BnStr, BnStrCompatible, BnString};
pub fn get_text_line_input(prompt: &str, title: &str) -> Option<String> {
- let prompt = CString::new(prompt).unwrap();
- let title = CString::new(title).unwrap();
let mut value: *mut libc::c_char = std::ptr::null_mut();
- let result = unsafe { BNGetTextLineInput(&mut value, prompt.into_raw(), title.into_raw()) };
+ let result = unsafe {
+ BNGetTextLineInput(
+ &mut value,
+ prompt.into_bytes_with_nul().as_ptr() as *mut _,
+ title.into_bytes_with_nul().as_ptr() as *mut _,
+ )
+ };
if !result {
return None;
}
@@ -38,11 +41,15 @@ pub fn get_text_line_input(prompt: &str, title: &str) -> Option<String> {
}
pub fn get_integer_input(prompt: &str, title: &str) -> Option<i64> {
- let prompt = CString::new(prompt).unwrap();
- let title = CString::new(title).unwrap();
let mut value: i64 = 0;
- let result = unsafe { BNGetIntegerInput(&mut value, prompt.into_raw(), title.into_raw()) };
+ let result = unsafe {
+ BNGetIntegerInput(
+ &mut value,
+ prompt.into_bytes_with_nul().as_ptr() as *mut _,
+ title.into_bytes_with_nul().as_ptr() as *mut _,
+ )
+ };
if !result {
return None;
@@ -52,15 +59,13 @@ pub fn get_integer_input(prompt: &str, title: &str) -> Option<i64> {
}
pub fn get_address_input(prompt: &str, title: &str) -> Option<u64> {
- let prompt = CString::new(prompt).unwrap();
- let title = CString::new(title).unwrap();
let mut value: u64 = 0;
let result = unsafe {
BNGetAddressInput(
&mut value,
- prompt.into_raw(),
- title.into_raw(),
+ prompt.into_bytes_with_nul().as_ptr() as *mut _,
+ title.into_bytes_with_nul().as_ptr() as *mut _,
std::ptr::null_mut(),
0,
)
@@ -74,12 +79,15 @@ pub fn get_address_input(prompt: &str, title: &str) -> Option<u64> {
}
pub fn get_open_filename_input(prompt: &str, extension: &str) -> Option<PathBuf> {
- let prompt = CString::new(prompt).unwrap();
- let extension = CString::new(extension).unwrap();
let mut value: *mut libc::c_char = std::ptr::null_mut();
- let result =
- unsafe { BNGetOpenFileNameInput(&mut value, prompt.into_raw(), extension.into_raw()) };
+ let result = unsafe {
+ BNGetOpenFileNameInput(
+ &mut value,
+ prompt.into_bytes_with_nul().as_ptr() as *mut _,
+ extension.into_bytes_with_nul().as_ptr() as *mut _,
+ )
+ };
if !result {
return None;
}
@@ -89,17 +97,14 @@ pub fn get_open_filename_input(prompt: &str, extension: &str) -> Option<PathBuf>
}
pub fn get_save_filename_input(prompt: &str, title: &str, default_name: &str) -> Option<PathBuf> {
- let prompt = CString::new(prompt).unwrap();
- let title = CString::new(title).unwrap();
- let default_name = CString::new(default_name).unwrap();
let mut value: *mut libc::c_char = std::ptr::null_mut();
let result = unsafe {
BNGetSaveFileNameInput(
&mut value,
- prompt.into_raw(),
- title.into_raw(),
- default_name.into_raw(),
+ prompt.into_bytes_with_nul().as_ptr() as *mut _,
+ title.into_bytes_with_nul().as_ptr() as *mut _,
+ default_name.into_bytes_with_nul().as_ptr() as *mut _,
)
};
if !result {
@@ -111,12 +116,15 @@ pub fn get_save_filename_input(prompt: &str, title: &str, default_name: &str) ->
}
pub fn get_directory_name_input(prompt: &str, default_name: &str) -> Option<PathBuf> {
- let prompt = CString::new(prompt).unwrap();
- let default_name = CString::new(default_name).unwrap();
let mut value: *mut libc::c_char = std::ptr::null_mut();
- let result =
- unsafe { BNGetDirectoryNameInput(&mut value, prompt.into_raw(), default_name.into_raw()) };
+ let result = unsafe {
+ BNGetDirectoryNameInput(
+ &mut value,
+ prompt.into_bytes_with_nul().as_ptr() as *mut _,
+ default_name.into_bytes_with_nul().as_ptr() as *mut _,
+ )
+ };
if !result {
return None;
}
@@ -134,10 +142,14 @@ pub fn show_message_box(
buttons: MessageBoxButtonSet,
icon: MessageBoxIcon,
) -> MessageBoxButtonResult {
- let title = CString::new(title).unwrap();
- let text = CString::new(text).unwrap();
-
- unsafe { BNShowMessageBox(title.as_ptr(), text.as_ptr(), buttons, icon) }
+ unsafe {
+ BNShowMessageBox(
+ title.into_bytes_with_nul().as_ptr() as *mut _,
+ text.into_bytes_with_nul().as_ptr() as *mut _,
+ buttons,
+ icon,
+ )
+ }
}
pub enum FormResponses {
@@ -467,12 +479,11 @@ impl FormInputBuilder {
/// println!("{} {} likes {}", &first_name, &last_name, food);
/// ```
pub fn get_form_input(&mut self, title: &str) -> Vec<FormResponses> {
- let safe_title = title.into_bytes_with_nul();
if unsafe {
BNGetFormInput(
self.fields.as_mut_ptr(),
self.fields.len(),
- safe_title.as_ptr() as *const _,
+ title.into_bytes_with_nul().as_ptr() as *const _,
)
} {
let result = self
@@ -524,8 +535,6 @@ pub fn run_progress_dialog<F: Fn(Box<dyn Fn(usize, usize) -> Result<(), ()>>)>(
can_cancel: bool,
task: F,
) -> Result<(), ()> {
- let title = CString::new(title).unwrap();
-
let mut ctxt = TaskContext::<F>(task);
unsafe extern "C" fn cb_task<F: Fn(Box<dyn Fn(usize, usize) -> Result<(), ()>>)>(
@@ -553,7 +562,7 @@ pub fn run_progress_dialog<F: Fn(Box<dyn Fn(usize, usize) -> Result<(), ()>>)>(
if unsafe {
BNRunProgressDialog(
- title.as_ptr(),
+ title.into_bytes_with_nul().as_ptr() as *mut _,
can_cancel,
Some(cb_task::<F>),
&mut ctxt as *mut _ as *mut c_void,
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 7039a69d..352ecef9 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -166,12 +166,12 @@ pub mod templatesimplifier;
pub mod types;
use std::path::PathBuf;
-use std::ptr::null_mut;
pub use binaryninjacore_sys::BNBranchType as BranchType;
pub use binaryninjacore_sys::BNEndianness as Endianness;
use binaryview::BinaryView;
use metadata::Metadata;
+use metadata::MetadataType;
use rc::Ref;
use string::BnStrCompatible;
@@ -197,13 +197,14 @@ const BN_INVALID_EXPR: usize = usize::MAX;
pub fn load<S: BnStrCompatible>(filename: S) -> Option<rc::Ref<binaryview::BinaryView>> {
let filename = filename.into_bytes_with_nul();
+ let metadata = Metadata::new_of_type(MetadataType::KeyValueDataType);
let handle = unsafe {
binaryninjacore_sys::BNLoadFilename(
filename.as_ref().as_ptr() as *mut _,
true,
None,
- null_mut() as *mut _,
+ metadata.handle,
)
};
@@ -235,7 +236,7 @@ pub fn load_with_options<S: BnStrCompatible>(
if let Some(options) = options {
options.as_ref().handle
} else {
- null_mut() as *mut _
+ Metadata::new_of_type(MetadataType::KeyValueDataType).handle
},
)
};
diff --git a/rust/src/metadata.rs b/rust/src/metadata.rs
index 1ea8225d..e29789e5 100644
--- a/rust/src/metadata.rs
+++ b/rust/src/metadata.rs
@@ -24,6 +24,10 @@ impl Metadata {
Ref::new(Self::from_raw(handle))
}
+ pub fn new_of_type(metadata_type: MetadataType) -> Ref<Self> {
+ unsafe { Self::ref_from_raw(BNCreateMetadataOfType(metadata_type)) }
+ }
+
pub fn get_type(&self) -> MetadataType {
unsafe { BNMetadataGetType(self.handle) }
}