LCOV - code coverage report
Current view: top level - src/pe - export.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 37.2 % 180 67
Test Date: 2026-04-12:00:00:00 Functions: 32.6 % 46 15

            Line data    Source code
       1              : //! PE export module
       2              : 
       3              : use lief_ffi as ffi;
       4              : 
       5              : use crate::common::into_optional;
       6              : use crate::common::{AsFFI, FromFFI};
       7              : use crate::declare_iterator;
       8              : use crate::generic;
       9              : use std::pin::Pin;
      10              : 
      11              : use std::marker::PhantomData;
      12              : 
      13              : pub struct Export<'a> {
      14              :     ptr: cxx::UniquePtr<ffi::PE_Export>,
      15              :     _owner: PhantomData<&'a ffi::PE_Binary>,
      16              : }
      17              : 
      18              : impl Export<'_> {
      19              :     /// Create a new Export object
      20            0 :     pub fn new() -> Export<'static> {
      21            0 :         Export::from_ffi(ffi::PE_Export::create())
      22            0 :     }
      23              : 
      24              :     /// According to the PE specifications this value is reserved and should be set to 0
      25          104 :     pub fn export_flags(&self) -> u32 {
      26          104 :         self.ptr.export_flags()
      27          104 :     }
      28              : 
      29              :     /// The time and date that the export data was created
      30          104 :     pub fn timestamp(&self) -> u32 {
      31          104 :         self.ptr.timestamp()
      32          104 :     }
      33              : 
      34              :     /// The major version number (can be user-defined)
      35          104 :     pub fn major_version(&self) -> u16 {
      36          104 :         self.ptr.major_version()
      37          104 :     }
      38              : 
      39              :     /// The minor version number (can be user-defined)
      40          104 :     pub fn minor_version(&self) -> u16 {
      41          104 :         self.ptr.minor_version()
      42          104 :     }
      43              : 
      44              :     /// The starting number for the exports. Usually this value is set to 1
      45          104 :     pub fn ordinal_base(&self) -> u32 {
      46          104 :         self.ptr.ordinal_base()
      47          104 :     }
      48              : 
      49              :     /// The name of the library exported (e.g. `KERNEL32.dll`)
      50          104 :     pub fn name(&self) -> String {
      51          104 :         self.ptr.name().to_string()
      52          104 :     }
      53              : 
      54              :     /// Iterator over the different [`Entry`] exported by this table
      55          104 :     pub fn entries(&self) -> ExportEntries<'_> {
      56          104 :         ExportEntries::new(self.ptr.entries())
      57          104 :     }
      58              : 
      59              :     /// Address of the ASCII DLL's name (RVA)
      60            0 :     pub fn name_rva(&self) -> u32 {
      61            0 :         self.ptr.name_rva()
      62            0 :     }
      63              : 
      64              :     /// RVA to the list of exported names
      65            0 :     pub fn names_addr_table_rva(&self) -> u32 {
      66            0 :         self.ptr.names_addr_table_rva()
      67            0 :     }
      68              : 
      69              :     /// Number of exports by name
      70            0 :     pub fn names_addr_table_cnt(&self) -> u32 {
      71            0 :         self.ptr.names_addr_table_cnt()
      72            0 :     }
      73              : 
      74              :     /// RVA of the export address table
      75            0 :     pub fn export_addr_table_rva(&self) -> u32 {
      76            0 :         self.ptr.export_addr_table_rva()
      77            0 :     }
      78              : 
      79              :     /// Number of entries in the export address table
      80            0 :     pub fn export_addr_table_cnt(&self) -> u32 {
      81            0 :         self.ptr.export_addr_table_cnt()
      82            0 :     }
      83              : 
      84              :     /// RVA to the list of exported ordinals
      85            0 :     pub fn ord_addr_table_rva(&self) -> u32 {
      86            0 :         self.ptr.ord_addr_table_rva()
      87            0 :     }
      88              : 
      89              :     /// Change or set the export flags
      90            0 :     pub fn set_export_flags(&mut self, flags: u32) -> &mut Self {
      91            0 :         self.ptr.pin_mut().set_export_flags(flags);
      92            0 :         self
      93            0 :     }
      94              : 
      95              :     /// Change or set the timestamp
      96            0 :     pub fn set_timestamp(&mut self, timestamp: u32) -> &mut Self {
      97            0 :         self.ptr.pin_mut().set_export_flags(timestamp);
      98            0 :         self
      99            0 :     }
     100              : 
     101              :     /// Change or set the major version of the DLL
     102            0 :     pub fn set_major_version(&mut self, version: u32) -> &mut Self {
     103            0 :         self.ptr.pin_mut().set_major_version(version);
     104            0 :         self
     105            0 :     }
     106              : 
     107              :     /// Change or set the minor version of the DLL
     108            0 :     pub fn set_minor_version(&mut self, version: u32) -> &mut Self {
     109            0 :         self.ptr.pin_mut().set_minor_version(version);
     110            0 :         self
     111            0 :     }
     112              : 
     113              :     /// Change or set the name of the DLL
     114            0 :     pub fn set_name(&mut self, name: &str) -> &mut Self {
     115            0 :         self.ptr.pin_mut().set_name(name);
     116            0 :         self
     117            0 :     }
     118              : 
     119              :     /// Find the export entry with the given name
     120            0 :     pub fn entry_by_name(&self, name: &str) -> Option<Entry<'_>> {
     121            0 :         into_optional(self.ptr.entry_by_name(name))
     122            0 :     }
     123              : 
     124              :     /// Find the export entry with the given ordinal number
     125            0 :     pub fn entry_by_ordinal(&self, ordinal: u32) -> Option<Entry<'_>> {
     126            0 :         into_optional(self.ptr.entry_by_ordinal(ordinal))
     127            0 :     }
     128              : 
     129              :     /// Find the export entry at the provided RVA
     130            0 :     pub fn entry_at_rva(&self, rva: u32) -> Option<Entry<'_>> {
     131            0 :         into_optional(self.ptr.entry_at_rva(rva))
     132            0 :     }
     133              : 
     134              :     /// Add the given export and return the newly created and added export
     135            0 :     pub fn add_entry(&mut self, entry: &Entry) -> Entry<'_> {
     136            0 :         Entry::from_ffi(self.ptr.pin_mut().add_entry(entry.ptr.as_ref().unwrap()))
     137            0 :     }
     138              : 
     139              :     /// Add a new export entry given its name and its RVA
     140            0 :     pub fn add_entry_by_name(&mut self, name: &str, rva: u32) -> Entry<'_> {
     141            0 :         Entry::from_ffi(self.ptr.pin_mut().add_entry_by_name(name, rva))
     142            0 :     }
     143              : 
     144              :     /// Remove the given export entry
     145            0 :     pub fn remove_entry(&mut self, entry: Entry) -> bool {
     146            0 :         self.ptr.pin_mut().remove_entry(entry.ptr)
     147            0 :     }
     148              : 
     149              :     /// Remove the export entry with the given RVA
     150            0 :     pub fn remove_entry_at(&mut self, rva: u32) -> bool {
     151            0 :         self.ptr.pin_mut().remove_entry_at(rva)
     152            0 :     }
     153              : 
     154              :     /// Remove the export entry with the given RVA
     155            0 :     pub fn remove_entry_by_name(&mut self, name: &str) -> bool {
     156            0 :         self.ptr.pin_mut().remove_entry_by_name(name)
     157            0 :     }
     158              : }
     159              : 
     160              : impl std::fmt::Debug for Export<'_> {
     161          104 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     162          104 :         f.debug_struct("Export")
     163          104 :             .field("export_flags", &self.export_flags())
     164          104 :             .field("timestamp", &self.timestamp())
     165          104 :             .field("major_version", &self.major_version())
     166          104 :             .field("minor_version", &self.minor_version())
     167          104 :             .field("ordinal_base", &self.ordinal_base())
     168          104 :             .field("name", &self.name())
     169          104 :             .finish()
     170          104 :     }
     171              : }
     172              : 
     173              : impl<'a> FromFFI<ffi::PE_Export> for Export<'a> {
     174          104 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_Export>) -> Self {
     175          104 :         Export {
     176          104 :             ptr,
     177          104 :             _owner: PhantomData,
     178          104 :         }
     179          104 :     }
     180              : }
     181              : 
     182              : impl<'a> AsFFI<ffi::PE_Export> for Export<'a> {
     183            0 :     fn as_ffi(&self) -> &ffi::PE_Export {
     184            0 :         self.ptr.as_ref().unwrap()
     185            0 :     }
     186              : 
     187            0 :     fn as_mut_ffi(&mut self) -> std::pin::Pin<&mut ffi::PE_Export> {
     188            0 :         self.ptr.pin_mut()
     189            0 :     }
     190              : }
     191              : 
     192              : /// Structure which represents an entry in the export table.
     193              : ///
     194              : /// It implements the [`generic::Symbol`] trait that exposes [`generic::Symbol::name`] and
     195              : /// [`generic::Symbol::value`].
     196              : pub struct Entry<'a> {
     197              :     ptr: cxx::UniquePtr<ffi::PE_ExportEntry>,
     198              :     _owner: PhantomData<&'a ffi::PE_Export>,
     199              : }
     200              : 
     201              : impl Entry<'_> {
     202              :     /// Ordinal value associated with this exported entry.
     203              :     ///
     204              :     /// This value is computed as the index of this entry in the address table
     205              :     /// plus the ordinal base ([`Export::ordinal_base`])
     206       161538 :     pub fn ordinal(&self) -> u16 {
     207       161538 :         self.ptr.ordinal()
     208       161538 :     }
     209              : 
     210              :     /// Address of the current exported function in the DLL.
     211              :     ///
     212              :     /// If this entry is **external** to the DLL then it returns 0
     213              :     /// and the external address is returned by [`Entry::function_rva`]
     214       161538 :     pub fn address(&self) -> u32 {
     215       161538 :         self.ptr.address()
     216       161538 :     }
     217              : 
     218            0 :     pub fn function_rva(&self) -> u32 {
     219            0 :         self.ptr.function_rva()
     220            0 :     }
     221              : 
     222            0 :     pub fn is_extern(&self) -> bool {
     223            0 :         self.ptr.is_extern()
     224            0 :     }
     225              : 
     226            0 :     pub fn is_forwarded(&self) -> bool {
     227            0 :         self.ptr.is_forwarded()
     228            0 :     }
     229              : 
     230              :     /// Demangled representation of the symbol or an empty string if it can't
     231              :     /// be demangled
     232            0 :     pub fn demangled_name(&self) -> String {
     233            0 :         self.ptr.demangled_name().to_string()
     234            0 :     }
     235              : 
     236            0 :     pub fn forward_info(&self) -> Option<ForwardInfo> {
     237            0 :         if !self.ptr.is_forwarded() {
     238            0 :             return None;
     239            0 :         }
     240            0 :         Some(ForwardInfo::with_values(
     241            0 :             self.ptr.fwd_library().to_string(),
     242            0 :             self.ptr.fwd_function().to_string(),
     243            0 :         ))
     244            0 :     }
     245              : 
     246            0 :     pub fn set_ordinal(&mut self, ordinal: u16) -> &mut Self {
     247            0 :         self.ptr.pin_mut().set_ordinal(ordinal);
     248            0 :         self
     249            0 :     }
     250              : 
     251            0 :     pub fn set_address(&mut self, address: u32) -> &mut Self {
     252            0 :         self.ptr.pin_mut().set_address(address);
     253            0 :         self
     254            0 :     }
     255              : }
     256              : 
     257              : impl generic::Symbol for Entry<'_> {
     258       484614 :     fn as_generic(&self) -> &ffi::AbstractSymbol {
     259       484614 :         self.ptr.as_ref().unwrap().as_ref()
     260       484614 :     }
     261              : 
     262            0 :     fn as_pin_mut_generic(&mut self) -> Pin<&mut ffi::AbstractSymbol> {
     263            0 :         unsafe {
     264            0 :             Pin::new_unchecked({
     265            0 :                 (self.ptr.as_ref().unwrap().as_ref() as *const ffi::AbstractSymbol
     266            0 :                     as *mut ffi::AbstractSymbol)
     267            0 :                     .as_mut()
     268            0 :                     .unwrap()
     269            0 :             })
     270            0 :         }
     271            0 :     }
     272              : }
     273              : 
     274              : impl std::fmt::Debug for Entry<'_> {
     275       161538 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     276       161538 :         let base = self as &dyn generic::Symbol;
     277       161538 :         f.debug_struct("ExportEntry")
     278       161538 :             .field("base", &base)
     279       161538 :             .field("ordinal", &self.ordinal())
     280       161538 :             .field("address", &self.address())
     281       161538 :             .finish()
     282       161538 :     }
     283              : }
     284              : 
     285              : impl<'a> FromFFI<ffi::PE_ExportEntry> for Entry<'a> {
     286       161538 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_ExportEntry>) -> Self {
     287       161538 :         Entry {
     288       161538 :             ptr,
     289       161538 :             _owner: PhantomData,
     290       161538 :         }
     291       161538 :     }
     292              : }
     293              : 
     294              : pub struct ForwardInfo {
     295              :     pub library: String,
     296              :     pub function: String,
     297              : }
     298              : 
     299              : impl ForwardInfo {
     300            0 :     pub fn with_values(library: String, function: String) -> Self {
     301            0 :         Self { library, function }
     302            0 :     }
     303              : }
     304              : 
     305       161538 : declare_iterator!(
     306       161538 :     ExportEntries,
     307       161538 :     Entry<'a>,
     308       161538 :     ffi::PE_ExportEntry,
     309       161538 :     ffi::PE_Export,
     310       161538 :     ffi::PE_Export_it_entries
     311       161538 : );
        

Generated by: LCOV version 2.1-1