1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15- //! A view on binary data and queryable interface of a binary file.
16- //!
17- //! One key job of BinaryView is file format parsing which allows Binary Ninja to read, write,
18- //! insert, remove portions of the file given a virtual address.
19- //!
20- //! For the purposes of this documentation we define a virtual address as the memory address that
21- //! the various pieces of the physical file will be loaded at.
22- //! TODO : Mirror the Python docs for this
15+ //! A view on binary data and queryable interface of a binary files analysis.
2316
2417use binaryninjacore_sys:: * ;
2518
@@ -104,6 +97,7 @@ pub trait BinaryViewBase: AsRef<BinaryView> {
10497 0
10598 }
10699
100+ /// Check if the offset is valid for the current view.
107101 fn offset_valid ( & self , offset : u64 ) -> bool {
108102 let mut buf = [ 0u8 ; 1 ] ;
109103
@@ -112,22 +106,28 @@ pub trait BinaryViewBase: AsRef<BinaryView> {
112106 self . as_ref ( ) . read ( & mut buf[ ..] , offset) == buf. len ( )
113107 }
114108
109+ /// Check if the offset is readable for the current view.
115110 fn offset_readable ( & self , offset : u64 ) -> bool {
116111 self . offset_valid ( offset)
117112 }
118113
114+ /// Check if the offset is writable for the current view.
119115 fn offset_writable ( & self , offset : u64 ) -> bool {
120116 self . offset_valid ( offset)
121117 }
122118
119+ /// Check if the offset is executable for the current view.
123120 fn offset_executable ( & self , offset : u64 ) -> bool {
124121 self . offset_valid ( offset)
125122 }
126123
124+ /// Check if the offset is backed by the original file and not added after the fact.
127125 fn offset_backed_by_file ( & self , offset : u64 ) -> bool {
128126 self . offset_valid ( offset)
129127 }
130128
129+ /// Get the next valid offset after the provided `offset`, useful if you need to iterate over all
130+ /// readable offsets in the view.
131131 fn next_valid_offset_after ( & self , offset : u64 ) -> u64 {
132132 let start = self . as_ref ( ) . start ( ) ;
133133
@@ -138,15 +138,17 @@ pub trait BinaryViewBase: AsRef<BinaryView> {
138138 }
139139 }
140140
141- # [ allow ( unused ) ]
142- fn modification_status ( & self , offset : u64 ) -> ModificationStatus {
141+ /// Whether the data at the given `offset` been modified (patched).
142+ fn modification_status ( & self , _offset : u64 ) -> ModificationStatus {
143143 ModificationStatus :: Original
144144 }
145145
146+ /// The lowest address in the view.
146147 fn start ( & self ) -> u64 {
147148 0
148149 }
149150
151+ /// The length of the view.
150152 fn len ( & self ) -> u64 {
151153 0
152154 }
@@ -546,8 +548,6 @@ pub trait BinaryViewExt: BinaryViewBase {
546548 }
547549
548550 /// The highest address in the view.
549- ///
550- /// NOTE: If operating within a [`Workflow`], consider using [`AnalysisContext::end`].
551551 fn end ( & self ) -> u64 {
552552 unsafe { BNGetEndOffset ( self . as_ref ( ) . handle ) }
553553 }
@@ -2454,6 +2454,26 @@ pub trait BinaryViewExt: BinaryViewBase {
24542454
24552455impl < T : BinaryViewBase > BinaryViewExt for T { }
24562456
2457+ /// Represents the "whole view" of the binary and its analysis.
2458+ ///
2459+ /// Analysis information:
2460+ ///
2461+ /// - [`BinaryViewExt::functions`]
2462+ /// - [`BinaryViewExt::data_variables`]
2463+ /// - [`BinaryViewExt::strings`]
2464+ ///
2465+ /// Annotation information:
2466+ ///
2467+ /// - [`BinaryViewExt::symbols`]
2468+ /// - [`BinaryViewExt::tags_all_scopes`]
2469+ /// - [`BinaryViewExt::comments`]
2470+ ///
2471+ /// Data representation and binary information:
2472+ ///
2473+ /// - [`BinaryViewExt::types`]
2474+ /// - [`BinaryViewExt::segments`]
2475+ /// - [`BinaryViewExt::sections`]
2476+ ///
24572477/// # Cleaning up
24582478///
24592479/// [`BinaryView`] has a cyclic relationship with the associated [`FileMetadata`], each holds a strong
@@ -2476,21 +2496,20 @@ impl BinaryView {
24762496 Ref :: new ( Self { handle } )
24772497 }
24782498
2479- /// Construct the raw binary view from the given metadata. Before calling this make sure you have
2480- /// a valid file path set for the [`FileMetadata`]. It is required that the [`FileMetadata::file_path`]
2481- /// exist on the local filesystem.
2499+ /// Construct the raw binary view from the given metadata.
2500+ ///
2501+ /// Before calling this, make sure you have a valid file path set for the [`FileMetadata`]. It is
2502+ /// required that the [`FileMetadata::file_path`] exist in the local filesystem.
24822503 pub fn from_metadata ( meta : & FileMetadata ) -> Result < Ref < Self > > {
24832504 if !meta. file_path ( ) . exists ( ) {
24842505 return Err ( ( ) ) ;
24852506 }
24862507 let file = meta. file_path ( ) . to_cstr ( ) ;
24872508 let handle =
24882509 unsafe { BNCreateBinaryDataViewFromFilename ( meta. handle , file. as_ptr ( ) as * mut _ ) } ;
2489-
24902510 if handle. is_null ( ) {
24912511 return Err ( ( ) ) ;
24922512 }
2493-
24942513 unsafe { Ok ( Ref :: new ( Self { handle } ) ) }
24952514 }
24962515
@@ -2503,29 +2522,34 @@ impl BinaryView {
25032522 Self :: from_metadata ( meta)
25042523 }
25052524
2506- pub fn from_accessor < A : Accessor > (
2525+ // TODO: Provide an API that manages the lifetime of the accessor and the view.
2526+ /// Construct the raw binary view from the given `accessor` and metadata.
2527+ ///
2528+ /// It is the responsibility of the caller to keep the accessor alive for the lifetime of the view;
2529+ /// because of this, we mark the function as unsafe.
2530+ pub unsafe fn from_accessor < A : Accessor > (
25072531 meta : & FileMetadata ,
2508- file : & mut FileAccessor < A > ,
2532+ accessor : & mut FileAccessor < A > ,
25092533 ) -> Result < Ref < Self > > {
2510- let handle = unsafe { BNCreateBinaryDataViewFromFile ( meta. handle , & mut file. raw ) } ;
2511-
2534+ let handle = unsafe { BNCreateBinaryDataViewFromFile ( meta. handle , & mut accessor. raw ) } ;
25122535 if handle. is_null ( ) {
25132536 return Err ( ( ) ) ;
25142537 }
2515-
25162538 unsafe { Ok ( Ref :: new ( Self { handle } ) ) }
25172539 }
25182540
2519- pub fn from_data ( meta : & FileMetadata , data : & [ u8 ] ) -> Result < Ref < Self > > {
2541+ /// Construct the raw binary view from the given `data` and metadata.
2542+ ///
2543+ /// The data will be copied into the view, so the caller does not need to keep the data alive.
2544+ pub fn from_data ( meta : & FileMetadata , data : & [ u8 ] ) -> Ref < Self > {
25202545 let handle = unsafe {
25212546 BNCreateBinaryDataViewFromData ( meta. handle , data. as_ptr ( ) as * mut _ , data. len ( ) )
25222547 } ;
2523-
2524- if handle. is_null ( ) {
2525- return Err ( ( ) ) ;
2526- }
2527-
2528- unsafe { Ok ( Ref :: new ( Self { handle } ) ) }
2548+ assert ! (
2549+ !handle. is_null( ) ,
2550+ "BNCreateBinaryDataViewFromData should always succeed"
2551+ ) ;
2552+ unsafe { Ref :: new ( Self { handle } ) }
25292553 }
25302554
25312555 /// Save the original binary file to the provided `file_path` along with any modifications.
@@ -2571,45 +2595,26 @@ impl BinaryViewBase for BinaryView {
25712595 unsafe { BNRemoveViewData ( self . handle , offset, len as u64 ) }
25722596 }
25732597
2574- /// Check if the offset is valid for the current view.
2575- ///
2576- /// NOTE: If operating within a [`Workflow`], consider using [`AnalysisContext::is_offset_valid`].
25772598 fn offset_valid ( & self , offset : u64 ) -> bool {
25782599 unsafe { BNIsValidOffset ( self . handle , offset) }
25792600 }
25802601
2581- /// Check if the offset is readable for the current view.
2582- ///
2583- /// NOTE: If operating within a [`Workflow`], consider using [`AnalysisContext::is_offset_valid`].
25842602 fn offset_readable ( & self , offset : u64 ) -> bool {
25852603 unsafe { BNIsOffsetReadable ( self . handle , offset) }
25862604 }
25872605
2588- /// Check if the offset is writable for the current view.
2589- ///
2590- /// NOTE: If operating within a [`Workflow`], consider using [`AnalysisContext::is_offset_writable`].
25912606 fn offset_writable ( & self , offset : u64 ) -> bool {
25922607 unsafe { BNIsOffsetWritable ( self . handle , offset) }
25932608 }
25942609
2595- /// Check if the offset is executable for the current view.
2596- ///
2597- /// NOTE: If operating within a [`Workflow`], consider using [`AnalysisContext::is_offset_executable`].
25982610 fn offset_executable ( & self , offset : u64 ) -> bool {
25992611 unsafe { BNIsOffsetExecutable ( self . handle , offset) }
26002612 }
26012613
2602- /// Check if the offset is backed by the original file and not added after the fact.
2603- ///
2604- /// NOTE: If operating within a [`Workflow`], consider using [`AnalysisContext::is_offset_backed_by_file`].
26052614 fn offset_backed_by_file ( & self , offset : u64 ) -> bool {
26062615 unsafe { BNIsOffsetBackedByFile ( self . handle , offset) }
26072616 }
26082617
2609- /// Get the next valid offset after the provided `offset`, useful if you need to iterate over all
2610- /// readable offsets in the view.
2611- ///
2612- /// NOTE: If operating within a [`Workflow`], consider using [`AnalysisContext::next_valid_offset`].
26132618 fn next_valid_offset_after ( & self , offset : u64 ) -> u64 {
26142619 unsafe { BNGetNextValidOffset ( self . handle , offset) }
26152620 }
@@ -2618,16 +2623,10 @@ impl BinaryViewBase for BinaryView {
26182623 unsafe { BNGetModification ( self . handle , offset) }
26192624 }
26202625
2621- /// The lowest address in the view.
2622- ///
2623- /// NOTE: If operating within a [`Workflow`], consider using [`AnalysisContext::start`].
26242626 fn start ( & self ) -> u64 {
26252627 unsafe { BNGetStartOffset ( self . handle ) }
26262628 }
26272629
2628- /// The length of the view, lowest to highest address.
2629- ///
2630- /// NOTE: If operating within a [`Workflow`], consider using [`AnalysisContext::length`].
26312630 fn len ( & self ) -> u64 {
26322631 unsafe { BNGetViewLength ( self . handle ) }
26332632 }
0 commit comments