From 69a8b507bb0245be64dc5f5ae0133381ca05175e Mon Sep 17 00:00:00 2001 From: polymeric <229394044+p0lymeric@users.noreply.github.com> Date: Wed, 22 Apr 2026 17:08:02 -0400 Subject: [PATCH 1/2] Updated to work with BN 5.3.9434 (latest stable). - Updated Cargo.toml to track BN API tag "stable/5.3.9434" - Replaced log with tracing per API changes in https://github.com/Vector35/binaryninja-api/pull/7808#issuecomment-3677133975 --- Cargo.toml | 4 ++-- src/lib.rs | 63 +++++++++++++++++++++++++++--------------------------- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4b203e6..41eaee9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ crate-type = ["cdylib"] # Local Development # binaryninja = { path = "../binaryninja-api/rust" } -log = "0.4.17" +tracing = "0.1" clipboard = "0.5" rayon = "1.11" iced-x86 = "1.17.0" @@ -26,4 +26,4 @@ binary-search = "0.1.3" # Dev # binaryninja = { git = "https://github.com/Vector35/binaryninja-api", branch = "dev" } # Stable -binaryninja = { git = "https://github.com/Vector35/binaryninja-api", tag = "stable/5.1.8104" } +binaryninja = { git = "https://github.com/Vector35/binaryninja-api", tag = "stable/5.3.9434" } diff --git a/src/lib.rs b/src/lib.rs index 6dcd45e..47398e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -168,7 +168,7 @@ impl FromSignature for OwnedPattern {} trait FromSignature { fn from_signature(mut pattern: String, signature_type: SignatureType) -> Option { - log::info!("attempting to parse a {signature_type}-style signature! \"{pattern}\""); + tracing::info!("attempting to parse a {signature_type}-style signature! \"{pattern}\""); pattern = pattern.replace("\n", ""); pattern = pattern.replace("\r", ""); @@ -194,7 +194,7 @@ trait FromSignature { } else { let Ok(byte) = u8::from_str_radix(&format!("{}{}", byte[0], byte[1]), 16) else { - log::error!("unable to parse pattern!"); + tracing::error!("unable to parse pattern!"); return None; }; @@ -220,7 +220,7 @@ trait FromSignature { let parts = pattern.split(" ").collect::>(); if parts.len() != 2 { - log::error!("unable to parse pattern!"); + tracing::error!("unable to parse pattern!"); return None; } @@ -244,7 +244,7 @@ trait FromSignature { let mut result = vec![ u8::from_str_radix(&byte, 16) .map_err(|x| { - log::error!("unable to parse pattern!"); + tracing::error!("unable to parse pattern!"); x }) .ok(), @@ -271,7 +271,7 @@ trait FromSignature { pattern.push(None); } _ => { - log::error!("invalid char encountered!"); + tracing::error!("invalid char encountered!"); } } } @@ -452,7 +452,7 @@ fn create_pattern_internal_binarysearch( data: &[(u64, Vec)], include_operands: bool, ) -> Result { - log::info!("creating pattern for address {:#04X}", addr); + tracing::info!("creating pattern for address {:#04X}", addr); let time = SystemTime::now(); let mut formatter = NasmFormatter::new(); @@ -477,7 +477,7 @@ fn create_pattern_internal_binarysearch( .ok_or(SignatureError::InvalidSegment)?; #[cfg(debug_assertions)] - log::info!("max sig size: {max_size}"); + tracing::info!("max sig size: {max_size}"); loop { let instr_addr = addr + current_offset; @@ -523,7 +523,7 @@ fn create_pattern_internal_binarysearch( )?; #[cfg(debug_assertions)] - log::info!( + tracing::info!( "{}: {}", instr_string, RustPattern(Cow::Borrowed(&instr_pattern)) @@ -555,7 +555,7 @@ fn create_pattern_internal_binarysearch( let pat = ¤t_pattern[0..instr.0 as usize + instr.1]; #[cfg(debug_assertions)] - log::info!("{}", RustPattern(Cow::Borrowed(&pat.to_vec()))); + tracing::info!("{}", RustPattern(Cow::Borrowed(&pat.to_vec()))); match is_pattern_unique(&data, pat) { false => Direction::Low(()), @@ -573,7 +573,7 @@ fn create_pattern_internal_binarysearch( current_pattern.pop(); } - log::info!( + tracing::info!( "binsearch created pattern in {}ms", SystemTime::now().duration_since(time).unwrap().as_millis() ); @@ -587,7 +587,7 @@ fn create_pattern_internal( data: &[(u64, Vec)], include_operands: bool, ) -> Result { - log::info!("creating pattern for address {:#04X}", addr); + tracing::info!("creating pattern for address {:#04X}", addr); let time = SystemTime::now(); let mut formatter = NasmFormatter::new(); @@ -611,7 +611,7 @@ fn create_pattern_internal( .ok_or(SignatureError::InvalidSegment)?; #[cfg(debug_assertions)] - log::info!("max sig size: {max_size}"); + tracing::info!("max sig size: {max_size}"); while !pattern_unique { let instr_addr = addr + current_offset; @@ -657,7 +657,7 @@ fn create_pattern_internal( )?; #[cfg(debug_assertions)] - log::info!( + tracing::info!( "{}: {}", instr_string, RustPattern(Cow::Borrowed(&instr_pattern)) @@ -689,7 +689,7 @@ fn create_pattern_internal( current_pattern.pop(); } - log::info!( + tracing::info!( "created pattern in {}ms", SystemTime::now().duration_since(time).unwrap().as_millis() ); @@ -709,14 +709,14 @@ fn create_pattern(bv: &BinaryView, addr: u64) -> Result Result Result Result bool { fn get_signature_type(_bv: &BinaryView) -> SignatureType { SignatureType::from_str(Settings::new().get_string("coolsigmaker.sig_type").as_str()) .map_err(|_| { - log::error!("invalid value for coolsigmaker.sig_type! falling back to default!") + tracing::error!("invalid value for coolsigmaker.sig_type! falling back to default!") }) .unwrap_or(SignatureType::IDATwo) } @@ -937,7 +937,7 @@ impl AddressCommand for SigMakerCommand { emit_result(format!("{}", pattern)); } Err(e) => { - log::error!("unable to create pattern! {e}"); + tracing::error!("unable to create pattern! {e}"); } } } @@ -951,7 +951,7 @@ impl AddressCommand for SigMakerCommand { impl Command for SigFinderCommand { fn action(&self, bv: &BinaryView) { let Ok(sig) = get_clipboard_contents() else { - log::error!("unable to get signature from clipboard!"); + tracing::error!("unable to get signature from clipboard!"); return; }; @@ -960,14 +960,14 @@ impl Command for SigFinderCommand { let data = get_code(bv); let Some(pattern) = OwnedPattern::from_signature(sig, get_signature_type(bv)) else { - log::error!("failed to parse pattern."); + tracing::error!("failed to parse pattern."); return; }; find_patterns(&data, &pattern) - .for_each(|occurrence| log::info!("found signature at {:#04X}", occurrence)); + .for_each(|occurrence| tracing::info!("found signature at {:#04X}", occurrence)); - log::info!( + tracing::info!( "scan finished in {}ms.", SystemTime::now().duration_since(time).unwrap().as_millis() ); @@ -980,15 +980,14 @@ impl Command for SigFinderCommand { #[unsafe(no_mangle)] pub extern "C" fn CorePluginInit() -> bool { - let logger = binaryninja::logger::Logger::new("CoolSigMaker"); - logger.with_level(log::LevelFilter::Info).init(); + binaryninja::tracing_init!("CoolSigMaker"); // TODO: (maybe) if signature not found, maybe go back a few instructions and attempt to create a signature with an offset. // TODO: introduce a setting for "dumb" searches, where we also search non-executable segments for uniqueness, incase the user doesn't want to check the segments before scanning them. // TODO: make a fancy regex to distinguish signature types automagically (without accidental mismatches occurring) - log::info!("binja_coolsigmaker by unknowntrojan loaded!"); - log::info!("say hello to the little ninja in your binja"); + tracing::info!("binja_coolsigmaker by unknowntrojan loaded!"); + tracing::info!("say hello to the little ninja in your binja"); #[cfg(debug_assertions)] std::panic::set_hook(Box::new(|info| { @@ -1002,7 +1001,7 @@ pub extern "C" fn CorePluginInit() -> bool { // #[cfg(debug_assertions)] let _ = std::fs::write("E:\\log.txt", &string); - log::info!("{}", &string); + tracing::info!("{}", &string); })); register_settings(); From d94d0770f6d490e623cc6b37867709c201e28dac Mon Sep 17 00:00:00 2001 From: polymeric <229394044+p0lymeric@users.noreply.github.com> Date: Wed, 22 Apr 2026 17:13:43 -0400 Subject: [PATCH 2/2] Extend the spinner range for Maximum Signature Size. --- src/lib.rs | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 47398e5..6709d8c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,6 +42,7 @@ use iced_x86::{ ConstantOffsets, FlowControl, Formatter, Instruction, NasmFormatter, OpKind, }; use rayon::prelude::{IntoParallelRefIterator, ParallelBridge, ParallelIterator}; +use serde_json::json; use strum::{Display, EnumIter, EnumMessage, EnumString, IntoEnumIterator, VariantNames}; type OwnedPattern = Vec>; @@ -799,28 +800,24 @@ fn register_settings() { description: &str, typ: &str, default: T, + extra_properties: &[(&str, &serde_json::Value)], ) where - T: core::fmt::Display, + T: core::fmt::Display + serde::Serialize, { - let default = if typ == "string" { - format!("\"{}\"", default) - } else { - format!("{}", default) - }; + let mut properties_val = json!({ + "title": title, + "type": typ, + "default": default, + "description": description, + "ignore": ["SettingsProjectScope", "SettingsResourceScope"], + }); - let properties = format!( - r#" - {{ - "title": "{title}", - "type": "{typ}", - "default": {default}, - "description": "{description}", - "ignore": ["SettingsProjectScope", "SettingsResourceScope"] - }} - "# - ); + let properties = properties_val.as_object_mut().unwrap(); + for (key, val) in extra_properties { + properties.insert(key.to_string(), (*val).clone()); + } - settings.register_setting_json(name, &properties); + settings.register_setting_json(name, &properties_val.to_string()); } fn register_enum_setting(settings: &Settings, name: &str, title: &str, description: &str) @@ -863,6 +860,7 @@ fn register_settings() { "Include immediate operands that aren't memory-relative or relocated when creating signatures. This results in smaller, but potentially more fragile, signatures. If no unique signature can be generated without operands, we fall back to including them.", "boolean", false, + &[], ); register_setting::( @@ -872,6 +870,7 @@ fn register_settings() { "Use a binary search to determine instruction uniqueness. For small binaries, this will be slower than the default, while for bigger binaries it might be faster. It starts scanning at half the maximum signature size. There is no heuristic implemented to automatically determine this yet.", "boolean", false, + &[], ); register_setting::( @@ -881,6 +880,11 @@ fn register_settings() { "The maximum size the signature will accumulate before giving up.", "number", 64, + &[ + ("minValue", &json!(0)), + // i32::MAX is one before when the widget changes from a spinner to a hex input box + ("maxValue", &json!(i32::MAX)), + ], ); register_enum_setting::(