From ce5995c3b8c8765811521d9d9f0eadcf3b601415 Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Thu, 1 Aug 2024 17:03:39 -0400 Subject: [PATCH] Pass length to free flag conditions list callback and remove libc from rust api Allows language bindings like rust to free conditions lists sanely # Conflicts: # rust/Cargo.lock --- arch/riscv/Cargo.lock | 1 - architecture.cpp | 2 +- binaryninjaapi.h | 2 +- binaryninjacore.h | 2 +- python/architecture.py | 2 +- rust/Cargo.toml | 1 - rust/src/architecture.rs | 38 +++++++++++++++++--------------------- rust/src/filemetadata.rs | 5 +++-- rust/src/interaction.rs | 11 +++++------ rust/src/lib.rs | 1 - 10 files changed, 29 insertions(+), 36 deletions(-) diff --git a/arch/riscv/Cargo.lock b/arch/riscv/Cargo.lock index fc9e86ee3..369430706 100644 --- a/arch/riscv/Cargo.lock +++ b/arch/riscv/Cargo.lock @@ -33,7 +33,6 @@ version = "0.1.0" dependencies = [ "binaryninjacore-sys", "lazy_static", - "libc", "log", "rayon", ] diff --git a/architecture.cpp b/architecture.cpp index 8a13e8f3c..1d849f5b9 100644 --- a/architecture.cpp +++ b/architecture.cpp @@ -462,7 +462,7 @@ BNFlagConditionForSemanticClass* Architecture::GetFlagConditionsForSemanticFlagG } -void Architecture::FreeFlagConditionsForSemanticFlagGroupCallback(void*, BNFlagConditionForSemanticClass* conditions) +void Architecture::FreeFlagConditionsForSemanticFlagGroupCallback(void*, BNFlagConditionForSemanticClass* conditions, size_t) { delete[] conditions; } diff --git a/binaryninjaapi.h b/binaryninjaapi.h index d3d19c3f0..66d6fd459 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -7743,7 +7743,7 @@ namespace BinaryNinja { static BNFlagConditionForSemanticClass* GetFlagConditionsForSemanticFlagGroupCallback( void* ctxt, uint32_t semGroup, size_t* count); static void FreeFlagConditionsForSemanticFlagGroupCallback( - void* ctxt, BNFlagConditionForSemanticClass* conditions); + void* ctxt, BNFlagConditionForSemanticClass* conditions, size_t count); static uint32_t* GetFlagsWrittenByFlagWriteTypeCallback(void* ctxt, uint32_t writeType, size_t* count); static uint32_t GetSemanticClassForFlagWriteTypeCallback(void* ctxt, uint32_t writeType); static size_t GetFlagWriteLowLevelILCallback(void* ctxt, BNLowLevelILOperation op, size_t size, diff --git a/binaryninjacore.h b/binaryninjacore.h index 284eff449..53463266a 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1831,7 +1831,7 @@ extern "C" uint32_t* (*getFlagsRequiredForSemanticFlagGroup)(void* ctxt, uint32_t semGroup, size_t* count); BNFlagConditionForSemanticClass* (*getFlagConditionsForSemanticFlagGroup)( void* ctxt, uint32_t semGroup, size_t* count); - void (*freeFlagConditionsForSemanticFlagGroup)(void* ctxt, BNFlagConditionForSemanticClass* conditions); + void (*freeFlagConditionsForSemanticFlagGroup)(void* ctxt, BNFlagConditionForSemanticClass* conditions, size_t count); uint32_t* (*getFlagsWrittenByFlagWriteType)(void* ctxt, uint32_t writeType, size_t* count); uint32_t (*getSemanticClassForFlagWriteType)(void* ctxt, uint32_t writeType); size_t (*getFlagWriteLowLevelIL)(void* ctxt, BNLowLevelILOperation op, size_t size, uint32_t flagWriteType, diff --git a/python/architecture.py b/python/architecture.py index e4d381917..64c4d7730 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -914,7 +914,7 @@ def _get_flag_conditions_for_semantic_flag_group(self, ctxt, sem_group, count): count[0] = 0 return None - def _free_flag_conditions_for_semantic_flag_group(self, ctxt, conditions): + def _free_flag_conditions_for_semantic_flag_group(self, ctxt, conditions, count): try: buf = ctypes.cast(conditions, ctypes.c_void_p) if buf.value not in self._pending_condition_lists: diff --git a/rust/Cargo.toml b/rust/Cargo.toml index cd60c741c..56e26daf2 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -11,7 +11,6 @@ noexports = [] [dependencies] lazy_static = "1.4.0" log = "0.4" -libc = "0.2" rayon = { version = "1.8", optional = true } binaryninjacore-sys = { path = "binaryninjacore-sys" } diff --git a/rust/src/architecture.rs b/rust/src/architecture.rs index f456badc5..0e649e6c9 100644 --- a/rust/src/architecture.rs +++ b/rust/src/architecture.rs @@ -1940,7 +1940,7 @@ where None => BnString::new("invalid_flag_group").into_raw(), } } - + extern "C" fn cb_registers_full_width(ctxt: *mut c_void, count: *mut usize) -> *mut u32 where A: 'static + Architecture> + Send + Sync, @@ -2101,7 +2101,7 @@ where if let Some(group) = custom_arch.flag_group_from_id(group) { let mut flags = group.flags_required(); - + // SAFETY: `count` is an out parameter unsafe { *count = flags.len() }; let regs_ptr = flags.as_mut_ptr(); @@ -2127,23 +2127,13 @@ where if let Some(group) = custom_arch.flag_group_from_id(group) { let flag_conditions = group.flag_conditions(); + let mut flags = flag_conditions.values().collect::>(); - unsafe { - let allocation_size = - mem::size_of::() * flag_conditions.len(); - let result = libc::malloc(allocation_size) as *mut BNFlagConditionForSemanticClass; - let out_slice = slice::from_raw_parts_mut(result, flag_conditions.len()); - - for (i, (class, cond)) in flag_conditions.iter().enumerate() { - let out = out_slice.get_unchecked_mut(i); - - out.semanticClass = class.id(); - out.condition = *cond; - } - - *count = flag_conditions.len(); - result - } + // SAFETY: `count` is an out parameter + unsafe { *count = flags.len() }; + let regs_ptr = flags.as_mut_ptr(); + mem::forget(flags); + regs_ptr as *mut _ } else { unsafe { *count = 0; @@ -2155,11 +2145,17 @@ where extern "C" fn cb_free_flag_conditions_for_semantic_flag_group( _ctxt: *mut c_void, conds: *mut BNFlagConditionForSemanticClass, + count: usize, ) where A: 'static + Architecture> + Send + Sync, { + if conds.is_null() { + return; + } + unsafe { - libc::free(conds as *mut _); + let regs_ptr = ptr::slice_from_raw_parts_mut(conds, count); + let _regs = Box::from_raw(regs_ptr); } } @@ -2175,7 +2171,7 @@ where if let Some(write_type) = custom_arch.flag_write_from_id(write_type) { let mut written = write_type.flags_written(); - + // SAFETY: `count` is an out parameter unsafe { *count = written.len() }; let regs_ptr = written.as_mut_ptr(); @@ -2449,7 +2445,7 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; let mut intrinsics = custom_arch.intrinsics(); - + // SAFETY: Passed in to be written unsafe { *count = intrinsics.len() }; let regs_ptr = intrinsics.as_mut_ptr(); diff --git a/rust/src/filemetadata.rs b/rust/src/filemetadata.rs index 08cffecfb..d2818517d 100644 --- a/rust/src/filemetadata.rs +++ b/rust/src/filemetadata.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::ffi::c_void; use binaryninjacore_sys::{ BNBeginUndoActions, BNCloseFile, @@ -224,7 +225,7 @@ impl FileMetadata { BNCreateDatabaseWithProgress( handle, filename_ptr, - func as *mut libc::c_void, + func as *mut c_void, Some(cb_progress_func), ptr::null_mut(), ) @@ -273,7 +274,7 @@ impl FileMetadata { BNOpenExistingDatabaseWithProgress( self.handle, filename_ptr, - func as *mut libc::c_void, + func as *mut c_void, Some(cb_progress_func), ) }, diff --git a/rust/src/interaction.rs b/rust/src/interaction.rs index 7d10bbe4a..9d66730de 100644 --- a/rust/src/interaction.rs +++ b/rust/src/interaction.rs @@ -16,8 +16,7 @@ use binaryninjacore_sys::*; -use std::ffi::CStr; -use std::os::raw::{c_char, c_void}; +use std::ffi::{c_char, c_void, CStr}; use std::path::PathBuf; use crate::binaryview::BinaryView; @@ -25,7 +24,7 @@ use crate::rc::Ref; use crate::string::{BnStrCompatible, BnString}; pub fn get_text_line_input(prompt: &str, title: &str) -> Option { - let mut value: *mut libc::c_char = std::ptr::null_mut(); + let mut value: *mut c_char = std::ptr::null_mut(); let result = unsafe { BNGetTextLineInput( @@ -80,7 +79,7 @@ pub fn get_address_input(prompt: &str, title: &str) -> Option { } pub fn get_open_filename_input(prompt: &str, extension: &str) -> Option { - let mut value: *mut libc::c_char = std::ptr::null_mut(); + let mut value: *mut c_char = std::ptr::null_mut(); let result = unsafe { BNGetOpenFileNameInput( @@ -98,7 +97,7 @@ pub fn get_open_filename_input(prompt: &str, extension: &str) -> Option } pub fn get_save_filename_input(prompt: &str, title: &str, default_name: &str) -> Option { - let mut value: *mut libc::c_char = std::ptr::null_mut(); + let mut value: *mut c_char = std::ptr::null_mut(); let result = unsafe { BNGetSaveFileNameInput( @@ -117,7 +116,7 @@ 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 { - let mut value: *mut libc::c_char = std::ptr::null_mut(); + let mut value: *mut c_char = std::ptr::null_mut(); let result = unsafe { BNGetDirectoryNameInput( diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 65e4b72e0..1985ee6a5 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -124,7 +124,6 @@ extern crate log; #[doc(hidden)] pub extern crate binaryninjacore_sys; -extern crate libc; #[cfg(feature = "rayon")] extern crate rayon;