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

            Line data    Source code
       1              : //! This module represents PE's Imports
       2              : 
       3              : use std::marker::PhantomData;
       4              : 
       5              : use crate::common::into_optional;
       6              : use crate::declare_iterator;
       7              : use crate::pe::DataDirectory;
       8              : use crate::{common::FromFFI, generic};
       9              : use lief_ffi as ffi;
      10              : 
      11              : pub struct Import<'a> {
      12              :     ptr: cxx::UniquePtr<ffi::PE_Import>,
      13              :     _owner: PhantomData<&'a ffi::PE_Binary>,
      14              : }
      15              : 
      16              : impl std::fmt::Debug for Import<'_> {
      17          610 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      18          610 :         f.debug_struct("Import")
      19          610 :             .field("name", &self.name())
      20          610 :             .field("forwarder_chain", &self.forwarder_chain())
      21          610 :             .field("timedatestamp", &self.timedatestamp())
      22          610 :             .field("import_address_table_rva", &self.import_address_table_rva())
      23          610 :             .field("import_lookup_table_rva", &self.import_lookup_table_rva())
      24          610 :             .field("directory", &self.directory())
      25          610 :             .field("iat_directory", &self.iat_directory())
      26          610 :             .finish()
      27          610 :     }
      28              : }
      29              : 
      30              : impl<'a> FromFFI<ffi::PE_Import> for Import<'a> {
      31          620 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_Import>) -> Self {
      32          620 :         Import {
      33          620 :             ptr,
      34          620 :             _owner: PhantomData,
      35          620 :         }
      36          620 :     }
      37              : }
      38              : 
      39              : impl Import<'_> {
      40              :     /// Iterator over the [`ImportEntry`]
      41          610 :     pub fn entries(&self) -> ImportEntries {
      42          610 :         ImportEntries::new(self.ptr.entries())
      43          610 :     }
      44              : 
      45              :     /// The index of the first forwarder reference
      46          610 :     pub fn forwarder_chain(&self) -> u32 {
      47          610 :         self.ptr.forwarder_chain()
      48          610 :     }
      49              : 
      50              :     /// The stamp that is set to zero until the image is bound.
      51              :     /// After the image is bound, this field is set to the time/data stamp of the DLL
      52          610 :     pub fn timedatestamp(&self) -> u32 {
      53          610 :         self.ptr.timedatestamp()
      54          610 :     }
      55              : 
      56              :     /// The RVA of the import address table (`IAT`). The content of this table is
      57              :     /// **identical** to the content of the Import Lookup Table (`ILT`) until the image is bound.
      58              :     ///
      59              :     /// <div class="warning">This address could change when re-building the binary</div>
      60          610 :     pub fn import_address_table_rva(&self) -> u32 {
      61          610 :         self.ptr.import_address_table_rva()
      62          610 :     }
      63              : 
      64              :     /// Return the relative virtual address of the import lookup table
      65              :     ///
      66              :     /// <div class="warning">This address could change when re-building the binary</div>
      67          610 :     pub fn import_lookup_table_rva(&self) -> u32 {
      68          610 :         self.ptr.import_lookup_table_rva()
      69          610 :     }
      70              : 
      71              :     /// Return the library's name (e.g. `kernel32.dll`)
      72          610 :     pub fn name(&self) -> String {
      73          610 :         self.ptr.name().to_string()
      74          610 :     }
      75              : 
      76              :     /// Return the [`DataDirectory`] associated with this import.
      77          610 :     pub fn directory(&self) -> Option<DataDirectory> {
      78          610 :         into_optional(self.ptr.directory())
      79          610 :     }
      80              : 
      81              :     /// Return the [`DataDirectory`] associated with the IAT (import address table).
      82          610 :     pub fn iat_directory(&self) -> Option<DataDirectory> {
      83          610 :         into_optional(self.ptr.iat_directory())
      84          610 :     }
      85              : 
      86              :     /// Try to find an [`ImportEntry`] by its name
      87            0 :     pub fn entry_by_name(&self, name: &str) -> Option<ImportEntry> {
      88            0 :         into_optional(self.ptr.entry_by_name(name))
      89            0 :     }
      90              : }
      91              : 
      92              : /// Structure that represents an entry (i.e. an import) in the regular import table.
      93              : ///
      94              : /// It implements the [`generic::Symbol`] trait that exposes [`generic::Symbol::name`] and
      95              : /// [`generic::Symbol::value`].
      96              : pub struct ImportEntry<'a> {
      97              :     ptr: cxx::UniquePtr<ffi::PE_ImportEntry>,
      98              :     _owner: PhantomData<&'a ffi::PE_Import>,
      99              : }
     100              : 
     101              : impl ImportEntry<'_> {
     102              :     /// `True` if it is an import by ordinal
     103            0 :     pub fn is_ordinal(&self) -> bool {
     104            0 :         self.ptr.is_ordinal()
     105            0 :     }
     106              : 
     107              :     /// The ordinal value
     108        14620 :     pub fn ordinal(&self) -> u16 {
     109        14620 :         self.ptr.ordinal()
     110        14620 :     }
     111        14620 :     pub fn hint_name_rva(&self) -> u64 {
     112        14620 :         self.ptr.hint_name_rva()
     113        14620 :     }
     114              : 
     115              :     /// Index into the export table that is used to speed-up the resolution
     116        14620 :     pub fn hint(&self) -> u16 {
     117        14620 :         self.ptr.hint()
     118        14620 :     }
     119              : 
     120              :     /// Value of the current entry in the Import Address Table.
     121              :     /// It should match the lookup table value
     122        14620 :     pub fn iat_value(&self) -> u64 {
     123        14620 :         self.ptr.iat_value()
     124        14620 :     }
     125              : 
     126              :     /// Raw value
     127        14620 :     pub fn data(&self) -> u64 {
     128        14620 :         self.ptr.data()
     129        14620 :     }
     130              : 
     131              :     /// **Original** address of the entry in the Import Address Table
     132        14620 :     pub fn iat_address(&self) -> u64 {
     133        14620 :         self.ptr.iat_address()
     134        14620 :     }
     135              : 
     136              :     /// Demangled representation of the symbol or an empty string if it can't
     137              :     /// be demangled
     138            0 :     pub fn demangled_name(&self) -> String {
     139            0 :         self.ptr.demangled_name().to_string()
     140            0 :     }
     141              : }
     142              : 
     143              : impl<'a> FromFFI<ffi::PE_ImportEntry> for ImportEntry<'a> {
     144        14620 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_ImportEntry>) -> Self {
     145        14620 :         ImportEntry {
     146        14620 :             ptr,
     147        14620 :             _owner: PhantomData,
     148        14620 :         }
     149        14620 :     }
     150              : }
     151              : 
     152              : impl generic::Symbol for ImportEntry<'_> {
     153        43860 :     fn as_generic(&self) -> &ffi::AbstractSymbol {
     154        43860 :         self.ptr.as_ref().unwrap().as_ref()
     155        43860 :     }
     156              : }
     157              : 
     158              : impl std::fmt::Debug for ImportEntry<'_> {
     159        14620 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     160        14620 :         let base = self as &dyn generic::Symbol;
     161        14620 :         f.debug_struct("ImportEntry")
     162        14620 :             .field("base", &base)
     163        14620 :             .field("ordinal", &self.ordinal())
     164        14620 :             .field("hint_name_rva", &self.hint_name_rva())
     165        14620 :             .field("hint", &self.hint())
     166        14620 :             .field("iat_value", &self.iat_value())
     167        14620 :             .field("data", &self.data())
     168        14620 :             .field("iat_address", &self.iat_address())
     169        14620 :             .finish()
     170        14620 :     }
     171              : }
     172              : 
     173        14620 : declare_iterator!(
     174        14620 :     ImportEntries,
     175        14620 :     ImportEntry<'a>,
     176        14620 :     ffi::PE_ImportEntry,
     177        14620 :     ffi::PE_Import,
     178        14620 :     ffi::PE_Import_it_entries
     179        14620 : );
     180          610 : declare_iterator!(
     181          610 :     Imports,
     182          610 :     Import<'a>,
     183          610 :     ffi::PE_Import,
     184          610 :     ffi::PE_Binary,
     185          610 :     ffi::PE_Binary_it_imports
     186          610 : );
        

Generated by: LCOV version 2.1-1