LCOV - code coverage report
Current view: top level - src/coff - binary.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 56.6 % 99 56
Test Date: 2025-06-24:00:00:00 Functions: 54.5 % 22 12

            Line data    Source code
       1              : use lief_ffi as ffi;
       2              : use crate::common::FromFFI;
       3              : use crate::declare_fwd_iterator;
       4              : use crate::common::into_optional;
       5              : use crate::declare_iterator;
       6              : use crate::assembly::Instructions;
       7              : use super::{Relocation, Symbol, Section, Header, String};
       8              : 
       9              : pub struct Binary {
      10              :     ptr: cxx::UniquePtr<ffi::COFF_Binary>,
      11              : }
      12              : 
      13              : impl FromFFI<ffi::COFF_Binary> for Binary {
      14           84 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_Binary>) -> Self {
      15           84 :         Self { ptr }
      16           84 :     }
      17              : }
      18              : 
      19              : impl Binary {
      20              :     /// Parse from a file path given as a string
      21           96 :     pub fn parse(path: &str) -> Option<Self> {
      22           96 :         let ffi = ffi::COFF_Binary::parse(path);
      23           96 :         if ffi.is_null() {
      24           12 :             return None;
      25           84 :         }
      26           84 :         Some(Binary::from_ffi(ffi))
      27           96 :     }
      28              : 
      29              :     /// The COFF header
      30           84 :     pub fn header(&self) -> Header {
      31           84 :         Header::from_ffi(self.ptr.header())
      32           84 :     }
      33              : 
      34              :     /// Iterator over the different sections located in this COFF binary
      35           84 :     pub fn sections(&self) -> Sections {
      36           84 :         Sections::new(self.ptr.sections())
      37           84 :     }
      38              : 
      39              :     /// Iterator over **all** the relocations used by this COFF binary
      40           84 :     pub fn relocations(&self) -> Relocations {
      41           84 :         Relocations::new(self.ptr.relocations())
      42           84 :     }
      43              : 
      44              :     /// Iterator over the COFF's symbols
      45           84 :     pub fn symbols(&self) -> Symbols {
      46           84 :         Symbols::new(self.ptr.symbols())
      47           84 :     }
      48              : 
      49              :     /// Iterator over the functions implemented in this COFF
      50           84 :     pub fn functions(&self) -> Functions {
      51           84 :         Functions::new(self.ptr.functions())
      52           84 :     }
      53              : 
      54              :     /// Iterator over the COFF's strings
      55            0 :     pub fn string_table(&self) -> Strings {
      56            0 :         Strings::new(self.ptr.string_table())
      57            0 :     }
      58              : 
      59              :     /// Try to find the COFF string at the given offset in the COFF string table.
      60              :     ///
      61              :     /// <div class="warning">
      62              :     /// This offset must include the first 4 bytes holding the size of the table. Hence,
      63              :     /// the first string starts a the offset 4.
      64              :     /// </div>
      65          168 :     pub fn find_string(&self, offset: u32) -> Option<String> {
      66          168 :         into_optional(self.ptr.find_string(offset))
      67          168 :     }
      68              : 
      69              :     /// Try to find the function (symbol) with the given name
      70            0 :     pub fn find_function(&self, name: &str) -> Option<Symbol> {
      71            0 :         into_optional(self.ptr.find_function(name))
      72            0 :     }
      73              : 
      74              :     /// Try to find the function (symbol) with the given **demangled** name
      75            0 :     pub fn find_demangled_function(&self, name: &str) -> Option<Symbol> {
      76            0 :         into_optional(self.ptr.find_demangled_function(name))
      77            0 :     }
      78              : 
      79              :     /// Disassemble code provided by the given slice at the specified `address` parameter.
      80              :     ///
      81              :     /// See also [`crate::assembly::Instruction`] and [`crate::assembly::Instructions`]
      82            0 :     pub fn disassemble_slice(&self, slice: &[u8], address: u64) -> InstructionsIt {
      83            0 :         unsafe {
      84            0 :             InstructionsIt::new(self.ptr.disassemble_buffer(
      85            0 :                     slice.as_ptr(), slice.len().try_into().unwrap(),
      86            0 :                     address))
      87            0 :         }
      88            0 :     }
      89              : 
      90              :     /// Disassemble code for the given function name
      91              :     ///
      92              :     /// ```
      93              :     /// let insts = binary.disassemble_function("int __cdecl bar(int, int)");
      94              :     /// for inst in insts {
      95              :     ///     println!("{}", inst.to_string());
      96              :     /// }
      97              :     /// ```
      98              :     ///
      99              :     /// See also [`crate::assembly::Instruction`] and [`crate::assembly::Instructions`]
     100            0 :     pub fn disassemble_function(&self, name: &str) -> InstructionsIt {
     101            0 :         InstructionsIt::new(self.ptr.disassemble_function(name.to_string()))
     102            0 :     }
     103              : 
     104              : 
     105              :     /// Disassemble code for the given symbol
     106              :     ///
     107              :     /// ```
     108              :     /// let symbol = binary.find_demangled_function("int __cdecl bar(int, int)").unwrap();
     109              :     /// let insts = binary.disassemble_symbol(&symbol);
     110              :     /// for inst in insts {
     111              :     ///     println!("{}", inst.to_string());
     112              :     /// }
     113              :     /// ```
     114              :     ///
     115              :     /// See also [`crate::assembly::Instruction`] and [`crate::assembly::Instructions`]
     116            0 :     pub fn disassemble_symbol(&self, symbol: &Symbol) -> InstructionsIt {
     117            0 :         InstructionsIt::new(self.ptr.disassemble_symbol(symbol.ptr.as_ref().unwrap()))
     118            0 :     }
     119              : }
     120              : 
     121              : impl std::fmt::Display for Binary {
     122            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     123            0 :         write!(f, "{}", self.ptr.to_string())
     124            0 :     }
     125              : }
     126              : 
     127              : impl std::fmt::Debug for Binary {
     128            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     129            0 :         f.debug_struct("COFF Binary")
     130            0 :             .finish()
     131            0 :     }
     132              : }
     133              : 
     134              : 
     135              : 
     136        11184 : declare_iterator!(
     137        11184 :     Relocations,
     138        11184 :     Relocation<'a>,
     139        11184 :     ffi::COFF_Relocation,
     140        11184 :     ffi::COFF_Binary,
     141        11184 :     ffi::COFF_Binary_it_relocations
     142        11184 : );
     143              : 
     144         4020 : declare_iterator!(
     145         4020 :     Sections,
     146         4020 :     Section<'a>,
     147         4020 :     ffi::COFF_Section,
     148         4020 :     ffi::COFF_Binary,
     149         4020 :     ffi::COFF_Binary_it_sections
     150         4020 : );
     151              : 
     152         9384 : declare_iterator!(
     153         9384 :     Symbols,
     154         9384 :     Symbol<'a>,
     155         9384 :     ffi::COFF_Symbol,
     156         9384 :     ffi::COFF_Binary,
     157         9384 :     ffi::COFF_Binary_it_symbols
     158         9384 : );
     159              : 
     160            0 : declare_iterator!(
     161            0 :     Strings,
     162            0 :     String<'a>,
     163            0 :     ffi::COFF_String,
     164            0 :     ffi::COFF_Binary,
     165            0 :     ffi::COFF_Binary_it_strings
     166            0 : );
     167              : 
     168         1392 : declare_iterator!(
     169         1392 :     Functions,
     170         1392 :     Symbol<'a>,
     171         1392 :     ffi::COFF_Symbol,
     172         1392 :     ffi::COFF_Binary,
     173         1392 :     ffi::COFF_Binary_it_functions
     174         1392 : );
     175              : 
     176              : 
     177            0 : declare_fwd_iterator!(
     178            0 :     InstructionsIt,
     179            0 :     Instructions,
     180            0 :     ffi::asm_Instruction,
     181            0 :     ffi::COFF_Binary,
     182            0 :     ffi::COFF_Binary_it_instructions
     183            0 : );
        

Generated by: LCOV version 2.1-1