LCOV - code coverage report
Current view: top level - src - pe.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 11.6 % 112 13
Test Date: 2026-04-12:00:00:00 Functions: 12.0 % 25 3

            Line data    Source code
       1              : //! Module for the PE file format support in LIEF.
       2              : //!
       3              : //! The [`Binary`] structure exposes the main API to inspect a PE file. It can be instantiated,
       4              : //! using either: [`crate::pe::parse`], [`crate::pe::Binary::parse`] or [`crate::Binary::parse`]
       5              : //!
       6              : //! ```
       7              : //! let pe = lief::pe::parse("demo.exe").unwrap();
       8              : //! for section in pe.sections() {
       9              : //!     println!("section: {}", section.name());
      10              : //! }
      11              : //! ```
      12              : 
      13              : use lief_ffi as ffi;
      14              : use std::path::Path;
      15              : 
      16              : pub mod binary;
      17              : pub mod builder;
      18              : pub mod chpe_metadata_arm64;
      19              : pub mod chpe_metadata_x86;
      20              : pub mod code_integrity;
      21              : pub mod data_directory;
      22              : pub mod debug;
      23              : pub mod delay_import;
      24              : pub mod dynamic_fixups;
      25              : pub mod dynamic_relocation;
      26              : pub mod enclave_configuration;
      27              : pub mod exception;
      28              : pub mod exception_aarch64;
      29              : pub mod exception_x64;
      30              : pub mod export;
      31              : pub mod factory;
      32              : pub mod headers;
      33              : pub mod import;
      34              : pub mod load_configuration;
      35              : pub mod parser_config;
      36              : pub mod relocation;
      37              : pub mod resources;
      38              : pub mod rich_header;
      39              : pub mod section;
      40              : pub mod signature;
      41              : pub mod tls;
      42              : pub mod volatile_metadata;
      43              : 
      44              : #[doc(inline)]
      45              : pub use binary::Binary;
      46              : #[doc(inline)]
      47              : pub use data_directory::DataDirectory;
      48              : #[doc(inline)]
      49              : pub use delay_import::DelayImport;
      50              : #[doc(inline)]
      51              : pub use dynamic_fixups::DynamicFixup;
      52              : #[doc(inline)]
      53              : pub use dynamic_relocation::DynamicRelocation;
      54              : #[doc(inline)]
      55              : pub use enclave_configuration::{EnclaveConfiguration, EnclaveImport};
      56              : #[doc(inline)]
      57              : pub use exception::{ExceptionInfo, RuntimeExceptionFunction};
      58              : #[doc(inline)]
      59              : pub use export::Export;
      60              : #[doc(inline)]
      61              : pub use factory::Factory;
      62              : #[doc(inline)]
      63              : pub use headers::{DosHeader, Header, OptionalHeader};
      64              : #[doc(inline)]
      65              : pub use import::Import;
      66              : #[doc(inline)]
      67              : pub use load_configuration::{CHPEMetadata, LoadConfiguration};
      68              : #[doc(inline)]
      69              : pub use parser_config::Config as ParserConfig;
      70              : #[doc(inline)]
      71              : pub use relocation::Relocation;
      72              : #[doc(inline)]
      73              : pub use resources::Accelerator as ResourceAccelerator;
      74              : #[doc(inline)]
      75              : pub use resources::Icon as ResourceIcon;
      76              : #[doc(inline)]
      77              : pub use resources::Manager as ResourcesManager;
      78              : #[doc(inline)]
      79              : pub use resources::Node as ResourceNode;
      80              : #[doc(inline)]
      81              : pub use resources::StringEntry as ResourceStringEntry;
      82              : #[doc(inline)]
      83              : pub use resources::Version as ResourceVersion;
      84              : #[doc(inline)]
      85              : pub use rich_header::{RichEntry, RichHeader};
      86              : #[doc(inline)]
      87              : pub use section::Section;
      88              : #[doc(inline)]
      89              : pub use signature::Signature;
      90              : #[doc(inline)]
      91              : pub use tls::TLS;
      92              : #[doc(inline)]
      93              : pub use volatile_metadata::VolatileMetadata;
      94              : 
      95              : use crate::common::AsFFI;
      96              : 
      97              : /// PE type: 32-bit or 64-bit
      98              : #[allow(non_camel_case_types)]
      99            0 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
     100              : pub enum PE_TYPE {
     101              :     /// 32-bit PE
     102              :     PE32,
     103              :     /// 64-bit PE
     104              :     PE32_PLUS,
     105              :     UNKNOWN(u32),
     106              : }
     107              : 
     108              : impl From<u32> for PE_TYPE {
     109            0 :     fn from(value: u32) -> Self {
     110            0 :         match value {
     111            0 :             0x10b => PE_TYPE::PE32,
     112            0 :             0x20b => PE_TYPE::PE32_PLUS,
     113            0 :             _ => PE_TYPE::UNKNOWN(value),
     114              :         }
     115            0 :     }
     116              : }
     117              : 
     118              : impl From<PE_TYPE> for u32 {
     119            0 :     fn from(value: PE_TYPE) -> u32 {
     120            0 :         match value {
     121            0 :             PE_TYPE::PE32 => 0x10b,
     122            0 :             PE_TYPE::PE32_PLUS => 0x20b,
     123            0 :             PE_TYPE::UNKNOWN(v) => v,
     124              :         }
     125            0 :     }
     126              : }
     127              : 
     128              : #[allow(non_camel_case_types)]
     129         1066 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
     130              : pub enum Algorithms {
     131              :     SHA_512,
     132              :     SHA_384,
     133              :     SHA_256,
     134              :     SHA_1,
     135              :     MD5,
     136              :     MD4,
     137              :     MD2,
     138              :     RSA,
     139              :     EC,
     140              :     MD5_RSA,
     141              :     SHA1_DSA,
     142              :     SHA1_RSA,
     143              :     SHA_256_RSA,
     144              :     SHA_384_RSA,
     145              :     SHA_512_RSA,
     146              :     SHA1_ECDSA,
     147              :     SHA_256_ECDSA,
     148              :     SHA_384_ECDSA,
     149              :     SHA_512_ECDSA,
     150              :     UNKNOWN(u32),
     151              : }
     152              : 
     153              : impl From<u32> for Algorithms {
     154         1066 :     fn from(value: u32) -> Self {
     155         1066 :         match value {
     156            0 :             0x00000001 => Algorithms::SHA_512,
     157            0 :             0x00000002 => Algorithms::SHA_384,
     158          494 :             0x00000003 => Algorithms::SHA_256,
     159          208 :             0x00000004 => Algorithms::SHA_1,
     160           39 :             0x00000005 => Algorithms::MD5,
     161            0 :             0x00000006 => Algorithms::MD4,
     162            0 :             0x00000007 => Algorithms::MD2,
     163          260 :             0x00000008 => Algorithms::RSA,
     164            0 :             0x00000009 => Algorithms::EC,
     165            0 :             0x0000000a => Algorithms::MD5_RSA,
     166            0 :             0x0000000b => Algorithms::SHA1_DSA,
     167            0 :             0x0000000c => Algorithms::SHA1_RSA,
     168           65 :             0x0000000d => Algorithms::SHA_256_RSA,
     169            0 :             0x0000000e => Algorithms::SHA_384_RSA,
     170            0 :             0x0000000f => Algorithms::SHA_512_RSA,
     171            0 :             0x00000010 => Algorithms::SHA1_ECDSA,
     172            0 :             0x00000011 => Algorithms::SHA_256_ECDSA,
     173            0 :             0x00000012 => Algorithms::SHA_384_ECDSA,
     174            0 :             0x00000013 => Algorithms::SHA_512_ECDSA,
     175            0 :             _ => Algorithms::UNKNOWN(value),
     176              :         }
     177         1066 :     }
     178              : }
     179              : 
     180              : impl From<Algorithms> for u32 {
     181          169 :     fn from(value: Algorithms) -> u32 {
     182          169 :         match value {
     183            0 :             Algorithms::SHA_512 => 0x00000001,
     184            0 :             Algorithms::SHA_384 => 0x00000002,
     185          169 :             Algorithms::SHA_256 => 0x00000003,
     186            0 :             Algorithms::SHA_1 => 0x00000004,
     187            0 :             Algorithms::MD5 => 0x00000005,
     188            0 :             Algorithms::MD4 => 0x00000006,
     189            0 :             Algorithms::MD2 => 0x00000007,
     190            0 :             Algorithms::RSA => 0x00000008,
     191            0 :             Algorithms::EC => 0x00000009,
     192            0 :             Algorithms::MD5_RSA => 0x0000000a,
     193            0 :             Algorithms::SHA1_DSA => 0x0000000b,
     194            0 :             Algorithms::SHA1_RSA => 0x0000000c,
     195            0 :             Algorithms::SHA_256_RSA => 0x0000000d,
     196            0 :             Algorithms::SHA_384_RSA => 0x0000000e,
     197            0 :             Algorithms::SHA_512_RSA => 0x0000000f,
     198            0 :             Algorithms::SHA1_ECDSA => 0x00000010,
     199            0 :             Algorithms::SHA_256_ECDSA => 0x00000011,
     200            0 :             Algorithms::SHA_384_ECDSA => 0x00000012,
     201            0 :             Algorithms::SHA_512_ECDSA => 0x00000013,
     202            0 :             Algorithms::UNKNOWN(_) => 0,
     203              :         }
     204          169 :     }
     205              : }
     206              : 
     207              : /// Parse a PE file from the given file path
     208            0 : pub fn parse<P: AsRef<Path>>(path: P) -> Option<Binary> {
     209            0 :     Binary::parse(path)
     210            0 : }
     211              : 
     212              : /// Parse a PE file from the given file path and configuration
     213            0 : pub fn parse_with_config<P: AsRef<Path>>(path: P, config: &ParserConfig) -> Option<Binary> {
     214            0 :     Binary::parse_with_config(path, config)
     215            0 : }
     216              : 
     217              : /// Check that the layout of the given binary is correct from the Windows loader
     218              : /// perspective
     219            0 : pub fn check_layout(binary: &Binary) -> Result<(), String> {
     220            0 :     cxx::let_cxx_string!(error = "");
     221            0 :     unsafe {
     222            0 :         if ffi::PE_Utils::check_layout(binary.as_ffi(), error.as_mut().get_unchecked_mut()) {
     223            0 :             return Ok(());
     224            0 :         }
     225            0 :     }
     226            0 :     Err(error.to_string())
     227            0 : }
     228              : 
     229              : /// Determine the PE type (PE32 or PE32+) of the given file
     230            0 : pub fn get_type<P: AsRef<Path>>(path: P) -> Option<PE_TYPE> {
     231            0 :     let val = ffi::PE_Utils::get_type(path.as_ref().to_str().unwrap_or("").to_string());
     232            0 :     if val == 0 {
     233            0 :         return None;
     234            0 :     }
     235            0 :     Some(PE_TYPE::from(val))
     236            0 : }
     237              : 
     238              : /// Compute the import hash of the given binary
     239            0 : pub fn get_imphash(binary: &Binary, mode: ImphashMode) -> String {
     240            0 :     ffi::PE_Utils::get_imphash(binary.as_ffi(), mode.into()).to_string()
     241            0 : }
     242              : 
     243              : /// Convert an OID string to a human-readable string
     244            0 : pub fn oid_to_string(oid: &str) -> String {
     245            0 :     ffi::PE_Utils::oid_to_string(oid.to_string()).to_string()
     246            0 : }
     247              : 
     248              : /// Try to resolve import ordinals using the well-known ordinal lookup table
     249            0 : pub fn resolve_ordinals<'a>(
     250            0 :     imp: &'a Import<'a>,
     251            0 :     strict: bool,
     252            0 :     use_std: bool,
     253            0 : ) -> Option<Import<'a>> {
     254            0 :     crate::common::into_optional(ffi::PE_Utils::resolve_ordinals(
     255            0 :         imp.as_ffi(),
     256            0 :         strict,
     257            0 :         use_std,
     258            0 :     ))
     259            0 : }
     260              : 
     261              : /// Mode used for computing the import hash
     262              : #[allow(non_camel_case_types)]
     263            0 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
     264              : pub enum ImphashMode {
     265              :     /// Default LIEF implementation
     266              :     DEFAULT,
     267              :     /// Use pefile algorithm (same as VirusTotal)
     268              :     PEFILE,
     269              :     UNKNOWN(u32),
     270              : }
     271              : 
     272              : impl From<u32> for ImphashMode {
     273            0 :     fn from(value: u32) -> Self {
     274            0 :         match value {
     275            0 :             0x00000000 => ImphashMode::DEFAULT,
     276            0 :             0x00000001 => ImphashMode::PEFILE,
     277            0 :             _ => ImphashMode::UNKNOWN(value),
     278              :         }
     279            0 :     }
     280              : }
     281              : 
     282              : impl From<ImphashMode> for u32 {
     283            0 :     fn from(value: ImphashMode) -> u32 {
     284            0 :         match value {
     285            0 :             ImphashMode::DEFAULT => 0x00000000,
     286            0 :             ImphashMode::PEFILE => 0x00000001,
     287            0 :             ImphashMode::UNKNOWN(v) => v,
     288              :         }
     289            0 :     }
     290              : }
        

Generated by: LCOV version 2.1-1