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 | |
| parent | 911203528b5a5bfc7a98e86ad55b80f7a1385969 (diff) | |
Add actual logger api to rust
| -rw-r--r-- | arch/msp430/src/lib.rs | 4 | ||||
| -rw-r--r-- | arch/riscv/src/lib.rs | 5 | ||||
| -rw-r--r-- | plugins/warp/src/plugin.rs | 3 | ||||
| -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 | ||||
| -rw-r--r-- | view/bintxt/src/lib.rs | 4 |
13 files changed, 99 insertions, 35 deletions
diff --git a/arch/msp430/src/lib.rs b/arch/msp430/src/lib.rs index fd8af7a7..7654b33c 100644 --- a/arch/msp430/src/lib.rs +++ b/arch/msp430/src/lib.rs @@ -2,6 +2,7 @@ extern crate binaryninja; extern crate log; extern crate msp430_asm; +use log::LevelFilter; use binaryninja::{add_optional_plugin_dependency, architecture::ArchitectureExt, callingconvention, custombinaryview::{BinaryViewType, BinaryViewTypeExt}, Endianness}; mod architecture; @@ -10,11 +11,12 @@ mod lift; mod register; use architecture::Msp430; +use binaryninja::logger::Logger; #[no_mangle] #[allow(non_snake_case)] pub extern "C" fn CorePluginInit() -> bool { - binaryninja::logger::init(log::LevelFilter::Info); + Logger::new("MSP430").with_level(LevelFilter::Info).init(); let arch = binaryninja::architecture::register_architecture( "msp430", |custom_handle, handle| Msp430::new(handle, custom_handle), diff --git a/arch/riscv/src/lib.rs b/arch/riscv/src/lib.rs index e59f68e9..b56d15c4 100644 --- a/arch/riscv/src/lib.rs +++ b/arch/riscv/src/lib.rs @@ -8,7 +8,7 @@ use std::borrow::Cow; use std::fmt; use std::hash::Hash; use std::marker::PhantomData; - +use log::LevelFilter; use binaryninja::relocation::{Relocation, RelocationHandlerExt}; use binaryninja::{ add_optional_plugin_dependency, architecture, @@ -42,6 +42,7 @@ use riscv_dis::{ FloatReg, FloatRegType, Instr, IntRegType, Op, RegFile, Register as RiscVRegister, RiscVDisassembler, RoundMode, }; +use binaryninja::logger::Logger; enum RegType { Integer(u32), @@ -2891,7 +2892,7 @@ impl FunctionRecognizer for RiscVELFPLTRecognizer { #[no_mangle] #[allow(non_snake_case)] pub extern "C" fn CorePluginInit() -> bool { - binaryninja::logger::init(log::LevelFilter::Trace); + Logger::new("RISCV").with_level(LevelFilter::Trace).init(); use riscv_dis::{RiscVIMACDisassembler, Rv32GRegs, Rv64GRegs}; let arch32 = diff --git a/plugins/warp/src/plugin.rs b/plugins/warp/src/plugin.rs index f250f104..7ae78c02 100644 --- a/plugins/warp/src/plugin.rs +++ b/plugins/warp/src/plugin.rs @@ -15,6 +15,7 @@ use binaryninja::rc::Ref; use binaryninja::tags::TagType; use binaryninja::ObjectDestructor; use warp::signature::function::Function as WarpFunction; +use binaryninja::logger::Logger; mod copy; mod create; @@ -150,7 +151,7 @@ impl Command for DebugInvalidateCache { #[no_mangle] #[allow(non_snake_case)] pub extern "C" fn CorePluginInit() -> bool { - binaryninja::logger::init(LevelFilter::Debug); + Logger::new("WARP").with_level(LevelFilter::Debug).init(); // Register our matcher settings. MatcherSettings::register(); 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); diff --git a/view/bintxt/src/lib.rs b/view/bintxt/src/lib.rs index fbf3682d..392fe4ce 100644 --- a/view/bintxt/src/lib.rs +++ b/view/bintxt/src/lib.rs @@ -8,11 +8,13 @@ use srec::*; use titxt::*; use std::ops::Range; +use log::LevelFilter; +use binaryninja::logger::Logger; #[no_mangle] #[allow(non_snake_case)] pub extern "C" fn CorePluginInit() -> bool { - binaryninja::logger::init(log::LevelFilter::Error); + Logger::new("BINTXT").with_level(LevelFilter::Info).init(); binaryninja::custombinaryview::register_view_type(c"ti-txt", c"TI-TXT", |core| { TiTxtViewConstructor { core } |
