summaryrefslogtreecommitdiff
path: root/plugins/warp/src/plugin/create.rs
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2024-10-23 20:47:31 -0400
committerMason Reed <mason@vector35.com>2024-10-24 17:03:11 -0400
commite151425087b6c0ee8c4d099bfc2d6d1268201db0 (patch)
tree25160cf81aa6d650cf1497a078acc50f0062757c /plugins/warp/src/plugin/create.rs
parent0f53c21d6a7abbfd48fd59ec7c15586f02777b7e (diff)
Add WARP integration
https://github.com/Vector35/warp/
Diffstat (limited to 'plugins/warp/src/plugin/create.rs')
-rw-r--r--plugins/warp/src/plugin/create.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/plugins/warp/src/plugin/create.rs b/plugins/warp/src/plugin/create.rs
new file mode 100644
index 00000000..2b1ad60e
--- /dev/null
+++ b/plugins/warp/src/plugin/create.rs
@@ -0,0 +1,71 @@
+use crate::cache::cached_function;
+use crate::convert::from_bn_type;
+use binaryninja::binaryview::{BinaryView, BinaryViewExt};
+use binaryninja::command::Command;
+use rayon::prelude::*;
+use std::io::Write;
+use std::thread;
+use std::time::Instant;
+use warp::r#type::ComputedType;
+
+pub struct CreateSignatureFile;
+
+// TODO: Prompt the user to add the newly created signature file to the signature blacklist (so that it doesn't keep getting applied)
+
+impl Command for CreateSignatureFile {
+ fn action(&self, view: &BinaryView) {
+ let mut signature_dir = binaryninja::user_directory().unwrap().join("signatures/");
+ // TODO: This needs to split out each platform into its own bucket...
+ if let Some(default_plat) = view.default_platform() {
+ // If there is a default platform, put the signature in there.
+ signature_dir.push(default_plat.name().to_string());
+ }
+ let view = view.to_owned();
+ thread::spawn(move || {
+ let background_task = binaryninja::backgroundtask::BackgroundTask::new(
+ format!("Generating {} signatures... ", view.functions().len()),
+ true,
+ )
+ .unwrap();
+
+ let start = Instant::now();
+
+ let mut data = warp::signature::Data::default();
+ data.functions.par_extend(
+ view.functions()
+ .par_iter()
+ .filter_map(|func| cached_function(&func, func.low_level_il().ok()?.as_ref())),
+ );
+ data.types.extend(view.types().iter().map(|ty| {
+ let ref_ty = ty.type_object().to_owned();
+ ComputedType::new(from_bn_type(&view, ref_ty, u8::MAX))
+ }));
+
+ // And type generation :3
+ log::info!("Signature generation took {:?}", start.elapsed());
+
+ if let Some(sig_file_name) = binaryninja::interaction::get_text_line_input(
+ "Signature File",
+ "Create Signature File",
+ ) {
+ let save_file = signature_dir.join(sig_file_name + ".sbin");
+ log::info!("Saving to signatures to {:?}...", &save_file);
+ // TODO: Should we overwrite? Prompt user.
+ if let Ok(mut file) = std::fs::File::create(&save_file) {
+ match file.write_all(&data.to_bytes()) {
+ Ok(_) => log::info!("Signature file saved successfully."),
+ Err(e) => log::error!("Failed to write data to signature file: {:?}", e),
+ }
+ } else {
+ log::error!("Could not create signature file: {:?}", save_file);
+ }
+ }
+
+ background_task.finish();
+ });
+ }
+
+ fn valid(&self, _view: &BinaryView) -> bool {
+ true
+ }
+}