@@ -34,7 +34,7 @@ use crate::external_library::{ExternalLibrary, ExternalLocation};
3434use crate :: file_accessor:: { Accessor , FileAccessor } ;
3535use crate :: file_metadata:: FileMetadata ;
3636use crate :: flowgraph:: FlowGraph ;
37- use crate :: function:: { Function , NativeBlock } ;
37+ use crate :: function:: { Function , FunctionViewType , NativeBlock } ;
3838use crate :: linear_view:: { LinearDisassemblyLine , LinearViewCursor } ;
3939use crate :: metadata:: Metadata ;
4040use crate :: platform:: Platform ;
@@ -66,8 +66,11 @@ use std::{result, slice};
6666
6767pub mod memory_map;
6868pub mod reader;
69+ pub mod search;
6970pub mod writer;
7071
72+ use crate :: binary_view:: search:: SearchQuery ;
73+ use crate :: disassembly:: DisassemblySettings ;
7174use crate :: workflow:: Workflow ;
7275pub use memory_map:: MemoryMap ;
7376pub use reader:: BinaryReader ;
@@ -78,6 +81,7 @@ pub type BinaryViewEventType = BNBinaryViewEventType;
7881pub type AnalysisState = BNAnalysisState ;
7982pub type ModificationStatus = BNModificationStatus ;
8083pub type StringType = BNStringType ;
84+ pub type FindFlag = BNFindFlag ;
8185
8286#[ allow( clippy:: len_without_is_empty) ]
8387pub trait BinaryViewBase : AsRef < BinaryView > {
@@ -230,6 +234,197 @@ pub trait BinaryViewExt: BinaryViewBase {
230234 read_size
231235 }
232236
237+ /// Search the view using the query options.
238+ fn search < C : FnMut ( u64 , & DataBuffer ) -> bool > ( & self , query : & SearchQuery , on_match : C ) -> bool {
239+ self . search_with_progress ( query, on_match, NoProgressCallback )
240+ }
241+
242+ /// Search the view using the query options.
243+ fn search_with_progress < P : ProgressCallback , C : FnMut ( u64 , & DataBuffer ) -> bool > (
244+ & self ,
245+ query : & SearchQuery ,
246+ mut on_match : C ,
247+ mut progress : P ,
248+ ) -> bool {
249+ unsafe extern "C" fn cb_on_match < C : FnMut ( u64 , & DataBuffer ) -> bool > (
250+ ctx : * mut c_void ,
251+ offset : u64 ,
252+ data : * mut BNDataBuffer ,
253+ ) -> bool {
254+ let f = ctx as * mut C ;
255+ let buffer = DataBuffer :: from_raw ( data) ;
256+ ( * f) ( offset, & buffer)
257+ }
258+
259+ let query = query. to_json ( ) . to_cstr ( ) ;
260+ unsafe {
261+ BNSearch (
262+ self . as_ref ( ) . handle ,
263+ query. as_ptr ( ) ,
264+ & mut progress as * mut P as * mut c_void ,
265+ Some ( P :: cb_progress_callback) ,
266+ & mut on_match as * const C as * mut c_void ,
267+ Some ( cb_on_match :: < C > ) ,
268+ )
269+ }
270+ }
271+
272+ fn find_next_data ( & self , start : u64 , end : u64 , data : & DataBuffer ) -> Option < u64 > {
273+ self . find_next_data_with_opts (
274+ start,
275+ end,
276+ data,
277+ FindFlag :: FindCaseInsensitive ,
278+ NoProgressCallback ,
279+ )
280+ }
281+
282+ /// # Warning
283+ ///
284+ /// This function is likely to be changed to take in a "query" structure. Or deprecated entirely.
285+ fn find_next_data_with_opts < P : ProgressCallback > (
286+ & self ,
287+ start : u64 ,
288+ end : u64 ,
289+ data : & DataBuffer ,
290+ flag : FindFlag ,
291+ mut progress : P ,
292+ ) -> Option < u64 > {
293+ let mut result: u64 = 0 ;
294+ let found = unsafe {
295+ BNFindNextDataWithProgress (
296+ self . as_ref ( ) . handle ,
297+ start,
298+ end,
299+ data. as_raw ( ) ,
300+ & mut result,
301+ flag,
302+ & mut progress as * mut P as * mut c_void ,
303+ Some ( P :: cb_progress_callback) ,
304+ )
305+ } ;
306+
307+ if found {
308+ Some ( result)
309+ } else {
310+ None
311+ }
312+ }
313+
314+ fn find_next_constant (
315+ & self ,
316+ start : u64 ,
317+ end : u64 ,
318+ constant : u64 ,
319+ view_type : FunctionViewType ,
320+ ) -> Option < u64 > {
321+ // TODO: What are the best "default" settings?
322+ let settings = DisassemblySettings :: new ( ) ;
323+ self . find_next_constant_with_opts (
324+ start,
325+ end,
326+ constant,
327+ & settings,
328+ view_type,
329+ NoProgressCallback ,
330+ )
331+ }
332+
333+ /// # Warning
334+ ///
335+ /// This function is likely to be changed to take in a "query" structure.
336+ fn find_next_constant_with_opts < P : ProgressCallback > (
337+ & self ,
338+ start : u64 ,
339+ end : u64 ,
340+ constant : u64 ,
341+ disasm_settings : & DisassemblySettings ,
342+ view_type : FunctionViewType ,
343+ mut progress : P ,
344+ ) -> Option < u64 > {
345+ let mut result: u64 = 0 ;
346+ let raw_view_type = FunctionViewType :: into_raw ( view_type) ;
347+ let found = unsafe {
348+ BNFindNextConstantWithProgress (
349+ self . as_ref ( ) . handle ,
350+ start,
351+ end,
352+ constant,
353+ & mut result,
354+ disasm_settings. handle ,
355+ raw_view_type,
356+ & mut progress as * mut P as * mut c_void ,
357+ Some ( P :: cb_progress_callback) ,
358+ )
359+ } ;
360+ FunctionViewType :: free_raw ( raw_view_type) ;
361+
362+ if found {
363+ Some ( result)
364+ } else {
365+ None
366+ }
367+ }
368+
369+ fn find_next_text (
370+ & self ,
371+ start : u64 ,
372+ end : u64 ,
373+ text : & str ,
374+ view_type : FunctionViewType ,
375+ ) -> Option < u64 > {
376+ // TODO: What are the best "default" settings?
377+ let settings = DisassemblySettings :: new ( ) ;
378+ self . find_next_text_with_opts (
379+ start,
380+ end,
381+ text,
382+ & settings,
383+ FindFlag :: FindCaseInsensitive ,
384+ view_type,
385+ NoProgressCallback ,
386+ )
387+ }
388+
389+ /// # Warning
390+ ///
391+ /// This function is likely to be changed to take in a "query" structure.
392+ fn find_next_text_with_opts < P : ProgressCallback > (
393+ & self ,
394+ start : u64 ,
395+ end : u64 ,
396+ text : & str ,
397+ disasm_settings : & DisassemblySettings ,
398+ flag : FindFlag ,
399+ view_type : FunctionViewType ,
400+ mut progress : P ,
401+ ) -> Option < u64 > {
402+ let text = text. to_cstr ( ) ;
403+ let raw_view_type = FunctionViewType :: into_raw ( view_type) ;
404+ let mut result: u64 = 0 ;
405+ let found = unsafe {
406+ BNFindNextTextWithProgress (
407+ self . as_ref ( ) . handle ,
408+ start,
409+ end,
410+ text. as_ptr ( ) ,
411+ & mut result,
412+ disasm_settings. handle ,
413+ flag,
414+ raw_view_type,
415+ & mut progress as * mut P as * mut c_void ,
416+ Some ( P :: cb_progress_callback) ,
417+ )
418+ } ;
419+ FunctionViewType :: free_raw ( raw_view_type) ;
420+
421+ if found {
422+ Some ( result)
423+ } else {
424+ None
425+ }
426+ }
427+
233428 fn notify_data_written ( & self , offset : u64 , len : usize ) {
234429 unsafe {
235430 BNNotifyDataWritten ( self . as_ref ( ) . handle , offset, len) ;
0 commit comments