summaryrefslogtreecommitdiff
path: root/plugins/warp/src/plugin
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2025-10-06 19:09:00 -0400
committerMason Reed <mason@vector35.com>2025-10-07 14:11:02 -0400
commit43476710a30c1ce7abdfbd4371a2892b8038e55e (patch)
tree3f871cbeaeec226738263fe524b7cdefb97afb6a /plugins/warp/src/plugin
parentbbda2672f57de2f432222cf64b47f1f2631d3df7 (diff)
[WARP] Let BNDB processing optionally skip analysis updates
This helps when you have analyzed large binaries and want to create signatures after-the-fact, skipping analysis. This can speed up the time to create large datasets drastically.
Diffstat (limited to 'plugins/warp/src/plugin')
-rw-r--r--plugins/warp/src/plugin/project.rs40
1 files changed, 35 insertions, 5 deletions
diff --git a/plugins/warp/src/plugin/project.rs b/plugins/warp/src/plugin/project.rs
index 6c851745..725d164c 100644
--- a/plugins/warp/src/plugin/project.rs
+++ b/plugins/warp/src/plugin/project.rs
@@ -1,6 +1,6 @@
use crate::processor::{
new_processing_state_background_thread, CompressionTypeField, FileDataKindField,
- FileFilterField, WarpFileProcessor,
+ FileFilterField, ProcessingFileState, RequestAnalysisField, WarpFileProcessor,
};
use crate::report::{ReportGenerator, ReportKindField};
use binaryninja::background_task::BackgroundTask;
@@ -30,6 +30,7 @@ impl CreateSignaturesForm {
form.add_field(Self::compression_type_field());
form.add_field(Self::save_individual_files_field());
form.add_field(Self::skip_existing_warp_files_field());
+ form.add_field(Self::request_analysis_field());
form.add_field(Self::processing_thread_count_field());
Self { form }
}
@@ -46,7 +47,7 @@ impl CreateSignaturesForm {
FileFilterField::to_field()
}
- pub fn file_filter(&self) -> Option<Regex> {
+ pub fn file_filter(&self) -> Option<Result<Regex, regex::Error>> {
FileFilterField::from_form(&self.form)
}
@@ -100,6 +101,14 @@ impl CreateSignaturesForm {
}
}
+ pub fn request_analysis_field() -> FormInputField {
+ RequestAnalysisField::default().to_field()
+ }
+
+ pub fn request_analysis(&self) -> RequestAnalysisField {
+ RequestAnalysisField::from_form(&self.form).unwrap_or_default()
+ }
+
pub fn processing_thread_count_field() -> FormInputField {
let default = rayon::current_num_threads();
FormInputField::Integer {
@@ -136,6 +145,7 @@ impl CreateSignatures {
let compression_type = form.compression_type();
let save_individual_files = form.save_individual_files();
let skip_existing_warp_files = form.skip_existing_warp_files();
+ let request_analysis = form.request_analysis();
let processing_thread_count = form.processing_thread_count();
// Save the warp file to the project.
@@ -189,7 +199,8 @@ impl CreateSignatures {
let mut processor = WarpFileProcessor::new()
.with_file_data(file_data_kind)
.with_compression_type(compression_type)
- .with_skip_warp_files(skip_existing_warp_files);
+ .with_skip_warp_files(skip_existing_warp_files)
+ .with_request_analysis(request_analysis == RequestAnalysisField::Yes);
if save_individual_files {
processor = processor.with_processed_file_callback(save_individual_files_cb);
@@ -198,7 +209,18 @@ impl CreateSignatures {
// Construct the user-supplied file filter. This will filter files in the project only, files
// in an archive will be considered a part of the archive file.
if let Some(filter) = form.file_filter() {
- processor = processor.with_file_filter(filter);
+ match filter {
+ Ok(f) => {
+ processor = processor.with_file_filter(f);
+ }
+ Err(err) => {
+ log::error!("Failed to parse file filter: {}", err);
+ log::error!(
+ "Consider using a substring instead of a glob pattern, e.g. *.exe => exe"
+ );
+ return;
+ }
+ }
}
// This thread will show the state in a background task.
@@ -234,7 +256,15 @@ impl CreateSignatures {
log::error!("Failed to process project: {}", e);
}
});
- log::info!("Processing project files took: {:?}", start.elapsed());
+
+ let processed_file_count = processor
+ .state()
+ .files_with_state(ProcessingFileState::Processed);
+ log::info!(
+ "Processing {} project files took: {:?}",
+ processed_file_count,
+ start.elapsed()
+ );
// Reset the worker thread count to the user specified; either way it will not persist.
set_worker_thread_count(previous_worker_thread_count);
// Tells the processing state thread to finish.