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-02-23: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           90 :     pub fn size(&self) -> u32 {
      32           90 :         self.ptr.size()
      33           90 :     }
      34              : 
      35              :     /// The date and time stamp value
      36           90 :     pub fn timedatestamp(&self) -> u32 {
      37           90 :         self.ptr.timedatestamp()
      38           90 :     }
      39              : 
      40              :     /// Major version
      41           90 :     pub fn major_version(&self) -> u16 {
      42           90 :         self.ptr.major_version()
      43           90 :     }
      44              : 
      45              :     /// Minor version
      46           90 :     pub fn minor_version(&self) -> u16 {
      47           90 :         self.ptr.minor_version()
      48           90 :     }
      49              : 
      50              :     /// The global flags that control system behavior. For more information, see `Gflags.exe`.
      51           90 :     pub fn global_flags_clear(&self) -> u32 {
      52           90 :         self.ptr.global_flags_clear()
      53           90 :     }
      54              : 
      55              :     /// The global flags that control system behavior. For more information, see `Gflags.exe`.
      56           90 :     pub fn global_flags_set(&self) -> u32 {
      57           90 :         self.ptr.global_flags_set()
      58           90 :     }
      59              : 
      60              :     /// The critical section default time-out value.
      61           90 :     pub fn critical_section_default_timeout(&self) -> u32 {
      62           90 :         self.ptr.critical_section_default_timeout()
      63           90 :     }
      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           90 :     pub fn decommit_free_block_threshold(&self) -> u64 {
      68           90 :         self.ptr.decommit_free_block_threshold()
      69           90 :     }
      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           90 :     pub fn decommit_total_free_threshold(&self) -> u64 {
      74           90 :         self.ptr.decommit_total_free_threshold()
      75           90 :     }
      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           90 :     pub fn lock_prefix_table(&self) -> u64 {
      80           90 :         self.ptr.lock_prefix_table()
      81           90 :     }
      82              : 
      83              :     /// The maximum allocation size, in bytes. This member is obsolete and is used only for
      84              :     /// debugging purposes.
      85           90 :     pub fn maximum_allocation_size(&self) -> u64 {
      86           90 :         self.ptr.maximum_allocation_size()
      87           90 :     }
      88              : 
      89              :     /// The maximum block size that can be allocated from heap segments, in bytes.
      90           90 :     pub fn virtual_memory_threshold(&self) -> u64 {
      91           90 :         self.ptr.virtual_memory_threshold()
      92           90 :     }
      93              : 
      94              :     /// The process affinity mask. For more information, see `GetProcessAffinityMask`. This member
      95              :     /// is available only for `.exe` files.
      96           90 :     pub fn process_affinity_mask(&self) -> u64 {
      97           90 :         self.ptr.process_affinity_mask()
      98           90 :     }
      99              : 
     100              :     /// The process heap flags. For more information, see `HeapCreate`.
     101           90 :     pub fn process_heap_flags(&self) -> u32 {
     102           90 :         self.ptr.process_heap_flags()
     103           90 :     }
     104              : 
     105              :     /// The service pack version.
     106           90 :     pub fn csd_version(&self) -> u16 {
     107           90 :         self.ptr.csd_version()
     108           90 :     }
     109              : 
     110              :     /// See: [`LoadConfiguration::dependent_load_flags`]
     111           90 :     pub fn reserved1(&self) -> u16 {
     112           90 :         self.ptr.reserved1()
     113           90 :     }
     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           90 :     pub fn dependent_load_flags(&self) -> u16 {
     121           90 :         self.ptr.dependent_load_flags()
     122           90 :     }
     123              : 
     124              :     /// Reserved for use by the system.
     125           90 :     pub fn editlist(&self) -> u32 {
     126           90 :         self.ptr.editlist()
     127           90 :     }
     128              : 
     129              :     /// A pointer to a cookie that is used by Visual C++ or GS implementation.
     130           90 :     pub fn security_cookie(&self) -> u64 {
     131           90 :         self.ptr.security_cookie()
     132           90 :     }
     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           90 :     pub fn se_handler_table(&self) -> Option<u64> {
     137           90 :         to_opt!(&lief_ffi::PE_LoadConfiguration::se_handler_table, &self);
     138           90 :     }
     139              : 
     140              :     /// The count of unique handlers in the table. This member is available only for x86.
     141           90 :     pub fn se_handler_count(&self) -> Option<u64> {
     142           90 :         to_opt!(&lief_ffi::PE_LoadConfiguration::se_handler_count, &self);
     143           90 :     }
     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           90 :     pub fn guard_cf_check_function_pointer(&self) -> Option<u64> {
     152           90 :         to_opt!(
     153           90 :             &lief_ffi::PE_LoadConfiguration::guard_cf_check_function_pointer,
     154           90 :             &self
     155           90 :         );
     156           90 :     }
     157              : 
     158              :     /// The VA where Control Flow Guard dispatch-function pointer is stored.
     159           90 :     pub fn guard_cf_dispatch_function_pointer(&self) -> Option<u64> {
     160           90 :         to_opt!(
     161           90 :             &lief_ffi::PE_LoadConfiguration::guard_cf_dispatch_function_pointer,
     162           90 :             &self
     163           90 :         );
     164           90 :     }
     165              : 
     166              :     /// The VA of the sorted table of RVAs of each Control Flow Guard function in the image.
     167           90 :     pub fn guard_cf_function_table(&self) -> Option<u64> {
     168           90 :         to_opt!(
     169           90 :             &lief_ffi::PE_LoadConfiguration::guard_cf_function_table,
     170           90 :             &self
     171           90 :         );
     172           90 :     }
     173              : 
     174              :     /// The count of unique RVAs in the [`LoadConfiguration::guard_cf_function_table`] table.
     175           90 :     pub fn guard_cf_function_count(&self) -> Option<u64> {
     176           90 :         to_opt!(
     177           90 :             &lief_ffi::PE_LoadConfiguration::guard_cf_function_count,
     178           90 :             &self
     179           90 :         );
     180           90 :     }
     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           90 :     pub fn guard_flags(&self) -> Option<ImageGuardFlags> {
     190           90 :         to_conv_opt!(
     191           90 :             &lief_ffi::PE_LoadConfiguration::guard_flags,
     192           90 :             &self,
     193           90 :             |e: u32| ImageGuardFlags::from(e)
     194              :         );
     195           90 :     }
     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           90 :     pub fn guard_address_taken_iat_entry_table(&self) -> Option<u64> {
     204           90 :         to_opt!(
     205           90 :             &lief_ffi::PE_LoadConfiguration::guard_address_taken_iat_entry_table,
     206           90 :             &self
     207           90 :         );
     208           90 :     }
     209              : 
     210              :     /// The count of unique RVAs in the table pointed by
     211              :     /// [`LoadConfiguration::guard_address_taken_iat_entry_table`].
     212           90 :     pub fn guard_address_taken_iat_entry_count(&self) -> Option<u64> {
     213           90 :         to_opt!(
     214           90 :             &lief_ffi::PE_LoadConfiguration::guard_address_taken_iat_entry_count,
     215           90 :             &self
     216           90 :         );
     217           90 :     }
     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           90 :     pub fn guard_long_jump_target_table(&self) -> Option<u64> {
     227           90 :         to_opt!(
     228           90 :             &lief_ffi::PE_LoadConfiguration::guard_long_jump_target_table,
     229           90 :             &self
     230           90 :         );
     231           90 :     }
     232              : 
     233              :     /// The count of unique RVAs in the table pointed by
     234              :     /// [`LoadConfiguration::guard_long_jump_target_table`].
     235           90 :     pub fn guard_long_jump_target_count(&self) -> Option<u64> {
     236           90 :         to_opt!(
     237           90 :             &lief_ffi::PE_LoadConfiguration::guard_long_jump_target_count,
     238           90 :             &self
     239           90 :         );
     240           90 :     }
     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           90 :     pub fn dynamic_value_reloc_table(&self) -> Option<u64> {
     250           90 :         to_opt!(
     251           90 :             &lief_ffi::PE_LoadConfiguration::dynamic_value_reloc_table,
     252           90 :             &self
     253           90 :         );
     254           90 :     }
     255              : 
     256              :     /// Alias for [`LoadConfiguration::chpe_metadata_pointer`]
     257           90 :     pub fn hybrid_metadata_pointer(&self) -> Option<u64> {
     258           90 :         to_opt!(
     259           90 :             &lief_ffi::PE_LoadConfiguration::hybrid_metadata_pointer,
     260           90 :             &self
     261           90 :         );
     262           90 :     }
     263              : 
     264              :     /// VA to the extra Compiled Hybrid Portable Executable (CHPE) metadata.
     265           90 :     pub fn chpe_metadata_pointer(&self) -> Option<u64> {
     266           90 :         to_opt!(
     267           90 :             &lief_ffi::PE_LoadConfiguration::chpe_metadata_pointer,
     268           90 :             &self
     269           90 :         );
     270           90 :     }
     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           90 :     pub fn guard_rf_failure_routine(&self) -> Option<u64> {
     279           90 :         to_opt!(
     280           90 :             &lief_ffi::PE_LoadConfiguration::guard_rf_failure_routine,
     281           90 :             &self
     282           90 :         );
     283           90 :     }
     284              : 
     285              :     /// VA of the failure routine `fptr`.
     286           90 :     pub fn guard_rf_failure_routine_function_pointer(&self) -> Option<u64> {
     287           90 :         to_opt!(
     288           90 :             &lief_ffi::PE_LoadConfiguration::guard_rf_failure_routine_function_pointer,
     289           90 :             &self
     290           90 :         );
     291           90 :     }
     292              : 
     293              :     /// Offset of dynamic relocation table relative to the relocation table
     294           90 :     pub fn dynamic_value_reloctable_offset(&self) -> Option<u32> {
     295           90 :         to_opt!(
     296           90 :             &lief_ffi::PE_LoadConfiguration::dynamic_value_reloctable_offset,
     297           90 :             &self
     298           90 :         );
     299           90 :     }
     300              : 
     301              :     /// The section index of the dynamic value relocation table
     302           90 :     pub fn dynamic_value_reloctable_section(&self) -> Option<u16> {
     303           90 :         to_opt!(
     304           90 :             &lief_ffi::PE_LoadConfiguration::dynamic_value_reloctable_section,
     305           90 :             &self
     306           90 :         );
     307           90 :     }
     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           90 :     pub fn reserved2(&self) -> Option<u16> {
     316           90 :         to_opt!(&lief_ffi::PE_LoadConfiguration::reserved2, &self);
     317           90 :     }
     318              : 
     319              :     /// VA of the Function verifying the stack pointer
     320           90 :     pub fn guard_rf_verify_stackpointer_function_pointer(&self) -> Option<u64> {
     321           90 :         to_opt!(
     322           90 :             &lief_ffi::PE_LoadConfiguration::guard_rf_verify_stackpointer_function_pointer,
     323           90 :             &self
     324           90 :         );
     325           90 :     }
     326              : 
     327           90 :     pub fn hotpatch_table_offset(&self) -> Option<u32> {
     328           90 :         to_opt!(
     329           90 :             &lief_ffi::PE_LoadConfiguration::hotpatch_table_offset,
     330           90 :             &self
     331           90 :         );
     332           90 :     }
     333              : 
     334           90 :     pub fn reserved3(&self) -> Option<u32> {
     335           90 :         to_opt!(&lief_ffi::PE_LoadConfiguration::reserved3, &self);
     336           90 :     }
     337              : 
     338           90 :     pub fn enclave_config(&self) -> Option<EnclaveConfiguration> {
     339           90 :         into_optional(self.ptr.enclave_config())
     340           90 :     }
     341              : 
     342           90 :     pub fn enclave_configuration_ptr(&self) -> Option<u64> {
     343           90 :         to_opt!(
     344           90 :             &lief_ffi::PE_LoadConfiguration::enclave_configuration_ptr,
     345           90 :             &self
     346           90 :         );
     347           90 :     }
     348              : 
     349           90 :     pub fn volatile_metadata_pointer(&self) -> Option<u64> {
     350           90 :         to_opt!(
     351           90 :             &lief_ffi::PE_LoadConfiguration::volatile_metadata_pointer,
     352           90 :             &self
     353           90 :         );
     354           90 :     }
     355              : 
     356           90 :     pub fn volatile_metadata(&self) -> Option<VolatileMetadata> {
     357           90 :         into_optional(self.ptr.volatile_metadata())
     358           90 :     }
     359              : 
     360           90 :     pub fn guard_eh_continuation_table(&self) -> Option<u64> {
     361           90 :         to_opt!(
     362           90 :             &lief_ffi::PE_LoadConfiguration::guard_eh_continuation_table,
     363           90 :             &self
     364           90 :         );
     365           90 :     }
     366              : 
     367           90 :     pub fn guard_eh_continuation_count(&self) -> Option<u64> {
     368           90 :         to_opt!(
     369           90 :             &lief_ffi::PE_LoadConfiguration::guard_eh_continuation_count,
     370           90 :             &self
     371           90 :         );
     372           90 :     }
     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           90 :     pub fn guard_xfg_check_function_pointer(&self) -> Option<u64> {
     381           90 :         to_opt!(
     382           90 :             &lief_ffi::PE_LoadConfiguration::guard_xfg_check_function_pointer,
     383           90 :             &self
     384           90 :         );
     385           90 :     }
     386              : 
     387           90 :     pub fn guard_xfg_dispatch_function_pointer(&self) -> Option<u64> {
     388           90 :         to_opt!(
     389           90 :             &lief_ffi::PE_LoadConfiguration::guard_xfg_dispatch_function_pointer,
     390           90 :             &self
     391           90 :         );
     392           90 :     }
     393              : 
     394           90 :     pub fn guard_xfg_table_dispatch_function_pointer(&self) -> Option<u64> {
     395           90 :         to_opt!(
     396           90 :             &lief_ffi::PE_LoadConfiguration::guard_xfg_table_dispatch_function_pointer,
     397           90 :             &self
     398           90 :         );
     399           90 :     }
     400              : 
     401           90 :     pub fn cast_guard_os_determined_failure_mode(&self) -> Option<u64> {
     402           90 :         to_opt!(
     403           90 :             &lief_ffi::PE_LoadConfiguration::cast_guard_os_determined_failure_mode,
     404           90 :             &self
     405           90 :         );
     406           90 :     }
     407              : 
     408           90 :     pub fn guard_memcpy_function_pointer(&self) -> Option<u64> {
     409           90 :         to_opt!(
     410           90 :             &lief_ffi::PE_LoadConfiguration::guard_memcpy_function_pointer,
     411           90 :             &self
     412           90 :         );
     413           90 :     }
     414              : }
     415              : 
     416              : impl<'a> FromFFI<ffi::PE_LoadConfiguration> for LoadConfiguration<'a> {
     417           90 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_LoadConfiguration>) -> Self {
     418           90 :         Self {
     419           90 :             ptr,
     420           90 :             _owner: PhantomData,
     421           90 :         }
     422           90 :     }
     423              : }
     424              : 
     425              : impl std::fmt::Debug for LoadConfiguration<'_> {
     426           90 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     427           90 :         f.debug_struct("LoadConfiguration")
     428           90 :             .field("size", &self.size())
     429           90 :             .field("timedatestamp", &self.timedatestamp())
     430           90 :             .field("major_version", &self.major_version())
     431           90 :             .field("minor_version", &self.minor_version())
     432           90 :             .field("global_flags_clear", &self.global_flags_clear())
     433           90 :             .field("global_flags_set", &self.global_flags_set())
     434           90 :             .field(
     435           90 :                 "critical_section_default_timeout",
     436           90 :                 &self.critical_section_default_timeout(),
     437           90 :             )
     438           90 :             .field(
     439           90 :                 "decommit_free_block_threshold",
     440           90 :                 &self.decommit_free_block_threshold(),
     441           90 :             )
     442           90 :             .field(
     443           90 :                 "decommit_total_free_threshold",
     444           90 :                 &self.decommit_total_free_threshold(),
     445           90 :             )
     446           90 :             .field("lock_prefix_table", &self.lock_prefix_table())
     447           90 :             .field("maximum_allocation_size", &self.maximum_allocation_size())
     448           90 :             .field("virtual_memory_threshold", &self.virtual_memory_threshold())
     449           90 :             .field("process_affinity_mask", &self.process_affinity_mask())
     450           90 :             .field("process_heap_flags", &self.process_heap_flags())
     451           90 :             .field("csd_version", &self.csd_version())
     452           90 :             .field("reserved1", &self.reserved1())
     453           90 :             .field("dependent_load_flags", &self.dependent_load_flags())
     454           90 :             .field("editlist", &self.editlist())
     455           90 :             .field("security_cookie", &self.security_cookie())
     456           90 :             .field("se_handler_table", &self.se_handler_table())
     457           90 :             .field("se_handler_count", &self.se_handler_count())
     458           90 :             .field(
     459           90 :                 "guard_cf_check_function_pointer",
     460           90 :                 &self.guard_cf_check_function_pointer(),
     461           90 :             )
     462           90 :             .field(
     463           90 :                 "guard_cf_dispatch_function_pointer",
     464           90 :                 &self.guard_cf_dispatch_function_pointer(),
     465           90 :             )
     466           90 :             .field("guard_cf_function_table", &self.guard_cf_function_table())
     467           90 :             .field("guard_cf_function_count", &self.guard_cf_function_count())
     468           90 :             .field("guard_flags", &self.guard_flags())
     469           90 :             .field(
     470           90 :                 "guard_address_taken_iat_entry_table",
     471           90 :                 &self.guard_address_taken_iat_entry_table(),
     472           90 :             )
     473           90 :             .field(
     474           90 :                 "guard_address_taken_iat_entry_count",
     475           90 :                 &self.guard_address_taken_iat_entry_count(),
     476           90 :             )
     477           90 :             .field(
     478           90 :                 "guard_long_jump_target_table",
     479           90 :                 &self.guard_long_jump_target_table(),
     480           90 :             )
     481           90 :             .field(
     482           90 :                 "guard_long_jump_target_count",
     483           90 :                 &self.guard_long_jump_target_count(),
     484           90 :             )
     485           90 :             .field(
     486           90 :                 "dynamic_value_reloc_table",
     487           90 :                 &self.dynamic_value_reloc_table(),
     488           90 :             )
     489           90 :             .field("hybrid_metadata_pointer", &self.hybrid_metadata_pointer())
     490           90 :             .field("chpe_metadata_pointer", &self.chpe_metadata_pointer())
     491           90 :             .field("guard_rf_failure_routine", &self.guard_rf_failure_routine())
     492           90 :             .field(
     493           90 :                 "guard_rf_failure_routine_function_pointer",
     494           90 :                 &self.guard_rf_failure_routine_function_pointer(),
     495           90 :             )
     496           90 :             .field(
     497           90 :                 "dynamic_value_reloctable_offset",
     498           90 :                 &self.dynamic_value_reloctable_offset(),
     499           90 :             )
     500           90 :             .field(
     501           90 :                 "dynamic_value_reloctable_section",
     502           90 :                 &self.dynamic_value_reloctable_section(),
     503           90 :             )
     504           90 :             .field("reserved2", &self.reserved2())
     505           90 :             .field(
     506           90 :                 "guard_rf_verify_stackpointer_function_pointer",
     507           90 :                 &self.guard_rf_verify_stackpointer_function_pointer(),
     508           90 :             )
     509           90 :             .field("hotpatch_table_offset", &self.hotpatch_table_offset())
     510           90 :             .field("reserved3", &self.reserved3())
     511           90 :             .field("enclave_configuration_ptr", &self.enclave_configuration_ptr())
     512           90 :             .field(
     513           90 :                 "volatile_metadata_pointer",
     514           90 :                 &self.volatile_metadata_pointer(),
     515           90 :             )
     516           90 :             .field(
     517           90 :                 "guard_eh_continuation_table",
     518           90 :                 &self.guard_eh_continuation_table(),
     519           90 :             )
     520           90 :             .field(
     521           90 :                 "guard_eh_continuation_count",
     522           90 :                 &self.guard_eh_continuation_count(),
     523           90 :             )
     524           90 :             .field(
     525           90 :                 "guard_xfg_check_function_pointer",
     526           90 :                 &self.guard_xfg_check_function_pointer(),
     527           90 :             )
     528           90 :             .field(
     529           90 :                 "guard_xfg_dispatch_function_pointer",
     530           90 :                 &self.guard_xfg_dispatch_function_pointer(),
     531           90 :             )
     532           90 :             .field(
     533           90 :                 "guard_xfg_table_dispatch_function_pointer",
     534           90 :                 &self.guard_xfg_table_dispatch_function_pointer(),
     535           90 :             )
     536           90 :             .field(
     537           90 :                 "cast_guard_os_determined_failure_mode",
     538           90 :                 &self.cast_guard_os_determined_failure_mode(),
     539           90 :             )
     540           90 :             .field(
     541           90 :                 "guard_memcpy_function_pointer",
     542           90 :                 &self.guard_memcpy_function_pointer(),
     543           90 :             )
     544           90 :             .finish()
     545           90 :     }
     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           90 :     #[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           90 :     fn from(value: u32) -> Self {
     606           90 :         ImageGuardFlags::from_bits_truncate(value)
     607           90 :     }
     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