diff options
| author | Mason Reed <mason@vector35.com> | 2024-11-11 17:05:44 -0500 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2024-11-11 17:05:44 -0500 |
| commit | e856d391d377d0a723563925bb0a841ead5ae012 (patch) | |
| tree | 197df92e0dfc44e1f1e243bf4b35cd08ef8c1cfd /rust | |
| parent | 911203528b5a5bfc7a98e86ad55b80f7a1385969 (diff) | |
Add actual logger api to rust
Diffstat (limited to 'rust')
| -rw-r--r-- | rust/Cargo.toml | 2 | ||||
| -rw-r--r-- | rust/examples/dwarf/dwarf_export/src/lib.rs | 4 | ||||
| -rw-r--r-- | rust/examples/dwarf/dwarf_import/src/lib.rs | 4 | ||||
| -rw-r--r-- | rust/examples/idb_import/src/lib.rs | 3 | ||||
| -rw-r--r-- | rust/examples/minidump/src/lib.rs | 3 | ||||
| -rw-r--r-- | rust/examples/pdb-ng/src/lib.rs | 5 | ||||
| -rw-r--r-- | rust/examples/test_demangler/src/lib.rs | 3 | ||||
| -rw-r--r-- | rust/examples/workflow/src/lib.rs | 3 | ||||
| -rw-r--r-- | rust/src/logger.rs | 91 |
9 files changed, 88 insertions, 30 deletions
diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 04ccb865..59c71c6b 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -10,7 +10,7 @@ noexports = [] [dependencies] lazy_static = "1.4.0" -log = "0.4" +log = { version = "0.4", features = ["std"] } libc = "0.2" rayon = { version = "1.8", optional = true } binaryninjacore-sys = { path = "binaryninjacore-sys" } diff --git a/rust/examples/dwarf/dwarf_export/src/lib.rs b/rust/examples/dwarf/dwarf_export/src/lib.rs index 05592f5f..18cc1e21 100644 --- a/rust/examples/dwarf/dwarf_export/src/lib.rs +++ b/rust/examples/dwarf/dwarf_export/src/lib.rs @@ -15,13 +15,13 @@ use binaryninja::{ command::{register, Command}, interaction, interaction::{FormResponses, FormResponses::Index}, - logger::init, rc::Ref, string::BnString, symbol::SymbolType, types::{Conf, MemberAccess, StructureType, Type, TypeClass}, }; use log::{error, info, LevelFilter}; +use binaryninja::logger::Logger; fn export_type( name: String, @@ -781,7 +781,7 @@ impl Command for MyCommand { #[no_mangle] pub extern "C" fn CorePluginInit() -> bool { - init(LevelFilter::Debug); + Logger::new("DWARF Export").with_level(LevelFilter::Debug).init(); register( "Export as DWARF", diff --git a/rust/examples/dwarf/dwarf_import/src/lib.rs b/rust/examples/dwarf/dwarf_import/src/lib.rs index 20076d0c..b0617ee3 100644 --- a/rust/examples/dwarf/dwarf_import/src/lib.rs +++ b/rust/examples/dwarf/dwarf_import/src/lib.rs @@ -42,7 +42,7 @@ use gimli::{constants, CfaRule, DebuggingInformationEntry, Dwarf, DwarfFileType, use helpers::{get_build_id, load_debug_info_for_build_id}; use log::{debug, error, warn, LevelFilter}; - +use binaryninja::logger::Logger; trait ReaderType: Reader<Offset = usize> {} impl<T: Reader<Offset = usize>> ReaderType for T {} @@ -658,7 +658,7 @@ impl CustomDebugInfoParser for DWARFParser { #[no_mangle] pub extern "C" fn CorePluginInit() -> bool { - logger::init(LevelFilter::Debug); + Logger::new("DWARF").init(); let settings = Settings::new(""); diff --git a/rust/examples/idb_import/src/lib.rs b/rust/examples/idb_import/src/lib.rs index 0de688be..1faf188c 100644 --- a/rust/examples/idb_import/src/lib.rs +++ b/rust/examples/idb_import/src/lib.rs @@ -16,6 +16,7 @@ use idb_rs::til::Type as TILType; use log::{error, trace, warn, LevelFilter}; use anyhow::Result; +use binaryninja::logger::Logger; struct IDBDebugInfoParser; impl CustomDebugInfoParser for IDBDebugInfoParser { @@ -337,7 +338,7 @@ fn parse_id0_section_info( #[allow(non_snake_case)] #[no_mangle] pub extern "C" fn CorePluginInit() -> bool { - logger::init(LevelFilter::Error); + Logger::new("IDB Import").with_level(LevelFilter::Error).init(); DebugInfoParser::register("IDB Parser", IDBDebugInfoParser); DebugInfoParser::register("TIL Parser", TILDebugInfoParser); true diff --git a/rust/examples/minidump/src/lib.rs b/rust/examples/minidump/src/lib.rs index c899591b..62898301 100644 --- a/rust/examples/minidump/src/lib.rs +++ b/rust/examples/minidump/src/lib.rs @@ -2,6 +2,7 @@ use binaryninja::binaryview::BinaryView; use binaryninja::command::{register, Command}; use binaryninja::custombinaryview::register_view_type; use log::{debug, LevelFilter}; +use binaryninja::logger::Logger; mod command; mod view; @@ -21,7 +22,7 @@ impl Command for PrintMemoryInformationCommand { #[no_mangle] #[allow(non_snake_case)] pub extern "C" fn CorePluginInit() -> bool { - binaryninja::logger::init(LevelFilter::Trace); + Logger::new("Minidump").with_level(LevelFilter::Trace).init(); debug!("Registering minidump binary view type"); register_view_type("Minidump", "Minidump", view::MinidumpBinaryViewType::new); diff --git a/rust/examples/pdb-ng/src/lib.rs b/rust/examples/pdb-ng/src/lib.rs index bc12caae..47eed6ea 100644 --- a/rust/examples/pdb-ng/src/lib.rs +++ b/rust/examples/pdb-ng/src/lib.rs @@ -21,7 +21,7 @@ use std::sync::mpsc; use std::{env, fs}; use anyhow::{anyhow, Result}; -use log::{debug, error, info, LevelFilter}; +use log::{debug, error, info}; use pdb::PDB; use binaryninja::binaryview::{BinaryView, BinaryViewBase, BinaryViewExt}; @@ -31,6 +31,7 @@ use binaryninja::interaction::{MessageBoxButtonResult, MessageBoxButtonSet}; use binaryninja::settings::Settings; use binaryninja::string::BnString; use binaryninja::{add_optional_plugin_dependency, interaction, logger, user_directory}; +use binaryninja::logger::Logger; use parser::PDBParserInstance; /// PDB Parser!! @@ -697,7 +698,7 @@ pub extern "C" fn PDBPluginInit() -> bool { } fn init_plugin() -> bool { - logger::init(LevelFilter::Debug); + Logger::new("PDB").init(); DebugInfoParser::register("PDB", PDBParser {}); let settings = Settings::new(""); diff --git a/rust/examples/test_demangler/src/lib.rs b/rust/examples/test_demangler/src/lib.rs index 6735d5fb..d7dc9eec 100644 --- a/rust/examples/test_demangler/src/lib.rs +++ b/rust/examples/test_demangler/src/lib.rs @@ -4,6 +4,7 @@ use binaryninja::binaryview::BinaryView; use binaryninja::{command, logger}; use binaryninja::command::Command; use binaryninja::demangle::{Demangler, CustomDemangler}; +use binaryninja::logger::Logger; use binaryninja::rc::Ref; use binaryninja::types::{QualifiedName, Type}; @@ -57,7 +58,7 @@ impl Command for DemangleCommand { #[no_mangle] pub extern "C" fn CorePluginInit() -> bool { - logger::init(LevelFilter::Info); + Logger::new("Demangle Test").with_level(LevelFilter::Info).init(); Demangler::register("Test", TestDemangler {}); command::register("Demangle Test", "Test", DemangleCommand {}); true diff --git a/rust/examples/workflow/src/lib.rs b/rust/examples/workflow/src/lib.rs index 47a8d2c8..6f415941 100644 --- a/rust/examples/workflow/src/lib.rs +++ b/rust/examples/workflow/src/lib.rs @@ -3,6 +3,7 @@ use binaryninja::llil::{ }; use binaryninja::workflow::{Activity, AnalysisContext, Workflow}; use log::LevelFilter; +use binaryninja::logger::Logger; const RUST_ACTIVITY_NAME: &'static str = "analysis.plugins.rustexample"; const RUST_ACTIVITY_CONFIG: &'static str = r#"{ @@ -55,7 +56,7 @@ fn example_activity(analysis_context: &AnalysisContext) { #[no_mangle] #[allow(non_snake_case)] pub extern "C" fn CorePluginInit() -> bool { - binaryninja::logger::init(LevelFilter::Info); + Logger::new("Workflow Example").with_level(LevelFilter::Info).init(); log::info!("Initialized the plugin"); diff --git a/rust/src/logger.rs b/rust/src/logger.rs index 4e9dd1f9..487761e3 100644 --- a/rust/src/logger.rs +++ b/rust/src/logger.rs @@ -3,11 +3,11 @@ //! To use logging in your script, do something like: //! //! ```no-test -//! use binaryninja::logger; +//! use binaryninja::logger::Logger; //! use log::{info, LevelFilter}; //! //! fn main() { -//! logger::init(LevelFilter::Warn).expect("Unable to initialize logger"); +//! Logger::default().init(); //! info!("The logger has been initialized!"); //! // Your code here... //! } @@ -16,12 +16,12 @@ //! or //! //!```no-test -//! use binaryninja::logger; +//! use binaryninja::logger::Logger; //! use log::{info, LevelFilter}; //! //! #[no_mangle] //! pub extern "C" fn CorePluginInit() -> bool { -//! logger::init(LevelFilter::Warn).expect("Unable to initialize logger"); +//! Logger::new("My Plugin").with_level(LevelFilter::Warn).init(); //! info!("The logger has been initialized!"); //! // Your code here... //! true @@ -30,14 +30,73 @@ //! pub use binaryninjacore_sys::BNLogLevel as Level; -use binaryninjacore_sys::{BNLogListener, BNUpdateLogListeners}; +use binaryninjacore_sys::{ + BNFreeLogger, BNLogCreateLogger, BNLogListener, BNLogger, BNLoggerGetName, + BNLoggerGetSessionId, BNUpdateLogListeners, +}; +use crate::string::BnString; use log; -use std::ffi::CStr; +use log::LevelFilter; +use std::ffi::{CStr, CString}; use std::os::raw::{c_char, c_void}; +use std::ptr::NonNull; -struct Logger; -static LOGGER: Logger = Logger; +const LOGGER_DEFAULT_SESSION_ID: usize = 0; + +pub struct Logger { + handle: NonNull<BNLogger>, + level: LevelFilter, +} + +impl Logger { + pub fn new(name: &str) -> Logger { + Self::new_with_session(name, LOGGER_DEFAULT_SESSION_ID) + } + + pub fn new_with_session(name: &str, session_id: usize) -> Logger { + let name_raw = CString::new(name).unwrap(); + let handle = unsafe { BNLogCreateLogger(name_raw.as_ptr(), session_id) }; + Logger { + handle: NonNull::new(handle).unwrap(), + level: LevelFilter::Debug, + } + } + + pub fn with_level(mut self, level: LevelFilter) -> Logger { + self.level = level; + self + } + + /// Calling this will set the global logger to `self`. + /// + /// NOTE: There is no guarantee that logs will be sent to BinaryNinja as another log sink + /// may have already been initialized beforehand. + pub fn init(self) { + log::set_max_level(self.level); + let _ = log::set_boxed_logger(Box::new(self)); + } + + pub fn name(&self) -> BnString { + unsafe { BnString::from_raw(BNLoggerGetName(self.handle.as_ptr())) } + } + + pub fn session_id(&self) -> usize { + unsafe { BNLoggerGetSessionId(self.handle.as_ptr()) } + } +} + +impl Default for Logger { + fn default() -> Self { + Logger::new("Default") + } +} + +impl Drop for Logger { + fn drop(&mut self) { + unsafe { BNFreeLogger(self.handle.as_ptr()) }; + } +} impl log::Log for Logger { fn enabled(&self, _metadata: &log::Metadata) -> bool { @@ -48,7 +107,6 @@ impl log::Log for Logger { use self::Level::*; use binaryninjacore_sys::BNLog; use log::Level; - use std::ffi::CString; let level = match record.level() { Level::Error => ErrorLog, @@ -59,11 +117,12 @@ impl log::Log for Logger { if let Ok(msg) = CString::new(format!("{}", record.args())) { let percent_s = CString::new("%s").expect("'%s' has no null bytes"); + let logger_name = self.name(); unsafe { BNLog( - 0, + self.session_id(), level, - std::ptr::null(), + logger_name.into_raw(), 0, percent_s.as_ptr(), msg.as_ptr(), @@ -75,14 +134,8 @@ impl log::Log for Logger { fn flush(&self) {} } -/// Uses BinaryNinja's logging functionality as the sink for Rust's `log` crate. -/// -/// NOTE: There is no guarantee that logs will be sent to BinaryNinja as another log sink -/// may have already been initialized beforehand. -pub fn init(filter: log::LevelFilter) { - log::set_max_level(filter); - let _ = log::set_logger(&LOGGER); -} +unsafe impl Send for Logger {} +unsafe impl Sync for Logger {} pub trait LogListener: 'static + Sync { fn log(&self, session: usize, level: Level, msg: &CStr, logger_name: &CStr, tid: usize); |
