diff options
| author | Glenn Smith <glenn@vector35.com> | 2024-03-05 02:08:55 -0500 |
|---|---|---|
| committer | Glenn Smith <glenn@vector35.com> | 2024-03-05 14:01:26 -0500 |
| commit | 2596349220399080054037011947884060414345 (patch) | |
| tree | e28ac5e7efb9a0be5bbd0754c01c90b50acf32a2 /rust/src/binaryview.rs | |
| parent | 69d4d1fa5b397bf591a4d124bb0f1d8106d072df (diff) | |
Rust: Add support for querying analysis status
Diffstat (limited to 'rust/src/binaryview.rs')
| -rw-r--r-- | rust/src/binaryview.rs | 88 |
1 files changed, 85 insertions, 3 deletions
diff --git a/rust/src/binaryview.rs b/rust/src/binaryview.rs index a6b2b540..ded8115b 100644 --- a/rust/src/binaryview.rs +++ b/rust/src/binaryview.rs @@ -19,15 +19,16 @@ use binaryninjacore_sys::*; +pub use binaryninjacore_sys::BNAnalysisState as AnalysisState; pub use binaryninjacore_sys::BNModificationStatus as ModificationStatus; use std::collections::HashMap; use std::ffi::c_void; -use std::ops; use std::ops::Range; use std::os::raw::c_char; use std::ptr; use std::result; +use std::{ops, slice}; use crate::architecture::Architecture; use crate::architecture::CoreArchitecture; @@ -145,6 +146,28 @@ pub trait BinaryViewBase: AsRef<BinaryView> { } } +#[derive(Debug, Clone)] +pub struct ActiveAnalysisInfo { + pub func: Ref<Function>, + pub analysis_time: u64, + pub update_count: usize, + pub submit_count: usize, +} + +#[derive(Debug, Clone)] +pub struct AnalysisInfo { + pub state: AnalysisState, + pub analysis_time: u64, + pub active_info: Vec<ActiveAnalysisInfo>, +} + +#[derive(Debug, Clone)] +pub struct AnalysisProgress { + pub state: AnalysisState, + pub count: usize, + pub total: usize, +} + // TODO: Copied from debuginfo.rs, this should be consolidated struct ProgressContext(Option<Box<dyn Fn(usize, usize) -> Result<()>>>); @@ -273,18 +296,77 @@ pub trait BinaryViewExt: BinaryViewBase { unsafe { BNGetEndOffset(self.as_ref().handle) } } - fn update_analysis_and_wait(&self) { + fn add_analysis_option(&self, name: impl BnStrCompatible) { unsafe { - BNUpdateAnalysisAndWait(self.as_ref().handle); + BNAddAnalysisOption( + self.as_ref().handle, + name.into_bytes_with_nul().as_ref().as_ptr() as *mut _, + ) } } + fn has_initial_analysis(&self) -> bool { + unsafe { BNHasInitialAnalysis(self.as_ref().handle) } + } + + fn set_analysis_hold(&self, enable: bool) { + unsafe { BNSetAnalysisHold(self.as_ref().handle, enable) } + } + fn update_analysis(&self) { unsafe { BNUpdateAnalysis(self.as_ref().handle); } } + fn update_analysis_and_wait(&self) { + unsafe { + BNUpdateAnalysisAndWait(self.as_ref().handle); + } + } + + fn abort_analysis(&self) { + unsafe { BNAbortAnalysis(self.as_ref().handle) } + } + + fn analysis_info(&self) -> Result<AnalysisInfo> { + let info_ref = unsafe { BNGetAnalysisInfo(self.as_ref().handle) }; + if info_ref.is_null() { + return Err(()); + } + let info = unsafe { *info_ref }; + let active_infos = unsafe { slice::from_raw_parts(info.activeInfo, info.count) }; + + let mut active_info_list = vec![]; + for active_info in active_infos { + let func = unsafe { Function::from_raw(BNNewFunctionReference(active_info.func)) }; + active_info_list.push(ActiveAnalysisInfo { + func, + analysis_time: active_info.analysisTime, + update_count: active_info.updateCount, + submit_count: active_info.submitCount, + }); + } + + let result = AnalysisInfo { + state: info.state, + analysis_time: info.analysisTime, + active_info: vec![], + }; + + unsafe { BNFreeAnalysisInfo(info_ref) }; + Ok(result) + } + + fn analysis_progress(&self) -> AnalysisProgress { + let progress = unsafe { BNGetAnalysisProgress(self.as_ref().handle) }; + AnalysisProgress { + state: progress.state, + count: progress.count, + total: progress.total, + } + } + fn default_arch(&self) -> Option<CoreArchitecture> { unsafe { let raw = BNGetDefaultArchitecture(self.as_ref().handle); |
