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/lib.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/lib.rs')
| -rw-r--r-- | rust/src/lib.rs | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/rust/src/lib.rs b/rust/src/lib.rs new file mode 100644 index 00000000..68df9948 --- /dev/null +++ b/rust/src/lib.rs @@ -0,0 +1,171 @@ +#[macro_use] +extern crate log; +#[cfg(feature = "rayon")] +extern crate rayon; +extern crate libc; +extern crate binaryninjacore_sys; + +// TODO +// move some options to results +// replace `fn handle` with `AsRef` bounds +// possible values +// arch rework +// cc possible values +// bv reorg +// core fileaccessor (for bv saving) +// headless wrapper for shutdown +// platform cc + +#[macro_use] +mod ffi; + +pub mod architecture; +pub mod basicblock; +pub mod binaryview; +pub mod segment; +pub mod section; +pub mod symbol; +pub mod callingconvention; +pub mod command; +pub mod fileaccessor; +pub mod filemetadata; +pub mod function; +pub mod platform; +pub mod llil; +pub mod types; +pub mod rc; +pub mod headless; +pub mod string; +pub mod settings; + +pub use binaryninjacore_sys::BNEndianness as Endianness; +pub use binaryninjacore_sys::BNBranchType as BranchType; + +pub mod logger { + use std::os::raw::{c_void, c_char}; + + use log; + + use crate::string::BnStr; + + use binaryninjacore_sys::{BNLogListener, BNUpdateLogListeners}; + pub use binaryninjacore_sys::BNLogLevel as Level; + + struct Logger; + static LOGGER: Logger = Logger; + + impl log::Log for Logger { + fn enabled(&self, _metadata: &log::Metadata) -> bool { + true + } + + fn log(&self, record: &log::Record) { + use binaryninjacore_sys::BNLog; + use std::ffi::CString; + use self::Level::*; + use log::Level; + + let level = match record.level() { + Level::Error => ErrorLog, + Level::Warn => WarningLog, + Level::Info => InfoLog, + Level::Debug | + Level::Trace => DebugLog, + }; + + if let Ok(msg) = CString::new(format!("{}", record.args())) { + unsafe { BNLog(level, msg.as_ptr()); } + }; + } + + fn flush(&self) {} + } + + /// Uses BinaryNinja's logging functionality as the sink for + /// Rust's `log` crate. + pub fn init(filter: log::LevelFilter) -> Result<(), log::SetLoggerError> { + log::set_max_level(filter); + log::set_logger(&LOGGER) + } + + pub trait LogListener: 'static + Sync { + fn log(&self, level: Level, msg: &BnStr); + fn level(&self) -> Level; + fn close(&self) {} + } + + pub struct LogGuard<L: LogListener> { + ctxt: *mut L, + } + + impl<L: LogListener> Drop for LogGuard<L> { + fn drop(&mut self) { + use binaryninjacore_sys::BNUnregisterLogListener; + + let mut bn_obj = BNLogListener { + context: self.ctxt as *mut _, + log: Some(cb_log::<L>), + close: Some(cb_close::<L>), + getLogLevel: Some(cb_level::<L>), + }; + + unsafe { + BNUnregisterLogListener(&mut bn_obj); + BNUpdateLogListeners(); + + let _listener = Box::from_raw(self.ctxt); + } + } + } + + pub fn register_listener<L: LogListener>(listener: L) -> LogGuard<L> { + use binaryninjacore_sys::BNRegisterLogListener; + + let raw = Box::into_raw(Box::new(listener)); + let mut bn_obj = BNLogListener { + context: raw as *mut _, + log: Some(cb_log::<L>), + close: Some(cb_close::<L>), + getLogLevel: Some(cb_level::<L>), + }; + + unsafe { + BNRegisterLogListener(&mut bn_obj); + BNUpdateLogListeners(); + } + + LogGuard { + ctxt: raw, + } + } + + extern "C" fn cb_log<L>(ctxt: *mut c_void, level: Level, msg: *const c_char) + where + L: LogListener, + { + ffi_wrap!("LogListener::log", unsafe { + let listener = &*(ctxt as *const L); + listener.log(level, BnStr::from_raw(msg)); + }) + } + + extern "C" fn cb_close<L>(ctxt: *mut c_void) + where + L: LogListener, + { + ffi_wrap!("LogListener::close", unsafe { + let listener = &*(ctxt as *const L); + listener.close(); + }) + } + + extern "C" fn cb_level<L>(ctxt: *mut c_void) -> Level + where + L: LogListener, + { + ffi_wrap!("LogListener::log", unsafe { + let listener = &*(ctxt as *const L); + listener.level() + }) + } +} |
