@@ -58,14 +58,16 @@ use crate::Endianness;
5858use std:: collections:: HashMap ;
5959use std:: ffi:: { c_char, c_void} ;
6060use std:: ops:: Range ;
61- use std:: path:: Path ;
61+ use std:: path:: { Path , PathBuf } ;
6262use std:: ptr:: NonNull ;
6363use std:: { result, slice} ;
6464// TODO : general reorg of modules related to bv
6565
66+ pub mod custom;
6667pub mod memory_map;
6768pub mod reader;
6869pub mod search;
70+ pub mod types;
6971pub mod writer;
7072
7173use crate :: binary_view:: search:: SearchQuery ;
@@ -535,11 +537,9 @@ pub trait BinaryViewExt: BinaryViewBase {
535537 }
536538 }
537539
538- fn analysis_info ( & self ) -> Result < AnalysisInfo > {
540+ fn analysis_info ( & self ) -> AnalysisInfo {
539541 let info_ref = unsafe { BNGetAnalysisInfo ( self . as_ref ( ) . handle ) } ;
540- if info_ref. is_null ( ) {
541- return Err ( ( ) ) ;
542- }
542+ assert ! ( !info_ref. is_null( ) ) ;
543543 let info = unsafe { * info_ref } ;
544544 let active_infos = unsafe { slice:: from_raw_parts ( info. activeInfo , info. count ) } ;
545545
@@ -561,7 +561,7 @@ pub trait BinaryViewExt: BinaryViewBase {
561561 } ;
562562
563563 unsafe { BNFreeAnalysisInfo ( info_ref) } ;
564- Ok ( result)
564+ result
565565 }
566566
567567 fn analysis_progress ( & self ) -> AnalysisProgress {
@@ -1182,17 +1182,22 @@ pub trait BinaryViewExt: BinaryViewBase {
11821182 address : u64 ,
11831183 platform : & Platform ,
11841184 ) -> Option < Ref < Function > > {
1185- self . add_auto_function_ext ( address, platform, None )
1185+ self . add_auto_function_ext ( address, platform, None , true )
11861186 }
11871187
11881188 /// Add an auto function at the given `address` with the `platform` and function type.
11891189 ///
1190+ /// If you set `auto_discovered` to `false`, the function will not be considered for unused function
1191+ /// deletion, nor will it allow the function to be "blacklisted", that is, the function will always
1192+ /// be created.
1193+ ///
11901194 /// NOTE: If the view's default platform is not set, this will set it to `platform`.
11911195 fn add_auto_function_ext (
11921196 & self ,
11931197 address : u64 ,
11941198 platform : & Platform ,
11951199 func_type : Option < & Type > ,
1200+ auto_discovered : bool ,
11961201 ) -> Option < Ref < Function > > {
11971202 unsafe {
11981203 let func_type = match func_type {
@@ -1204,7 +1209,7 @@ pub trait BinaryViewExt: BinaryViewBase {
12041209 self . as_ref ( ) . handle ,
12051210 platform. handle ,
12061211 address,
1207- true ,
1212+ auto_discovered ,
12081213 func_type,
12091214 ) ;
12101215
@@ -1285,7 +1290,7 @@ pub trait BinaryViewExt: BinaryViewBase {
12851290 }
12861291 }
12871292
1288- fn entry_point_function ( & self ) -> Option < Ref < Function > > {
1293+ fn analysis_entry_point_function ( & self ) -> Option < Ref < Function > > {
12891294 unsafe {
12901295 let raw_func_ptr = BNGetAnalysisEntryPoint ( self . as_ref ( ) . handle ) ;
12911296 match raw_func_ptr. is_null ( ) {
@@ -1295,6 +1300,11 @@ pub trait BinaryViewExt: BinaryViewBase {
12951300 }
12961301 }
12971302
1303+ /// This list contains the analysis entry function, and functions like init_array, fini_array,
1304+ /// and TLS callbacks etc.
1305+ ///
1306+ /// We see `entry_functions` as good starting points for analysis, these functions normally don't
1307+ /// have internal references. Exported functions in a dll/so file are not included.
12981308 fn entry_point_functions ( & self ) -> Array < Function > {
12991309 unsafe {
13001310 let mut count = 0 ;
@@ -1381,7 +1391,7 @@ pub trait BinaryViewExt: BinaryViewBase {
13811391
13821392 /// Checks if target analysis should be skipped.
13831393 ///
1384- /// NOTE: This function should **only** be used by within an [`Architecture`].
1394+ /// NOTE: This function should **only** be used by within [`Architecture::analyze_basic_blocks `].
13851395 fn should_skip_target_analysis < L : Into < Location > > (
13861396 & self ,
13871397 source : L ,
@@ -1403,12 +1413,12 @@ pub trait BinaryViewExt: BinaryViewBase {
14031413 }
14041414 }
14051415
1406- fn read_buffer ( & self , offset : u64 , len : usize ) -> Result < DataBuffer > {
1416+ fn read_buffer ( & self , offset : u64 , len : usize ) -> Option < DataBuffer > {
14071417 let read_buffer = unsafe { BNReadViewBuffer ( self . as_ref ( ) . handle , offset, len) } ;
14081418 if read_buffer. is_null ( ) {
1409- Err ( ( ) )
1419+ None
14101420 } else {
1411- Ok ( DataBuffer :: from_raw ( read_buffer) )
1421+ Some ( DataBuffer :: from_raw ( read_buffer) )
14121422 }
14131423 }
14141424
@@ -1424,51 +1434,19 @@ pub trait BinaryViewExt: BinaryViewBase {
14241434 unsafe { BNApplyDebugInfo ( self . as_ref ( ) . handle , debug_info. handle ) }
14251435 }
14261436
1427- fn show_plaintext_report ( & self , title : & str , plaintext : & str ) {
1428- let title = title. to_cstr ( ) ;
1429- let plaintext = plaintext. to_cstr ( ) ;
1430- unsafe {
1431- BNShowPlainTextReport (
1432- self . as_ref ( ) . handle ,
1433- title. as_ref ( ) . as_ptr ( ) as * mut _ ,
1434- plaintext. as_ref ( ) . as_ptr ( ) as * mut _ ,
1435- )
1436- }
1437- }
1438-
1437+ /// Wrapper for [`crate::interaction::show_markdown_report`].
14391438 fn show_markdown_report ( & self , title : & str , contents : & str , plaintext : & str ) {
1440- let title = title. to_cstr ( ) ;
1441- let contents = contents. to_cstr ( ) ;
1442- let plaintext = plaintext. to_cstr ( ) ;
1443- unsafe {
1444- BNShowMarkdownReport (
1445- self . as_ref ( ) . handle ,
1446- title. as_ref ( ) . as_ptr ( ) as * mut _ ,
1447- contents. as_ref ( ) . as_ptr ( ) as * mut _ ,
1448- plaintext. as_ref ( ) . as_ptr ( ) as * mut _ ,
1449- )
1450- }
1439+ crate :: interaction:: show_markdown_report ( Some ( self . as_ref ( ) ) , title, contents, plaintext) ;
14511440 }
14521441
1442+ /// Wrapper for [`crate::interaction::show_html_report`].
14531443 fn show_html_report ( & self , title : & str , contents : & str , plaintext : & str ) {
1454- let title = title. to_cstr ( ) ;
1455- let contents = contents. to_cstr ( ) ;
1456- let plaintext = plaintext. to_cstr ( ) ;
1457- unsafe {
1458- BNShowHTMLReport (
1459- self . as_ref ( ) . handle ,
1460- title. as_ref ( ) . as_ptr ( ) as * mut _ ,
1461- contents. as_ref ( ) . as_ptr ( ) as * mut _ ,
1462- plaintext. as_ref ( ) . as_ptr ( ) as * mut _ ,
1463- )
1464- }
1444+ crate :: interaction:: show_html_report ( Some ( self . as_ref ( ) ) , title, contents, plaintext) ;
14651445 }
14661446
1447+ /// Wrapper for [`crate::interaction::show_graph_report`].
14671448 fn show_graph_report ( & self , raw_name : & str , graph : & FlowGraph ) {
1468- let raw_name = raw_name. to_cstr ( ) ;
1469- unsafe {
1470- BNShowGraphReport ( self . as_ref ( ) . handle , raw_name. as_ptr ( ) , graph. handle ) ;
1471- }
1449+ crate :: interaction:: show_graph_report ( Some ( self . as_ref ( ) ) , raw_name, graph) ;
14721450 }
14731451
14741452 fn load_settings ( & self , view_type_name : & str ) -> Result < Ref < Settings > > {
@@ -1608,6 +1586,7 @@ pub trait BinaryViewExt: BinaryViewBase {
16081586 result
16091587 }
16101588
1589+ // TODO: Why is this impl'd here?
16111590 /// Retrieves a list of the previous disassembly lines.
16121591 ///
16131592 /// `get_previous_linear_disassembly_lines` retrieves an [Array] over [LinearDisassemblyLine] objects for the
@@ -1643,6 +1622,9 @@ pub trait BinaryViewExt: BinaryViewBase {
16431622 }
16441623 }
16451624
1625+ /// Retrieve the metadata as the type `T`.
1626+ ///
1627+ /// Fails if the metadata does not exist, or if the metadata failed to coerce to type `T`.
16461628 fn get_metadata < T > ( & self , key : & str ) -> Option < Result < T > >
16471629 where
16481630 T : for < ' a > TryFrom < & ' a Metadata > ,
@@ -1672,7 +1654,7 @@ pub trait BinaryViewExt: BinaryViewBase {
16721654 unsafe { BNBinaryViewRemoveMetadata ( self . as_ref ( ) . handle , key. as_ptr ( ) ) } ;
16731655 }
16741656
1675- /// Retrieves a list of [CodeReference]s pointing to a given address.
1657+ /// Retrieves a list of [` CodeReference` ]s pointing to a given address.
16761658 fn code_refs_to_addr ( & self , addr : u64 ) -> Array < CodeReference > {
16771659 unsafe {
16781660 let mut count = 0 ;
@@ -1681,7 +1663,7 @@ pub trait BinaryViewExt: BinaryViewBase {
16811663 }
16821664 }
16831665
1684- /// Retrieves a list of [CodeReference]s pointing into a given [Range].
1666+ /// Retrieves a list of [` CodeReference` ]s pointing into a given [` Range` ].
16851667 fn code_refs_into_range ( & self , range : Range < u64 > ) -> Array < CodeReference > {
16861668 unsafe {
16871669 let mut count = 0 ;
@@ -2171,16 +2153,20 @@ pub trait BinaryViewExt: BinaryViewBase {
21712153 Array :: new ( strings, count, ( ) )
21722154 }
21732155 }
2174- fn string_at ( & self , addr : u64 ) -> Option < BNStringReference > {
2156+
2157+ /// Retrieve the string that falls on a given virtual address.
2158+ ///
2159+ /// NOTE: This returns discovered strings and is therefore governed by `analysis.limits.minStringLength` and other settings.
2160+ fn string_at ( & self , addr : u64 ) -> Option < StringReference > {
21752161 let mut str_ref = BNStringReference :: default ( ) ;
21762162 let success = unsafe { BNGetStringAtAddress ( self . as_ref ( ) . handle , addr, & mut str_ref) } ;
2177-
21782163 if success {
2179- Some ( str_ref)
2164+ Some ( str_ref. into ( ) )
21802165 } else {
21812166 None
21822167 }
21832168 }
2169+
21842170 /// Retrieve all known strings within the provided `range`.
21852171 ///
21862172 /// NOTE: This returns a list of [`StringReference`] as strings may not be representable
@@ -2199,23 +2185,43 @@ pub trait BinaryViewExt: BinaryViewBase {
21992185 }
22002186 }
22012187
2202- //
2203- // fn type_archives(&self) -> Array<TypeArchive> {
2204- // let mut ids: *mut *mut c_char = std::ptr::null_mut();
2205- // let mut paths: *mut *mut c_char = std::ptr::null_mut();
2206- // let count = unsafe { BNBinaryViewGetTypeArchives(self.as_ref().handle, &mut ids, &mut paths) };
2207- // let path_list = unsafe { Array::<BnString>::new(paths, count, ()) };
2208- // let ids_list = unsafe { std::slice::from_raw_parts(ids, count).to_vec() };
2209- // let archives = ids_list.iter().filter_map(|id| {
2210- // let archive_raw = unsafe { BNBinaryViewGetTypeArchive(self.as_ref().handle, *id) };
2211- // match archive_raw.is_null() {
2212- // true => None,
2213- // false => Some(archive_raw)
2214- // }
2215- // }).collect();
2216- // unsafe { BNFreeStringList(ids, count) };
2217- // Array::new(archives)
2218- // }
2188+ /// Retrieve the attached type archives as a tuple of id and path.
2189+ ///
2190+ /// Using the returned id you can retrieve the [`TypeArchive`] with [`BinaryViewExt::type_archive_by_id`].
2191+ fn attached_type_archives ( & self ) -> Vec < ( String , String ) > {
2192+ let mut ids: * mut * mut c_char = std:: ptr:: null_mut ( ) ;
2193+ let mut paths: * mut * mut c_char = std:: ptr:: null_mut ( ) ;
2194+ let count =
2195+ unsafe { BNBinaryViewGetTypeArchives ( self . as_ref ( ) . handle , & mut ids, & mut paths) } ;
2196+ let path_list = unsafe { Array :: < BnString > :: new ( paths, count, ( ) ) } ;
2197+ let id_list = unsafe { Array :: < BnString > :: new ( ids, count, ( ) ) } ;
2198+ path_list
2199+ . iter ( )
2200+ . zip ( id_list. iter ( ) )
2201+ . map ( |( path, id) | ( id. to_string ( ) , path. to_string ( ) ) )
2202+ . collect ( )
2203+ }
2204+
2205+ /// Look up a connected [`TypeArchive`] by its `id`.
2206+ ///
2207+ /// NOTE: A [`TypeArchive`] can be attached but not connected, returning `None`.
2208+ fn type_archive_by_id ( & self , id : & str ) -> Option < Ref < TypeArchive > > {
2209+ let id = id. to_cstr ( ) ;
2210+ let result = unsafe { BNBinaryViewGetTypeArchive ( self . as_ref ( ) . handle , id. as_ptr ( ) ) } ;
2211+ let result_ptr = NonNull :: new ( result) ?;
2212+ Some ( unsafe { TypeArchive :: ref_from_raw ( result_ptr) } )
2213+ }
2214+
2215+ /// Look up the path for an attached (but not necessarily connected) [`TypeArchive`] by its `id`.
2216+ fn type_archive_path_by_id ( & self , id : & str ) -> Option < PathBuf > {
2217+ let id = id. to_cstr ( ) ;
2218+ let result = unsafe { BNBinaryViewGetTypeArchivePath ( self . as_ref ( ) . handle , id. as_ptr ( ) ) } ;
2219+ if result. is_null ( ) {
2220+ return None ;
2221+ }
2222+ let path_str = unsafe { BnString :: into_string ( result) } ;
2223+ Some ( PathBuf :: from ( path_str) )
2224+ }
22192225}
22202226
22212227impl < T : BinaryViewBase > BinaryViewExt for T { }
@@ -2428,6 +2434,7 @@ impl std::fmt::Debug for BinaryView {
24282434 . field ( "address_size" , & self . address_size ( ) )
24292435 . field ( "sections" , & self . sections ( ) . to_vec ( ) )
24302436 . field ( "segments" , & self . segments ( ) . to_vec ( ) )
2437+ . field ( "attached_type_archives" , & self . attached_type_archives ( ) )
24312438 . finish ( )
24322439 }
24332440}
0 commit comments