@@ -59,9 +59,9 @@ use crate::types::{
5959 NamedTypeReference , QualifiedName , QualifiedNameAndType , QualifiedNameTypeAndId , Type ,
6060} ;
6161use crate :: variable:: DataVariable ;
62- use crate :: Endianness ;
62+ use crate :: { Endianness , BN_FULL_CONFIDENCE } ;
6363use std:: collections:: HashMap ;
64- use std:: ffi:: { c_char, c_void} ;
64+ use std:: ffi:: { c_char, c_void, CString } ;
6565use std:: ops:: Range ;
6666use std:: path:: Path ;
6767use std:: ptr:: NonNull ;
@@ -222,10 +222,8 @@ pub trait BinaryViewExt: BinaryViewBase {
222222 /// Reads up to `len` bytes from address `offset`
223223 fn read_vec ( & self , offset : u64 , len : usize ) -> Vec < u8 > {
224224 let mut ret = vec ! [ 0 ; len] ;
225-
226225 let size = self . read ( & mut ret, offset) ;
227226 ret. truncate ( size) ;
228-
229227 ret
230228 }
231229
@@ -238,6 +236,22 @@ pub trait BinaryViewExt: BinaryViewBase {
238236 read_size
239237 }
240238
239+ /// Reads up to `len` bytes from the address `offset` returning a `CString` if available.
240+ fn read_c_string_at ( & self , offset : u64 , len : usize ) -> Option < CString > {
241+ let mut buf = vec ! [ 0 ; len] ;
242+ let size = self . read ( & mut buf, offset) ;
243+ let string = CString :: new ( buf[ ..size] . to_vec ( ) ) . ok ( ) ?;
244+ Some ( string)
245+ }
246+
247+ /// Reads up to `len` bytes from the address `offset` returning a `String` if available.
248+ fn read_utf8_string_at ( & self , offset : u64 , len : usize ) -> Option < String > {
249+ let mut buf = vec ! [ 0 ; len] ;
250+ let size = self . read ( & mut buf, offset) ;
251+ let string = String :: from_utf8 ( buf[ ..size] . to_vec ( ) ) . ok ( ) ?;
252+ Some ( string)
253+ }
254+
241255 /// Search the view using the query options.
242256 ///
243257 /// In the `on_match` callback return `false` to stop searching.
@@ -562,17 +576,15 @@ pub trait BinaryViewExt: BinaryViewBase {
562576 }
563577 }
564578
565- fn analysis_info ( & self ) -> Result < AnalysisInfo > {
566- let info_ref = unsafe { BNGetAnalysisInfo ( self . as_ref ( ) . handle ) } ;
567- if info_ref. is_null ( ) {
568- return Err ( ( ) ) ;
569- }
570- let info = unsafe { * info_ref } ;
579+ fn analysis_info ( & self ) -> AnalysisInfo {
580+ let info_ptr = unsafe { BNGetAnalysisInfo ( self . as_ref ( ) . handle ) } ;
581+ assert ! ( !info_ptr. is_null( ) ) ;
582+ let info = unsafe { * info_ptr } ;
571583 let active_infos = unsafe { slice:: from_raw_parts ( info. activeInfo , info. count ) } ;
572584
573585 let mut active_info_list = vec ! [ ] ;
574586 for active_info in active_infos {
575- let func = unsafe { Function :: ref_from_raw ( active_info. func ) } ;
587+ let func = unsafe { Function :: from_raw ( active_info. func ) . to_owned ( ) } ;
576588 active_info_list. push ( ActiveAnalysisInfo {
577589 func,
578590 analysis_time : active_info. analysisTime ,
@@ -584,11 +596,11 @@ pub trait BinaryViewExt: BinaryViewBase {
584596 let result = AnalysisInfo {
585597 state : info. state ,
586598 analysis_time : info. analysisTime ,
587- active_info : vec ! [ ] ,
599+ active_info : active_info_list ,
588600 } ;
589601
590- unsafe { BNFreeAnalysisInfo ( info_ref ) } ;
591- Ok ( result)
602+ unsafe { BNFreeAnalysisInfo ( info_ptr ) } ;
603+ result
592604 }
593605
594606 fn analysis_progress ( & self ) -> AnalysisProgress {
@@ -772,7 +784,7 @@ pub trait BinaryViewExt: BinaryViewBase {
772784 } else {
773785 std:: ptr:: null_mut ( )
774786 } ,
775- confidence : 255 , // BN_FULL_CONFIDENCE
787+ confidence : BN_FULL_CONFIDENCE ,
776788 } ;
777789
778790 unsafe {
@@ -2235,6 +2247,14 @@ pub trait BinaryViewExt: BinaryViewBase {
22352247 /// NOTE: This returns a list of [`StringReference`] as strings may not be representable
22362248 /// as a [`String`] or even a [`BnString`]. It is the caller's responsibility to read the underlying
22372249 /// data and convert it to a representable form.
2250+ ///
2251+ /// Some helpers for reading strings are available:
2252+ ///
2253+ /// - [`BinaryViewExt::read_c_string_at`]
2254+ /// - [`BinaryViewExt::read_utf8_string_at`]
2255+ ///
2256+ /// NOTE: This returns discovered strings and is therefore governed by `analysis.limits.minStringLength`
2257+ /// and other settings.
22382258 fn strings ( & self ) -> Array < StringReference > {
22392259 unsafe {
22402260 let mut count = 0 ;
@@ -2245,13 +2265,22 @@ pub trait BinaryViewExt: BinaryViewBase {
22452265
22462266 /// Retrieve the string that falls on a given virtual address.
22472267 ///
2248- /// NOTE: This returns discovered strings and is therefore governed by `analysis.limits.minStringLength` and other settings.
2249- fn string_at ( & self , addr : u64 ) -> Option < BNStringReference > {
2268+ /// NOTE: This returns a [`StringReference`] and since strings may not be representable as a Rust
2269+ /// [`String`] or even a [`BnString`]. It is the caller's responsibility to read the underlying
2270+ /// data and convert it to a representable form.
2271+ ///
2272+ /// Some helpers for reading strings are available:
2273+ ///
2274+ /// - [`BinaryViewExt::read_c_string_at`]
2275+ /// - [`BinaryViewExt::read_utf8_string_at`]
2276+ ///
2277+ /// NOTE: This returns discovered strings and is therefore governed by `analysis.limits.minStringLength`
2278+ /// and other settings.
2279+ fn string_at ( & self , addr : u64 ) -> Option < StringReference > {
22502280 let mut str_ref = BNStringReference :: default ( ) ;
22512281 let success = unsafe { BNGetStringAtAddress ( self . as_ref ( ) . handle , addr, & mut str_ref) } ;
2252-
22532282 if success {
2254- Some ( str_ref)
2283+ Some ( str_ref. into ( ) )
22552284 } else {
22562285 None
22572286 }
@@ -2262,6 +2291,14 @@ pub trait BinaryViewExt: BinaryViewBase {
22622291 /// NOTE: This returns a list of [`StringReference`] as strings may not be representable
22632292 /// as a [`String`] or even a [`BnString`]. It is the caller's responsibility to read the underlying
22642293 /// data and convert it to a representable form.
2294+ ///
2295+ /// Some helpers for reading strings are available:
2296+ ///
2297+ /// - [`BinaryViewExt::read_c_string_at`]
2298+ /// - [`BinaryViewExt::read_utf8_string_at`]
2299+ ///
2300+ /// NOTE: This returns discovered strings and is therefore governed by `analysis.limits.minStringLength`
2301+ /// and other settings.
22652302 fn strings_in_range ( & self , range : Range < u64 > ) -> Array < StringReference > {
22662303 unsafe {
22672304 let mut count = 0 ;
0 commit comments