LCOV - code coverage report
Current view: top level - src/pe - binary.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 49.5 % 368 182
Test Date: 2026-04-12:00:00:00 Functions: 49.0 % 100 49

            Line data    Source code
       1              : use lief_ffi as ffi;
       2              : 
       3              : use num_traits::{cast, Num};
       4              : use std::mem::size_of;
       5              : use std::path::Path;
       6              : use std::pin::Pin;
       7              : 
       8              : use super::builder::Config;
       9              : use super::data_directory::{DataDirectories, DataDirectory};
      10              : use super::debug::CodeViewPDB;
      11              : use super::debug::{self, DebugEntry, Entries};
      12              : use super::delay_import::{DelayImport, DelayImports};
      13              : use super::exception::RuntimeExceptionFunction;
      14              : use super::export::Export;
      15              : use super::import::{Import, Imports};
      16              : use super::load_configuration::LoadConfiguration;
      17              : use super::parser_config::Config as ParserConfig;
      18              : use super::relocation::Relocations;
      19              : use super::resources::Node as ResourceNode;
      20              : use super::resources::{Manager as ResourcesManager, NodeBase};
      21              : use super::rich_header::RichHeader;
      22              : use super::section::{Section, Sections};
      23              : use super::signature::Signatures;
      24              : use super::tls::TLS;
      25              : use super::{data_directory, signature};
      26              : use crate::coff;
      27              : use crate::coff::Symbol;
      28              : 
      29              : use crate::common::{into_optional, AsFFI, FromFFI};
      30              : use crate::declare_iterator;
      31              : use crate::generic;
      32              : use crate::to_conv_result;
      33              : use crate::to_slice;
      34              : use crate::Error;
      35              : 
      36              : use super::Algorithms;
      37              : use super::{DosHeader, Header, OptionalHeader};
      38              : 
      39              : /// This is the main interface to read and write PE binary attributes.
      40              : ///
      41              : /// Note that this structure implements the [`generic::Binary`] trait from which other generic
      42              : /// functions are exposed
      43              : ///
      44              : /// ```
      45              : /// fn use_trait(pe: &Binary) {
      46              : ///     let generic_binary = pe as &dyn generic::Binary;
      47              : ///     println!("{}", generic_binary.entrypoint());
      48              : /// }
      49              : ///
      50              : /// ```
      51              : pub struct Binary {
      52              :     ptr: cxx::UniquePtr<ffi::PE_Binary>,
      53              : }
      54              : 
      55              : impl FromFFI<ffi::PE_Binary> for Binary {
      56          351 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_Binary>) -> Self {
      57          351 :         Self { ptr }
      58          351 :     }
      59              : }
      60              : 
      61              : impl Binary {
      62              :     /// Parse from a filepath given as a string
      63            2 :     pub fn parse<P: AsRef<Path>>(path: P) -> Option<Self> {
      64            2 :         let ffi = ffi::PE_Binary::parse(path.as_ref().to_str().unwrap());
      65            2 :         if ffi.is_null() {
      66            0 :             return None;
      67            2 :         }
      68            2 :         Some(Binary::from_ffi(ffi))
      69            2 :     }
      70              : 
      71              :     /// Parse from a string file path and with a provided configuration
      72           12 :     pub fn parse_with_config<P: AsRef<Path>>(path: P, config: &ParserConfig) -> Option<Self> {
      73           12 :         let ffi_config = config.to_ffi();
      74           12 :         let ffi = ffi::PE_Binary::parse_with_config(path.as_ref().to_str().unwrap(), &ffi_config);
      75           12 :         if ffi.is_null() {
      76            0 :             return None;
      77           12 :         }
      78           12 :         Some(Binary::from_ffi(ffi))
      79           12 :     }
      80              : 
      81              :     /// DosHeader which starts the PE files
      82          169 :     pub fn dos_header(&self) -> DosHeader<'_> {
      83          169 :         DosHeader::from_ffi(self.ptr.dos_header())
      84          169 :     }
      85              : 
      86              :     /// Header that follows the [`Binary::header`]. It is named
      87              :     /// *optional* from the COFF specification but it is mandatory in a PE file.
      88          182 :     pub fn optional_header(&self) -> OptionalHeader<'_> {
      89          182 :         OptionalHeader::from_ffi(self.ptr.optional_header())
      90          182 :     }
      91              : 
      92              :     /// Re-compute the value of [`OptionalHeader::checksum`]
      93          169 :     pub fn compute_checksum(&self) -> u32 {
      94          169 :         self.ptr.compute_checksum()
      95          169 :     }
      96              : 
      97              :     /// Next header after the [`Binary::dos_header`]
      98          169 :     pub fn header(&self) -> Header<'_> {
      99          169 :         Header::from_ffi(self.ptr.header())
     100          169 :     }
     101              : 
     102              :     /// Return TLS information if present
     103          169 :     pub fn tls(&self) -> Option<TLS<'_>> {
     104          169 :         into_optional(self.ptr.tls())
     105          169 :     }
     106              : 
     107              :     /// Return rich header information if present.
     108          169 :     pub fn rich_header(&self) -> Option<RichHeader<'_>> {
     109          169 :         into_optional(self.ptr.rich_header())
     110          169 :     }
     111              : 
     112              :     /// Return export information
     113          169 :     pub fn export(&self) -> Option<Export<'_>> {
     114          169 :         into_optional(self.ptr.get_export())
     115          169 :     }
     116              : 
     117              :     /// Return the root of the PE's resource tree
     118          338 :     pub fn resources(&self) -> Option<ResourceNode<'_>> {
     119          338 :         into_optional(self.ptr.resources())
     120          338 :     }
     121              : 
     122              :     /// Return a manager interface to read and manipulate the resources tree with a user friendly
     123              :     /// interface.
     124          169 :     pub fn resources_manager(&self) -> Option<ResourcesManager<'_>> {
     125          169 :         into_optional(self.ptr.resources_manager())
     126          169 :     }
     127              : 
     128              :     /// Return the imports as an **iterator** over the [`Import`] structure
     129          169 :     pub fn imports(&self) -> Imports<'_> {
     130          169 :         Imports::new(self.ptr.imports())
     131          169 :     }
     132              : 
     133              :     /// Return the data directories as an iterator over the [`DataDirectory`] structure
     134          169 :     pub fn data_directories(&self) -> DataDirectories<'_> {
     135          169 :         DataDirectories::new(self.ptr.data_directories())
     136          169 :     }
     137              : 
     138              :     /// Return the sections as an iterator over the [`Section`] structure
     139          169 :     pub fn sections(&self) -> Sections<'_> {
     140          169 :         Sections::new(self.ptr.sections())
     141          169 :     }
     142              : 
     143              :     /// Return the relocations as an iterator over the [`super::Relocation`] structure
     144          169 :     pub fn relocations(&self) -> Relocations<'_> {
     145          169 :         Relocations::new(self.ptr.relocations())
     146          169 :     }
     147              : 
     148              :     /// Return the delayed imports as an iterator over the [`DelayImport`] structure
     149          169 :     pub fn delay_imports(&self) -> DelayImports<'_> {
     150          169 :         DelayImports::new(self.ptr.delay_imports())
     151          169 :     }
     152              : 
     153              :     /// Return an iterator over the [`signature::Signature`] if the current PE is authenticode-signed.
     154          182 :     pub fn signatures(&self) -> Signatures<'_> {
     155          182 :         Signatures::new(self.ptr.signatures())
     156          182 :     }
     157              : 
     158              :     /// Return an iterator over the [`debug::Entries`] of the binary.
     159          169 :     pub fn debug(&self) -> DebugEntries<'_> {
     160          169 :         DebugEntries::new(self.ptr.debug())
     161          169 :     }
     162              : 
     163              :     /// Compute the authentihash for the current PE with the given algorithms.
     164          169 :     pub fn authentihash(&self, algo: Algorithms) -> Vec<u8> {
     165          169 :         Vec::from(self.ptr.authentihash(algo.into()).as_slice())
     166          169 :     }
     167              : 
     168              :     /// Return load configuration info if present.
     169          169 :     pub fn load_configuration(&self) -> Option<LoadConfiguration<'_>> {
     170          169 :         into_optional(self.ptr.load_configuration())
     171          169 :     }
     172              : 
     173              :     /// Return the raw data between the [`Binary::dos_header`] and the regular [`Binary::header`]
     174          169 :     pub fn dos_stub(&self) -> &[u8] {
     175          169 :         to_slice!(self.ptr.dos_stub());
     176          169 :     }
     177              : 
     178              :     /// Return the original overlay data of the file
     179          169 :     pub fn overlay(&self) -> &[u8] {
     180          169 :         to_slice!(self.ptr.overlay());
     181          169 :     }
     182              : 
     183              :     /// Return the offset computed by LIEF to identify overlay data
     184          169 :     pub fn overlay_offset(&self) -> u64 {
     185          169 :         self.ptr.overlay_offset()
     186          169 :     }
     187              : 
     188              :     /// Convert a **relative** virtual address into an offset
     189           13 :     pub fn rva_to_offset(&self, rva: u64) -> u64 {
     190           13 :         self.ptr.rva_to_offset(rva)
     191           13 :     }
     192              : 
     193              :     /// Convert an **absolute** virtual address into an offset.
     194           13 :     pub fn va_to_offset(&self, va: u64) -> u64 {
     195           13 :         self.ptr.va_to_offset(va)
     196           13 :     }
     197              : 
     198              :     /// Convert the given offset into a relative virtual address (RVA).
     199           13 :     pub fn offset_to_rva(&self, offset: u64) -> u64 {
     200           13 :         self.ptr.offset_to_rva(offset)
     201           13 :     }
     202              : 
     203              :     /// Return the size of the current binary when loaded in memory.
     204          169 :     pub fn virtual_size(&self) -> u64 {
     205          169 :         self.ptr.virtual_size()
     206          169 :     }
     207              : 
     208              :     /// Compute the size of all the headers.
     209          169 :     pub fn sizeof_headers(&self) -> u64 {
     210          169 :         self.ptr.sizeof_headers()
     211          169 :     }
     212              : 
     213              :     /// Find a section by its offset
     214           26 :     pub fn section_from_offset(&self, offset: u64) -> Option<Section<'_>> {
     215           26 :         into_optional(self.ptr.section_from_offset(offset))
     216           26 :     }
     217              : 
     218              :     /// Find a section by its **relative** virtual address
     219           26 :     pub fn section_from_rva(&self, rva: u64) -> Option<Section<'_>> {
     220           26 :         into_optional(self.ptr.section_from_rva(rva))
     221           26 :     }
     222              : 
     223              :     /// Find a section by its name
     224           52 :     pub fn section_by_name(&self, name: &str) -> Option<Section<'_>> {
     225           52 :         into_optional(self.ptr.section_by_name(name))
     226           52 :     }
     227              : 
     228              :     /// Add a section to the binary and return the section added.
     229            0 :     pub fn add_section(&mut self, section: Section) -> Option<Section<'_>> {
     230            0 :         into_optional(self.ptr.as_mut().unwrap().add_section(section.as_ffi()))
     231            0 :     }
     232              : 
     233              :     /// Find the data directory with the given type
     234          182 :     pub fn data_directory_by_type(
     235          182 :         &self,
     236          182 :         dir_type: data_directory::Type,
     237          182 :     ) -> Option<DataDirectory<'_>> {
     238          182 :         into_optional(self.ptr.data_directory_by_type(dir_type.into()))
     239          182 :     }
     240              : 
     241              :     /// Verify the binary against the embedded signature(s) (if any)
     242              :     ///
     243              :     /// First, it checks that the embedded signatures are correct (c.f. [`signature::Signature::check`])
     244              :     /// and then, it checks that the authentihash matches [`crate::pe::signature::content_info::ContentInfo::digest`]
     245           13 :     pub fn verify_signature(
     246           13 :         &self,
     247           13 :         checks: signature::VerificationChecks,
     248           13 :     ) -> signature::VerificationFlags {
     249           13 :         signature::VerificationFlags::from(self.ptr.verify_signature(checks.into()))
     250           13 :     }
     251              : 
     252              :     /// Verify the binary with the [`signature::Signature`] object provided in the first parameter.
     253              :     /// It can be used to verify a detached signature:
     254              :     ///
     255              :     /// ```
     256              :     /// if let Some(sig) = Signature::from_file(path_str.unwrap()) {
     257              :     ///     pe.verify_signature(&sig, signature::VerificationChecks::DEFAULT);
     258              :     /// }
     259              :     /// ```
     260           13 :     pub fn verify_with_signature(
     261           13 :         &self,
     262           13 :         sig: &signature::Signature,
     263           13 :         checks: signature::VerificationChecks,
     264           13 :     ) -> signature::VerificationFlags {
     265           13 :         signature::VerificationFlags::from(
     266           13 :             self.ptr.verify_with_signature(sig.into(), checks.into()),
     267           13 :         )
     268           13 :     }
     269              : 
     270              :     /// Find an import by its DLL name (case insensitive)
     271           26 :     pub fn import_by_name(&self, name: &str) -> Option<Import<'_>> {
     272           26 :         into_optional(self.ptr.import_by_name(name))
     273           26 :     }
     274              : 
     275              :     /// Find a delayed import by its name
     276           26 :     pub fn delay_import_by_name(&self, name: &str) -> Option<DelayImport<'_>> {
     277           26 :         into_optional(self.ptr.delay_import_by_name(name))
     278           26 :     }
     279              : 
     280              :     /// Return the sized content from the virtual address
     281           39 :     pub fn content_from_virtual_address(&self, address: u64, size: u64) -> &[u8] {
     282           39 :         to_slice!(self.ptr.get_content_from_virtual_address(address, size));
     283           39 :     }
     284              : 
     285          169 :     pub fn functions(&self) -> generic::Functions<'_> {
     286          169 :         generic::Functions::new(self.ptr.functions())
     287          169 :     }
     288              : 
     289              :     /// Return the data directory associated with the export table
     290            0 :     pub fn export_dir(&self) -> Option<DataDirectory<'_>> {
     291            0 :         into_optional(self.ptr.export_dir())
     292            0 :     }
     293              : 
     294              :     /// Return the data directory associated with the import table
     295            0 :     pub fn import_dir(&self) -> Option<DataDirectory<'_>> {
     296            0 :         into_optional(self.ptr.import_dir())
     297            0 :     }
     298              : 
     299              :     /// Return the data directory associated with the resources tree
     300            0 :     pub fn rsrc_dir(&self) -> Option<DataDirectory<'_>> {
     301            0 :         into_optional(self.ptr.rsrc_dir())
     302            0 :     }
     303              : 
     304              :     /// Return the data directory associated with the exceptions
     305            0 :     pub fn exceptions_dir(&self) -> Option<DataDirectory<'_>> {
     306            0 :         into_optional(self.ptr.exceptions_dir())
     307            0 :     }
     308              : 
     309              :     /// Return the data directory associated with the certificate table
     310              :     /// (authenticode)
     311            0 :     pub fn cert_dir(&self) -> Option<DataDirectory<'_>> {
     312            0 :         into_optional(self.ptr.cert_dir())
     313            0 :     }
     314              : 
     315              :     /// Return the data directory associated with the relocation table
     316            0 :     pub fn relocation_dir(&self) -> Option<DataDirectory<'_>> {
     317            0 :         into_optional(self.ptr.relocation_dir())
     318            0 :     }
     319              : 
     320              :     /// Return the data directory associated with the debug table
     321            0 :     pub fn debug_dir(&self) -> Option<DataDirectory<'_>> {
     322            0 :         into_optional(self.ptr.debug_dir())
     323            0 :     }
     324              : 
     325              :     /// Return the data directory associated with TLS
     326            0 :     pub fn tls_dir(&self) -> Option<DataDirectory<'_>> {
     327            0 :         into_optional(self.ptr.tls_dir())
     328            0 :     }
     329              : 
     330              :     /// Return the data directory associated with the load config
     331            0 :     pub fn load_config_dir(&self) -> Option<DataDirectory<'_>> {
     332            0 :         into_optional(self.ptr.load_config_dir())
     333            0 :     }
     334              : 
     335              :     /// Return the data directory associated with the IAT
     336            0 :     pub fn iat_dir(&self) -> Option<DataDirectory<'_>> {
     337            0 :         into_optional(self.ptr.iat_dir())
     338            0 :     }
     339              : 
     340              :     /// Return the data directory associated with delayed imports
     341            0 :     pub fn export_delay_dirdir(&self) -> Option<DataDirectory<'_>> {
     342            0 :         into_optional(self.ptr.delay_dir())
     343            0 :     }
     344              : 
     345              :     /// Get the integer value at the given virtual address
     346            0 :     pub fn get_int_from_virtual_address<T>(&self, addr: u64) -> Result<T, Error>
     347            0 :     where
     348            0 :         T: Num + cast::FromPrimitive + cast::ToPrimitive,
     349            0 :     {
     350            0 :         // Can't be in the generic trait because of:
     351            0 :         //   > for a trait to be "object safe" it needs to allow building a vtable to allow the call
     352            0 :         //   > to be resolvable dynamically; for more information visit
     353            0 :         //   > https://doc.rust-lang.org/reference/items/traits.html#object-safety
     354            0 :         if size_of::<T>() == size_of::<u8>() {
     355            0 :             to_conv_result!(
     356            0 :                 ffi::AbstractBinary::get_u8,
     357            0 :                 self.ptr.as_ref().unwrap().as_ref(),
     358            0 :                 |value| {
     359            0 :                     T::from_u8(value).unwrap_or_else(|| panic!("Can't cast value: {value}"))
     360            0 :                 },
     361            0 :                 addr
     362              :             );
     363            0 :         }
     364            0 : 
     365            0 :         if size_of::<T>() == size_of::<u16>() {
     366            0 :             to_conv_result!(
     367            0 :                 ffi::AbstractBinary::get_u16,
     368            0 :                 self.ptr.as_ref().unwrap().as_ref(),
     369            0 :                 |value| {
     370            0 :                     T::from_u16(value).unwrap_or_else(|| panic!("Can't cast value: {value}"))
     371            0 :                 },
     372            0 :                 addr
     373              :             );
     374            0 :         }
     375            0 : 
     376            0 :         if size_of::<T>() == size_of::<u32>() {
     377            0 :             to_conv_result!(
     378            0 :                 ffi::AbstractBinary::get_u32,
     379            0 :                 self.ptr.as_ref().unwrap().as_ref(),
     380            0 :                 |value| {
     381            0 :                     T::from_u32(value).unwrap_or_else(|| panic!("Can't cast value: {value}"))
     382            0 :                 },
     383            0 :                 addr
     384              :             );
     385            0 :         }
     386            0 : 
     387            0 :         if size_of::<T>() == size_of::<u64>() {
     388            0 :             to_conv_result!(
     389            0 :                 ffi::AbstractBinary::get_u64,
     390            0 :                 self.ptr.as_ref().unwrap().as_ref(),
     391            0 :                 |value| {
     392            0 :                     T::from_u64(value).unwrap_or_else(|| panic!("Can't cast value: {value}"))
     393            0 :                 },
     394            0 :                 addr
     395              :             );
     396            0 :         }
     397            0 : 
     398            0 :         Err(Error::NotSupported)
     399            0 :     }
     400              : 
     401              :     /// Add an imported library (i.e. `DLL`) to the binary
     402            0 :     pub fn add_import<'a>(&'a mut self, name: &str) -> Import<'a> {
     403            0 :         Import::from_ffi(self.ptr.pin_mut().add_import(name))
     404            0 :     }
     405              : 
     406              :     /// Add an imported library (i.e. `DLL`) to the binary.
     407              :     ///
     408              :     /// The second parameter `pos` defines where to insert the import.
     409            0 :     pub fn add_import_at_pos<'a>(&'a mut self, name: &str, pos: u32) -> Import<'a> {
     410            0 :         Import::from_ffi(self.ptr.pin_mut().add_import_pos(name, pos))
     411            0 :     }
     412              : 
     413              :     /// Remove the imported library with the given `name`
     414            0 :     pub fn remove_import(&mut self, name: &str) {
     415            0 :         self.ptr.pin_mut().remove_import(name);
     416            0 :     }
     417              : 
     418              :     /// Remove all libraries in the binary
     419            0 :     pub fn remove_all_imports(&mut self) {
     420            0 :         self.ptr.pin_mut().remove_all_imports();
     421            0 :     }
     422              : 
     423              :     /// Remove the TLS from the binary
     424            0 :     pub fn remove_tls(&mut self) {
     425            0 :         self.ptr.pin_mut().remove_tls();
     426            0 :     }
     427              : 
     428              :     /// Set or change the TLS information
     429            0 :     pub fn set_tls(&mut self, tls: &TLS) {
     430            0 :         self.ptr.pin_mut().set_tls(tls.as_ffi());
     431            0 :     }
     432              : 
     433              :     /// Change or set the resources tree to given node
     434            0 :     pub fn set_resources(&mut self, node: &dyn NodeBase) {
     435            0 :         self.ptr.pin_mut().set_resources(node.get_base());
     436            0 :     }
     437              : 
     438              :     /// Add a new debug entry
     439            0 :     pub fn add_debug_info<'a>(&'a mut self, entry: &dyn DebugEntry) -> Option<Entries<'a>> {
     440            0 :         into_optional(self.ptr.pin_mut().add_debug_info(entry.get_base()))
     441            0 :     }
     442              : 
     443              :     /// Remove a specific debug entry
     444            0 :     pub fn remove_debug(&mut self, entry: &dyn DebugEntry) -> bool {
     445            0 :         self.ptr.pin_mut().remove_debug(entry.get_base())
     446            0 :     }
     447              : 
     448              :     /// Remove all debug info
     449            0 :     pub fn clear_debug(&mut self) -> bool {
     450            0 :         self.ptr.pin_mut().clear_debug()
     451            0 :     }
     452              : 
     453              :     /// Return the [`CodeViewPDB`] object if present
     454            0 :     pub fn codeview_pdb(&self) -> Option<CodeViewPDB<'_>> {
     455            0 :         into_optional(self.ptr.codeview_pdb())
     456            0 :     }
     457              : 
     458              :     /// Write back the current PE binary into the file specified in parameter
     459            0 :     pub fn write<P: AsRef<Path>>(&mut self, output: P) {
     460            0 :         self.ptr
     461            0 :             .as_mut()
     462            0 :             .unwrap()
     463            0 :             .write(output.as_ref().to_str().unwrap());
     464            0 :     }
     465              : 
     466              :     /// Write back the current PE binary into the file specified in parameter with the
     467              :     /// configuration provided in the second parameter.
     468            0 :     pub fn write_with_config<P: AsRef<Path>>(&mut self, output: P, config: Config) {
     469            0 :         let ffi_config = config.to_ffi();
     470            0 :         self.ptr.as_mut().unwrap().write_with_config(
     471            0 :             output.as_ref().to_str().unwrap(),
     472            0 :             ffi_config.as_ref().unwrap(),
     473            0 :         );
     474            0 :     }
     475              : 
     476              :     /// Iterator over the strings located in the COFF string table
     477          169 :     pub fn coff_string_table(&self) -> COFFStrings<'_> {
     478          169 :         COFFStrings::new(self.ptr.coff_string_table())
     479          169 :     }
     480              : 
     481              :     /// Return an iterator over the binary (COFF) symbols (if any).
     482          169 :     pub fn symbols(&self) -> Symbols<'_> {
     483          169 :         Symbols::new(self.ptr.symbols())
     484          169 :     }
     485              : 
     486              :     /// Try to find the COFF string at the given offset in the COFF string table.
     487              :     ///
     488              :     /// <div class="warning">
     489              :     /// This offset must include the first 4 bytes holding the size of the table.
     490              :     /// Hence, the first string starts a the offset 4.
     491              :     /// </div>
     492            0 :     pub fn find_coff_string_at(&self, offset: u32) -> Option<coff::String<'_>> {
     493            0 :         into_optional(self.ptr.find_coff_string_at(offset))
     494            0 :     }
     495              : 
     496              :     /// Iterator over the exception (`_RUNTIME_FUNCTION`) functions
     497              :     ///
     498              :     /// This function requires that the option [`ParserConfig::parse_exceptions`] was turned on
     499              :     /// (default is `false`) when parsing the binary.
     500          169 :     pub fn exceptions(&self) -> Exceptions<'_> {
     501          169 :         Exceptions::new(self.ptr.exceptions())
     502          169 :     }
     503              : 
     504              :     /// Try to find the exception info at the given RVA
     505              :     ///
     506              :     /// This function requires that the option [`ParserConfig::parse_exceptions`] was turned on
     507              :     /// (default is `false`) when parsing the binary.
     508            0 :     pub fn find_exception_at(&self, rva: u32) -> Option<RuntimeExceptionFunction<'_>> {
     509            0 :         into_optional(self.ptr.find_exception_at(rva))
     510            0 :     }
     511              : 
     512              :     /// True if this binary is compiled in ARM64EC mode (emulation compatible)
     513            0 :     pub fn is_arm64ec(&self) -> bool {
     514            0 :         self.ptr.is_arm64ec()
     515            0 :     }
     516              : 
     517              :     /// True if this binary is compiled in ARM64X mode (contains both ARM64 and ARM64EC).
     518            0 :     pub fn is_arm64x(&self) -> bool {
     519            0 :         self.ptr.is_arm64x()
     520            0 :     }
     521              : 
     522              :     /// If the current binary contains dynamic relocations
     523              :     /// (e.g. LIEF::PE::DynamicFixupARM64X), this function returns the
     524              :     /// **relocated** view of the current PE.
     525              :     ///
     526              :     /// This can be used to get the alternative PE binary, targeting a different
     527              :     /// architectures.
     528              :     ///
     529              :     /// <div class="warning">
     530              :     /// This function is <b>moving</b> and taking the ownership of the nested
     531              :     /// PE binary. This means that subsequent calls to this function will return None.
     532              :     /// </div>
     533              :     ///
     534              :     /// This function requires that the option [`ParserConfig::parse_arm64x_binary`] was turned on
     535              :     /// (default is `false`) when parsing the binary.
     536          169 :     pub fn nested_pe_binary(&self) -> Option<Binary> {
     537          169 :         into_optional(self.ptr.nested_pe_binary())
     538          169 :     }
     539              : 
     540              :     /// Set or change the export table
     541            0 :     pub fn set_export(&mut self, export: &Export) {
     542            0 :         self.ptr.pin_mut().set_export(export.as_ffi());
     543            0 :     }
     544              : 
     545              :     /// Whether the current binary is a reproducible build
     546            0 :     pub fn is_reproducible_build(&self) -> bool {
     547            0 :         self.ptr.is_reproducible_build()
     548            0 :     }
     549              : 
     550              :     /// Check if the binary imports the given library name
     551            0 :     pub fn has_import(&self, name: &str) -> bool {
     552            0 :         self.ptr.has_import(name.to_string())
     553            0 :     }
     554              : 
     555              :     /// Check if the binary has a delay import with the given name
     556            0 :     pub fn has_delay_import(&self, name: &str) -> bool {
     557            0 :         self.ptr.has_delay_import(name.to_string())
     558            0 :     }
     559              : 
     560              :     /// Return the exception functions (from the exception directory)
     561            0 :     pub fn exception_functions(&self) -> generic::Functions<'_> {
     562            0 :         generic::Functions::new(self.ptr.exception_functions())
     563            0 :     }
     564              : 
     565              :     /// Remove the section with the given name
     566            0 :     pub fn remove_section(&mut self, name: &str, clear: bool) {
     567            0 :         self.ptr.pin_mut().remove_section(name.to_string(), clear);
     568            0 :     }
     569              : 
     570              :     /// Fill the content at the given virtual address with the specified value
     571            0 :     pub fn fill_address(&mut self, address: u64, size: u64, value: u8) {
     572            0 :         self.ptr.pin_mut().fill_address(address, size, value);
     573            0 :     }
     574              : 
     575              :     /// Remove all relocations
     576            0 :     pub fn remove_all_relocations(&mut self) {
     577            0 :         self.ptr.pin_mut().remove_all_relocations();
     578            0 :     }
     579              : }
     580              : 
     581              : impl AsFFI<ffi::PE_Binary> for Binary {
     582            0 :     fn as_ffi(&self) -> &ffi::PE_Binary {
     583            0 :         self.ptr.as_ref().unwrap()
     584            0 :     }
     585              : 
     586            0 :     fn as_mut_ffi(&mut self) -> std::pin::Pin<&mut ffi::PE_Binary> {
     587            0 :         self.ptr.pin_mut()
     588            0 :     }
     589              : }
     590              : 
     591              : impl std::fmt::Debug for Binary {
     592          169 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     593          169 :         f.debug_struct("Binary").finish()
     594          169 :     }
     595              : }
     596              : 
     597              : impl generic::Binary for Binary {
     598          195 :     fn as_generic(&self) -> &ffi::AbstractBinary {
     599          195 :         self.ptr.as_ref().unwrap().as_ref()
     600          195 :     }
     601              : 
     602            0 :     fn as_pin_mut_generic(&mut self) -> Pin<&mut ffi::AbstractBinary> {
     603            0 :         unsafe {
     604            0 :             Pin::new_unchecked({
     605            0 :                 (self.ptr.as_ref().unwrap().as_ref() as *const ffi::AbstractBinary
     606            0 :                     as *mut ffi::AbstractBinary)
     607            0 :                     .as_mut()
     608            0 :                     .unwrap()
     609            0 :             })
     610            0 :         }
     611            0 :     }
     612              : }
     613              : 
     614          403 : declare_iterator!(
     615          403 :     DebugEntries,
     616          403 :     debug::Entries<'a>,
     617          403 :     ffi::PE_Debug,
     618          403 :     ffi::PE_Binary,
     619          403 :     ffi::PE_Binary_it_debug
     620          403 : );
     621              : 
     622       320515 : declare_iterator!(
     623       320515 :     COFFStrings,
     624       320515 :     coff::String<'a>,
     625       320515 :     ffi::PE_COFFString,
     626       320515 :     ffi::PE_Binary,
     627       320515 :     ffi::PE_Binary_it_strings_table
     628       320515 : );
     629              : 
     630       396721 : declare_iterator!(
     631       396721 :     Symbols,
     632       396721 :     Symbol<'a>,
     633       396721 :     ffi::PE_Symbol,
     634       396721 :     ffi::PE_Binary,
     635       396721 :     ffi::PE_Binary_it_symbols
     636       396721 : );
     637              : 
     638      1002417 : declare_iterator!(
     639      1002417 :     Exceptions,
     640      1002417 :     RuntimeExceptionFunction<'a>,
     641      1002417 :     ffi::PE_ExceptionInfo,
     642      1002417 :     ffi::PE_Binary,
     643      1002417 :     ffi::PE_Binary_it_exceptions
     644      1002417 : );
        

Generated by: LCOV version 2.1-1