LCOV - code coverage report
Current view: top level - src/pe - delay_import.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 94.0 % 100 94
Test Date: 2024-11-30:00:00:00 Functions: 91.3 % 23 21

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

Generated by: LCOV version 2.1-1