LCOV - code coverage report
Current view: top level - src/coff - binary.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 56.0 % 100 56
Test Date: 2026-04-12:00:00:00 Functions: 52.2 % 23 12

            Line data    Source code
       1              : use super::{Header, Relocation, Section, String, Symbol};
       2              : use crate::assembly::Instructions;
       3              : use crate::common::into_optional;
       4              : use crate::common::FromFFI;
       5              : use crate::{declare_iterator, declare_lazy_iterator};
       6              : use lief_ffi as ffi;
       7              : use std::path::Path;
       8              : 
       9              : pub struct Binary {
      10              :     ptr: cxx::UniquePtr<ffi::COFF_Binary>,
      11              : }
      12              : 
      13              : impl FromFFI<ffi::COFF_Binary> for Binary {
      14           91 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_Binary>) -> Self {
      15           91 :         Self { ptr }
      16           91 :     }
      17              : }
      18              : 
      19              : impl Binary {
      20              :     /// Parse from a file path given as a string
      21            8 :     pub fn parse<P: AsRef<Path>>(path: P) -> Option<Self> {
      22            8 :         let ffi = ffi::COFF_Binary::parse(path.as_ref().to_str().unwrap());
      23            8 :         if ffi.is_null() {
      24            1 :             return None;
      25            7 :         }
      26            7 :         Some(Binary::from_ffi(ffi))
      27            8 :     }
      28              : 
      29              :     /// The COFF header
      30           91 :     pub fn header(&self) -> Header<'_> {
      31           91 :         Header::from_ffi(self.ptr.header())
      32           91 :     }
      33              : 
      34              :     /// Iterator over the different sections located in this COFF binary
      35           91 :     pub fn sections(&self) -> Sections<'_> {
      36           91 :         Sections::new(self.ptr.sections())
      37           91 :     }
      38              : 
      39              :     /// Iterator over **all** the relocations used by this COFF binary
      40           91 :     pub fn relocations(&self) -> Relocations<'_> {
      41           91 :         Relocations::new(self.ptr.relocations())
      42           91 :     }
      43              : 
      44              :     /// Iterator over the COFF's symbols
      45           91 :     pub fn symbols(&self) -> Symbols<'_> {
      46           91 :         Symbols::new(self.ptr.symbols())
      47           91 :     }
      48              : 
      49              :     /// Iterator over the functions implemented in this COFF
      50           91 :     pub fn functions(&self) -> Functions<'_> {
      51           91 :         Functions::new(self.ptr.functions())
      52           91 :     }
      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          182 :     pub fn find_string(&self, offset: u32) -> Option<String<'_>> {
      66          182 :         into_optional(self.ptr.find_string(offset))
      67          182 :     }
      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(),
      86            0 :                 slice.len().try_into().unwrap(),
      87            0 :                 address,
      88            0 :             ))
      89            0 :         }
      90            0 :     }
      91              : 
      92              :     /// Disassemble code for the given function name
      93              :     ///
      94              :     /// ```
      95              :     /// let insts = binary.disassemble_function("int __cdecl bar(int, int)");
      96              :     /// for inst in insts {
      97              :     ///     println!("{}", inst.to_string());
      98              :     /// }
      99              :     /// ```
     100              :     ///
     101              :     /// See also [`crate::assembly::Instruction`] and [`crate::assembly::Instructions`]
     102            0 :     pub fn disassemble_function(&self, name: &str) -> InstructionsIt<'_> {
     103            0 :         InstructionsIt::new(self.ptr.disassemble_function(name.to_string()))
     104            0 :     }
     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").finish()
     131            0 :     }
     132              : }
     133              : 
     134        12116 : declare_iterator!(
     135        12116 :     Relocations,
     136        12116 :     Relocation<'a>,
     137        12116 :     ffi::COFF_Relocation,
     138        12116 :     ffi::COFF_Binary,
     139        12116 :     ffi::COFF_Binary_it_relocations
     140        12116 : );
     141              : 
     142         4355 : declare_iterator!(
     143         4355 :     Sections,
     144         4355 :     Section<'a>,
     145         4355 :     ffi::COFF_Section,
     146         4355 :     ffi::COFF_Binary,
     147         4355 :     ffi::COFF_Binary_it_sections
     148         4355 : );
     149              : 
     150        10166 : declare_iterator!(
     151        10166 :     Symbols,
     152        10166 :     Symbol<'a>,
     153        10166 :     ffi::COFF_Symbol,
     154        10166 :     ffi::COFF_Binary,
     155        10166 :     ffi::COFF_Binary_it_symbols
     156        10166 : );
     157              : 
     158            0 : declare_iterator!(
     159            0 :     Strings,
     160            0 :     String<'a>,
     161            0 :     ffi::COFF_String,
     162            0 :     ffi::COFF_Binary,
     163            0 :     ffi::COFF_Binary_it_strings
     164            0 : );
     165              : 
     166         1508 : declare_iterator!(
     167         1508 :     Functions,
     168         1508 :     Symbol<'a>,
     169         1508 :     ffi::COFF_Symbol,
     170         1508 :     ffi::COFF_Binary,
     171         1508 :     ffi::COFF_Binary_it_functions
     172         1508 : );
     173              : 
     174            0 : declare_lazy_iterator!(
     175            0 :     InstructionsIt,
     176            0 :     Instructions,
     177            0 :     ffi::asm_Instruction,
     178            0 :     ffi::COFF_Binary,
     179            0 :     ffi::COFF_Binary_it_instructions
     180            0 : );
        

Generated by: LCOV version 2.1-1