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

Generated by: LCOV version 2.1-1