LCOV - code coverage report
Current view: top level - src/pe - load_configuration.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 72.7 % 505 367
Test Date: 2025-06-24:00:00:00 Functions: 64.8 % 88 57

            Line data    Source code
       1              : use super::chpe_metadata_arm64;
       2              : use super::chpe_metadata_x86;
       3              : use super::volatile_metadata::VolatileMetadata;
       4              : use super::dynamic_relocation::DynamicRelocation;
       5              : use super::enclave_configuration::EnclaveConfiguration;
       6              : use crate::common::{into_optional, FromFFI};
       7              : use crate::pe::code_integrity::CodeIntegrity;
       8              : use crate::{declare_iterator, to_conv_opt, to_opt};
       9              : use bitflags::bitflags;
      10              : use lief_ffi as ffi;
      11              : use std::marker::PhantomData;
      12              : 
      13              : /// This structure represents the load configuration data associated with the
      14              : /// `IMAGE_LOAD_CONFIG_DIRECTORY`.
      15              : ///
      16              : /// This structure is frequently updated by Microsoft to add new metadata.
      17              : ///
      18              : /// Reference: <https://github.com/MicrosoftDocs/sdk-api/blob/cbeab4d371e8bc7e352c4d3a4c5819caa08c6a1c/sdk-api-src/content/winnt/ns-winnt-image_load_config_directory64.md#L2>
      19              : pub struct LoadConfiguration<'a> {
      20              :     ptr: cxx::UniquePtr<ffi::PE_LoadConfiguration>,
      21              :     _owner: PhantomData<&'a ffi::PE_Binary>,
      22              : }
      23              : 
      24              : impl LoadConfiguration<'_> {
      25              :     /// Characteristics of the structure which is defined by its size
      26            0 :     pub fn characteristics(&self) -> u32 {
      27            0 :         self.ptr.characteristics()
      28            0 :     }
      29              : 
      30              :     /// Size of the current structure
      31          108 :     pub fn size(&self) -> u32 {
      32          108 :         self.ptr.size()
      33          108 :     }
      34              : 
      35              :     /// The date and time stamp value
      36          108 :     pub fn timedatestamp(&self) -> u32 {
      37          108 :         self.ptr.timedatestamp()
      38          108 :     }
      39              : 
      40              :     /// Major version
      41          108 :     pub fn major_version(&self) -> u16 {
      42          108 :         self.ptr.major_version()
      43          108 :     }
      44              : 
      45              :     /// Minor version
      46          108 :     pub fn minor_version(&self) -> u16 {
      47          108 :         self.ptr.minor_version()
      48          108 :     }
      49              : 
      50              :     /// The global flags that control system behavior. For more information, see `Gflags.exe`.
      51          108 :     pub fn global_flags_clear(&self) -> u32 {
      52          108 :         self.ptr.global_flags_clear()
      53          108 :     }
      54              : 
      55              :     /// The global flags that control system behavior. For more information, see `Gflags.exe`.
      56          108 :     pub fn global_flags_set(&self) -> u32 {
      57          108 :         self.ptr.global_flags_set()
      58          108 :     }
      59              : 
      60              :     /// The critical section default time-out value.
      61          108 :     pub fn critical_section_default_timeout(&self) -> u32 {
      62          108 :         self.ptr.critical_section_default_timeout()
      63          108 :     }
      64              : 
      65              :     /// The size of the minimum block that must be freed before it is freed (de-committed), in bytes.
      66              :     /// This value is advisory.
      67          108 :     pub fn decommit_free_block_threshold(&self) -> u64 {
      68          108 :         self.ptr.decommit_free_block_threshold()
      69          108 :     }
      70              : 
      71              :     /// The size of the minimum total memory that must be freed in the process heap before it is
      72              :     /// freed (de-committed), in bytes. This value is advisory.
      73          108 :     pub fn decommit_total_free_threshold(&self) -> u64 {
      74          108 :         self.ptr.decommit_total_free_threshold()
      75          108 :     }
      76              : 
      77              :     /// The VA of a list of addresses where the `LOCK` prefix is used. These will be replaced by
      78              :     /// `NOP` on single-processor systems. This member is available only for x86.
      79          108 :     pub fn lock_prefix_table(&self) -> u64 {
      80          108 :         self.ptr.lock_prefix_table()
      81          108 :     }
      82              : 
      83              :     /// The maximum allocation size, in bytes. This member is obsolete and is used only for
      84              :     /// debugging purposes.
      85          108 :     pub fn maximum_allocation_size(&self) -> u64 {
      86          108 :         self.ptr.maximum_allocation_size()
      87          108 :     }
      88              : 
      89              :     /// The maximum block size that can be allocated from heap segments, in bytes.
      90          108 :     pub fn virtual_memory_threshold(&self) -> u64 {
      91          108 :         self.ptr.virtual_memory_threshold()
      92          108 :     }
      93              : 
      94              :     /// The process affinity mask. For more information, see `GetProcessAffinityMask`. This member
      95              :     /// is available only for `.exe` files.
      96          108 :     pub fn process_affinity_mask(&self) -> u64 {
      97          108 :         self.ptr.process_affinity_mask()
      98          108 :     }
      99              : 
     100              :     /// The process heap flags. For more information, see `HeapCreate`.
     101          108 :     pub fn process_heap_flags(&self) -> u32 {
     102          108 :         self.ptr.process_heap_flags()
     103          108 :     }
     104              : 
     105              :     /// The service pack version.
     106          108 :     pub fn csd_version(&self) -> u16 {
     107          108 :         self.ptr.csd_version()
     108          108 :     }
     109              : 
     110              :     /// See: [`LoadConfiguration::dependent_load_flags`]
     111          108 :     pub fn reserved1(&self) -> u16 {
     112          108 :         self.ptr.reserved1()
     113          108 :     }
     114              : 
     115              :     /// Alias for [`LoadConfiguration::reserved1`].
     116              :     ///
     117              :     /// The default load flags used when the operating system resolves the
     118              :     /// statically linked imports of a module. For more information, see
     119              :     /// `LoadLibraryEx`.
     120          108 :     pub fn dependent_load_flags(&self) -> u16 {
     121          108 :         self.ptr.dependent_load_flags()
     122          108 :     }
     123              : 
     124              :     /// Reserved for use by the system.
     125          108 :     pub fn editlist(&self) -> u32 {
     126          108 :         self.ptr.editlist()
     127          108 :     }
     128              : 
     129              :     /// A pointer to a cookie that is used by Visual C++ or GS implementation.
     130          108 :     pub fn security_cookie(&self) -> u64 {
     131          108 :         self.ptr.security_cookie()
     132          108 :     }
     133              : 
     134              :     /// The VA of the sorted table of RVAs of each valid, unique handler in the image. This member
     135              :     /// is available only for x86.
     136          108 :     pub fn se_handler_table(&self) -> Option<u64> {
     137          108 :         to_opt!(&lief_ffi::PE_LoadConfiguration::se_handler_table, &self);
     138          108 :     }
     139              : 
     140              :     /// The count of unique handlers in the table. This member is available only for x86.
     141          108 :     pub fn se_handler_count(&self) -> Option<u64> {
     142          108 :         to_opt!(&lief_ffi::PE_LoadConfiguration::se_handler_count, &self);
     143          108 :     }
     144              : 
     145              :     /// Return the list of the function RVA in the SEH table (if any)
     146            0 :     pub fn seh_functions(&self) -> Vec<u32> {
     147            0 :         Vec::from(self.ptr.seh_functions().as_slice())
     148            0 :     }
     149              : 
     150              :     /// The VA where Control Flow Guard check-function pointer is stored.
     151          108 :     pub fn guard_cf_check_function_pointer(&self) -> Option<u64> {
     152          108 :         to_opt!(
     153          108 :             &lief_ffi::PE_LoadConfiguration::guard_cf_check_function_pointer,
     154          108 :             &self
     155          108 :         );
     156          108 :     }
     157              : 
     158              :     /// The VA where Control Flow Guard dispatch-function pointer is stored.
     159          108 :     pub fn guard_cf_dispatch_function_pointer(&self) -> Option<u64> {
     160          108 :         to_opt!(
     161          108 :             &lief_ffi::PE_LoadConfiguration::guard_cf_dispatch_function_pointer,
     162          108 :             &self
     163          108 :         );
     164          108 :     }
     165              : 
     166              :     /// The VA of the sorted table of RVAs of each Control Flow Guard function in the image.
     167          108 :     pub fn guard_cf_function_table(&self) -> Option<u64> {
     168          108 :         to_opt!(
     169          108 :             &lief_ffi::PE_LoadConfiguration::guard_cf_function_table,
     170          108 :             &self
     171          108 :         );
     172          108 :     }
     173              : 
     174              :     /// The count of unique RVAs in the [`LoadConfiguration::guard_cf_function_table`] table.
     175          108 :     pub fn guard_cf_function_count(&self) -> Option<u64> {
     176          108 :         to_opt!(
     177          108 :             &lief_ffi::PE_LoadConfiguration::guard_cf_function_count,
     178          108 :             &self
     179          108 :         );
     180          108 :     }
     181              : 
     182              :     /// Iterator over the Control Flow Guard functions referenced by
     183              :     /// [`LoadConfiguration::guard_cf_function_table`]
     184            0 :     pub fn guard_cf_functions(&self) -> GuardCFFunctions {
     185            0 :         GuardCFFunctions::new(self.ptr.guard_cf_functions())
     186            0 :     }
     187              : 
     188              :     /// Control Flow Guard related flags.
     189          108 :     pub fn guard_flags(&self) -> Option<ImageGuardFlags> {
     190          108 :         to_conv_opt!(
     191          108 :             &lief_ffi::PE_LoadConfiguration::guard_flags,
     192          108 :             &self,
     193          108 :             |e: u32| ImageGuardFlags::from(e)
     194              :         );
     195          108 :     }
     196              : 
     197              :     /// Code integrity information.
     198            0 :     pub fn code_integrity(&self) -> Option<CodeIntegrity> {
     199            0 :         into_optional(self.ptr.code_integrity())
     200            0 :     }
     201              : 
     202              :     /// The VA where Control Flow Guard address taken IAT table is stored.
     203          108 :     pub fn guard_address_taken_iat_entry_table(&self) -> Option<u64> {
     204          108 :         to_opt!(
     205          108 :             &lief_ffi::PE_LoadConfiguration::guard_address_taken_iat_entry_table,
     206          108 :             &self
     207          108 :         );
     208          108 :     }
     209              : 
     210              :     /// The count of unique RVAs in the table pointed by
     211              :     /// [`LoadConfiguration::guard_address_taken_iat_entry_table`].
     212          108 :     pub fn guard_address_taken_iat_entry_count(&self) -> Option<u64> {
     213          108 :         to_opt!(
     214          108 :             &lief_ffi::PE_LoadConfiguration::guard_address_taken_iat_entry_count,
     215          108 :             &self
     216          108 :         );
     217          108 :     }
     218              : 
     219              :     /// Iterator over the functions referenced by
     220              :     /// [`LoadConfiguration::guard_address_taken_iat_entry_table`]
     221            0 :     pub fn guard_address_taken_iat_entries(&self) -> GuardAddressTakenIATEntries {
     222            0 :         GuardAddressTakenIATEntries::new(self.ptr.guard_address_taken_iat_entries())
     223            0 :     }
     224              : 
     225              :     /// The VA where Control Flow Guard long jump target table is stored.
     226          108 :     pub fn guard_long_jump_target_table(&self) -> Option<u64> {
     227          108 :         to_opt!(
     228          108 :             &lief_ffi::PE_LoadConfiguration::guard_long_jump_target_table,
     229          108 :             &self
     230          108 :         );
     231          108 :     }
     232              : 
     233              :     /// The count of unique RVAs in the table pointed by
     234              :     /// [`LoadConfiguration::guard_long_jump_target_table`].
     235          108 :     pub fn guard_long_jump_target_count(&self) -> Option<u64> {
     236          108 :         to_opt!(
     237          108 :             &lief_ffi::PE_LoadConfiguration::guard_long_jump_target_count,
     238          108 :             &self
     239          108 :         );
     240          108 :     }
     241              : 
     242              :     /// Iterator over the functions referenced by
     243              :     /// [`LoadConfiguration::guard_long_jump_target_table`]
     244            0 :     pub fn guard_long_jump_targets(&self) -> GuardLongJumpTargets {
     245            0 :         GuardLongJumpTargets::new(self.ptr.guard_long_jump_targets())
     246            0 :     }
     247              : 
     248              :     /// VA of pointing to a `IMAGE_DYNAMIC_RELOCATION_TABLE`
     249          108 :     pub fn dynamic_value_reloc_table(&self) -> Option<u64> {
     250          108 :         to_opt!(
     251          108 :             &lief_ffi::PE_LoadConfiguration::dynamic_value_reloc_table,
     252          108 :             &self
     253          108 :         );
     254          108 :     }
     255              : 
     256              :     /// Alias for [`LoadConfiguration::chpe_metadata_pointer`]
     257          108 :     pub fn hybrid_metadata_pointer(&self) -> Option<u64> {
     258          108 :         to_opt!(
     259          108 :             &lief_ffi::PE_LoadConfiguration::hybrid_metadata_pointer,
     260          108 :             &self
     261          108 :         );
     262          108 :     }
     263              : 
     264              :     /// VA to the extra Compiled Hybrid Portable Executable (CHPE) metadata.
     265          108 :     pub fn chpe_metadata_pointer(&self) -> Option<u64> {
     266          108 :         to_opt!(
     267          108 :             &lief_ffi::PE_LoadConfiguration::chpe_metadata_pointer,
     268          108 :             &self
     269          108 :         );
     270          108 :     }
     271              : 
     272              :     /// Compiled Hybrid Portable Executable (CHPE) metadata (if any)
     273            0 :     pub fn chpe_metadata(&self) -> Option<CHPEMetadata> {
     274            0 :         into_optional(self.ptr.chpe_metadata())
     275            0 :     }
     276              : 
     277              :     /// VA of the failure routine
     278          108 :     pub fn guard_rf_failure_routine(&self) -> Option<u64> {
     279          108 :         to_opt!(
     280          108 :             &lief_ffi::PE_LoadConfiguration::guard_rf_failure_routine,
     281          108 :             &self
     282          108 :         );
     283          108 :     }
     284              : 
     285              :     /// VA of the failure routine `fptr`.
     286          108 :     pub fn guard_rf_failure_routine_function_pointer(&self) -> Option<u64> {
     287          108 :         to_opt!(
     288          108 :             &lief_ffi::PE_LoadConfiguration::guard_rf_failure_routine_function_pointer,
     289          108 :             &self
     290          108 :         );
     291          108 :     }
     292              : 
     293              :     /// Offset of dynamic relocation table relative to the relocation table
     294          108 :     pub fn dynamic_value_reloctable_offset(&self) -> Option<u32> {
     295          108 :         to_opt!(
     296          108 :             &lief_ffi::PE_LoadConfiguration::dynamic_value_reloctable_offset,
     297          108 :             &self
     298          108 :         );
     299          108 :     }
     300              : 
     301              :     /// The section index of the dynamic value relocation table
     302          108 :     pub fn dynamic_value_reloctable_section(&self) -> Option<u16> {
     303          108 :         to_opt!(
     304          108 :             &lief_ffi::PE_LoadConfiguration::dynamic_value_reloctable_section,
     305          108 :             &self
     306          108 :         );
     307          108 :     }
     308              : 
     309              :     /// Return an iterator over the Dynamic relocations (DVRT)
     310            0 :     pub fn dynamic_relocations(&self) -> DynamicRelocations {
     311            0 :         DynamicRelocations::new(self.ptr.dynamic_relocations())
     312            0 :     }
     313              : 
     314              :     /// Must be zero
     315          108 :     pub fn reserved2(&self) -> Option<u16> {
     316          108 :         to_opt!(&lief_ffi::PE_LoadConfiguration::reserved2, &self);
     317          108 :     }
     318              : 
     319              :     /// VA of the Function verifying the stack pointer
     320          108 :     pub fn guard_rf_verify_stackpointer_function_pointer(&self) -> Option<u64> {
     321          108 :         to_opt!(
     322          108 :             &lief_ffi::PE_LoadConfiguration::guard_rf_verify_stackpointer_function_pointer,
     323          108 :             &self
     324          108 :         );
     325          108 :     }
     326              : 
     327          108 :     pub fn hotpatch_table_offset(&self) -> Option<u32> {
     328          108 :         to_opt!(
     329          108 :             &lief_ffi::PE_LoadConfiguration::hotpatch_table_offset,
     330          108 :             &self
     331          108 :         );
     332          108 :     }
     333              : 
     334          108 :     pub fn reserved3(&self) -> Option<u32> {
     335          108 :         to_opt!(&lief_ffi::PE_LoadConfiguration::reserved3, &self);
     336          108 :     }
     337              : 
     338          108 :     pub fn enclave_config(&self) -> Option<EnclaveConfiguration> {
     339          108 :         into_optional(self.ptr.enclave_config())
     340          108 :     }
     341              : 
     342          108 :     pub fn enclave_configuration_ptr(&self) -> Option<u64> {
     343          108 :         to_opt!(
     344          108 :             &lief_ffi::PE_LoadConfiguration::enclave_configuration_ptr,
     345          108 :             &self
     346          108 :         );
     347          108 :     }
     348              : 
     349          108 :     pub fn volatile_metadata_pointer(&self) -> Option<u64> {
     350          108 :         to_opt!(
     351          108 :             &lief_ffi::PE_LoadConfiguration::volatile_metadata_pointer,
     352          108 :             &self
     353          108 :         );
     354          108 :     }
     355              : 
     356          108 :     pub fn volatile_metadata(&self) -> Option<VolatileMetadata> {
     357          108 :         into_optional(self.ptr.volatile_metadata())
     358          108 :     }
     359              : 
     360          108 :     pub fn guard_eh_continuation_table(&self) -> Option<u64> {
     361          108 :         to_opt!(
     362          108 :             &lief_ffi::PE_LoadConfiguration::guard_eh_continuation_table,
     363          108 :             &self
     364          108 :         );
     365          108 :     }
     366              : 
     367          108 :     pub fn guard_eh_continuation_count(&self) -> Option<u64> {
     368          108 :         to_opt!(
     369          108 :             &lief_ffi::PE_LoadConfiguration::guard_eh_continuation_count,
     370          108 :             &self
     371          108 :         );
     372          108 :     }
     373              : 
     374              :     /// Iterator over the Guard EH continuation functions referenced by
     375              :     /// [`LoadConfiguration::guard_eh_continuation_table`]
     376            0 :     pub fn guard_eh_continuation_functions(&self) -> GuardEhContinuationFunctions {
     377            0 :         GuardEhContinuationFunctions::new(self.ptr.guard_eh_continuation_functions())
     378            0 :     }
     379              : 
     380          108 :     pub fn guard_xfg_check_function_pointer(&self) -> Option<u64> {
     381          108 :         to_opt!(
     382          108 :             &lief_ffi::PE_LoadConfiguration::guard_xfg_check_function_pointer,
     383          108 :             &self
     384          108 :         );
     385          108 :     }
     386              : 
     387          108 :     pub fn guard_xfg_dispatch_function_pointer(&self) -> Option<u64> {
     388          108 :         to_opt!(
     389          108 :             &lief_ffi::PE_LoadConfiguration::guard_xfg_dispatch_function_pointer,
     390          108 :             &self
     391          108 :         );
     392          108 :     }
     393              : 
     394          108 :     pub fn guard_xfg_table_dispatch_function_pointer(&self) -> Option<u64> {
     395          108 :         to_opt!(
     396          108 :             &lief_ffi::PE_LoadConfiguration::guard_xfg_table_dispatch_function_pointer,
     397          108 :             &self
     398          108 :         );
     399          108 :     }
     400              : 
     401          108 :     pub fn cast_guard_os_determined_failure_mode(&self) -> Option<u64> {
     402          108 :         to_opt!(
     403          108 :             &lief_ffi::PE_LoadConfiguration::cast_guard_os_determined_failure_mode,
     404          108 :             &self
     405          108 :         );
     406          108 :     }
     407              : 
     408          108 :     pub fn guard_memcpy_function_pointer(&self) -> Option<u64> {
     409          108 :         to_opt!(
     410          108 :             &lief_ffi::PE_LoadConfiguration::guard_memcpy_function_pointer,
     411          108 :             &self
     412          108 :         );
     413          108 :     }
     414              : }
     415              : 
     416              : impl<'a> FromFFI<ffi::PE_LoadConfiguration> for LoadConfiguration<'a> {
     417          108 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_LoadConfiguration>) -> Self {
     418          108 :         Self {
     419          108 :             ptr,
     420          108 :             _owner: PhantomData,
     421          108 :         }
     422          108 :     }
     423              : }
     424              : 
     425              : impl std::fmt::Debug for LoadConfiguration<'_> {
     426          108 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     427          108 :         f.debug_struct("LoadConfiguration")
     428          108 :             .field("size", &self.size())
     429          108 :             .field("timedatestamp", &self.timedatestamp())
     430          108 :             .field("major_version", &self.major_version())
     431          108 :             .field("minor_version", &self.minor_version())
     432          108 :             .field("global_flags_clear", &self.global_flags_clear())
     433          108 :             .field("global_flags_set", &self.global_flags_set())
     434          108 :             .field(
     435          108 :                 "critical_section_default_timeout",
     436          108 :                 &self.critical_section_default_timeout(),
     437          108 :             )
     438          108 :             .field(
     439          108 :                 "decommit_free_block_threshold",
     440          108 :                 &self.decommit_free_block_threshold(),
     441          108 :             )
     442          108 :             .field(
     443          108 :                 "decommit_total_free_threshold",
     444          108 :                 &self.decommit_total_free_threshold(),
     445          108 :             )
     446          108 :             .field("lock_prefix_table", &self.lock_prefix_table())
     447          108 :             .field("maximum_allocation_size", &self.maximum_allocation_size())
     448          108 :             .field("virtual_memory_threshold", &self.virtual_memory_threshold())
     449          108 :             .field("process_affinity_mask", &self.process_affinity_mask())
     450          108 :             .field("process_heap_flags", &self.process_heap_flags())
     451          108 :             .field("csd_version", &self.csd_version())
     452          108 :             .field("reserved1", &self.reserved1())
     453          108 :             .field("dependent_load_flags", &self.dependent_load_flags())
     454          108 :             .field("editlist", &self.editlist())
     455          108 :             .field("security_cookie", &self.security_cookie())
     456          108 :             .field("se_handler_table", &self.se_handler_table())
     457          108 :             .field("se_handler_count", &self.se_handler_count())
     458          108 :             .field(
     459          108 :                 "guard_cf_check_function_pointer",
     460          108 :                 &self.guard_cf_check_function_pointer(),
     461          108 :             )
     462          108 :             .field(
     463          108 :                 "guard_cf_dispatch_function_pointer",
     464          108 :                 &self.guard_cf_dispatch_function_pointer(),
     465          108 :             )
     466          108 :             .field("guard_cf_function_table", &self.guard_cf_function_table())
     467          108 :             .field("guard_cf_function_count", &self.guard_cf_function_count())
     468          108 :             .field("guard_flags", &self.guard_flags())
     469          108 :             .field(
     470          108 :                 "guard_address_taken_iat_entry_table",
     471          108 :                 &self.guard_address_taken_iat_entry_table(),
     472          108 :             )
     473          108 :             .field(
     474          108 :                 "guard_address_taken_iat_entry_count",
     475          108 :                 &self.guard_address_taken_iat_entry_count(),
     476          108 :             )
     477          108 :             .field(
     478          108 :                 "guard_long_jump_target_table",
     479          108 :                 &self.guard_long_jump_target_table(),
     480          108 :             )
     481          108 :             .field(
     482          108 :                 "guard_long_jump_target_count",
     483          108 :                 &self.guard_long_jump_target_count(),
     484          108 :             )
     485          108 :             .field(
     486          108 :                 "dynamic_value_reloc_table",
     487          108 :                 &self.dynamic_value_reloc_table(),
     488          108 :             )
     489          108 :             .field("hybrid_metadata_pointer", &self.hybrid_metadata_pointer())
     490          108 :             .field("chpe_metadata_pointer", &self.chpe_metadata_pointer())
     491          108 :             .field("guard_rf_failure_routine", &self.guard_rf_failure_routine())
     492          108 :             .field(
     493          108 :                 "guard_rf_failure_routine_function_pointer",
     494          108 :                 &self.guard_rf_failure_routine_function_pointer(),
     495          108 :             )
     496          108 :             .field(
     497          108 :                 "dynamic_value_reloctable_offset",
     498          108 :                 &self.dynamic_value_reloctable_offset(),
     499          108 :             )
     500          108 :             .field(
     501          108 :                 "dynamic_value_reloctable_section",
     502          108 :                 &self.dynamic_value_reloctable_section(),
     503          108 :             )
     504          108 :             .field("reserved2", &self.reserved2())
     505          108 :             .field(
     506          108 :                 "guard_rf_verify_stackpointer_function_pointer",
     507          108 :                 &self.guard_rf_verify_stackpointer_function_pointer(),
     508          108 :             )
     509          108 :             .field("hotpatch_table_offset", &self.hotpatch_table_offset())
     510          108 :             .field("reserved3", &self.reserved3())
     511          108 :             .field("enclave_configuration_ptr", &self.enclave_configuration_ptr())
     512          108 :             .field(
     513          108 :                 "volatile_metadata_pointer",
     514          108 :                 &self.volatile_metadata_pointer(),
     515          108 :             )
     516          108 :             .field(
     517          108 :                 "guard_eh_continuation_table",
     518          108 :                 &self.guard_eh_continuation_table(),
     519          108 :             )
     520          108 :             .field(
     521          108 :                 "guard_eh_continuation_count",
     522          108 :                 &self.guard_eh_continuation_count(),
     523          108 :             )
     524          108 :             .field(
     525          108 :                 "guard_xfg_check_function_pointer",
     526          108 :                 &self.guard_xfg_check_function_pointer(),
     527          108 :             )
     528          108 :             .field(
     529          108 :                 "guard_xfg_dispatch_function_pointer",
     530          108 :                 &self.guard_xfg_dispatch_function_pointer(),
     531          108 :             )
     532          108 :             .field(
     533          108 :                 "guard_xfg_table_dispatch_function_pointer",
     534          108 :                 &self.guard_xfg_table_dispatch_function_pointer(),
     535          108 :             )
     536          108 :             .field(
     537          108 :                 "cast_guard_os_determined_failure_mode",
     538          108 :                 &self.cast_guard_os_determined_failure_mode(),
     539          108 :             )
     540          108 :             .field(
     541          108 :                 "guard_memcpy_function_pointer",
     542          108 :                 &self.guard_memcpy_function_pointer(),
     543          108 :             )
     544          108 :             .finish()
     545          108 :     }
     546              : }
     547              : 
     548              : pub struct GuardFunction<'a> {
     549              :     ptr: cxx::UniquePtr<ffi::PE_LoadConfiguration_guard_function_t>,
     550              :     _owner: PhantomData<&'a ffi::PE_LoadConfiguration>,
     551              : }
     552              : 
     553              : impl<'a> FromFFI<ffi::PE_LoadConfiguration_guard_function_t> for GuardFunction<'a> {
     554            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_LoadConfiguration_guard_function_t>) -> Self {
     555            0 :         Self {
     556            0 :             ptr,
     557            0 :             _owner: PhantomData,
     558            0 :         }
     559            0 :     }
     560              : }
     561              : 
     562              : impl GuardFunction<'_> {
     563              :     /// RVA of the function
     564            0 :     pub fn rva(&self) -> u32 {
     565            0 :         self.ptr.rva()
     566            0 :     }
     567              : 
     568              :     /// Additional information whose meaning is not officially documented
     569            0 :     pub fn extra(&self) -> u32 {
     570            0 :         self.ptr.extra()
     571            0 :     }
     572              : }
     573              : 
     574              : impl std::fmt::Debug for GuardFunction<'_> {
     575            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     576            0 :         f.debug_struct("GuardFunction")
     577            0 :             .field("rva", &self.rva())
     578            0 :             .field("extra", &self.extra())
     579            0 :             .finish()
     580            0 :     }
     581              : }
     582              : 
     583            0 : bitflags! {
     584          108 :     #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
     585            0 :     pub struct ImageGuardFlags: u32 {
     586            0 :         const NONE = 0x0;
     587            0 :         const CF_INSTRUMENTED = 0x100;
     588            0 :         const CFW_INSTRUMENTED = 0x200;
     589            0 :         const CF_FUNCTION_TABLE_PRESENT = 0x400;
     590            0 :         const SECURITY_COOKIE_UNUSED = 0x800;
     591            0 :         const PROTECT_DELAYLOAD_IAT = 0x1000;
     592            0 :         const DELAYLOAD_IAT_IN_ITS_OWN_SECTION = 0x2000;
     593            0 :         const CF_EXPORT_SUPPRESSION_INFO_PRESENT = 0x4000;
     594            0 :         const CF_ENABLE_EXPORT_SUPPRESSION = 0x8000;
     595            0 :         const CF_LONGJUMP_TABLE_PRESENT = 0x10000;
     596            0 :         const RF_INSTRUMENTED = 0x20000;
     597            0 :         const RF_ENABLE = 0x40000;
     598            0 :         const RF_STRICT = 0x80000;
     599            0 :         const RETPOLINE_PRESENT = 0x100000;
     600            0 :         const EH_CONTINUATION_TABLE_PRESENT = 0x200000;
     601            0 :     }
     602            0 : }
     603              : 
     604              : impl From<u32> for ImageGuardFlags {
     605          108 :     fn from(value: u32) -> Self {
     606          108 :         ImageGuardFlags::from_bits_truncate(value)
     607          108 :     }
     608              : }
     609              : impl From<ImageGuardFlags> for u32 {
     610            0 :     fn from(value: ImageGuardFlags) -> Self {
     611            0 :         value.bits()
     612            0 :     }
     613              : }
     614              : impl std::fmt::Display for ImageGuardFlags {
     615            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     616            0 :         bitflags::parser::to_writer(self, f)
     617            0 :     }
     618              : }
     619              : 
     620            0 : #[derive(Debug)]
     621              : pub enum CHPEMetadata<'a> {
     622              :     ARM64(chpe_metadata_arm64::CHPEMetadata<'a>),
     623              :     X86(chpe_metadata_x86::CHPEMetadata<'a>),
     624              : }
     625              : 
     626              : impl<'a> FromFFI<ffi::PE_CHPEMetadata> for CHPEMetadata<'a> {
     627            0 :     fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_CHPEMetadata>) -> Self {
     628            0 :         unsafe {
     629            0 :             let obj_ref = ffi_entry.as_ref().unwrap();
     630            0 :             if ffi::PE_CHPEMetadataARM64::classof(obj_ref) {
     631            0 :                 let raw = {
     632            0 :                     type From = cxx::UniquePtr<ffi::PE_CHPEMetadata>;
     633            0 :                     type To = cxx::UniquePtr<ffi::PE_CHPEMetadataARM64>;
     634            0 :                     std::mem::transmute::<From, To>(ffi_entry)
     635            0 :                 };
     636            0 :                 CHPEMetadata::ARM64(chpe_metadata_arm64::CHPEMetadata::from_ffi(raw))
     637            0 :             } else if ffi::PE_CHPEMetadataX86::classof(obj_ref) {
     638            0 :                 let raw = {
     639            0 :                     type From = cxx::UniquePtr<ffi::PE_CHPEMetadata>;
     640            0 :                     type To = cxx::UniquePtr<ffi::PE_CHPEMetadataX86>;
     641            0 :                     std::mem::transmute::<From, To>(ffi_entry)
     642            0 :                 };
     643            0 :                 CHPEMetadata::X86(chpe_metadata_x86::CHPEMetadata::from_ffi(raw))
     644              :             } else {
     645            0 :                 panic!("unsupported architecture");
     646              :             }
     647              :         }
     648            0 :     }
     649              : }
     650              : 
     651              : /// Trait shared by all architecture-specific CHPEMetadata
     652              : pub trait AsCHPEMetadata {
     653              :     #[doc(hidden)]
     654              :     fn as_generic(&self) -> &ffi::PE_CHPEMetadata;
     655              : 
     656              :     /// Version of the structure
     657            0 :     fn version(&self) -> u32 {
     658            0 :         self.as_generic().version()
     659            0 :     }
     660              : }
     661              : 
     662              : impl std::fmt::Display for &dyn AsCHPEMetadata {
     663            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     664            0 :         write!(f, "{}", self.as_generic().to_string())
     665            0 :     }
     666              : }
     667              : 
     668              : impl AsCHPEMetadata for CHPEMetadata<'_> {
     669            0 :     fn as_generic(&self) -> &ffi::PE_CHPEMetadata {
     670            0 :         match &self {
     671            0 :             CHPEMetadata::ARM64(entry) => {
     672            0 :                 entry.as_generic()
     673              :             }
     674              : 
     675            0 :             CHPEMetadata::X86(entry) => {
     676            0 :                 entry.as_generic()
     677              :             }
     678              :         }
     679            0 :     }
     680              : }
     681              : 
     682            0 : declare_iterator!(
     683            0 :     GuardCFFunctions,
     684            0 :     GuardFunction<'a>,
     685            0 :     ffi::PE_LoadConfiguration_guard_function_t,
     686            0 :     ffi::PE_LoadConfiguration,
     687            0 :     ffi::PE_LoadConfiguration_it_guard_cf_functions
     688            0 : );
     689              : 
     690            0 : declare_iterator!(
     691            0 :     GuardAddressTakenIATEntries,
     692            0 :     GuardFunction<'a>,
     693            0 :     ffi::PE_LoadConfiguration_guard_function_t,
     694            0 :     ffi::PE_LoadConfiguration,
     695            0 :     ffi::PE_LoadConfiguration_it_guard_address_taken_iat_entries
     696            0 : );
     697              : 
     698            0 : declare_iterator!(
     699            0 :     GuardLongJumpTargets,
     700            0 :     GuardFunction<'a>,
     701            0 :     ffi::PE_LoadConfiguration_guard_function_t,
     702            0 :     ffi::PE_LoadConfiguration,
     703            0 :     ffi::PE_LoadConfiguration_it_guard_long_jump_targets
     704            0 : );
     705              : 
     706            0 : declare_iterator!(
     707            0 :     GuardEhContinuationFunctions,
     708            0 :     GuardFunction<'a>,
     709            0 :     ffi::PE_LoadConfiguration_guard_function_t,
     710            0 :     ffi::PE_LoadConfiguration,
     711            0 :     ffi::PE_LoadConfiguration_it_guard_eh_continuation
     712            0 : );
     713              : 
     714            0 : declare_iterator!(
     715            0 :     DynamicRelocations,
     716            0 :     DynamicRelocation<'a>,
     717            0 :     ffi::PE_DynamicRelocation,
     718            0 :     ffi::PE_LoadConfiguration,
     719            0 :     ffi::PE_LoadConfiguration_it_dynamic_relocations
     720            0 : );
        

Generated by: LCOV version 2.1-1