summaryrefslogtreecommitdiff
path: root/plugins/warp/src/plugin.rs
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/warp/src/plugin.rs')
-rw-r--r--plugins/warp/src/plugin.rs279
1 files changed, 78 insertions, 201 deletions
diff --git a/plugins/warp/src/plugin.rs b/plugins/warp/src/plugin.rs
index 4adab293..f8c4c0c5 100644
--- a/plugins/warp/src/plugin.rs
+++ b/plugins/warp/src/plugin.rs
@@ -1,186 +1,40 @@
use crate::cache::register_cache_destructor;
+use std::time::Instant;
+use crate::cache::container::add_cached_container;
+use crate::container::disk::DiskContainer;
use crate::matcher::MatcherSettings;
use crate::plugin::render_layer::HighlightRenderLayer;
-use binaryninja::binary_view::{BinaryView, BinaryViewExt};
-use binaryninja::command::{Command, FunctionCommand};
-use binaryninja::function::{Function, FunctionUpdateType};
+use crate::plugin::settings::PluginSettings;
+use crate::{core_signature_dir, user_signature_dir};
+use binaryninja::background_task::BackgroundTask;
+use binaryninja::command::{
+ register_command, register_command_for_function, register_command_for_project,
+};
use binaryninja::logger::Logger;
-use binaryninja::rc::Ref;
-use binaryninja::tags::TagType;
-use binaryninja::ObjectDestructor;
+use binaryninja::settings::Settings;
use log::LevelFilter;
-use warp::signature::function::constraints::FunctionConstraint;
-use warp::signature::function::Function as WarpFunction;
-mod add;
-mod copy;
mod create;
-mod find;
+mod debug;
+mod ffi;
+mod file;
+mod function;
mod load;
+mod project;
mod render_layer;
-mod types;
+mod settings;
mod workflow;
-// TODO: This icon is a little much
-const TAG_ICON: &str = "🌏";
-const TAG_NAME: &str = "WARP";
-
-fn get_warp_tag_type(view: &BinaryView) -> Ref<TagType> {
- view.tag_type_by_name(TAG_NAME)
- .unwrap_or_else(|| view.create_tag_type(TAG_NAME, TAG_ICON))
-}
-
-// What happens to the function when it is matched.
-// TODO: add user: bool
-// TODO: Rename to markup_function or something.
-pub fn on_matched_function(function: &Function, matched: &WarpFunction) {
- let view = function.view();
- // TODO: Using user symbols here is problematic
- // TODO: For one they queue up a bunch of main thread actions
- // TODO: Secondly by queueing up those main thread actions if you attempt to save the file
- // TODO: Before the undo actions are done completing
- view.define_user_symbol(&to_bn_symbol_at_address(
- &view,
- &matched.symbol,
- function.symbol().address(),
- ));
- function.set_user_type(&to_bn_type(&function.arch(), &matched.ty));
- // TODO: Add metadata. (both binja metadata and warp metadata)
- function.add_tag(
- &get_warp_tag_type(&view),
- &matched.guid.to_string(),
- None,
- true,
- None,
- );
- // Seems to be the only way to get the analysis update to work correctly.
- function.mark_updates_required(FunctionUpdateType::FullAutoFunctionUpdate);
-}
-
-struct DebugFunction;
-
-impl FunctionCommand for DebugFunction {
- fn action(&self, _view: &BinaryView, func: &Function) {
- if let Ok(llil) = func.low_level_il() {
- log::info!("{:#?}", build_function(func, &llil));
- }
- }
-
- fn valid(&self, _view: &BinaryView, _func: &Function) -> bool {
- true
- }
-}
-
-struct DebugMatcher;
-
-impl FunctionCommand for DebugMatcher {
- fn action(&self, _view: &BinaryView, function: &Function) {
- let Ok(llil) = function.low_level_il() else {
- log::error!("No LLIL for function 0x{:x}", function.start());
- return;
- };
- let platform = function.platform();
- // Build the matcher every time this is called to make sure we aren't in a bad state.
- let matcher = Matcher::from_platform(platform);
- let func = build_function(function, &llil);
- // TODO: Clean this up.
- if let Some(possible_matches) = matcher.functions.get(&func.guid) {
- let print_constraint = |prefix: &str, constraint: &FunctionConstraint| {
- log::info!(
- " {} {} ({})",
- prefix,
- constraint
- .to_owned()
- .symbol
- .map(|s| s.name)
- .unwrap_or("*".to_string()),
- constraint
- .guid
- .map(|g| g.to_string())
- .unwrap_or("*".to_string())
- );
- };
- for possible_match in possible_matches.value() {
- log::info!("{} ({})", possible_match.symbol.name, possible_match.guid);
- for constraint in &possible_match.constraints.call_sites {
- print_constraint("CS", constraint);
- }
- for constraint in &possible_match.constraints.call_sites {
- print_constraint("ADJ", constraint);
- }
- }
- } else {
- log::error!(
- "No possible matches found for the function 0x{:x}",
- function.start()
- );
- };
- }
-
- fn valid(&self, _view: &BinaryView, _function: &Function) -> bool {
- true
- }
-}
-
-struct DebugCache;
-
-impl Command for DebugCache {
- fn action(&self, view: &BinaryView) {
- let view_id = ViewID::from(view);
- let function_cache = FUNCTION_CACHE.get_or_init(Default::default);
- if let Some(cache) = function_cache.get(&view_id) {
- log::info!("View functions: {}", cache.cache.len());
- }
-
- let matched_function_cache = MATCHED_FUNCTION_CACHE.get_or_init(Default::default);
- if let Some(cache) = matched_function_cache.get(&view_id) {
- log::info!("View matched functions: {}", cache.cache.len());
- }
-
- let function_guid_cache = GUID_CACHE.get_or_init(Default::default);
- if let Some(cache) = function_guid_cache.get(&view_id) {
- log::info!("View function guids: {}", cache.cache.len());
- }
-
- let plat_cache = PLAT_MATCHER_CACHE.get_or_init(Default::default);
- if let Some(plat) = view.default_platform() {
- let platform_id = PlatformID::from(plat);
- if let Some(cache) = plat_cache.get(&platform_id) {
- log::info!("Platform functions: {}", cache.functions.len());
- log::info!("Platform types: {}", cache.types.len());
- log::info!("Platform settings: {:?}", cache.settings);
- }
- }
- }
-
- fn valid(&self, _view: &BinaryView) -> bool {
- true
- }
-}
-
-struct DebugInvalidateCache;
-
-impl Command for DebugInvalidateCache {
- fn action(&self, view: &BinaryView) {
- invalidate_function_matcher_cache();
- let destructor = cache::CacheDestructor {};
- destructor.destruct_view(view);
- log::info!("Invalidated all WARP caches...");
- }
-
- fn valid(&self, _view: &BinaryView) -> bool {
- true
- }
-}
-
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CorePluginInit() -> bool {
Logger::new("WARP").with_level(LevelFilter::Debug).init();
- // Register our matcher settings.
- MatcherSettings::register();
+ // Register our matcher and plugin settings globally.
+ let mut global_bn_settings = Settings::new();
+ MatcherSettings::register(&mut global_bn_settings);
+ PluginSettings::register(&mut global_bn_settings);
// Make sure caches are flushed when the views get destructed.
register_cache_destructor();
@@ -190,70 +44,93 @@ pub extern "C" fn CorePluginInit() -> bool {
workflow::insert_workflow();
- binaryninja::command::register_command(
+ let plugin_settings = PluginSettings::from_settings(&global_bn_settings);
+ // We want to load all the bundled directories into the container cache.
+ let background_task = BackgroundTask::new("Loading WARP files...", false);
+ let start = Instant::now();
+ if plugin_settings.load_bundled_files {
+ let core_disk_container = DiskContainer::new_from_dir(core_signature_dir());
+ log::debug!("{:#?}", core_disk_container);
+ add_cached_container(core_disk_container);
+ }
+ if plugin_settings.load_user_files {
+ let user_disk_container = DiskContainer::new_from_dir(user_signature_dir());
+ log::debug!("{:#?}", user_disk_container);
+ add_cached_container(user_disk_container);
+ }
+ log::info!("Loading bundled files took {:?}", start.elapsed());
+ background_task.finish();
+
+ register_command(
"WARP\\Run Matcher",
"Run the matcher manually",
workflow::RunMatcher {},
);
- binaryninja::command::register_command(
+ register_command(
"WARP\\Debug\\Cache",
"Debug cache sizes... because...",
- DebugCache {},
+ debug::DebugCache {},
);
- binaryninja::command::register_command(
+ register_command(
"WARP\\Debug\\Invalidate Caches",
"Invalidate all WARP caches",
- DebugInvalidateCache {},
+ debug::DebugInvalidateCache {},
);
- binaryninja::command::register_command_for_function(
+ register_command_for_function(
"WARP\\Debug\\Function Signature",
"Print the entire signature for the function",
- DebugFunction {},
- );
-
- binaryninja::command::register_command_for_function(
- "WARP\\Debug\\Function Matcher",
- "Print all possible matches for the function",
- DebugMatcher {},
+ debug::DebugFunction {},
);
- binaryninja::command::register_command(
- "WARP\\Debug\\Apply Signature File Types",
- "Load all types from a signature file and ignore functions",
- types::LoadTypes {},
- );
-
- binaryninja::command::register_command(
- "WARP\\Load Signature File",
+ register_command(
+ "WARP\\Load File",
"Load file into the matcher, this does NOT kick off matcher analysis",
load::LoadSignatureFile {},
);
- binaryninja::command::register_command_for_function(
- "WARP\\Copy Function GUID",
+ register_command_for_function(
+ "WARP\\Function\\Include",
+ "Add current function to the list of functions to add to the signature file",
+ function::IncludeFunction {},
+ );
+
+ register_command_for_function(
+ "WARP\\Function\\Copy GUID",
"Copy the computed GUID for the function",
- copy::CopyFunctionGUID {},
+ function::CopyFunctionGUID {},
);
- binaryninja::command::register_command(
- "WARP\\Find Function From GUID",
+ register_command(
+ "WARP\\Function\\Find GUID",
"Locate the function in the view using a GUID",
- find::FindFunctionFromGUID {},
+ function::FindFunctionFromGUID {},
+ );
+
+ register_command(
+ "WARP\\Create\\From Current View",
+ "Creates a signature file containing all selected functions",
+ create::CreateFromCurrentView {},
+ );
+
+ register_command(
+ "WARP\\Create\\From File(s)",
+ "Creates a signature file containing all selected functions",
+ create::CreateFromFiles {},
);
- binaryninja::command::register_command(
- "WARP\\Generate Signature File",
- "Generates a signature file containing all binary view functions",
- create::CreateSignatureFile {},
+ register_command(
+ "WARP\\Show Report",
+ "Creates a report for the selected file, displaying info on functions and types",
+ file::ShowFileReport {},
);
- binaryninja::command::register_command_for_function(
- "WARP\\Add Function Signature to File",
- "Stores the signature for the function in the signature file",
- add::AddFunctionSignature {},
+ register_command_for_project(
+ "WARP\\Create\\From Project",
+ "Create signature files from select project files",
+ project::CreateSignatures {},
);
true