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-08-10:00:00:00 Functions: 52.2 % 23 12

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

Generated by: LCOV version 2.1-1