diff options
| author | Ryan Snyder <ryan@vector35.com> | 2021-01-21 18:27:48 +0000 |
|---|---|---|
| committer | KyleMiles <krm504@nyu.edu> | 2021-01-21 19:06:55 +0000 |
| commit | d3140edec185f47235b9e4642bdd56d6c585a341 (patch) | |
| tree | a61859c29e4e3539daea2b761bb1439d942beaf4 /rust/src/symbol.rs | |
| parent | c0ddbf0c76d3f1bb7a2b2024f749afc8b9482575 (diff) | |
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
Diffstat (limited to 'rust/src/symbol.rs')
| -rw-r--r-- | rust/src/symbol.rs | 241 |
1 files changed, 241 insertions, 0 deletions
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<BNSymbolType> 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<BNSymbolType> 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<BNSymbolBinding> 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<BNSymbolBinding> 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<S: BnStrCompatible> { + ty: SymType, + binding: Binding, + addr: u64, + raw_name: S, + short_name: Option<S>, + full_name: Option<S>, + ordinal: u64, +} + +impl<S: BnStrCompatible> SymbolBuilder<S> { + 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<Symbol> { + 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<S: BnStrCompatible>(ty: SymType, raw_name: S, addr: u64) -> SymbolBuilder<S> { + 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, "<sym {:?} '{}' @ {:x} (handle: {:?})>", self.sym_type(), self.name(), self.address(), self.handle) + } +} + +impl ToOwned for Symbol { + type Owned = Ref<Self>; + + fn to_owned(&self) -> Self::Owned { + unsafe { RefCountable::inc_ref(self) } + } +} + +unsafe impl RefCountable for Symbol { + unsafe fn inc_ref(handle: &Self) -> Ref<Self> { + 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) + } +} |
