LCOV - code coverage report
Current view: top level - src/pe - delay_import.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 85.5 % 110 94
Test Date: 2026-04-12:00:00:00 Functions: 87.5 % 24 21

            Line data    Source code
       1              : //! PE Delayed import module
       2              : use crate::{common::FromFFI, declare_iterator, generic};
       3              : use lief_ffi as ffi;
       4              : use std::marker::PhantomData;
       5              : use std::pin::Pin;
       6              : 
       7              : pub struct DelayImport<'a> {
       8              :     ptr: cxx::UniquePtr<ffi::PE_DelayImport>,
       9              :     _owner: PhantomData<&'a ffi::PE_Binary>,
      10              : }
      11              : 
      12              : impl DelayImport<'_> {
      13              :     /// According to the official PE specifications, this value is reserved and should be set to 0
      14          169 :     pub fn attribute(&self) -> u32 {
      15          169 :         self.ptr.attribute()
      16          169 :     }
      17              : 
      18              :     /// Return the library's name (e.g. `kernel32.dll`)
      19          169 :     pub fn name(&self) -> String {
      20          169 :         self.ptr.name().to_string()
      21          169 :     }
      22              : 
      23              :     /// The RVA of the module handle (in the ``.data`` section).
      24              :     /// It is used for storage by the routine that is supplied to manage delay-loading.
      25          169 :     pub fn handle(&self) -> u32 {
      26          169 :         self.ptr.handle()
      27          169 :     }
      28              : 
      29              :     /// RVA of the delay-load import address table.
      30          169 :     pub fn iat(&self) -> u32 {
      31          169 :         self.ptr.iat()
      32          169 :     }
      33              : 
      34              :     /// RVA of the delay-load import names table.
      35              :     ///
      36              :     /// The content of this table has the layout as the Import lookup table
      37          169 :     pub fn names_table(&self) -> u32 {
      38          169 :         self.ptr.names_table()
      39          169 :     }
      40              : 
      41              :     /// RVA of the **bound** delay-load import address table or 0 if the table does not exist.
      42          169 :     pub fn biat(&self) -> u32 {
      43          169 :         self.ptr.biat()
      44          169 :     }
      45              : 
      46              :     /// RVA of the **unload** delay-load import address table or 0
      47              :     /// if the table does not exist.
      48              :     ///
      49              :     /// According to the PE specifications, this table is an
      50              :     /// exact copy of the delay import address table that can be
      51              :     /// used to to restore the original IAT the case of unloading.
      52          169 :     pub fn uiat(&self) -> u32 {
      53          169 :         self.ptr.uiat()
      54          169 :     }
      55              : 
      56              :     /// The timestamp of the DLL to which this image has been bound.
      57          169 :     pub fn timestamp(&self) -> u32 {
      58          169 :         self.ptr.timestamp()
      59          169 :     }
      60              : 
      61              :     /// Iterator over the DelayImport's entries ([`DelayImportEntry`])
      62          169 :     pub fn entries(&self) -> Entries<'_> {
      63          169 :         Entries::new(self.ptr.entries())
      64          169 :     }
      65              : }
      66              : 
      67              : impl std::fmt::Debug for DelayImport<'_> {
      68          169 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      69          169 :         f.debug_struct("DelayImport")
      70          169 :             .field("attribute", &self.attribute())
      71          169 :             .field("name", &self.name())
      72          169 :             .field("handle", &self.handle())
      73          169 :             .field("iat", &self.iat())
      74          169 :             .field("names_table", &self.names_table())
      75          169 :             .field("biat", &self.biat())
      76          169 :             .field("uiat", &self.uiat())
      77          169 :             .field("timestamp", &self.timestamp())
      78          169 :             .finish()
      79          169 :     }
      80              : }
      81              : 
      82              : impl<'a> FromFFI<ffi::PE_DelayImport> for DelayImport<'a> {
      83          182 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DelayImport>) -> Self {
      84          182 :         DelayImport {
      85          182 :             ptr,
      86          182 :             _owner: PhantomData,
      87          182 :         }
      88          182 :     }
      89              : }
      90              : 
      91              : /// Structure that represents an entry (i.e. an import) in the delay import table.
      92              : ///
      93              : /// It implements the [`generic::Symbol`] trait that exposes [`generic::Symbol::name`] and
      94              : /// [`generic::Symbol::value`].
      95              : ///
      96              : /// The meaning of [`generic::Symbol::value`] for this PE object is the address (as an RVA) in the
      97              : /// IAT where the resolution should take place.
      98              : pub struct DelayImportEntry<'a> {
      99              :     ptr: cxx::UniquePtr<ffi::PE_DelayImportEntry>,
     100              :     _owner: PhantomData<&'a ffi::PE_DelayImport>,
     101              : }
     102              : 
     103              : impl DelayImportEntry<'_> {
     104              :     /// `True` if it is an import by ordinal
     105            0 :     pub fn is_ordinal(&self) -> bool {
     106            0 :         self.ptr.is_ordinal()
     107            0 :     }
     108              : 
     109              :     /// The ordinal value
     110          832 :     pub fn ordinal(&self) -> u16 {
     111          832 :         self.ptr.ordinal()
     112          832 :     }
     113              : 
     114              :     /// See: [`DelayImportEntry::data`]
     115          832 :     pub fn hint_name_rva(&self) -> u64 {
     116          832 :         self.ptr.hint_name_rva()
     117          832 :     }
     118              : 
     119              :     /// Index into the export table that is used to speed-up the symbol resolution
     120          832 :     pub fn hint(&self) -> u16 {
     121          832 :         self.ptr.hint()
     122          832 :     }
     123              : 
     124              :     /// Value of the current entry in the Import Address Table.
     125          832 :     pub fn iat_value(&self) -> u64 {
     126          832 :         self.ptr.iat_value()
     127          832 :     }
     128              : 
     129              :     /// Raw value
     130          832 :     pub fn data(&self) -> u64 {
     131          832 :         self.ptr.data()
     132          832 :     }
     133              : 
     134              :     /// Demangled representation of the symbol or an empty string if it can't
     135              :     /// be demangled
     136            0 :     pub fn demangled_name(&self) -> String {
     137            0 :         self.ptr.demangled_name().to_string()
     138            0 :     }
     139              : }
     140              : 
     141              : impl generic::Symbol for DelayImportEntry<'_> {
     142         2496 :     fn as_generic(&self) -> &ffi::AbstractSymbol {
     143         2496 :         self.ptr.as_ref().unwrap().as_ref()
     144         2496 :     }
     145              : 
     146            0 :     fn as_pin_mut_generic(&mut self) -> Pin<&mut ffi::AbstractSymbol> {
     147            0 :         unsafe {
     148            0 :             Pin::new_unchecked({
     149            0 :                 (self.ptr.as_ref().unwrap().as_ref() as *const ffi::AbstractSymbol
     150            0 :                     as *mut ffi::AbstractSymbol)
     151            0 :                     .as_mut()
     152            0 :                     .unwrap()
     153            0 :             })
     154            0 :         }
     155            0 :     }
     156              : }
     157              : 
     158              : impl std::fmt::Debug for DelayImportEntry<'_> {
     159          832 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     160          832 :         let base = self as &dyn generic::Symbol;
     161          832 :         f.debug_struct("DelayImportEntry")
     162          832 :             .field("base", &base)
     163          832 :             .field("ordinal", &self.ordinal())
     164          832 :             .field("hint_name_rva", &self.hint_name_rva())
     165          832 :             .field("hint", &self.hint())
     166          832 :             .field("iat_value", &self.iat_value())
     167          832 :             .field("data", &self.data())
     168          832 :             .finish()
     169          832 :     }
     170              : }
     171              : 
     172              : impl<'a> FromFFI<ffi::PE_DelayImportEntry> for DelayImportEntry<'a> {
     173          832 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DelayImportEntry>) -> Self {
     174          832 :         Self {
     175          832 :             ptr,
     176          832 :             _owner: PhantomData,
     177          832 :         }
     178          832 :     }
     179              : }
     180              : 
     181          169 : declare_iterator!(
     182          169 :     DelayImports,
     183          169 :     DelayImport<'a>,
     184          169 :     ffi::PE_DelayImport,
     185          169 :     ffi::PE_Binary,
     186          169 :     ffi::PE_Binary_it_delay_imports
     187          169 : );
     188          832 : declare_iterator!(
     189          832 :     Entries,
     190          832 :     DelayImportEntry<'a>,
     191          832 :     ffi::PE_DelayImportEntry,
     192          832 :     ffi::PE_DelayImport,
     193          832 :     ffi::PE_DelayImport_it_entries
     194          832 : );
        

Generated by: LCOV version 2.1-1