From 77c3e7572ed556ab38b2a5c768588ff6d371d450 Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Thu, 11 Jul 2024 13:14:50 -0400 Subject: [PATCH] Fix clippy warnings and run rustfmt --- .../dwarf/dwarf_import/src/die_handlers.rs | 42 +++-- .../dwarf/dwarf_import/src/dwarfdebuginfo.rs | 87 +++++---- .../dwarf/dwarf_import/src/functions.rs | 31 +++- .../dwarf/dwarf_import/src/helpers.rs | 167 +++++++++--------- rust/examples/dwarf/dwarf_import/src/lib.rs | 126 +++++++------ rust/examples/dwarf/dwarf_import/src/types.rs | 52 +++--- rust/examples/dwarf/shared/src/lib.rs | 17 +- rust/examples/pdb-ng/src/lib.rs | 13 +- rust/examples/pdb-ng/src/parser.rs | 11 +- rust/examples/pdb-ng/src/type_parser.rs | 8 +- rust/src/binaryview.rs | 17 +- rust/src/callingconvention.rs | 4 +- rust/src/component.rs | 4 +- rust/src/database.rs | 8 +- rust/src/debuginfo.rs | 41 ++--- rust/src/demangle.rs | 5 +- rust/src/disassembly.rs | 10 +- rust/src/downloadprovider.rs | 2 +- rust/src/externallibrary.rs | 17 +- rust/src/filemetadata.rs | 4 +- rust/src/function.rs | 9 +- rust/src/headless.rs | 3 +- rust/src/lib.rs | 6 +- rust/src/llil/lifting.rs | 6 +- rust/src/llil/operation.rs | 8 +- rust/src/mlil/instruction.rs | 4 +- rust/src/mlil/operation.rs | 5 +- rust/src/project.rs | 10 +- rust/src/relocation.rs | 4 +- rust/src/typearchive.rs | 10 +- rust/src/typelibrary.rs | 4 +- rust/src/types.rs | 24 +-- rust/src/update.rs | 6 +- 33 files changed, 406 insertions(+), 359 deletions(-) diff --git a/rust/examples/dwarf/dwarf_import/src/die_handlers.rs b/rust/examples/dwarf/dwarf_import/src/die_handlers.rs index 51d52d5b7..bcad4f1ed 100644 --- a/rust/examples/dwarf/dwarf_import/src/die_handlers.rs +++ b/rust/examples/dwarf/dwarf_import/src/die_handlers.rs @@ -13,8 +13,8 @@ // limitations under the License. use crate::dwarfdebuginfo::{DebugInfoBuilder, DebugInfoBuilderContext, TypeUID}; -use crate::{helpers::*, ReaderType}; use crate::types::get_type; +use crate::{helpers::*, ReaderType}; use binaryninja::{ rc::*, @@ -172,7 +172,10 @@ pub(crate) fn handle_pointer( if let Some(pointer_size) = get_size_as_usize(entry) { if let Some(entry_type_offset) = entry_type { - let parent_type = debug_info_builder.get_type(entry_type_offset).unwrap().get_type(); + let parent_type = debug_info_builder + .get_type(entry_type_offset) + .unwrap() + .get_type(); Some(Type::pointer_of_width( parent_type.as_ref(), pointer_size, @@ -190,7 +193,10 @@ pub(crate) fn handle_pointer( )) } } else if let Some(entry_type_offset) = entry_type { - let parent_type = debug_info_builder.get_type(entry_type_offset).unwrap().get_type(); + let parent_type = debug_info_builder + .get_type(entry_type_offset) + .unwrap() + .get_type(); Some(Type::pointer_of_width( parent_type.as_ref(), debug_info_builder_context.default_address_size(), @@ -228,7 +234,10 @@ pub(crate) fn handle_array( // For multidimensional arrays, DW_TAG_subrange_type or DW_TAG_enumeration_type if let Some(entry_type_offset) = entry_type { - let parent_type = debug_info_builder.get_type(entry_type_offset).unwrap().get_type(); + let parent_type = debug_info_builder + .get_type(entry_type_offset) + .unwrap() + .get_type(); let mut tree = unit.entries_tree(Some(entry.offset())).unwrap(); let mut children = tree.root().unwrap().children(); @@ -286,12 +295,10 @@ pub(crate) fn handle_function( // or is otherwise DW_TAG_unspecified_parameters let return_type = match entry_type { - Some(entry_type_offset) => { - debug_info_builder - .get_type(entry_type_offset) - .expect("Subroutine return type was not processed") - .get_type() - } + Some(entry_type_offset) => debug_info_builder + .get_type(entry_type_offset) + .expect("Subroutine return type was not processed") + .get_type(), None => Type::void(), }; @@ -336,7 +343,10 @@ pub(crate) fn handle_function( } } - if debug_info_builder_context.get_name(dwarf, unit, entry).is_some() { + if debug_info_builder_context + .get_name(dwarf, unit, entry) + .is_some() + { debug_info_builder.remove_type(get_uid(dwarf, unit, entry)); } @@ -360,7 +370,10 @@ pub(crate) fn handle_const( // ?DW_AT_type if let Some(entry_type_offset) = entry_type { - let parent_type = debug_info_builder.get_type(entry_type_offset).unwrap().get_type(); + let parent_type = debug_info_builder + .get_type(entry_type_offset) + .unwrap() + .get_type(); Some((*parent_type).to_builder().set_const(true).finalize()) } else { Some(TypeBuilder::void().set_const(true).finalize()) @@ -380,7 +393,10 @@ pub(crate) fn handle_volatile( // ?DW_AT_type if let Some(entry_type_offset) = entry_type { - let parent_type = debug_info_builder.get_type(entry_type_offset).unwrap().get_type(); + let parent_type = debug_info_builder + .get_type(entry_type_offset) + .unwrap() + .get_type(); Some((*parent_type).to_builder().set_volatile(true).finalize()) } else { Some(TypeBuilder::void().set_volatile(true).finalize()) diff --git a/rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs b/rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs index 408b373fd..f35178b36 100644 --- a/rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs +++ b/rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs @@ -12,9 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{helpers::{get_uid, resolve_specification, DieReference}, ReaderType}; +use crate::{ + helpers::{get_uid, resolve_specification, DieReference}, + ReaderType, +}; use binaryninja::{ + binaryninjacore_sys::BNVariableSourceType, binaryview::{BinaryView, BinaryViewBase, BinaryViewExt}, debuginfo::{DebugFunctionInfo, DebugInfo}, platform::Platform, @@ -120,7 +124,6 @@ pub(crate) struct DebugInfoBuilderContext { impl DebugInfoBuilderContext { pub(crate) fn new(view: &BinaryView, dwarf: &Dwarf) -> Option { - let mut units = vec![]; let mut iter = dwarf.units(); while let Ok(Some(header)) = iter.next() { @@ -200,7 +203,7 @@ pub(crate) struct DebugInfoBuilder { full_function_name_indices: HashMap, types: HashMap, data_variables: HashMap, TypeUID)>, - range_data_offsets: iset::IntervalMap + range_data_offsets: iset::IntervalMap, } impl DebugInfoBuilder { @@ -234,10 +237,10 @@ impl DebugInfoBuilder { // TODO : Consider further falling back on address/architecture /* - If it has a raw_name and we know it, update it and return - Else if it has a full_name and we know it, update it and return - Else Add a new entry if we don't know the full_name or raw_name - */ + If it has a raw_name and we know it, update it and return + Else if it has a full_name and we know it, update it and return + Else Add a new entry if we don't know the full_name or raw_name + */ if let Some(ident) = &raw_name { // check if we already know about this raw name's index @@ -248,20 +251,20 @@ impl DebugInfoBuilder { let function = self.functions.get_mut(*idx).unwrap(); if function.full_name.is_some() && function.full_name != full_name { - self.full_function_name_indices.remove(function.full_name.as_ref().unwrap()); + self.full_function_name_indices + .remove(function.full_name.as_ref().unwrap()); } function.update(full_name, raw_name, return_type, address, parameters); - if function.full_name.is_some() { - self.full_function_name_indices.insert(function.full_name.clone().unwrap(), *idx); + if function.full_name.is_some() { + self.full_function_name_indices + .insert(function.full_name.clone().unwrap(), *idx); } return Some(*idx); } - } - - else if let Some(ident) = &full_name { + } else if let Some(ident) = &full_name { // check if we already know about this full name's index // if we do, and the raw name will change, remove the known raw index if it exists // update the function @@ -270,13 +273,15 @@ impl DebugInfoBuilder { let function = self.functions.get_mut(*idx).unwrap(); if function.raw_name.is_some() && function.raw_name != raw_name { - self.raw_function_name_indices.remove(function.raw_name.as_ref().unwrap()); + self.raw_function_name_indices + .remove(function.raw_name.as_ref().unwrap()); } function.update(full_name, raw_name, return_type, address, parameters); - if function.raw_name.is_some() { - self.raw_function_name_indices.insert(function.raw_name.clone().unwrap(), *idx); + if function.raw_name.is_some() { + self.raw_function_name_indices + .insert(function.raw_name.clone().unwrap(), *idx); } return Some(*idx); @@ -300,15 +305,17 @@ impl DebugInfoBuilder { }; if let Some(n) = &function.full_name { - self.full_function_name_indices.insert(n.clone(), self.functions.len()); + self.full_function_name_indices + .insert(n.clone(), self.functions.len()); } if let Some(n) = &function.raw_name { - self.raw_function_name_indices.insert(n.clone(), self.functions.len()); + self.raw_function_name_indices + .insert(n.clone(), self.functions.len()); } self.functions.push(function); - Some(self.functions.len()-1) + Some(self.functions.len() - 1) } pub(crate) fn functions(&self) -> &[FunctionInfoBuilder] { @@ -319,7 +326,13 @@ impl DebugInfoBuilder { self.types.values() } - pub(crate) fn add_type(&mut self, type_uid: TypeUID, name: &String, t: Ref, commit: bool) { + pub(crate) fn add_type( + &mut self, + type_uid: TypeUID, + name: &String, + t: Ref, + commit: bool, + ) { if let Some(DebugType { name: existing_name, t: existing_type, @@ -355,7 +368,6 @@ impl DebugInfoBuilder { self.types.contains_key(&type_uid) } - pub(crate) fn add_stack_variable( &mut self, fn_idx: Option, @@ -368,11 +380,10 @@ impl DebugInfoBuilder { if x.len() == 1 && x.chars().next() == Some('\x00') { // Anonymous variable, generate name format!("debug_var_{}", offset) - } - else { + } else { x } - }, + } None => { // Anonymous variable, generate name format!("debug_var_{}", offset) @@ -381,14 +392,16 @@ impl DebugInfoBuilder { let Some(function_index) = fn_idx else { // If we somehow lost track of what subprogram we're in or we're not actually in a subprogram - error!("Trying to add a local variable outside of a subprogram. Please report this issue."); + error!( + "Trying to add a local variable outside of a subprogram. Please report this issue." + ); return; }; // Either get the known type or use a 0 confidence void type so we at least get the name applied let t = match type_uid { Some(uid) => Conf::new(self.get_type(uid).unwrap().get_type(), 128), - None => Conf::new(Type::void(), 0) + None => Conf::new(Type::void(), 0), }; let function = &mut self.functions[function_index]; @@ -400,7 +413,8 @@ impl DebugInfoBuilder { return; }; - let Some(offset_adjustment) = self.range_data_offsets.values_overlap(func_addr).next() else { + let Some(offset_adjustment) = self.range_data_offsets.values_overlap(func_addr).next() + else { // Unknown why, but this is happening with MachO + external dSYM debug!("Refusing to add a local variable ({}@{}) to function at {} without a known CIE offset.", name, offset, func_addr); return; @@ -414,9 +428,14 @@ impl DebugInfoBuilder { return; } - let var = Variable::new(VariableSourceType::StackVariableSourceType, 0, adjusted_offset); - function.stack_variables.push(NamedTypedVariable::new(var, name, t, false)); - + let var = Variable::new( + VariableSourceType::StackVariableSourceType, + 0, + adjusted_offset, + ); + function + .stack_variables + .push(NamedTypedVariable::new(var, name, t, false)); } pub(crate) fn add_data_variable( @@ -464,7 +483,9 @@ impl DebugInfoBuilder { fn get_function_type(&self, function: &FunctionInfoBuilder) -> Ref { let return_type = match function.return_type { - Some(return_type_id) => Conf::new(self.get_type(return_type_id).unwrap().get_type(), 128), + Some(return_type_id) => { + Conf::new(self.get_type(return_type_id).unwrap().get_type(), 128) + } _ => Conf::new(binaryninja::types::Type::void(), 0), }; @@ -496,7 +517,7 @@ impl DebugInfoBuilder { Some(self.get_function_type(function)), function.address, function.platform.clone(), - vec![], // TODO : Components + vec![], // TODO : Components function.stack_variables.clone(), // TODO: local non-stack variables )); } @@ -536,7 +557,7 @@ impl DebugInfoBuilder { if let Some(address) = func.address.as_mut() { let diff = bv.start() - bv.original_image_base(); - *address += diff; // rebase the address + *address += diff; // rebase the address let existing_functions = bv.functions_at(*address); match existing_functions.len().cmp(&1) { Ordering::Greater => { diff --git a/rust/examples/dwarf/dwarf_import/src/functions.rs b/rust/examples/dwarf/dwarf_import/src/functions.rs index ea6aba4d8..ee9f1f505 100644 --- a/rust/examples/dwarf/dwarf_import/src/functions.rs +++ b/rust/examples/dwarf/dwarf_import/src/functions.rs @@ -15,8 +15,8 @@ use std::sync::OnceLock; use crate::dwarfdebuginfo::{DebugInfoBuilder, DebugInfoBuilderContext, TypeUID}; -use crate::{helpers::*, ReaderType}; use crate::types::get_type; +use crate::{helpers::*, ReaderType}; use binaryninja::templatesimplifier::simplify_str_to_str; use cpp_demangle::DemangleOptions; @@ -81,9 +81,21 @@ pub(crate) fn parse_function_entry( ) -> Option { // Collect function properties (if they exist in this DIE) let raw_name = get_raw_name(dwarf, unit, entry); - let return_type = get_type(dwarf, unit, entry, debug_info_builder_context, debug_info_builder); + let return_type = get_type( + dwarf, + unit, + entry, + debug_info_builder_context, + debug_info_builder, + ); let address = get_start_address(dwarf, unit, entry); - let (parameters, variable_arguments) = get_parameters(dwarf, unit, entry, debug_info_builder_context, debug_info_builder); + let (parameters, variable_arguments) = get_parameters( + dwarf, + unit, + entry, + debug_info_builder_context, + debug_info_builder, + ); // If we have a raw name, it might be mangled, see if we can demangle it into full_name // raw_name should contain a superset of the info we have in full_name @@ -99,9 +111,7 @@ pub(crate) fn parse_function_entry( }); static ABI_REGEX_MEM: OnceLock = OnceLock::new(); - let abi_regex = ABI_REGEX_MEM.get_or_init(|| { - Regex::new(r"\[abi:v\d+\]").unwrap() - }); + let abi_regex = ABI_REGEX_MEM.get_or_init(|| Regex::new(r"\[abi:v\d+\]").unwrap()); if let Ok(sym) = cpp_demangle::Symbol::new(possibly_mangled_name) { if let Ok(demangled) = sym.demangle(demangle_options) { let cleaned = abi_regex.replace_all(&demangled, ""); @@ -117,5 +127,12 @@ pub(crate) fn parse_function_entry( full_name = debug_info_builder_context.get_name(dwarf, unit, entry) } - debug_info_builder.insert_function(full_name, raw_name, return_type, address, ¶meters, variable_arguments) + debug_info_builder.insert_function( + full_name, + raw_name, + return_type, + address, + ¶meters, + variable_arguments, + ) } diff --git a/rust/examples/dwarf/dwarf_import/src/helpers.rs b/rust/examples/dwarf/dwarf_import/src/helpers.rs index 7127b2b8a..18889c5b6 100644 --- a/rust/examples/dwarf/dwarf_import/src/helpers.rs +++ b/rust/examples/dwarf/dwarf_import/src/helpers.rs @@ -13,23 +13,22 @@ // limitations under the License. use std::path::PathBuf; -use std::{ - collections::HashMap, - ops::Deref, - sync::mpsc, - str::FromStr -}; +use std::{collections::HashMap, ops::Deref, str::FromStr, sync::mpsc}; use crate::{DebugInfoBuilderContext, ReaderType}; use binaryninja::binaryview::BinaryViewBase; use binaryninja::filemetadata::FileMetadata; use binaryninja::Endianness; -use binaryninja::{binaryview::{BinaryView, BinaryViewExt}, downloadprovider::{DownloadInstanceInputOutputCallbacks, DownloadProvider}, rc::Ref, settings::Settings}; -use gimli::Dwarf; +use binaryninja::{ + binaryview::{BinaryView, BinaryViewExt}, + downloadprovider::{DownloadInstanceInputOutputCallbacks, DownloadProvider}, + rc::Ref, + settings::Settings, +}; use gimli::{ constants, Attribute, AttributeValue, AttributeValue::{DebugInfoRef, DebugInfoRefSup, UnitRef}, - DebuggingInformationEntry, Operation, Unit, UnitOffset, UnitSectionOffset, + DebuggingInformationEntry, Dwarf, Operation, Unit, UnitOffset, UnitSectionOffset, }; use log::warn; @@ -69,40 +68,55 @@ pub(crate) fn get_attr_die<'a, R: ReaderType>( if dwarf.sup().is_some() { for source_unit in debug_info_builder_context.units() { if let Some(new_offset) = offset.to_unit_offset(&source_unit.header) { - return Some(DieReference::UnitAndOffset((dwarf, source_unit, new_offset))); + return Some(DieReference::UnitAndOffset(( + dwarf, + source_unit, + new_offset, + ))); } } - } - else { + } else { // This could either have no supplementary file because it is one or because it just doesn't have one // operate on supplementary file if dwarf is a supplementary file, else self // It's possible this is a reference in the supplementary file to itself for source_unit in debug_info_builder_context.sup_units() { if let Some(new_offset) = offset.to_unit_offset(&source_unit.header) { - return Some(DieReference::UnitAndOffset((dwarf, source_unit, new_offset))); + return Some(DieReference::UnitAndOffset(( + dwarf, + source_unit, + new_offset, + ))); } } // ... or it just doesn't have a supplementary file for source_unit in debug_info_builder_context.units() { if let Some(new_offset) = offset.to_unit_offset(&source_unit.header) { - return Some(DieReference::UnitAndOffset((dwarf, source_unit, new_offset))); + return Some(DieReference::UnitAndOffset(( + dwarf, + source_unit, + new_offset, + ))); } } } None - }, + } Ok(Some(DebugInfoRefSup(offset))) => { for source_unit in debug_info_builder_context.sup_units() { if let Some(new_offset) = offset.to_unit_offset(&source_unit.header) { - return Some(DieReference::UnitAndOffset((dwarf.sup().unwrap(), source_unit, new_offset))); + return Some(DieReference::UnitAndOffset(( + dwarf.sup().unwrap(), + source_unit, + new_offset, + ))); } } warn!("Failed to fetch DIE. Supplementary debug information may be incomplete."); None - }, + } _ => None, } } @@ -140,7 +154,9 @@ pub(crate) fn resolve_specification<'a, R: ReaderType>( ) { match die_reference { DieReference::UnitAndOffset((dwarf, entry_unit, entry_offset)) => { - if entry_offset == entry.offset() && unit.header.offset() == entry_unit.header.offset() { + if entry_offset == entry.offset() + && unit.header.offset() == entry_unit.header.offset() + { warn!("DWARF information is invalid (infinite abstract origin reference cycle). Debug information may be incomplete."); DieReference::Err } else if let Ok(new_entry) = entry_unit.entry(entry_offset) { @@ -171,15 +187,12 @@ pub(crate) fn get_name( .unwrap() .attr_value(constants::DW_AT_name) { - if let Ok(attr_string) = dwarf.attr_string(entry_unit, attr_val.clone()) - { + if let Ok(attr_string) = dwarf.attr_string(entry_unit, attr_val.clone()) { if let Ok(attr_string) = attr_string.to_string() { return Some(attr_string.to_string()); } - } - else if let Some(dwarf) = &dwarf.sup { - if let Ok(attr_string) = dwarf.attr_string(entry_unit, attr_val) - { + } else if let Some(dwarf) = &dwarf.sup { + if let Ok(attr_string) = dwarf.attr_string(entry_unit, attr_val) { if let Ok(attr_string) = attr_string.to_string() { return Some(attr_string.to_string()); } @@ -207,15 +220,12 @@ pub(crate) fn get_raw_name( entry: &DebuggingInformationEntry, ) -> Option { if let Ok(Some(attr_val)) = entry.attr_value(constants::DW_AT_linkage_name) { - if let Ok(attr_string) = dwarf.attr_string(unit, attr_val.clone()) - { + if let Ok(attr_string) = dwarf.attr_string(unit, attr_val.clone()) { if let Ok(attr_string) = attr_string.to_string() { return Some(attr_string.to_string()); } - } - else if let Some(dwarf) = dwarf.sup() { - if let Ok(attr_string) = dwarf.attr_string(unit, attr_val) - { + } else if let Some(dwarf) = dwarf.sup() { + if let Ok(attr_string) = dwarf.attr_string(unit, attr_val) { if let Ok(attr_string) = attr_string.to_string() { return Some(attr_string.to_string()); } @@ -239,9 +249,7 @@ pub(crate) fn get_size_as_usize( } // Get the size of an object as a u64 -pub(crate) fn get_size_as_u64( - entry: &DebuggingInformationEntry, -) -> Option { +pub(crate) fn get_size_as_u64(entry: &DebuggingInformationEntry) -> Option { if let Ok(Some(attr)) = entry.attr(constants::DW_AT_byte_size) { get_attr_as_u64(&attr) } else if let Ok(Some(attr)) = entry.attr(constants::DW_AT_bit_size) { @@ -252,9 +260,7 @@ pub(crate) fn get_size_as_u64( } // Get the size of a subrange as a u64 -pub(crate) fn get_subrange_size( - entry: &DebuggingInformationEntry, -) -> u64 { +pub(crate) fn get_subrange_size(entry: &DebuggingInformationEntry) -> u64 { if let Ok(Some(attr)) = entry.attr(constants::DW_AT_upper_bound) { get_attr_as_u64(&attr).map_or(0, |v| v + 1) } else if let Ok(Some(attr)) = entry.attr(constants::DW_AT_count) { @@ -273,22 +279,18 @@ pub(crate) fn get_start_address( entry: &DebuggingInformationEntry, ) -> Option { if let Ok(Some(attr_val)) = entry.attr_value(constants::DW_AT_low_pc) { - match dwarf.attr_address(unit, attr_val) - { + match dwarf.attr_address(unit, attr_val) { Ok(Some(val)) => Some(val), _ => None, } } else if let Ok(Some(attr_val)) = entry.attr_value(constants::DW_AT_entry_pc) { - match dwarf.attr_address(unit, attr_val) - { + match dwarf.attr_address(unit, attr_val) { Ok(Some(val)) => Some(val), _ => None, } } else if let Ok(Some(attr_value)) = entry.attr_value(constants::DW_AT_ranges) { - if let Ok(Some(ranges_offset)) = dwarf.attr_ranges_offset(unit, attr_value) - { - if let Ok(mut ranges) = dwarf.ranges(unit, ranges_offset) - { + if let Ok(Some(ranges_offset)) = dwarf.attr_ranges_offset(unit, attr_value) { + if let Ok(mut ranges) = dwarf.ranges(unit, ranges_offset) { if let Ok(Some(range)) = ranges.next() { return Some(range.begin); } @@ -312,7 +314,7 @@ pub(crate) fn get_attr_as_u64(attr: &Attribute) -> Option 2 => data.read_u16().map(u64::from).ok(), 4 => data.read_u32().map(u64::from).ok(), 8 => data.read_u64().ok(), - _ => None + _ => None, } } else { None @@ -334,24 +336,20 @@ pub(crate) fn get_attr_as_usize(attr: Attribute) -> Option( - unit: &Unit, - attr: Attribute, -) -> Option { +pub(crate) fn get_expr_value(unit: &Unit, attr: Attribute) -> Option { if let AttributeValue::Exprloc(mut expression) = attr.value() { match Operation::parse(&mut expression.0, unit.encoding()) { Ok(Operation::PlusConstant { value }) => Some(value), Ok(Operation::UnsignedConstant { value }) => Some(value), Ok(Operation::Address { address: 0 }) => None, Ok(Operation::Address { address }) => Some(address), - _ => None + _ => None, } } else { None } } - pub(crate) fn get_build_id(view: &BinaryView) -> Result { let mut build_id: Option = None; @@ -362,7 +360,8 @@ pub(crate) fn get_build_id(view: &BinaryView) -> Result { // Type - 4 bytes // Name - n bytes // Desc - n bytes - let build_id_bytes = raw_view.read_vec(build_id_section.start(), build_id_section.len()); + let build_id_bytes = + raw_view.read_vec(build_id_section.start(), build_id_section.len()); if build_id_bytes.len() < 12 { return Err("Build id section must be at least 12 bytes".to_string()); } @@ -375,7 +374,7 @@ pub(crate) fn get_build_id(view: &BinaryView) -> Result { name_len = u32::from_le_bytes(build_id_bytes[0..4].try_into().unwrap()); desc_len = u32::from_le_bytes(build_id_bytes[4..8].try_into().unwrap()); note_type = u32::from_le_bytes(build_id_bytes[8..12].try_into().unwrap()); - }, + } Endianness::BigEndian => { name_len = u32::from_be_bytes(build_id_bytes[0..4].try_into().unwrap()); desc_len = u32::from_be_bytes(build_id_bytes[4..8].try_into().unwrap()); @@ -390,24 +389,29 @@ pub(crate) fn get_build_id(view: &BinaryView) -> Result { let expected_len = (12 + name_len + desc_len) as usize; if build_id_bytes.len() < expected_len { - return Err(format!("Build id section not expected length: expected {}, got {}", expected_len, build_id_bytes.len())); + return Err(format!( + "Build id section not expected length: expected {}, got {}", + expected_len, + build_id_bytes.len() + )); } - let desc: &[u8] = &build_id_bytes[(12+name_len as usize)..expected_len]; + let desc: &[u8] = &build_id_bytes[(12 + name_len as usize)..expected_len]; build_id = Some(desc.iter().map(|b| format!("{:02x}", b)).collect()); } } if let Some(x) = build_id { Ok(x) - } - else { + } else { Err("Failed to get build id".to_string()) } } - -pub(crate) fn download_debug_info(build_id: &String, view: &BinaryView) -> Result, String> { +pub(crate) fn download_debug_info( + build_id: &String, + view: &BinaryView, +) -> Result, String> { let settings = Settings::new(""); let debug_server_urls = settings.get_string_list("network.debuginfodServers", Some(view), None); @@ -477,22 +481,18 @@ pub(crate) fn download_debug_info(build_id: &String, view: &BinaryView) -> Resul return Err("Could not find a server with debug info for this file".to_string()); } - pub(crate) fn find_local_debug_file(build_id: &String, view: &BinaryView) -> Option { let settings = Settings::new(""); - let debug_info_paths = settings.get_string_list("analysis.debugInfo.debugDirectories", Some(view), None); + let debug_info_paths = + settings.get_string_list("analysis.debugInfo.debugDirectories", Some(view), None); if debug_info_paths.is_empty() { - return None + return None; } for debug_info_path in debug_info_paths.into_iter() { - if let Ok(path) = PathBuf::from_str(&debug_info_path.to_string()) - { - let elf_path = path - .join(&build_id[..2]) - .join(&build_id[2..]) - .join("elf"); + if let Ok(path) = PathBuf::from_str(&debug_info_path.to_string()) { + let elf_path = path.join(&build_id[..2]).join(&build_id[2..]).join("elf"); let debug_ext_path = path .join(&build_id[..2]) @@ -500,40 +500,33 @@ pub(crate) fn find_local_debug_file(build_id: &String, view: &BinaryView) -> Opt let final_path = if debug_ext_path.exists() { debug_ext_path - } - else if elf_path.exists() { + } else if elf_path.exists() { elf_path - } - else { + } else { // No paths exist in this dir, try the next one continue; }; - return final_path - .to_str() - .and_then(|x| Some(x.to_string())); + return final_path.to_str().and_then(|x| Some(x.to_string())); } } None } - -pub(crate) fn load_debug_info_for_build_id(build_id: &String, view: &BinaryView) -> (Option>, bool) { +pub(crate) fn load_debug_info_for_build_id( + build_id: &String, + view: &BinaryView, +) -> (Option>, bool) { if let Some(debug_file_path) = find_local_debug_file(build_id, view) { - return - ( + return ( binaryninja::load_with_options( debug_file_path, false, - Some("{\"analysis.debugInfo.internal\": false}") + Some("{\"analysis.debugInfo.internal\": false}"), ), - false - ); - } - else if Settings::new("").get_bool("network.enableDebuginfod", Some(view), None) { - return ( - download_debug_info(build_id, view).ok(), - true + false, ); + } else if Settings::new("").get_bool("network.enableDebuginfod", Some(view), None) { + return (download_debug_info(build_id, view).ok(), true); } (None, false) } diff --git a/rust/examples/dwarf/dwarf_import/src/lib.rs b/rust/examples/dwarf/dwarf_import/src/lib.rs index 78c99123d..c723b74df 100644 --- a/rust/examples/dwarf/dwarf_import/src/lib.rs +++ b/rust/examples/dwarf/dwarf_import/src/lib.rs @@ -37,22 +37,22 @@ use dwarfreader::{ create_section_reader, get_endian, is_dwo_dwarf, is_non_dwo_dwarf, is_raw_dwo_dwarf, }; -use gimli::{constants, DebuggingInformationEntry, Dwarf, DwarfFileType, Reader, Section, SectionId, Unit, UnwindSection}; +use gimli::{ + constants, DebuggingInformationEntry, Dwarf, DwarfFileType, Reader, Section, SectionId, Unit, + UnwindSection, +}; use helpers::{get_build_id, load_debug_info_for_build_id}; use log::{error, warn, LevelFilter}; - trait ReaderType: Reader {} impl> ReaderType for T {} - fn recover_names( dwarf: &Dwarf, debug_info_builder_context: &mut DebugInfoBuilderContext, progress: &dyn Fn(usize, usize) -> Result<(), ()>, ) -> bool { - let mut res = true; if let Some(sup_dwarf) = dwarf.sup() { res = recover_names_internal(sup_dwarf, debug_info_builder_context, progress); @@ -242,33 +242,50 @@ fn parse_unit( if let Some((_fn_idx, depth)) = functions_by_depth.last() { if current_depth <= *depth { functions_by_depth.pop(); + } else { + break; } - else { - break - } - } - else { + } else { break; } } match entry.tag() { constants::DW_TAG_subprogram => { - let fn_idx = parse_function_entry(dwarf, unit, entry, debug_info_builder_context, debug_info_builder); + let fn_idx = parse_function_entry( + dwarf, + unit, + entry, + debug_info_builder_context, + debug_info_builder, + ); functions_by_depth.push((fn_idx, current_depth)); - }, + } constants::DW_TAG_variable => { let current_fn_idx = functions_by_depth.last().and_then(|x| x.0); - parse_variable(dwarf, unit, entry, debug_info_builder_context, debug_info_builder, current_fn_idx) - }, - constants::DW_TAG_class_type | - constants::DW_TAG_enumeration_type | - constants::DW_TAG_structure_type | - constants::DW_TAG_union_type | - constants::DW_TAG_typedef => { + parse_variable( + dwarf, + unit, + entry, + debug_info_builder_context, + debug_info_builder, + current_fn_idx, + ) + } + constants::DW_TAG_class_type + | constants::DW_TAG_enumeration_type + | constants::DW_TAG_structure_type + | constants::DW_TAG_union_type + | constants::DW_TAG_typedef => { // Ensure types are loaded even if they're unused - types::get_type(dwarf, unit, entry, debug_info_builder_context, debug_info_builder); - }, + types::get_type( + dwarf, + unit, + entry, + debug_info_builder_context, + debug_info_builder, + ); + } _ => (), } } @@ -281,16 +298,28 @@ fn parse_eh_frame( eh_frame.set_address_size(view.address_size() as u8); let mut bases = gimli::BaseAddresses::default(); - if let Ok(section) = view.section_by_name(".eh_frame_hdr").or(view.section_by_name("__eh_frame_hdr")) { + if let Ok(section) = view + .section_by_name(".eh_frame_hdr") + .or(view.section_by_name("__eh_frame_hdr")) + { bases = bases.set_eh_frame_hdr(section.start()); } - if let Ok(section) = view.section_by_name(".eh_frame").or(view.section_by_name("__eh_frame")) { + if let Ok(section) = view + .section_by_name(".eh_frame") + .or(view.section_by_name("__eh_frame")) + { bases = bases.set_eh_frame(section.start()); } - if let Ok(section) = view.section_by_name(".text").or(view.section_by_name("__text")) { + if let Ok(section) = view + .section_by_name(".text") + .or(view.section_by_name("__text")) + { bases = bases.set_text(section.start()); } - if let Ok(section) = view.section_by_name(".got").or(view.section_by_name("__got")) { + if let Ok(section) = view + .section_by_name(".got") + .or(view.section_by_name("__got")) + { bases = bases.set_got(section.start()); } @@ -324,8 +353,8 @@ fn parse_eh_frame( // Store CIE offset for FDE range cie_data_offsets.insert( - fde.initial_address()..fde.initial_address()+fde.len(), - fde.cie().data_alignment_factor() + fde.initial_address()..fde.initial_address() + fde.len(), + fde.cie().data_alignment_factor(), ); } } @@ -347,11 +376,8 @@ fn get_supplementary_build_id(bv: &BinaryView) -> Option { .read_vec(start, len) .splitn(2, |x| *x == 0) .last() - .map(|a| { - a.iter().map(|b| format!("{:02x}", b)).collect() - }) - } - else { + .map(|a| a.iter().map(|b| format!("{:02x}", b)).collect()) + } else { None } } @@ -384,28 +410,29 @@ fn parse_dwarf( let mut dwarf = Dwarf::load(&mut section_reader).unwrap(); if dwo_file { dwarf.file_type = DwarfFileType::Dwo; - } - else { + } else { dwarf.file_type = DwarfFileType::Main; } if let Some(sup_bv) = supplementary_bv { let sup_endian = get_endian(sup_bv); let sup_dwo_file = is_dwo_dwarf(sup_bv) || is_raw_dwo_dwarf(sup_bv); - let sup_section_reader = - |section_id: SectionId| -> _ { create_section_reader(section_id, sup_bv, sup_endian, sup_dwo_file) }; + let sup_section_reader = |section_id: SectionId| -> _ { + create_section_reader(section_id, sup_bv, sup_endian, sup_dwo_file) + }; if let Err(e) = dwarf.load_sup(sup_section_reader) { error!("Failed to load supplementary file: {}", e); } } let eh_frame_endian = get_endian(bv); - let mut eh_frame_section_reader = - |section_id: SectionId| -> _ { create_section_reader(section_id, bv, eh_frame_endian, dwo_file) }; + let mut eh_frame_section_reader = |section_id: SectionId| -> _ { + create_section_reader(section_id, bv, eh_frame_endian, dwo_file) + }; let eh_frame = gimli::EhFrame::load(&mut eh_frame_section_reader).unwrap(); - let range_data_offsets = parse_eh_frame(bv, eh_frame) - .map_err(|e| error!("Error parsing .eh_frame: {}", e))?; + let range_data_offsets = + parse_eh_frame(bv, eh_frame).map_err(|e| error!("Error parsing .eh_frame: {}", e))?; // Create debug info builder and recover name mapping first // Since DWARF is stored as a tree with arbitrary implicit edges among leaves, @@ -475,33 +502,26 @@ impl CustomDebugInfoParser for DWARFParser { let (external_file, close_external) = if !dwarfreader::is_valid(bv) { if let Ok(build_id) = get_build_id(bv) { helpers::load_debug_info_for_build_id(&build_id, bv) - } - else { + } else { (None, false) } - } - else { + } else { (None, false) }; - let sup_bv = get_supplementary_build_id( - external_file - .as_deref() - .unwrap_or(debug_file) - ) + let sup_bv = get_supplementary_build_id(external_file.as_deref().unwrap_or(debug_file)) .and_then(|build_id| { load_debug_info_for_build_id(&build_id, bv) - .0 - .map(|x| x.raw_view().unwrap()) + .0 + .map(|x| x.raw_view().unwrap()) }); let result = match parse_dwarf( bv, external_file.as_deref().unwrap_or(debug_file), sup_bv.as_deref(), - progress - ) - { + progress, + ) { Ok(mut builder) => { builder.post_process(bv, debug_info).commit_info(debug_info); true diff --git a/rust/examples/dwarf/dwarf_import/src/types.rs b/rust/examples/dwarf/dwarf_import/src/types.rs index 35794e36f..a678c654c 100644 --- a/rust/examples/dwarf/dwarf_import/src/types.rs +++ b/rust/examples/dwarf/dwarf_import/src/types.rs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{die_handlers::*, ReaderType}; use crate::dwarfdebuginfo::{DebugInfoBuilder, DebugInfoBuilderContext, TypeUID}; use crate::helpers::*; +use crate::{die_handlers::*, ReaderType}; use binaryninja::{ rc::*, @@ -36,20 +36,26 @@ pub(crate) fn parse_variable( function_index: Option, ) { let full_name = debug_info_builder_context.get_name(dwarf, unit, entry); - let type_uid = get_type(dwarf, unit, entry, debug_info_builder_context, debug_info_builder); + let type_uid = get_type( + dwarf, + unit, + entry, + debug_info_builder_context, + debug_info_builder, + ); let Ok(Some(attr)) = entry.attr(constants::DW_AT_location) else { - return + return; }; let AttributeValue::Exprloc(mut expression) = attr.value() else { - return + return; }; match Operation::parse(&mut expression.0, unit.encoding()) { Ok(Operation::FrameOffset { offset }) => { debug_info_builder.add_stack_variable(function_index, offset, full_name, type_uid); - }, + } //Ok(Operation::RegisterOffset { register: _, offset: _, base_type: _ }) => { // //TODO: look up register by index (binja register indexes don't match processor indexes?) // //TODO: calculate absolute stack offset @@ -59,11 +65,14 @@ pub(crate) fn parse_variable( if let Some(uid) = type_uid { debug_info_builder.add_data_variable(address, full_name, uid) } - }, + } Ok(op) => { debug!("Unhandled operation type for variable: {:?}", op); - }, - Err(e) => error!("Error parsing operation type for variable {:?}: {}", full_name, e) + } + Err(e) => error!( + "Error parsing operation type for variable {:?}: {}", + full_name, e + ), } } @@ -255,15 +264,13 @@ pub(crate) fn get_type( ) { // This needs to recurse first (before the early return below) to ensure all sub-types have been parsed match die_reference { - DieReference::UnitAndOffset((dwarf, entry_unit, entry_offset)) => { - get_type( - dwarf, - entry_unit, - &entry_unit.entry(entry_offset).unwrap(), - debug_info_builder_context, - debug_info_builder, - ) - } + DieReference::UnitAndOffset((dwarf, entry_unit, entry_offset)) => get_type( + dwarf, + entry_unit, + &entry_unit.entry(entry_offset).unwrap(), + debug_info_builder_context, + debug_info_builder, + ), DieReference::Err => { warn!("Failed to fetch DIE when getting type through DW_AT_type. Debug information may be incomplete."); None @@ -286,7 +293,9 @@ pub(crate) fn get_type( } DieReference::UnitAndOffset(_) => None, DieReference::Err => { - warn!("Failed to fetch DIE when getting type. Debug information may be incomplete."); + warn!( + "Failed to fetch DIE when getting type. Debug information may be incomplete." + ); None } } @@ -338,9 +347,10 @@ pub(crate) fn get_type( } // Enum - constants::DW_TAG_enumeration_type => { - (handle_enum(dwarf, unit, entry, debug_info_builder_context), true) - } + constants::DW_TAG_enumeration_type => ( + handle_enum(dwarf, unit, entry, debug_info_builder_context), + true, + ), // Basic types constants::DW_TAG_typedef => { diff --git a/rust/examples/dwarf/shared/src/lib.rs b/rust/examples/dwarf/shared/src/lib.rs index 7a957c6b7..2f0225daf 100644 --- a/rust/examples/dwarf/shared/src/lib.rs +++ b/rust/examples/dwarf/shared/src/lib.rs @@ -19,8 +19,8 @@ use binaryninja::binaryninjacore_sys::*; use binaryninja::{ binaryview::{BinaryView, BinaryViewBase, BinaryViewExt}, databuffer::DataBuffer, - Endianness, settings::Settings, + Endianness, }; use std::{ffi::CString, rc::Rc}; @@ -54,14 +54,13 @@ pub fn is_raw_dwo_dwarf(view: &BinaryView) -> bool { } pub fn can_use_debuginfod(view: &BinaryView) -> bool { - has_build_id_section(view) && - Settings::new("") - .get_bool("network.enableDebuginfod", Some(view), None) + has_build_id_section(view) + && Settings::new("").get_bool("network.enableDebuginfod", Some(view), None) } pub fn has_build_id_section(view: &BinaryView) -> bool { if let Ok(raw_view) = view.raw_view() { - return raw_view.section_by_name(".note.gnu.build-id").is_ok() + return raw_view.section_by_name(".note.gnu.build-id").is_ok(); } false } @@ -114,22 +113,20 @@ pub fn create_section_reader<'a, Endian: 'a + Endianity>( .find(|section_header| { if view.address_size() == 4 { endian.read_u32(§ion_header[16..20]) as u64 == section.start() - } - else { + } else { endian.read_u64(§ion_header[24..32]) == section.start() } }) { let section_flags = if view.address_size() == 4 { endian.read_u32(¤t_section_header[8..12]) as u64 - } - else { + } else { endian.read_u64(¤t_section_header[8..16]) }; // If the section has the compressed bit set if (section_flags & 2048) != 0 { // Get section, trim header, decompress, return - let compressed_header_size = view.address_size()*3; + let compressed_header_size = view.address_size() * 3; let offset = section.start() + compressed_header_size as u64; let len = section.len() - compressed_header_size; diff --git a/rust/examples/pdb-ng/src/lib.rs b/rust/examples/pdb-ng/src/lib.rs index e2e3ec444..92c82b4fb 100644 --- a/rust/examples/pdb-ng/src/lib.rs +++ b/rust/examples/pdb-ng/src/lib.rs @@ -372,11 +372,8 @@ impl PDBParser { if check_guid { return Err(anyhow!("PDB GUID does not match")); } else { - let ask = settings.get_string( - "pdb.features.loadMismatchedPDB", - Some(view), - None, - ); + let ask = + settings.get_string("pdb.features.loadMismatchedPDB", Some(view), None); match ask.as_str() { "true" => {}, @@ -487,11 +484,7 @@ impl PDBParser { if check_guid { return Err(anyhow!("File not compiled with PDB information")); } else { - let ask = settings.get_string( - "pdb.features.loadMismatchedPDB", - Some(view), - None, - ); + let ask = settings.get_string("pdb.features.loadMismatchedPDB", Some(view), None); match ask.as_str() { "true" => {}, diff --git a/rust/examples/pdb-ng/src/parser.rs b/rust/examples/pdb-ng/src/parser.rs index 2d56a76d1..7e3d8a721 100644 --- a/rust/examples/pdb-ng/src/parser.rs +++ b/rust/examples/pdb-ng/src/parser.rs @@ -210,8 +210,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { type_, .. }) => { - let real_type = - type_.as_ref().unwrap_or(&min_confidence_type); + let real_type = type_.as_ref().unwrap_or(&min_confidence_type); if real_type.contents.type_class() == TypeClass::VoidTypeClass { if !allow_void { @@ -289,9 +288,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { unknown_names: &mut HashMap, ) { let used_name = name.name().to_string(); - if let Some(&found) = - unknown_names.get(&used_name) - { + if let Some(&found) = unknown_names.get(&used_name) { if found != name.class() { // Interesting case, not sure we care self.log(|| { @@ -457,9 +454,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { /// Lazy logging function that prints like 20MB of messages pub(crate) fn log D, D: Display>(&self, msg: F) { static MEM: OnceLock = OnceLock::new(); - let debug_pdb = MEM.get_or_init(|| { - env::var("BN_DEBUG_PDB").is_ok() - }); + let debug_pdb = MEM.get_or_init(|| env::var("BN_DEBUG_PDB").is_ok()); if *debug_pdb { let space = "\t".repeat(self.type_stack.len()) + &"\t".repeat(self.symbol_stack.len()); let msg = format!("{}", msg()); diff --git a/rust/examples/pdb-ng/src/type_parser.rs b/rust/examples/pdb-ng/src/type_parser.rs index caf732b25..41177c0cc 100644 --- a/rust/examples/pdb-ng/src/type_parser.rs +++ b/rust/examples/pdb-ng/src/type_parser.rs @@ -413,13 +413,9 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { } static MEM: OnceLock = OnceLock::new(); - let uint_regex = MEM.get_or_init(|| { - Regex::new(r"u?int\d+_t").unwrap() - }); + let uint_regex = MEM.get_or_init(|| Regex::new(r"u?int\d+_t").unwrap()); - let float_regex = MEM.get_or_init(|| { - Regex::new(r"float\d+").unwrap() - }); + let float_regex = MEM.get_or_init(|| Regex::new(r"float\d+").unwrap()); let mut remove_names = vec![]; for (name, _) in &self.named_types { diff --git a/rust/src/binaryview.rs b/rust/src/binaryview.rs index b20bc59c4..4cdcaba61 100644 --- a/rust/src/binaryview.rs +++ b/rust/src/binaryview.rs @@ -268,15 +268,11 @@ pub trait BinaryViewExt: BinaryViewBase { } fn original_image_base(&self) -> u64 { - unsafe { - BNGetOriginalImageBase(self.as_ref().handle) - } + unsafe { BNGetOriginalImageBase(self.as_ref().handle) } } fn set_original_image_base(&self, image_base: u64) { - unsafe { - BNSetOriginalImageBase(self.as_ref().handle, image_base) - } + unsafe { BNSetOriginalImageBase(self.as_ref().handle, image_base) } } fn end(&self) -> u64 { @@ -562,9 +558,9 @@ pub trait BinaryViewExt: BinaryViewBase { } fn data_variable_at_address(&self, addr: u64) -> Option> { - let dv = BNDataVariable::default(); + let mut dv = BNDataVariable::default(); unsafe { - if BNGetDataVariableAtAddress(self.as_ref().handle, addr, std::mem::transmute(&dv)) { + if BNGetDataVariableAtAddress(self.as_ref().handle, addr, &mut dv) { Some(DataVariable(dv).to_owned()) } else { None @@ -1411,10 +1407,7 @@ pub trait BinaryViewExt: BinaryViewBase { unsafe { BNRemoveComponentByGuid(self.as_ref().handle, path.as_ptr()) } } - fn data_variable_parent_components( - &self, - data_variable: &DataVariable, - ) -> Array { + fn data_variable_parent_components(&self, data_variable: &DataVariable) -> Array { let mut count = 0; let result = unsafe { BNGetDataVariableParentComponents( diff --git a/rust/src/callingconvention.rs b/rust/src/callingconvention.rs index a009b439e..8ffff80fe 100644 --- a/rust/src/callingconvention.rs +++ b/rust/src/callingconvention.rs @@ -25,9 +25,7 @@ use std::slice; use binaryninjacore_sys::*; use crate::architecture::{Architecture, ArchitectureExt, CoreArchitecture, Register}; -use crate::rc::{ - CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable, -}; +use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; use crate::string::*; // TODO diff --git a/rust/src/component.rs b/rust/src/component.rs index ec2350436..43b482146 100644 --- a/rust/src/component.rs +++ b/rust/src/component.rs @@ -1,4 +1,4 @@ -use core::{ffi, mem, ptr}; +use core::{ffi, ptr}; use crate::binaryview::{BinaryView, BinaryViewBase, BinaryViewExt}; use crate::function::Function; @@ -76,7 +76,7 @@ impl Component { pub(crate) unsafe fn ref_from_raw(handle: &*mut BNComponent) -> &Self { assert!(!handle.is_null()); - mem::transmute(handle) + &*(handle as *const _ as *const Self) } pub fn guid(&self) -> BnString { diff --git a/rust/src/database.rs b/rust/src/database.rs index 09cdde549..dbc07dc6d 100644 --- a/rust/src/database.rs +++ b/rust/src/database.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use std::{ffi, mem, ptr}; +use std::{ffi, ptr}; use binaryninjacore_sys::*; @@ -232,7 +232,7 @@ impl Snapshot { } pub(crate) unsafe fn ref_from_raw(handle: &*mut BNSnapshot) -> &Self { - mem::transmute(handle) + &*(handle as *const _ as *const Self) } #[allow(clippy::mut_from_ref)] @@ -520,7 +520,7 @@ impl UndoEntry { } pub(crate) unsafe fn ref_from_raw(handle: &*mut BNUndoEntry) -> &Self { - mem::transmute(handle) + &*(handle as *const _ as *const Self) } #[allow(clippy::mut_from_ref)] @@ -588,7 +588,7 @@ impl UndoAction { } pub(crate) unsafe fn ref_from_raw(handle: &*mut BNUndoAction) -> &Self { - mem::transmute(handle) + &*(handle as *const _ as *const Self) } #[allow(clippy::mut_from_ref)] diff --git a/rust/src/debuginfo.rs b/rust/src/debuginfo.rs index 2b43c9cc7..1ce404e5e 100644 --- a/rust/src/debuginfo.rs +++ b/rust/src/debuginfo.rs @@ -311,14 +311,11 @@ impl From<&BNDebugFunctionInfo> for DebugFunctionInfo { .map(|component| raw_to_string(*component as *const _).unwrap()) .collect(); - let local_variables: Vec = unsafe { slice::from_raw_parts(raw.localVariables, raw.localVariableN) } - .iter() - .map(|local_variable| { - unsafe { - NamedTypedVariable::from_raw(local_variable) - } - }) - .collect(); + let local_variables: Vec = + unsafe { slice::from_raw_parts(raw.localVariables, raw.localVariableN) } + .iter() + .map(|local_variable| unsafe { NamedTypedVariable::from_raw(local_variable) }) + .collect(); Self { short_name: raw_to_string(raw.shortName), @@ -433,10 +430,7 @@ impl DebugInfo { } /// Returns a generator of all functions provided by a named DebugInfoParser - pub fn functions_by_name( - &self, - parser_name: S - ) -> Vec { + pub fn functions_by_name(&self, parser_name: S) -> Vec { let parser_name = parser_name.into_bytes_with_nul(); let mut count: usize = 0; @@ -790,25 +784,26 @@ impl DebugInfo { let mut components_array: Vec<*mut ::std::os::raw::c_char> = Vec::with_capacity(new_func.components.len()); - let mut local_variables_array: Vec = Vec::with_capacity(new_func.local_variables.len()); unsafe { for component in &new_func.components { - components_array.push(BNAllocString(component.clone().into_bytes_with_nul().as_ptr() as _)); + components_array.push(BNAllocString( + component.clone().into_bytes_with_nul().as_ptr() as _, + )); } for local_variable in &new_func.local_variables { - local_variables_array.push( - BNVariableNameAndType { - var: local_variable.var.raw(), - autoDefined: local_variable.auto_defined, - typeConfidence: local_variable.ty.confidence, - name: BNAllocString(local_variable.name.clone().into_bytes_with_nul().as_ptr() as _), - type_: local_variable.ty.contents.handle, - } - ); + local_variables_array.push(BNVariableNameAndType { + var: local_variable.var.raw(), + autoDefined: local_variable.auto_defined, + typeConfidence: local_variable.ty.confidence, + name: BNAllocString( + local_variable.name.clone().into_bytes_with_nul().as_ptr() as _ + ), + type_: local_variable.ty.contents.handle, + }); } let result = BNAddDebugFunction( diff --git a/rust/src/demangle.rs b/rust/src/demangle.rs index 1b940ff91..636696939 100644 --- a/rust/src/demangle.rs +++ b/rust/src/demangle.rs @@ -26,10 +26,7 @@ use crate::rc::*; pub type Result = result::Result; -pub fn demangle_llvm( - mangled_name: S, - simplify: bool, -) -> Result> { +pub fn demangle_llvm(mangled_name: S, simplify: bool) -> Result> { let mangled_name_bwn = mangled_name.into_bytes_with_nul(); let mangled_name_ptr = mangled_name_bwn.as_ref(); let mut out_name: *mut *mut std::os::raw::c_char = unsafe { std::mem::zeroed() }; diff --git a/rust/src/disassembly.rs b/rust/src/disassembly.rs index 5d3da31e0..23d660c0a 100644 --- a/rust/src/disassembly.rs +++ b/rust/src/disassembly.rs @@ -100,7 +100,7 @@ pub enum InstructionTextTokenContents { impl InstructionTextToken { pub(crate) unsafe fn from_raw(raw: &BNInstructionTextToken) -> &Self { - mem::transmute(raw) + &*(raw as *const _ as *const Self) } pub(crate) fn into_raw(self) -> BNInstructionTextToken { @@ -279,7 +279,7 @@ unsafe impl CoreArrayProviderInner for InstructionTextToken { BNFreeInstructionText(raw, count) } unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> { - core::mem::transmute(raw) + Self::from_raw(raw) } } @@ -382,7 +382,9 @@ impl From<&Vec<&str>> for DisassemblyTextLine { fn from(string_tokens: &Vec<&str>) -> Self { let mut tokens: Box<[BNInstructionTextToken]> = string_tokens .iter() - .map(|&token| InstructionTextToken::new(token, InstructionTextTokenContents::Text).into_raw()) + .map(|&token| { + InstructionTextToken::new(token, InstructionTextTokenContents::Text).into_raw() + }) .collect(); // let (tokens_pointer, tokens_len, _) = unsafe { tokens.into_raw_parts() }; // Can't use for now...still a rust nighly feature @@ -466,7 +468,7 @@ unsafe impl CoreArrayProviderInner for DisassemblyTextLine { BNFreeDisassemblyTextLines(raw, count) } unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> { - core::mem::transmute(raw) + &*(raw as *const _ as *const Self) } } diff --git a/rust/src/downloadprovider.rs b/rust/src/downloadprovider.rs index 0d388486e..e98c287ea 100644 --- a/rust/src/downloadprovider.rs +++ b/rust/src/downloadprovider.rs @@ -1,4 +1,4 @@ -use crate::rc::{Array, CoreArrayProvider, Guard, CoreArrayProviderInner, Ref, RefCountable}; +use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; use crate::settings::Settings; use crate::string::{BnStrCompatible, BnString}; use binaryninjacore_sys::*; diff --git a/rust/src/externallibrary.rs b/rust/src/externallibrary.rs index a5dcefc8c..fcf95ac2f 100644 --- a/rust/src/externallibrary.rs +++ b/rust/src/externallibrary.rs @@ -1,4 +1,4 @@ -use core::{ffi, mem, ptr}; +use core::{ffi, ptr}; use binaryninjacore_sys::*; @@ -35,7 +35,7 @@ impl ExternalLibrary { pub(crate) unsafe fn ref_from_raw(handle: &*mut BNExternalLibrary) -> &Self { assert!(!handle.is_null()); - mem::transmute(handle) + &*(handle as *const _ as *const Self) } #[allow(clippy::mut_from_ref)] @@ -60,7 +60,7 @@ impl ExternalLibrary { /// Set the file backing this external library pub fn set_backing_file(&self, file: Option<&ProjectFile>) { let file_handle = file - .map(|x| unsafe {x.as_raw() as *mut _}) + .map(|x| unsafe { x.as_raw() as *mut _ }) .unwrap_or(ptr::null_mut()); unsafe { BNExternalLibrarySetBackingFile(self.as_raw(), file_handle) } } @@ -112,7 +112,7 @@ impl ExternalLocation { pub(crate) unsafe fn ref_from_raw(handle: &*mut BNExternalLocation) -> &Self { assert!(!handle.is_null()); - mem::transmute(handle) + &*(handle as *const _ as *const Self) } #[allow(clippy::mut_from_ref)] @@ -137,7 +137,7 @@ impl ExternalLocation { /// Set the ExternalLibrary that this ExternalLocation targets pub fn set_external_library(&self, lib: Option<&ExternalLibrary>) { let lib_handle = lib - .map(|x| unsafe {x.as_raw() as *mut _}) + .map(|x| unsafe { x.as_raw() as *mut _ }) .unwrap_or(ptr::null_mut()); unsafe { BNExternalLocationSetExternalLibrary(self.as_raw(), lib_handle) } } @@ -183,12 +183,7 @@ impl ExternalLocation { let symbol = symbol .map(|x| x.into_bytes_with_nul().as_ref().as_ptr() as *const ffi::c_char) .unwrap_or(ptr::null_mut()); - unsafe { - BNExternalLocationSetTargetSymbol( - self.as_raw(), - symbol, - ) - } + unsafe { BNExternalLocationSetTargetSymbol(self.as_raw(), symbol) } } } diff --git a/rust/src/filemetadata.rs b/rust/src/filemetadata.rs index 7d385a4c8..08cffecfb 100644 --- a/rust/src/filemetadata.rs +++ b/rust/src/filemetadata.rs @@ -22,12 +22,12 @@ use binaryninjacore_sys::{ BNFreeFileMetadata, BNGetCurrentOffset, BNGetCurrentView, + //BNSetFileMetadataNavigationHandler, + BNGetFileMetadataDatabase, BNGetFileViewOfType, BNGetFilename, BNIsAnalysisChanged, BNIsBackedByDatabase, - //BNSetFileMetadataNavigationHandler, - BNGetFileMetadataDatabase, BNIsFileModified, BNMarkFileModified, BNMarkFileSaved, diff --git a/rust/src/function.rs b/rust/src/function.rs index bfd8b587e..2cc6ef8f4 100644 --- a/rust/src/function.rs +++ b/rust/src/function.rs @@ -40,8 +40,8 @@ pub use binaryninjacore_sys::BNAnalysisSkipReason as AnalysisSkipReason; pub use binaryninjacore_sys::BNFunctionAnalysisSkipOverride as FunctionAnalysisSkipOverride; pub use binaryninjacore_sys::BNFunctionUpdateType as FunctionUpdateType; -use std::{fmt, mem}; use std::{ffi::c_char, hash::Hash, ops::Range}; +use std::{fmt, mem}; pub struct Location { pub arch: Option, @@ -2142,9 +2142,10 @@ impl Function { pub fn parent_components(&self) -> Array { let mut count = 0; - let result = unsafe{ BNGetFunctionParentComponents(self.view().handle, self.handle, &mut count) }; + let result = + unsafe { BNGetFunctionParentComponents(self.view().handle, self.handle, &mut count) }; assert!(!result.is_null()); - unsafe{ Array::new(result, count, ()) } + unsafe { Array::new(result, count, ()) } } } @@ -2241,7 +2242,7 @@ unsafe impl CoreArrayProviderInner for AddressRange { BNFreeAddressRanges(raw); } unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> { - mem::transmute(raw) + &*(raw as *const _ as *const Self) } } diff --git a/rust/src/headless.rs b/rust/src/headless.rs index fdde2608f..3d516f8c0 100644 --- a/rust/src/headless.rs +++ b/rust/src/headless.rs @@ -13,8 +13,7 @@ // limitations under the License. use crate::{ - binaryview, - rc, + binaryview, rc, string::{BnStrCompatible, IntoJson}, }; diff --git a/rust/src/lib.rs b/rust/src/lib.rs index baac888b4..153e70cb6 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -132,15 +132,15 @@ pub mod binaryview; pub mod binarywriter; pub mod callingconvention; pub mod command; +pub mod component; pub mod custombinaryview; pub mod database; pub mod databuffer; pub mod debuginfo; pub mod demangle; pub mod disassembly; -pub mod enterprise; -pub mod component; pub mod downloadprovider; +pub mod enterprise; pub mod externallibrary; pub mod fileaccessor; pub mod filemetadata; @@ -167,8 +167,8 @@ pub mod string; pub mod symbol; pub mod tags; pub mod templatesimplifier; -pub mod typelibrary; pub mod typearchive; +pub mod typelibrary; pub mod types; pub mod update; diff --git a/rust/src/llil/lifting.rs b/rust/src/llil/lifting.rs index f8b8257e8..a8eb150ab 100644 --- a/rust/src/llil/lifting.rs +++ b/rust/src/llil/lifting.rs @@ -610,9 +610,7 @@ where pub fn from_expr(expr: Expression<'a, A, Mutable, NonSSA, R>) -> Self { use binaryninjacore_sys::BNGetLowLevelILByIndex; - let instr = unsafe { - BNGetLowLevelILByIndex(expr.function.handle, expr.expr_idx) - }; + let instr = unsafe { BNGetLowLevelILByIndex(expr.function.handle, expr.expr_idx) }; ExpressionBuilder { function: expr.function, @@ -623,7 +621,7 @@ where op2: instr.operands[1], op3: instr.operands[2], op4: instr.operands[3], - _ty: PhantomData + _ty: PhantomData, } } diff --git a/rust/src/llil/operation.rs b/rust/src/llil/operation.rs index f42b3693b..cda0fe96e 100644 --- a/rust/src/llil/operation.rs +++ b/rust/src/llil/operation.rs @@ -294,10 +294,10 @@ where pub struct RegSplit; impl<'func, A, M, V> Operation<'func, A, M, NonSSA, RegSplit> - where - A: 'func + Architecture, - M: FunctionMutability, - V: NonSSAVariant, +where + A: 'func + Architecture, + M: FunctionMutability, + V: NonSSAVariant, { pub fn size(&self) -> usize { self.op.size diff --git a/rust/src/mlil/instruction.rs b/rust/src/mlil/instruction.rs index 88564cc61..fe3cbcc88 100644 --- a/rust/src/mlil/instruction.rs +++ b/rust/src/mlil/instruction.rs @@ -5,8 +5,8 @@ use crate::disassembly::InstructionTextToken; use crate::operand_iter::OperandIter; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref}; use crate::types::{ - Conf, ConstantData, DataFlowQueryOption, ILBranchDependence, PossibleValueSet, - RegisterValue, RegisterValueType, SSAVariable, Type, Variable, + Conf, ConstantData, DataFlowQueryOption, ILBranchDependence, PossibleValueSet, RegisterValue, + RegisterValueType, SSAVariable, Type, Variable, }; use super::lift::*; diff --git a/rust/src/mlil/operation.rs b/rust/src/mlil/operation.rs index 278d1edb7..37d80717c 100644 --- a/rust/src/mlil/operation.rs +++ b/rust/src/mlil/operation.rs @@ -1,6 +1,9 @@ use std::collections::BTreeMap; -use crate::{architecture::CoreIntrinsic, types::{ConstantData, SSAVariable, Variable}}; +use crate::{ + architecture::CoreIntrinsic, + types::{ConstantData, SSAVariable, Variable}, +}; use super::MediumLevelILLiftedInstruction; diff --git a/rust/src/project.rs b/rust/src/project.rs index a94b42e1e..65af3288b 100644 --- a/rust/src/project.rs +++ b/rust/src/project.rs @@ -1,6 +1,6 @@ +use std::ffi; use std::ptr::{null_mut, NonNull}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use std::{ffi, mem}; use binaryninjacore_sys::*; @@ -20,7 +20,7 @@ impl Project { pub(crate) unsafe fn ref_from_raw(handle: &*mut BNProject) -> &Self { debug_assert!(!handle.is_null()); - mem::transmute(handle) + &*(handle as *const _ as *const Self) } #[allow(clippy::mut_from_ref)] @@ -823,7 +823,7 @@ impl ProjectFolder { pub(crate) unsafe fn ref_from_raw(handle: &*mut BNProjectFolder) -> &Self { debug_assert!(!handle.is_null()); - mem::transmute(handle) + &*(handle as *const _ as *const Self) } #[allow(clippy::mut_from_ref)] @@ -965,7 +965,7 @@ impl ProjectFile { pub(crate) unsafe fn ref_from_raw(handle: &*mut BNProjectFile) -> &Self { debug_assert!(!handle.is_null()); - mem::transmute(handle) + &*(handle as *const _ as *const Self) } #[allow(clippy::mut_from_ref)] @@ -1107,7 +1107,7 @@ unsafe extern "C" fn cb_progress_func bool>( if ctxt.is_null() { return true; } - let closure: &mut F = mem::transmute(ctxt); + let closure = &mut *(ctxt as *mut F); closure(progress, total) } diff --git a/rust/src/relocation.rs b/rust/src/relocation.rs index f9ece0435..5da5c9083 100644 --- a/rust/src/relocation.rs +++ b/rust/src/relocation.rs @@ -500,7 +500,9 @@ where let name = name.into_bytes_with_nul(); - let raw = Box::leak(Box::new(MaybeUninit::>::zeroed())); + let raw = Box::leak(Box::new( + MaybeUninit::>::zeroed(), + )); let mut custom_handler = BNCustomRelocationHandler { context: raw.as_mut_ptr() as *mut _, freeObject: Some(cb_free::), diff --git a/rust/src/typearchive.rs b/rust/src/typearchive.rs index 71a7058e9..1d8ba1863 100644 --- a/rust/src/typearchive.rs +++ b/rust/src/typearchive.rs @@ -58,7 +58,7 @@ impl TypeArchive { pub(crate) unsafe fn ref_from_raw(handle: &*mut BNTypeArchive) -> &Self { assert!(!handle.is_null()); - mem::transmute(handle) + &*(handle as *const _ as *const Self) } #[allow(clippy::mut_from_ref)] @@ -205,10 +205,12 @@ impl TypeArchive { /// /// * `new_types` - Names and definitions of new types pub fn add_types(&self, new_types: &[QualifiedNameAndType]) { - // SAFETY BNQualifiedNameAndType and QualifiedNameAndType are transparent - let new_types_raw: &[BNQualifiedNameAndType] = unsafe { mem::transmute(new_types) }; let result = unsafe { - BNAddTypeArchiveTypes(self.as_raw(), new_types_raw.as_ptr(), new_types.len()) + BNAddTypeArchiveTypes( + self.as_raw(), + new_types.as_ptr() as *const _, + new_types.len(), + ) }; assert!(result); } diff --git a/rust/src/typelibrary.rs b/rust/src/typelibrary.rs index a0992e185..57f47ddd7 100644 --- a/rust/src/typelibrary.rs +++ b/rust/src/typelibrary.rs @@ -1,6 +1,6 @@ use binaryninjacore_sys::*; -use core::{ffi, mem, ptr}; +use core::{ffi, ptr}; use crate::{ architecture::CoreArchitecture, @@ -23,7 +23,7 @@ impl TypeLibrary { pub(crate) unsafe fn ref_from_raw(handle: &*mut BNTypeLibrary) -> &Self { assert!(!handle.is_null()); - mem::transmute(handle) + &*(handle as *const _ as *const Self) } #[allow(clippy::mut_from_ref)] diff --git a/rust/src/types.rs b/rust/src/types.rs index 1c8071e8c..056b8eab1 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -1354,7 +1354,7 @@ unsafe impl CoreArrayProviderInner for ComponentReferencedTypes { unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> { // SAFETY: BNType and Type are trasparent - core::mem::transmute(raw) + &*(raw as *const _ as *const Type) } } @@ -1475,7 +1475,7 @@ unsafe impl CoreArrayProviderInner for (&str, Variable, &Type) { ) -> (&'a str, Variable, &'a Type) { let name = CStr::from_ptr(raw.name).to_str().unwrap(); let var = Variable::from_raw(raw.var); - let var_type = core::mem::transmute(&raw.type_); + let var_type = &*(&raw.type_ as *const _ as *const Type); (name, var, var_type) } } @@ -2422,6 +2422,10 @@ impl Debug for NamedTypeReference { pub struct QualifiedName(pub(crate) BNQualifiedName); impl QualifiedName { + fn ref_from_raw(handle: &BNQualifiedName) -> &Self { + unsafe { &*(handle as *const _ as *const Self) } + } + // TODO : I think this is bad pub fn string(&self) -> String { unsafe { @@ -2544,7 +2548,7 @@ unsafe impl CoreArrayProviderInner for QualifiedName { BNFreeTypeNameList(raw, count); } unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> { - mem::transmute(raw) + Self::ref_from_raw(raw) } } @@ -2556,7 +2560,7 @@ pub struct QualifiedNameAndType(pub(crate) BNQualifiedNameAndType); impl QualifiedNameAndType { pub fn name(&self) -> &QualifiedName { - unsafe { mem::transmute(&self.0.name) } + QualifiedName::ref_from_raw(&self.0.name) } pub fn type_object(&self) -> Guard { @@ -2582,7 +2586,7 @@ unsafe impl CoreArrayProviderInner for QualifiedNameAndType { BNFreeTypeAndNameList(raw, count); } unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> { - mem::transmute(raw) + &*(raw as *const _ as *const Self) } } @@ -2594,7 +2598,7 @@ pub struct QualifiedNameTypeAndId(pub(crate) BNQualifiedNameTypeAndId); impl QualifiedNameTypeAndId { pub fn name(&self) -> &QualifiedName { - unsafe { mem::transmute(&self.0.name) } + QualifiedName::ref_from_raw(&self.0.name) } pub fn id(&self) -> &str { @@ -2624,7 +2628,7 @@ unsafe impl CoreArrayProviderInner for QualifiedNameTypeAndId { BNFreeTypeIdList(raw, count); } unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> { - mem::transmute(raw) + &*(raw as *const _ as *const Self) } } @@ -2656,7 +2660,7 @@ impl NameAndType { } pub fn t(&self) -> &Type { - unsafe { mem::transmute::<_, &Type>(&self.0.type_) } + unsafe { &*(&self.0.type_ as *const _ as *const Type) } } pub fn type_with_confidence(&self) -> Conf<&Type> { @@ -2730,7 +2734,7 @@ impl DataVariable { } pub fn t(&self) -> &Type { - unsafe { mem::transmute(&self.0.type_) } + unsafe { &*(&self.0.type_ as *const _ as *const Type) } } pub fn type_with_confidence(&self) -> Conf<&Type> { @@ -2775,7 +2779,7 @@ unsafe impl CoreArrayProviderInner for DataVariable { BNFreeDataVariables(raw, count); } unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> { - mem::transmute(raw) + &*(raw as *const _ as *const Self) } } diff --git a/rust/src/update.rs b/rust/src/update.rs index 026316f50..921e3a344 100644 --- a/rust/src/update.rs +++ b/rust/src/update.rs @@ -1,4 +1,4 @@ -use core::{ffi, mem, ptr}; +use core::{ffi, ptr}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use binaryninjacore_sys::*; @@ -19,7 +19,7 @@ pub struct UpdateChannel { impl UpdateChannel { pub(crate) unsafe fn ref_from_raw(handle: &BNUpdateChannel) -> &Self { - mem::transmute(handle) + &*(handle as *const _ as *const Self) } pub fn all() -> Result, BnString> { @@ -190,7 +190,7 @@ pub struct UpdateVersion { impl UpdateVersion { pub(crate) unsafe fn ref_from_raw(handle: &BNUpdateVersion) -> &Self { - mem::transmute(handle) + &*(handle as *const _ as *const Self) } pub fn time(&self) -> SystemTime {