From d3140edec185f47235b9e4642bdd56d6c585a341 Mon Sep 17 00:00:00 2001 From: Ryan Snyder Date: Thu, 21 Jan 2021 18:27:48 +0000 Subject: This is a combination of 23 commits, the work of Ryan Snyder: Initial fresh repo Add support for recent calling convention API updates and folds the binaryninjacore-sys crate directly into this one. Add support for auto function analysis suppression Finish moving binaryninjacore-sys back into this crate Update for Symbol/Segment core API changes Update for Symbol API cleanup api: advance submodule reference, support Token changes arch/lifting: support for flags in custom architectures arch/lifting: support default flag write behaviors, handle more ops build: enable headless binary support on MacOS via evil hack bv: add BinaryView wrapper support, remove wrong comment api: update to latest binja dev branch support deps: bump dep versions rust: bump to 2018 edition api: bump to avoid cargo submodule brokenness build: improve binaryninja path detection; enable linux linkhack bv: stub for bv load settings arch: fix flag related crash, minor llil update api: update for recent changes macos: disable linkhack briefly --- rust/src/symbol.rs | 241 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 rust/src/symbol.rs (limited to 'rust/src/symbol.rs') diff --git a/rust/src/symbol.rs b/rust/src/symbol.rs new file mode 100644 index 00000000..44021426 --- /dev/null +++ b/rust/src/symbol.rs @@ -0,0 +1,241 @@ +use std::fmt; +use std::ptr; + +use binaryninjacore_sys::*; +use crate::string::*; +use crate::rc::*; + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub enum SymType { + Function, + LibraryFunction, + ImportAddress, + ImportedFunction, + Data, + ImportedData, + External, +} + +impl From for SymType { + fn from(bn: BNSymbolType) -> SymType { + use self::BNSymbolType::*; + + match bn { + FunctionSymbol => SymType::Function, + LibraryFunctionSymbol => SymType::LibraryFunction, + ImportAddressSymbol => SymType::ImportAddress, + ImportedFunctionSymbol => SymType::ImportedFunction, + DataSymbol => SymType::Data, + ImportedDataSymbol => SymType::ImportedData, + ExternalSymbol => SymType::External, + } + } +} + +impl Into for SymType { + fn into(self) -> BNSymbolType { + use self::BNSymbolType::*; + + match self { + SymType::Function => FunctionSymbol, + SymType::LibraryFunction => LibraryFunctionSymbol, + SymType::ImportAddress => ImportAddressSymbol, + SymType::ImportedFunction => ImportedFunctionSymbol, + SymType::Data => DataSymbol, + SymType::ImportedData => ImportedDataSymbol, + SymType::External => ExternalSymbol, + } + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub enum Binding { + None, + Local, + Global, + Weak, +} + +impl From for Binding { + fn from(bn: BNSymbolBinding) -> Binding { + use self::BNSymbolBinding::*; + + match bn { + NoBinding => Binding::None, + LocalBinding => Binding::Local, + GlobalBinding => Binding::Global, + WeakBinding => Binding::Weak, + } + } +} + +impl Into for Binding { + fn into(self) -> BNSymbolBinding { + use self::BNSymbolBinding::*; + + match self { + Binding::None => NoBinding, + Binding::Local => LocalBinding, + Binding::Global => GlobalBinding, + Binding::Weak => WeakBinding, + } + } +} + +#[must_use] +pub struct SymbolBuilder { + ty: SymType, + binding: Binding, + addr: u64, + raw_name: S, + short_name: Option, + full_name: Option, + ordinal: u64, +} + +impl SymbolBuilder { + pub fn binding(mut self, binding: Binding) -> Self { + self.binding = binding; + self + } + + pub fn short_name(mut self, short_name: S) -> Self { + self.short_name = Some(short_name); + self + } + + pub fn full_name(mut self, full_name: S) -> Self { + self.full_name = Some(full_name); + self + } + + pub fn ordinal(mut self, ordinal: u64) -> Self { + self.ordinal = ordinal; + self + } + + pub fn create(self) -> Ref { + let raw_name = self.raw_name.as_bytes_with_nul(); + let short_name = self.short_name.map(|s| s.as_bytes_with_nul()); + let full_name = self.full_name.map(|s| s.as_bytes_with_nul()); + + unsafe { + let raw_name = raw_name.as_ref().as_ptr() as *mut _; + let short_name = short_name.as_ref().map_or(raw_name, |s| s.as_ref().as_ptr() as *mut _); + let full_name = full_name.as_ref().map_or(raw_name, |s| s.as_ref().as_ptr() as *mut _); + + let res = BNCreateSymbol(self.ty.into(), + short_name, full_name, raw_name, + self.addr, self.binding.into(), ptr::null_mut(), + self.ordinal); + + Ref::new(Symbol::from_raw(res)) + } + } +} + +#[derive(PartialEq, Eq, Hash)] +pub struct Symbol { + pub(crate) handle: *mut BNSymbol, +} + +unsafe impl Send for Symbol {} +unsafe impl Sync for Symbol {} + +impl Symbol { + pub(crate) unsafe fn from_raw(raw: *mut BNSymbol) -> Self { + Self { handle: raw } + } + + pub fn new(ty: SymType, raw_name: S, addr: u64) -> SymbolBuilder { + SymbolBuilder { + ty: ty, + binding: Binding::None, + addr: addr, + raw_name: raw_name, + short_name: None, + full_name: None, + ordinal: 0, + } + } + + pub fn sym_type(&self) -> SymType { + unsafe { BNGetSymbolType(self.handle).into() } + } + + pub fn binding(&self) -> Binding { + unsafe { BNGetSymbolBinding(self.handle).into() } + } + + pub fn name(&self) -> BnString { + unsafe { + let name = BNGetSymbolFullName(self.handle); + BnString::from_raw(name) + } + } + + pub fn short_name(&self) -> BnString { + unsafe { + let name = BNGetSymbolShortName(self.handle); + BnString::from_raw(name) + } + } + + pub fn raw_name(&self) -> BnString { + unsafe { + let name = BNGetSymbolRawName(self.handle); + BnString::from_raw(name) + } + } + + pub fn address(&self) -> u64 { + unsafe { BNGetSymbolAddress(self.handle) } + } + + pub fn auto_defined(&self) -> bool { + unsafe { BNIsSymbolAutoDefined(self.handle) } + } +} + +impl fmt::Debug for Symbol { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "", self.sym_type(), self.name(), self.address(), self.handle) + } +} + +impl ToOwned for Symbol { + type Owned = Ref; + + fn to_owned(&self) -> Self::Owned { + unsafe { RefCountable::inc_ref(self) } + } +} + +unsafe impl RefCountable for Symbol { + unsafe fn inc_ref(handle: &Self) -> Ref { + Ref::new(Self { + handle: BNNewSymbolReference(handle.handle), + }) + } + + unsafe fn dec_ref(handle: &Self) { + BNFreeSymbol(handle.handle); + } +} + +unsafe impl CoreOwnedArrayProvider for Symbol { + type Raw = *mut BNSymbol; + type Context = (); + + unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) { + BNFreeSymbolList(raw, count); + } +} + +unsafe impl<'a> CoreOwnedArrayWrapper<'a> for Symbol { + type Wrapped = Guard<'a, Symbol>; + + unsafe fn wrap_raw(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped { + Guard::new(Symbol::from_raw(*raw), context) + } +} -- cgit v1.3.1