LCOV - code coverage report
Current view: top level - src/pe - headers.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 61.1 % 468 286
Test Date: 2024-10-27:00:00:00 Functions: 75.5 % 94 71

            Line data    Source code
       1              : //! This module exposes the different headers that we can find in a PE binary.
       2              : //! It includes:
       3              : //! - [`DosHeader`]
       4              : //! - [`Header`]
       5              : //! - [`OptionalHeader`]
       6              : 
       7              : use bitflags::bitflags;
       8              : use std::marker::PhantomData;
       9              : 
      10              : use crate::common::FromFFI;
      11              : use lief_ffi as ffi;
      12              : 
      13              : /// Structure which represents the DosHeader, the **first** structure presents at the beginning of
      14              : /// a PE file.
      15              : ///
      16              : /// Most of the attributes of this structures are no longer relevant
      17              : pub struct DosHeader<'a> {
      18              :     ptr: cxx::UniquePtr<ffi::PE_DosHeader>,
      19              :     _owner: PhantomData<&'a ffi::PE_Binary>,
      20              : }
      21              : 
      22              : impl FromFFI<ffi::PE_DosHeader> for DosHeader<'_> {
      23           64 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DosHeader>) -> Self {
      24           64 :         Self {
      25           64 :             ptr,
      26           64 :             _owner: PhantomData,
      27           64 :         }
      28           64 :     }
      29              : }
      30              : 
      31              : impl<'a> DosHeader<'a> {
      32              :     /// Magic bytes identifying a DOS/PE binary
      33           64 :     pub fn magic(&self) -> u16 {
      34           64 :         self.ptr.magic()
      35           64 :     }
      36              : 
      37           64 :     pub fn used_bytes_in_last_page(&self) -> u16 {
      38           64 :         self.ptr.used_bytes_in_last_page()
      39           64 :     }
      40              : 
      41           64 :     pub fn file_size_in_pages(&self) -> u16 {
      42           64 :         self.ptr.file_size_in_pages()
      43           64 :     }
      44              : 
      45           64 :     pub fn numberof_relocation(&self) -> u16 {
      46           64 :         self.ptr.numberof_relocation()
      47           64 :     }
      48              : 
      49           64 :     pub fn header_size_in_paragraphs(&self) -> u16 {
      50           64 :         self.ptr.header_size_in_paragraphs()
      51           64 :     }
      52              : 
      53           64 :     pub fn minimum_extra_paragraphs(&self) -> u16 {
      54           64 :         self.ptr.minimum_extra_paragraphs()
      55           64 :     }
      56              : 
      57           64 :     pub fn maximum_extra_paragraphs(&self) -> u16 {
      58           64 :         self.ptr.maximum_extra_paragraphs()
      59           64 :     }
      60              : 
      61           64 :     pub fn initial_relative_ss(&self) -> u16 {
      62           64 :         self.ptr.initial_relative_ss()
      63           64 :     }
      64              : 
      65           64 :     pub fn initial_sp(&self) -> u16 {
      66           64 :         self.ptr.initial_sp()
      67           64 :     }
      68              : 
      69           64 :     pub fn checksum(&self) -> u16 {
      70           64 :         self.ptr.checksum()
      71           64 :     }
      72              : 
      73           64 :     pub fn initial_ip(&self) -> u16 {
      74           64 :         self.ptr.initial_ip()
      75           64 :     }
      76              : 
      77           64 :     pub fn initial_relative_cs(&self) -> u16 {
      78           64 :         self.ptr.initial_relative_cs()
      79           64 :     }
      80              : 
      81           64 :     pub fn addressof_relocation_table(&self) -> u16 {
      82           64 :         self.ptr.addressof_relocation_table()
      83           64 :     }
      84              : 
      85           64 :     pub fn overlay_number(&self) -> u16 {
      86           64 :         self.ptr.overlay_number()
      87           64 :     }
      88              : 
      89           64 :     pub fn reserved(&self) -> Vec<u16> {
      90          256 :         Vec::from_iter(self.ptr.reserved().iter().map(|x| *x as u16))
      91           64 :     }
      92              : 
      93           64 :     pub fn oem_id(&self) -> u16 {
      94           64 :         self.ptr.oem_id()
      95           64 :     }
      96              : 
      97           64 :     pub fn oem_info(&self) -> u16 {
      98           64 :         self.ptr.oem_info()
      99           64 :     }
     100              : 
     101           64 :     pub fn reserved2(&self) -> Vec<u16> {
     102          256 :         Vec::from_iter(self.ptr.reserved().iter().map(|x| *x as u16))
     103           64 :     }
     104              : 
     105              :     /// Return the offset to the [`Header`] structure.
     106           64 :     pub fn addressof_new_exeheader(&self) -> u32 {
     107           64 :         self.ptr.addressof_new_exeheader()
     108           64 :     }
     109              : }
     110              : 
     111              : impl std::fmt::Debug for DosHeader<'_> {
     112           64 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     113           64 :         f.debug_struct("DosHeader")
     114           64 :             .field("magic", &self.magic())
     115           64 :             .field("used_bytes_in_last_page", &self.used_bytes_in_last_page())
     116           64 :             .field("file_size_in_pages", &self.file_size_in_pages())
     117           64 :             .field("numberof_relocation", &self.numberof_relocation())
     118           64 :             .field(
     119           64 :                 "header_size_in_paragraphs",
     120           64 :                 &self.header_size_in_paragraphs(),
     121           64 :             )
     122           64 :             .field("minimum_extra_paragraphs", &self.minimum_extra_paragraphs())
     123           64 :             .field("maximum_extra_paragraphs", &self.maximum_extra_paragraphs())
     124           64 :             .field("initial_relative_ss", &self.initial_relative_ss())
     125           64 :             .field("initial_sp", &self.initial_sp())
     126           64 :             .field("checksum", &self.checksum())
     127           64 :             .field("initial_ip", &self.initial_ip())
     128           64 :             .field("initial_relative_cs", &self.initial_relative_cs())
     129           64 :             .field(
     130           64 :                 "addressof_relocation_table",
     131           64 :                 &self.addressof_relocation_table(),
     132           64 :             )
     133           64 :             .field("overlay_number", &self.overlay_number())
     134           64 :             .field("reserved", &self.reserved())
     135           64 :             .field("oem_info", &self.oem_info())
     136           64 :             .field("oem_id", &self.oem_id())
     137           64 :             .field("reserved2", &self.reserved2())
     138           64 :             .field("addressof_new_exeheader", &self.addressof_new_exeheader())
     139           64 :             .finish()
     140           64 :     }
     141              : }
     142              : 
     143              : /// Structure that represents the PE header (which follows the [`DosHeader`])
     144              : pub struct Header<'a> {
     145              :     ptr: cxx::UniquePtr<ffi::PE_Header>,
     146              :     _owner: PhantomData<&'a ffi::PE_Binary>,
     147              : }
     148              : 
     149              : impl FromFFI<ffi::PE_Header> for Header<'_> {
     150           64 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_Header>) -> Self {
     151           64 :         Self {
     152           64 :             ptr,
     153           64 :             _owner: PhantomData,
     154           64 :         }
     155           64 :     }
     156              : }
     157              : 
     158              : 
     159              : #[allow(non_camel_case_types)]
     160           64 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
     161              : pub enum MachineType {
     162              :     /// Matsushita AM33
     163              :     AM33,
     164              :     /// AMD x64
     165              :     AMD64,
     166              :     /// ARM little endian
     167              :     ARM,
     168              :     /// ARMv7 Thumb mode only
     169              :     ARMNT,
     170              :     /// ARMv8 in 64-bits mode
     171              :     ARM64,
     172              :     /// EFI byte code
     173              :     EBC,
     174              :     /// Intel 386 or later
     175              :     I386,
     176              :     /// Intel Itanium processor family
     177              :     IA64,
     178              :     /// Mitsubishi M32R little endian
     179              :     M32R,
     180              :     /// MIPS16
     181              :     MIPS16,
     182              :     /// MIPS with FPU
     183              :     MIPSFPU,
     184              :     /// MIPS16 with FPU
     185              :     MIPSFPU16,
     186              :     /// Power PC little endian
     187              :     POWERPC,
     188              :     /// Power PC with floating point
     189              :     POWERPCFP,
     190              :     /// Power PC big endian
     191              :     POWERPCBE,
     192              :     /// MIPS with little endian
     193              :     R4000,
     194              :     /// RISC-V 32-bit address space
     195              :     RISCV32,
     196              :     /// RISC-V 64-bit address space
     197              :     RISCV64,
     198              :     /// RISC-V 128-bit address space
     199              :     RISCV128,
     200              :     /// Hitachi SH3
     201              :     SH3,
     202              :     /// Hitachi SH3 DSP
     203              :     SH3DSP,
     204              :     /// Hitachi SH4
     205              :     SH4,
     206              :     /// Hitachi SH5
     207              :     SH5,
     208              :     /// ARM or Thumb
     209              :     THUMB,
     210              :     /// MIPS little-endian WCE v2
     211              :     WCEMIPSV2,
     212              :     UNKNOWN(u32),
     213              : }
     214              : 
     215              : impl From<u32> for MachineType {
     216           64 :     fn from(value: u32) -> Self {
     217           64 :         match value {
     218            0 :             0x000001d3 => MachineType::AM33,
     219           32 :             0x00008664 => MachineType::AMD64,
     220            0 :             0x000001c0 => MachineType::ARM,
     221            0 :             0x000001c4 => MachineType::ARMNT,
     222            0 :             0x0000aa64 => MachineType::ARM64,
     223            0 :             0x00000ebc => MachineType::EBC,
     224           32 :             0x0000014c => MachineType::I386,
     225            0 :             0x00000200 => MachineType::IA64,
     226            0 :             0x00009041 => MachineType::M32R,
     227            0 :             0x00000266 => MachineType::MIPS16,
     228            0 :             0x00000366 => MachineType::MIPSFPU,
     229            0 :             0x00000466 => MachineType::MIPSFPU16,
     230            0 :             0x000001f0 => MachineType::POWERPC,
     231            0 :             0x000001f1 => MachineType::POWERPCFP,
     232            0 :             0x000001f2 => MachineType::POWERPCBE,
     233            0 :             0x00000166 => MachineType::R4000,
     234            0 :             0x00005032 => MachineType::RISCV32,
     235            0 :             0x00005064 => MachineType::RISCV64,
     236            0 :             0x00005128 => MachineType::RISCV128,
     237            0 :             0x000001a2 => MachineType::SH3,
     238            0 :             0x000001a3 => MachineType::SH3DSP,
     239            0 :             0x000001a6 => MachineType::SH4,
     240            0 :             0x000001a8 => MachineType::SH5,
     241            0 :             0x000001c2 => MachineType::THUMB,
     242            0 :             0x00000169 => MachineType::WCEMIPSV2,
     243            0 :             _ => MachineType::UNKNOWN(value),
     244              : 
     245              :         }
     246           64 :     }
     247              : }
     248              : impl From<MachineType> for u32 {
     249            0 :     fn from(value: MachineType) -> u32 {
     250            0 :         match value {
     251            0 :             MachineType::AM33 => 0x000001d3,
     252            0 :             MachineType::AMD64 => 0x00008664,
     253            0 :             MachineType::ARM => 0x000001c0,
     254            0 :             MachineType::ARMNT => 0x000001c4,
     255            0 :             MachineType::ARM64 => 0x0000aa64,
     256            0 :             MachineType::EBC => 0x00000ebc,
     257            0 :             MachineType::I386 => 0x0000014c,
     258            0 :             MachineType::IA64 => 0x00000200,
     259            0 :             MachineType::M32R => 0x00009041,
     260            0 :             MachineType::MIPS16 => 0x00000266,
     261            0 :             MachineType::MIPSFPU => 0x00000366,
     262            0 :             MachineType::MIPSFPU16 => 0x00000466,
     263            0 :             MachineType::POWERPC => 0x000001f0,
     264            0 :             MachineType::POWERPCFP => 0x000001f1,
     265            0 :             MachineType::POWERPCBE => 0x000001f2,
     266            0 :             MachineType::R4000 => 0x00000166,
     267            0 :             MachineType::RISCV32 => 0x00005032,
     268            0 :             MachineType::RISCV64 => 0x00005064,
     269            0 :             MachineType::RISCV128 => 0x00005128,
     270            0 :             MachineType::SH3 => 0x000001a2,
     271            0 :             MachineType::SH3DSP => 0x000001a3,
     272            0 :             MachineType::SH4 => 0x000001a6,
     273            0 :             MachineType::SH5 => 0x000001a8,
     274            0 :             MachineType::THUMB => 0x000001c2,
     275            0 :             MachineType::WCEMIPSV2 => 0x00000169,
     276            0 :             MachineType::UNKNOWN(_) => 0,
     277              : 
     278              :         }
     279            0 :     }
     280              : }
     281              : 
     282              : 
     283            0 : bitflags! {
     284           64 :     #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
     285            0 :     pub struct Characteristics: u32 {
     286            0 :         const NONE = 0x0;
     287            0 : 
     288            0 :         /// The file does not contain base relocations and must be loaded at its preferred base.
     289            0 :         /// If this cannot be done, the loader will error.
     290            0 :         const RELOCS_STRIPPED = 0x1;
     291            0 : 
     292            0 :         /// File is executable (i.e. no unresolved externel references).
     293            0 :         const EXECUTABLE_IMAGE = 0x2;
     294            0 : 
     295            0 :         /// COFF line numbers have been stripped. This is deprecated and should be 0
     296            0 :         const LINE_NUMS_STRIPPED = 0x4;
     297            0 : 
     298            0 :         /// COFF symbol table entries for local symbols have been removed.
     299            0 :         /// This is deprecated and should be 0.
     300            0 :         const LOCAL_SYMS_STRIPPED = 0x8;
     301            0 : 
     302            0 :         /// Aggressively trim working set. This is deprecated and must be 0.
     303            0 :         const AGGRESSIVE_WS_TRIM = 0x10;
     304            0 : 
     305            0 :         /// App can handle >2gb addresses
     306            0 :         const LARGE_ADDRESS_AWARE = 0x20;
     307            0 : 
     308            0 :         /// Little endian: the LSB precedes the MSB in memory. This is deprecated and should be 0.
     309            0 :         const BYTES_REVERSED_LO = 0x80;
     310            0 : 
     311            0 :         /// Machine is based on a 32bit word architecture.
     312            0 :         const NEED_32BIT_MACHINE = 0x100;
     313            0 : 
     314            0 :         /// Debugging info has been removed.
     315            0 :         const DEBUG_STRIPPED = 0x200;
     316            0 : 
     317            0 :         /// If the image is on removable media, fully load it and copy it to swap.
     318            0 :         const REMOVABLE_RUN_FROM_SWAP = 0x400;
     319            0 : 
     320            0 :         /// If the image is on network media, fully load it and copy it to swap.
     321            0 :         const NET_RUN_FROM_SWAP = 0x800;
     322            0 : 
     323            0 :         /// The image file is a system file, not a user program.
     324            0 :         const SYSTEM = 0x1000;
     325            0 : 
     326            0 :         /// The image file is a DLL.
     327            0 :         const DLL = 0x2000;
     328            0 : 
     329            0 :         /// This file should only be run on a uniprocessor machine.
     330            0 :         const UP_SYSTEM_ONLY = 0x4000;
     331            0 : 
     332            0 :         /// Big endian: the MSB precedes the LSB in memory. This is deprecated
     333            0 :         const BYTES_REVERSED_HI = 0x8000;
     334            0 :     }
     335            0 : }
     336              : 
     337              : impl std::fmt::Display for Characteristics {
     338            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     339            0 :         bitflags::parser::to_writer(self, f)
     340            0 :     }
     341              : }
     342              : 
     343              : 
     344              : impl From<u32> for Characteristics {
     345           64 :     fn from(value: u32) -> Self {
     346           64 :         Characteristics::from_bits_truncate(value)
     347           64 :     }
     348              : }
     349              : impl From<Characteristics> for u32 {
     350            0 :     fn from(value: Characteristics) -> Self {
     351            0 :         value.bits()
     352            0 :     }
     353              : }
     354              : 
     355              : impl Header<'_> {
     356              :     /// The targeted machine architecture like ARM, x86, AMD64, ...
     357           64 :     pub fn machine(&self) -> MachineType {
     358           64 :         MachineType::from(self.ptr.machine())
     359           64 :     }
     360              : 
     361              :     /// The number of sections in the binary.
     362           64 :     pub fn nb_sections(&self) -> u16 {
     363           64 :         self.ptr.numberof_sections()
     364           64 :     }
     365              : 
     366              :     /// The low 32 bits of the number of seconds since January 1, 1970.
     367              :     /// It **indicates** when the file was created.
     368           64 :     pub fn time_date_stamp(&self) -> u32 {
     369           64 :         self.ptr.time_date_stamp()
     370           64 :     }
     371              : 
     372              :     /// The offset of the **COFF** symbol table.
     373              :     /// This value should be zero for an image because COFF debugging information is deprecated on
     374              :     /// in PE binary
     375           64 :     pub fn pointerto_symbol_table(&self) -> u32 {
     376           64 :         self.ptr.pointerto_symbol_table()
     377           64 :     }
     378              : 
     379              : 
     380              :     /// The number of entries in the symbol table. This data can be used to locate the string table
     381              :     /// which immediately follows the symbol table.
     382              :     ///
     383              :     /// This value should be zero for an image because COFF debugging information is deprecated in
     384              :     /// PE binary
     385           64 :     pub fn numberof_symbols(&self) -> u32 {
     386           64 :         self.ptr.numberof_symbols()
     387           64 :     }
     388              : 
     389              :     /// Size of the OptionalHeader **AND** the data directories which follows this header.
     390              :     ///
     391              :     /// This value is equivalent to:
     392              :     /// `sizeof(pe_optional_header) + NB_DATA_DIR * sizeof(data_directory)`
     393              :     ///
     394              :     /// This size **should** be either:
     395              :     /// * 0xE0 (224) for a PE32  (32 bits)
     396              :     /// * 0xF0 (240) for a PE32+ (64 bits)
     397           64 :     pub fn sizeof_optional_header(&self) -> u16 {
     398           64 :         self.ptr.sizeof_optional_header()
     399           64 :     }
     400              : 
     401              :     /// Characteristics of the binary like whether it is a DLL or an executable
     402           64 :     pub fn characteristics(&self) -> Characteristics {
     403           64 :         Characteristics::from(self.ptr.characteristics())
     404           64 :     }
     405              : }
     406              : 
     407              : impl std::fmt::Debug for Header<'_> {
     408           64 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     409           64 :         f.debug_struct("Header")
     410           64 :             .field("machine", &self.machine())
     411           64 :             .field("nb_sections", &self.nb_sections())
     412           64 :             .field("time_date_stamp", &self.time_date_stamp())
     413           64 :             .field("pointerto_symbol_table", &self.pointerto_symbol_table())
     414           64 :             .field("numberof_symbols", &self.numberof_symbols())
     415           64 :             .field("sizeof_optional_header", &self.sizeof_optional_header())
     416           64 :             .field("characteristics", &self.characteristics())
     417           64 :             .finish()
     418           64 :     }
     419              : }
     420              : 
     421              : 
     422              : /// Structure which represents the PE OptionalHeader (after [`Header`]).
     423              : ///
     424              : /// Note that the term *optional* comes from the COFF specifications but this header is
     425              : /// **mandatory** for a PE binary.
     426              : pub struct OptionalHeader<'a> {
     427              :     ptr: cxx::UniquePtr<ffi::PE_OptionalHeader>,
     428              :     _owner: PhantomData<&'a ffi::PE_Binary>,
     429              : }
     430              : 
     431              : impl FromFFI<ffi::PE_OptionalHeader> for OptionalHeader<'_> {
     432           64 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_OptionalHeader>) -> Self {
     433           64 :         Self {
     434           64 :             ptr,
     435           64 :             _owner: PhantomData,
     436           64 :         }
     437           64 :     }
     438              : }
     439              : 
     440            0 : bitflags! {
     441           64 :     #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
     442            0 :     pub struct DllCharacteristics: u32 {
     443            0 :         /// ASLR with 64 bit address space.
     444            0 :         const HIGH_ENTROPY_VA = 0x20;
     445            0 : 
     446            0 :         /// DLL can be relocated at load time.
     447            0 :         const DYNAMIC_BASE = 0x40;
     448            0 : 
     449            0 :         /// Code integrity checks are enforced.
     450            0 :         const FORCE_INTEGRITY = 0x80;
     451            0 : 
     452            0 :         /// Image is NX compatible.
     453            0 :         const NX_COMPAT = 0x100;
     454            0 : 
     455            0 :         /// Isolation aware, but do not isolate the image.
     456            0 :         const NO_ISOLATION = 0x200;
     457            0 : 
     458            0 :         /// Does not use structured exception handling (SEH).
     459            0 :         /// No SEH handler may be called in this image.
     460            0 :         const NO_SEH = 0x400;
     461            0 : 
     462            0 :         /// Do not bind the image.
     463            0 :         const NO_BIND = 0x800;
     464            0 : 
     465            0 :         /// Image should execute in an AppContainer.
     466            0 :         const APPCONTAINER = 0x1000;
     467            0 : 
     468            0 :         /// A WDM driver.
     469            0 :         const WDM_DRIVER = 0x2000;
     470            0 : 
     471            0 :         /// Image supports Control Flow Guard.
     472            0 :         const GUARD_CF = 0x4000;
     473            0 : 
     474            0 :         /// Terminal Server aware.
     475            0 :         const TERMINAL_SERVER_AWARE = 0x8000;
     476            0 :     }
     477            0 : }
     478              : 
     479              : 
     480              : impl From<u32> for DllCharacteristics {
     481           64 :     fn from(value: u32) -> Self {
     482           64 :         DllCharacteristics::from_bits_truncate(value)
     483           64 :     }
     484              : }
     485              : impl From<DllCharacteristics> for u32 {
     486            0 :     fn from(value: DllCharacteristics) -> Self {
     487            0 :         value.bits()
     488            0 :     }
     489              : }
     490              : impl std::fmt::Display for DllCharacteristics {
     491            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     492            0 :         bitflags::parser::to_writer(self, f)
     493            0 :     }
     494              : }
     495              : 
     496              : 
     497              : #[allow(non_camel_case_types)]
     498           64 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
     499              : pub enum Subsystem {
     500              :     /// Device drivers and native Windows processes
     501              :     NATIVE,
     502              : 
     503              :     /// The Windows GUI subsystem.
     504              :     WINDOWS_GUI,
     505              : 
     506              :     /// The Windows character subsystem.
     507              :     WINDOWS_CUI,
     508              : 
     509              :     /// The OS/2 character subsytem.
     510              :     OS2_CUI,
     511              : 
     512              :     /// The POSIX character subsystem.
     513              :     POSIX_CUI,
     514              : 
     515              :     /// Native Windows 9x driver.
     516              :     NATIVE_WINDOWS,
     517              : 
     518              :     /// Windows CE.
     519              :     WINDOWS_CE_GUI,
     520              : 
     521              :     /// An EFI application.
     522              :     EFI_APPLICATION,
     523              : 
     524              :     /// An EFI driver with boot services.
     525              :     EFI_BOOT_SERVICE_DRIVER,
     526              : 
     527              :     /// An EFI driver with run-time services.
     528              :     EFI_RUNTIME_DRIVER,
     529              : 
     530              :     /// An EFI ROM image.
     531              :     EFI_ROM,
     532              : 
     533              :     /// XBOX
     534              :     XBOX,
     535              : 
     536              :     /// A BCD application.
     537              :     WINDOWS_BOOT_APPLICATION,
     538              : 
     539              :     /// An unknown subsystem.
     540              :     UNKNOWN(u64),
     541              : }
     542              : 
     543              : impl From<u64> for Subsystem {
     544           64 :     fn from(value: u64) -> Self {
     545           64 :         match value {
     546            8 :             0x00000001 => Subsystem::NATIVE,
     547           24 :             0x00000002 => Subsystem::WINDOWS_GUI,
     548           32 :             0x00000003 => Subsystem::WINDOWS_CUI,
     549            0 :             0x00000005 => Subsystem::OS2_CUI,
     550            0 :             0x00000007 => Subsystem::POSIX_CUI,
     551            0 :             0x00000008 => Subsystem::NATIVE_WINDOWS,
     552            0 :             0x00000009 => Subsystem::WINDOWS_CE_GUI,
     553            0 :             0x0000000a => Subsystem::EFI_APPLICATION,
     554            0 :             0x0000000b => Subsystem::EFI_BOOT_SERVICE_DRIVER,
     555            0 :             0x0000000c => Subsystem::EFI_RUNTIME_DRIVER,
     556            0 :             0x0000000d => Subsystem::EFI_ROM,
     557            0 :             0x0000000e => Subsystem::XBOX,
     558            0 :             0x00000010 => Subsystem::WINDOWS_BOOT_APPLICATION,
     559            0 :             _ => Subsystem::UNKNOWN(value),
     560              : 
     561              :         }
     562           64 :     }
     563              : }
     564              : impl From<Subsystem> for u64 {
     565            0 :     fn from(value: Subsystem) -> u64 {
     566            0 :         match value {
     567            0 :             Subsystem::NATIVE => 0x00000001,
     568            0 :             Subsystem::WINDOWS_GUI => 0x00000002,
     569            0 :             Subsystem::WINDOWS_CUI => 0x00000003,
     570            0 :             Subsystem::OS2_CUI => 0x00000005,
     571            0 :             Subsystem::POSIX_CUI => 0x00000007,
     572            0 :             Subsystem::NATIVE_WINDOWS => 0x00000008,
     573            0 :             Subsystem::WINDOWS_CE_GUI => 0x00000009,
     574            0 :             Subsystem::EFI_APPLICATION => 0x0000000a,
     575            0 :             Subsystem::EFI_BOOT_SERVICE_DRIVER => 0x0000000b,
     576            0 :             Subsystem::EFI_RUNTIME_DRIVER => 0x0000000c,
     577            0 :             Subsystem::EFI_ROM => 0x0000000d,
     578            0 :             Subsystem::XBOX => 0x0000000e,
     579            0 :             Subsystem::WINDOWS_BOOT_APPLICATION => 0x00000010,
     580            0 :             Subsystem::UNKNOWN(_) => 0,
     581              : 
     582              :         }
     583            0 :     }
     584              : }
     585              : 
     586              : impl OptionalHeader<'_> {
     587              :     /// The linker major version
     588           64 :     pub fn major_linker_version(&self) -> u8 {
     589           64 :         self.ptr.major_linker_version()
     590           64 :     }
     591              : 
     592              :     /// The linker minor version
     593           64 :     pub fn minor_linker_version(&self) -> u8 {
     594           64 :         self.ptr.minor_linker_version()
     595           64 :     }
     596              : 
     597              :     /// The size of the code `.text` section or the sum of
     598              :     /// all the sections that contain code (i.e. sections with `CNT_CODE` flag)
     599           64 :     pub fn sizeof_code(&self) -> u32 {
     600           64 :         self.ptr.sizeof_code()
     601           64 :     }
     602              : 
     603              :     /// The size of the initialized data which are usually located in the `.data` section.
     604              :     /// If the initialized data are split across multiple sections, it is the sum of the sections.
     605           64 :     pub fn sizeof_initialized_data(&self) -> u32 {
     606           64 :         self.ptr.sizeof_initialized_data()
     607           64 :     }
     608              : 
     609              :     /// The size of the uninitialized data which are usually located in the `.bss` section.
     610              :     /// If the uninitialized data are split across multiple sections, it is the sum of the sections.
     611           64 :     pub fn sizeof_uninitialized_data(&self) -> u32 {
     612           64 :         self.ptr.sizeof_uninitialized_data()
     613           64 :     }
     614              : 
     615              :     /// The address of the entry point relative to the image base when the executable file is
     616              :     /// loaded into memory. For program images, this is the starting address. For device
     617              :     /// drivers, this is the address of the initialization function.
     618              :     ///
     619              :     /// An entry point is optional for DLLs. When no entry point is present, this field must be zero.
     620           64 :     pub fn addressof_entrypoint(&self) -> u32 {
     621           64 :         self.ptr.addressof_entrypoint()
     622           64 :     }
     623              : 
     624              :     /// Address relative to the imagebase where the binary's code starts.
     625           64 :     pub fn baseof_code(&self) -> u32 {
     626           64 :         self.ptr.baseof_code()
     627           64 :     }
     628              : 
     629              :     /// Address relative to the imagebase where the binary's data starts.
     630              :     ///
     631              :     /// <div class="warning">This value is not present for PE64 files</div>
     632           64 :     pub fn baseof_data(&self) -> u32 {
     633           64 :         self.ptr.baseof_data()
     634           64 :     }
     635              : 
     636              :     /// The preferred base address when mapping the binary in memory
     637           64 :     pub fn imagebase(&self) -> u64 {
     638           64 :         self.ptr.imagebase()
     639           64 :     }
     640              : 
     641              :     /// The alignment (in bytes) of sections when they are loaded into memory.
     642              :     ///
     643              :     /// It must be greater than or equal to file_alignment and
     644              :     /// the default is the page size for the architecture.
     645           64 :     pub fn section_alignment(&self) -> u32 {
     646           64 :         self.ptr.section_alignment()
     647           64 :     }
     648              : 
     649              :     /// The section's file alignment. This value must be a power of 2 between 512 and 64K.
     650              :     /// The default value is usually 512
     651           64 :     pub fn file_alignment(&self) -> u32 {
     652           64 :         self.ptr.file_alignment()
     653           64 :     }
     654              : 
     655              :     /// The **major** version number of the required operating system
     656           64 :     pub fn major_operating_system_version(&self) -> u32 {
     657           64 :         self.ptr.major_operating_system_version()
     658           64 :     }
     659              : 
     660              :     /// The **minor** version number of the required operating system
     661           64 :     pub fn minor_operating_system_version(&self) -> u32 {
     662           64 :         self.ptr.minor_operating_system_version()
     663           64 :     }
     664              : 
     665              :     /// The major version number of the image
     666           64 :     pub fn major_image_version(&self) -> u32 {
     667           64 :         self.ptr.major_image_version()
     668           64 :     }
     669              : 
     670              :     /// The minor version number of the image
     671           64 :     pub fn minor_image_version(&self) -> u32 {
     672           64 :         self.ptr.minor_image_version()
     673           64 :     }
     674              : 
     675              :     /// The major version number of the subsystem
     676           64 :     pub fn major_subsystem_version(&self) -> u32 {
     677           64 :         self.ptr.major_subsystem_version()
     678           64 :     }
     679              : 
     680              :     /// The minor version number of the subsystem
     681           64 :     pub fn minor_subsystem_version(&self) -> u32 {
     682           64 :         self.ptr.minor_subsystem_version()
     683           64 :     }
     684              : 
     685              :     /// According to the official PE specifications, this value
     686              :     /// is reserved and **should** be 0.
     687           64 :     pub fn win32_version_value(&self) -> u32 {
     688           64 :         self.ptr.win32_version_value()
     689           64 :     }
     690              : 
     691              :     /// The size (in bytes) of the image, including all headers, as the image is loaded in memory.
     692              :     ///
     693              :     /// It must be a multiple of section_alignment and should match [`crate::pe::Binary::virtual_size`]
     694           64 :     pub fn sizeof_image(&self) -> u32 {
     695           64 :         self.ptr.sizeof_image()
     696           64 :     }
     697              : 
     698              :     /// Size of the DosHeader + PE Header + Section headers rounded up to a multiple of the file_alignment
     699           64 :     pub fn sizeof_headers(&self) -> u32 {
     700           64 :         self.ptr.sizeof_headers()
     701           64 :     }
     702              : 
     703              :     /// The image file checksum. The algorithm for computing the checksum is incorporated into `IMAGHELP.DLL`.
     704              :     ///
     705              :     /// The following are checked for validation at load time all **drivers**, any **DLL loaded at boot**
     706              :     /// time, and any **DLL** that is loaded into a **critical** Windows process.
     707          128 :     pub fn checksum(&self) -> u32 {
     708          128 :         self.ptr.checksum()
     709          128 :     }
     710              : 
     711              :     /// Target subsystem like Driver, XBox, Windows GUI, ...
     712           64 :     pub fn subsystem(&self) -> Subsystem {
     713           64 :         Subsystem::from(self.ptr.subsystem())
     714           64 :     }
     715              : 
     716              :     /// Some characteristics of the underlying binary like the support of the PIE.
     717              :     /// The prefix ``dll`` comes from the official PE specifications but these characteristics
     718              :     /// are also used for **executables**
     719           64 :     pub fn dll_characteristics(&self) -> DllCharacteristics {
     720           64 :         DllCharacteristics::from(self.ptr.dll_characteristics())
     721           64 :     }
     722              : 
     723              : 
     724              :     /// Size of the stack to reserve when loading the PE binary
     725              :     ///
     726              :     /// Only [`OptionalHeader::sizeof_stack_commit`] is committed, the rest
     727              :     /// available one page at a time until the reserve size is reached.
     728           64 :     pub fn sizeof_stack_reserve(&self) -> u64 {
     729           64 :         self.ptr.sizeof_stack_reserve()
     730           64 :     }
     731              : 
     732              :     /// Size of the stack to commit
     733           64 :     pub fn sizeof_stack_commit(&self) -> u64 {
     734           64 :         self.ptr.sizeof_stack_commit()
     735           64 :     }
     736              : 
     737              :     /// Size of the heap to reserve when loading the PE binary
     738           64 :     pub fn sizeof_heap_reserve(&self) -> u64 {
     739           64 :         self.ptr.sizeof_heap_reserve()
     740           64 :     }
     741              : 
     742              :     /// Size of the stack to commit
     743           64 :     pub fn sizeof_heap_commit(&self) -> u64 {
     744           64 :         self.ptr.sizeof_heap_commit()
     745           64 :     }
     746              : 
     747              :     /// According to the PE specifications, this value is *reserved* and **should** be 0.
     748           64 :     pub fn loader_flags(&self) -> u32 {
     749           64 :         self.ptr.loader_flags()
     750           64 :     }
     751              : 
     752              :     /// The number of DataDirectory that follow this header.
     753           64 :     pub fn numberof_rva_and_size(&self) -> u32 {
     754           64 :         self.ptr.numberof_rva_and_size()
     755           64 :     }
     756              : }
     757              : 
     758              : impl std::fmt::Debug for OptionalHeader<'_> {
     759           64 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     760           64 :         f.debug_struct("OptionalHeader")
     761           64 :             .field("major_linker_version", &self.major_linker_version())
     762           64 :             .field("minor_linker_version", &self.minor_linker_version())
     763           64 :             .field("sizeof_code", &self.sizeof_code())
     764           64 :             .field("sizeof_initialized_data", &self.sizeof_initialized_data())
     765           64 :             .field(
     766           64 :                 "sizeof_uninitialized_data",
     767           64 :                 &self.sizeof_uninitialized_data(),
     768           64 :             )
     769           64 :             .field("addressof_entrypoint", &self.addressof_entrypoint())
     770           64 :             .field("baseof_code", &self.baseof_code())
     771           64 :             .field("baseof_data", &self.baseof_data())
     772           64 :             .field("imagebase", &self.imagebase())
     773           64 :             .field("section_alignment", &self.section_alignment())
     774           64 :             .field("file_alignment", &self.file_alignment())
     775           64 :             .field(
     776           64 :                 "major_operating_system_version",
     777           64 :                 &self.major_operating_system_version(),
     778           64 :             )
     779           64 :             .field(
     780           64 :                 "minor_operating_system_version",
     781           64 :                 &self.minor_operating_system_version(),
     782           64 :             )
     783           64 :             .field("major_image_version", &self.major_image_version())
     784           64 :             .field("minor_image_version", &self.minor_image_version())
     785           64 :             .field("major_subsystem_version", &self.major_subsystem_version())
     786           64 :             .field("minor_subsystem_version", &self.minor_subsystem_version())
     787           64 :             .field("win32_version_value", &self.win32_version_value())
     788           64 :             .field("sizeof_image", &self.sizeof_image())
     789           64 :             .field("sizeof_headers", &self.sizeof_headers())
     790           64 :             .field("checksum", &self.checksum())
     791           64 :             .field("subsystem", &self.subsystem())
     792           64 :             .field("dll_characteristics", &self.dll_characteristics())
     793           64 :             .field("sizeof_stack_reserve", &self.sizeof_stack_reserve())
     794           64 :             .field("sizeof_stack_commit", &self.sizeof_stack_commit())
     795           64 :             .field("sizeof_heap_reserve", &self.sizeof_heap_reserve())
     796           64 :             .field("sizeof_heap_commit", &self.sizeof_heap_commit())
     797           64 :             .field("loader_flags", &self.loader_flags())
     798           64 :             .field("numberof_rva_and_size", &self.numberof_rva_and_size())
     799           64 :             .finish()
     800           64 :     }
     801              : }
        

Generated by: LCOV version 2.1-1