use super::chpe_metadata_arm64;
use super::chpe_metadata_x86;
use super::dynamic_relocation::DynamicRelocation;
use super::enclave_configuration::EnclaveConfiguration;
use super::volatile_metadata::VolatileMetadata;
use crate::common::{FromFFI, into_optional};
use crate::pe::code_integrity::CodeIntegrity;
use crate::{declare_iterator, to_conv_opt, to_opt};
use bitflags::bitflags;
use lief_ffi as ffi;
use std::marker::PhantomData;
pub struct LoadConfiguration<'a> {
ptr: cxx::UniquePtr<ffi::PE_LoadConfiguration>,
_owner: PhantomData<&'a ffi::PE_Binary>,
}
impl LoadConfiguration<'_> {
pub fn characteristics(&self) -> u32 {
self.ptr.characteristics()
}
pub fn size(&self) -> u32 {
self.ptr.size()
}
pub fn timedatestamp(&self) -> u32 {
self.ptr.timedatestamp()
}
pub fn major_version(&self) -> u16 {
self.ptr.major_version()
}
pub fn minor_version(&self) -> u16 {
self.ptr.minor_version()
}
pub fn global_flags_clear(&self) -> u32 {
self.ptr.global_flags_clear()
}
pub fn global_flags_set(&self) -> u32 {
self.ptr.global_flags_set()
}
pub fn critical_section_default_timeout(&self) -> u32 {
self.ptr.critical_section_default_timeout()
}
pub fn decommit_free_block_threshold(&self) -> u64 {
self.ptr.decommit_free_block_threshold()
}
pub fn decommit_total_free_threshold(&self) -> u64 {
self.ptr.decommit_total_free_threshold()
}
pub fn lock_prefix_table(&self) -> u64 {
self.ptr.lock_prefix_table()
}
pub fn maximum_allocation_size(&self) -> u64 {
self.ptr.maximum_allocation_size()
}
pub fn virtual_memory_threshold(&self) -> u64 {
self.ptr.virtual_memory_threshold()
}
pub fn process_affinity_mask(&self) -> u64 {
self.ptr.process_affinity_mask()
}
pub fn process_heap_flags(&self) -> u32 {
self.ptr.process_heap_flags()
}
pub fn csd_version(&self) -> u16 {
self.ptr.csd_version()
}
pub fn reserved1(&self) -> u16 {
self.ptr.reserved1()
}
pub fn dependent_load_flags(&self) -> u16 {
self.ptr.dependent_load_flags()
}
pub fn editlist(&self) -> u64 {
self.ptr.editlist()
}
pub fn security_cookie(&self) -> u64 {
self.ptr.security_cookie()
}
pub fn se_handler_table(&self) -> Option<u64> {
to_opt!(&lief_ffi::PE_LoadConfiguration::se_handler_table, &self);
}
pub fn se_handler_count(&self) -> Option<u64> {
to_opt!(&lief_ffi::PE_LoadConfiguration::se_handler_count, &self);
}
pub fn seh_functions(&self) -> Vec<u32> {
Vec::from(self.ptr.seh_functions().as_slice())
}
pub fn guard_cf_check_function_pointer(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_cf_check_function_pointer,
&self
);
}
pub fn guard_cf_dispatch_function_pointer(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_cf_dispatch_function_pointer,
&self
);
}
pub fn guard_cf_function_table(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_cf_function_table,
&self
);
}
pub fn guard_cf_function_count(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_cf_function_count,
&self
);
}
pub fn guard_cf_functions(&self) -> GuardCFFunctions<'_> {
GuardCFFunctions::new(self.ptr.guard_cf_functions())
}
pub fn guard_flags(&self) -> Option<ImageGuardFlags> {
to_conv_opt!(
&lief_ffi::PE_LoadConfiguration::guard_flags,
&self,
|e: u32| ImageGuardFlags::from(e)
);
}
pub fn code_integrity(&self) -> Option<CodeIntegrity<'_>> {
into_optional(self.ptr.code_integrity())
}
pub fn guard_address_taken_iat_entry_table(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_address_taken_iat_entry_table,
&self
);
}
pub fn guard_address_taken_iat_entry_count(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_address_taken_iat_entry_count,
&self
);
}
pub fn guard_address_taken_iat_entries(&self) -> GuardAddressTakenIATEntries<'_> {
GuardAddressTakenIATEntries::new(self.ptr.guard_address_taken_iat_entries())
}
pub fn guard_long_jump_target_table(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_long_jump_target_table,
&self
);
}
pub fn guard_long_jump_target_count(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_long_jump_target_count,
&self
);
}
pub fn guard_long_jump_targets(&self) -> GuardLongJumpTargets<'_> {
GuardLongJumpTargets::new(self.ptr.guard_long_jump_targets())
}
pub fn dynamic_value_reloc_table(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::dynamic_value_reloc_table,
&self
);
}
pub fn hybrid_metadata_pointer(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::hybrid_metadata_pointer,
&self
);
}
pub fn chpe_metadata_pointer(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::chpe_metadata_pointer,
&self
);
}
pub fn chpe_metadata(&self) -> Option<CHPEMetadata<'_>> {
into_optional(self.ptr.chpe_metadata())
}
pub fn guard_rf_failure_routine(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_rf_failure_routine,
&self
);
}
pub fn guard_rf_failure_routine_function_pointer(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_rf_failure_routine_function_pointer,
&self
);
}
pub fn dynamic_value_reloctable_offset(&self) -> Option<u32> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::dynamic_value_reloctable_offset,
&self
);
}
pub fn dynamic_value_reloctable_section(&self) -> Option<u16> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::dynamic_value_reloctable_section,
&self
);
}
pub fn dynamic_relocations(&self) -> DynamicRelocations<'_> {
DynamicRelocations::new(self.ptr.dynamic_relocations())
}
pub fn reserved2(&self) -> Option<u16> {
to_opt!(&lief_ffi::PE_LoadConfiguration::reserved2, &self);
}
pub fn guard_rf_verify_stackpointer_function_pointer(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_rf_verify_stackpointer_function_pointer,
&self
);
}
pub fn hotpatch_table_offset(&self) -> Option<u32> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::hotpatch_table_offset,
&self
);
}
pub fn reserved3(&self) -> Option<u32> {
to_opt!(&lief_ffi::PE_LoadConfiguration::reserved3, &self);
}
pub fn enclave_config(&self) -> Option<EnclaveConfiguration<'_>> {
into_optional(self.ptr.enclave_config())
}
pub fn enclave_configuration_ptr(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::enclave_configuration_ptr,
&self
);
}
pub fn volatile_metadata_pointer(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::volatile_metadata_pointer,
&self
);
}
pub fn volatile_metadata(&self) -> Option<VolatileMetadata<'_>> {
into_optional(self.ptr.volatile_metadata())
}
pub fn guard_eh_continuation_table(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_eh_continuation_table,
&self
);
}
pub fn guard_eh_continuation_count(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_eh_continuation_count,
&self
);
}
pub fn guard_eh_continuation_functions(&self) -> GuardEhContinuationFunctions<'_> {
GuardEhContinuationFunctions::new(self.ptr.guard_eh_continuation_functions())
}
pub fn guard_xfg_check_function_pointer(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_xfg_check_function_pointer,
&self
);
}
pub fn guard_xfg_dispatch_function_pointer(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_xfg_dispatch_function_pointer,
&self
);
}
pub fn guard_xfg_table_dispatch_function_pointer(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_xfg_table_dispatch_function_pointer,
&self
);
}
pub fn cast_guard_os_determined_failure_mode(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::cast_guard_os_determined_failure_mode,
&self
);
}
pub fn guard_memcpy_function_pointer(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::guard_memcpy_function_pointer,
&self
);
}
pub fn uma_function_pointers(&self) -> Option<u64> {
to_opt!(
&lief_ffi::PE_LoadConfiguration::uma_function_pointers,
&self
);
}
pub fn set_characteristics(&mut self, value: u32) {
self.ptr.pin_mut().set_characteristics(value);
}
pub fn set_size(&mut self, value: u32) {
self.ptr.pin_mut().set_size(value);
}
pub fn set_timedatestamp(&mut self, value: u32) {
self.ptr.pin_mut().set_timedatestamp(value);
}
pub fn set_major_version(&mut self, value: u16) {
self.ptr.pin_mut().set_major_version(value);
}
pub fn set_minor_version(&mut self, value: u16) {
self.ptr.pin_mut().set_minor_version(value);
}
pub fn set_global_flags_clear(&mut self, value: u32) {
self.ptr.pin_mut().set_global_flags_clear(value);
}
pub fn set_global_flags_set(&mut self, value: u32) {
self.ptr.pin_mut().set_global_flags_set(value);
}
pub fn set_critical_section_default_timeout(&mut self, value: u32) {
self.ptr
.pin_mut()
.set_critical_section_default_timeout(value);
}
pub fn set_decommit_free_block_threshold(&mut self, value: u64) {
self.ptr.pin_mut().set_decommit_free_block_threshold(value);
}
pub fn set_decommit_total_free_threshold(&mut self, value: u64) {
self.ptr.pin_mut().set_decommit_total_free_threshold(value);
}
pub fn set_lock_prefix_table(&mut self, value: u64) {
self.ptr.pin_mut().set_lock_prefix_table(value);
}
pub fn set_maximum_allocation_size(&mut self, value: u64) {
self.ptr.pin_mut().set_maximum_allocation_size(value);
}
pub fn set_virtual_memory_threshold(&mut self, value: u64) {
self.ptr.pin_mut().set_virtual_memory_threshold(value);
}
pub fn set_process_affinity_mask(&mut self, value: u64) {
self.ptr.pin_mut().set_process_affinity_mask(value);
}
pub fn set_process_heap_flags(&mut self, value: u32) {
self.ptr.pin_mut().set_process_heap_flags(value);
}
pub fn set_csd_version(&mut self, value: u16) {
self.ptr.pin_mut().set_csd_version(value);
}
pub fn set_reserved1(&mut self, value: u16) {
self.ptr.pin_mut().set_reserved1(value);
}
pub fn set_dependent_load_flags(&mut self, value: u16) {
self.ptr.pin_mut().set_dependent_load_flags(value);
}
pub fn set_editlist(&mut self, value: u32) {
self.ptr.pin_mut().set_editlist(value);
}
pub fn set_security_cookie(&mut self, value: u64) {
self.ptr.pin_mut().set_security_cookie(value);
}
pub fn set_se_handler_table(&mut self, value: u64) {
self.ptr.pin_mut().set_se_handler_table(value);
}
pub fn set_se_handler_count(&mut self, value: u64) {
self.ptr.pin_mut().set_se_handler_count(value);
}
pub fn set_guard_cf_check_function_pointer(&mut self, value: u64) {
self.ptr
.pin_mut()
.set_guard_cf_check_function_pointer(value);
}
pub fn set_guard_cf_dispatch_function_pointer(&mut self, value: u64) {
self.ptr
.pin_mut()
.set_guard_cf_dispatch_function_pointer(value);
}
pub fn set_guard_cf_function_table(&mut self, value: u64) {
self.ptr.pin_mut().set_guard_cf_function_table(value);
}
pub fn set_guard_cf_function_count(&mut self, value: u64) {
self.ptr.pin_mut().set_guard_cf_function_count(value);
}
pub fn set_guard_flags(&mut self, flags: ImageGuardFlags) {
self.ptr.pin_mut().set_guard_flags(flags.bits());
}
pub fn set_guard_address_taken_iat_entry_table(&mut self, value: u64) {
self.ptr
.pin_mut()
.set_guard_address_taken_iat_entry_table(value);
}
pub fn set_guard_address_taken_iat_entry_count(&mut self, value: u64) {
self.ptr
.pin_mut()
.set_guard_address_taken_iat_entry_count(value);
}
pub fn set_guard_long_jump_target_table(&mut self, value: u64) {
self.ptr.pin_mut().set_guard_long_jump_target_table(value);
}
pub fn set_guard_long_jump_target_count(&mut self, value: u64) {
self.ptr.pin_mut().set_guard_long_jump_target_count(value);
}
pub fn set_dynamic_value_reloc_table(&mut self, value: u64) {
self.ptr.pin_mut().set_dynamic_value_reloc_table(value);
}
pub fn set_hybrid_metadata_pointer(&mut self, value: u64) {
self.ptr.pin_mut().set_hybrid_metadata_pointer(value);
}
pub fn set_guard_rf_failure_routine(&mut self, value: u64) {
self.ptr.pin_mut().set_guard_rf_failure_routine(value);
}
pub fn set_guard_rf_failure_routine_function_pointer(&mut self, value: u64) {
self.ptr
.pin_mut()
.set_guard_rf_failure_routine_function_pointer(value);
}
pub fn set_dynamic_value_reloctable_offset(&mut self, value: u32) {
self.ptr
.pin_mut()
.set_dynamic_value_reloctable_offset(value);
}
pub fn set_dynamic_value_reloctable_section(&mut self, value: u16) {
self.ptr
.pin_mut()
.set_dynamic_value_reloctable_section(value);
}
pub fn set_reserved2(&mut self, value: u16) {
self.ptr.pin_mut().set_reserved2(value);
}
pub fn set_guard_rf_verify_stackpointer_function_pointer(&mut self, value: u64) {
self.ptr
.pin_mut()
.set_guard_rf_verify_stackpointer_function_pointer(value);
}
pub fn set_hotpatch_table_offset(&mut self, value: u32) {
self.ptr.pin_mut().set_hotpatch_table_offset(value);
}
pub fn set_reserved3(&mut self, value: u32) {
self.ptr.pin_mut().set_reserved3(value);
}
pub fn set_enclave_configuration_ptr(&mut self, value: u64) {
self.ptr.pin_mut().set_enclave_configuration_ptr(value);
}
pub fn set_volatile_metadata_pointer(&mut self, value: u64) {
self.ptr.pin_mut().set_volatile_metadata_pointer(value);
}
pub fn set_guard_eh_continuation_table(&mut self, value: u64) {
self.ptr.pin_mut().set_guard_eh_continuation_table(value);
}
pub fn set_guard_eh_continuation_count(&mut self, value: u64) {
self.ptr.pin_mut().set_guard_eh_continuation_count(value);
}
pub fn set_guard_xfg_check_function_pointer(&mut self, value: u64) {
self.ptr
.pin_mut()
.set_guard_xfg_check_function_pointer(value);
}
pub fn set_guard_xfg_dispatch_function_pointer(&mut self, value: u64) {
self.ptr
.pin_mut()
.set_guard_xfg_dispatch_function_pointer(value);
}
pub fn set_guard_xfg_table_dispatch_function_pointer(&mut self, value: u64) {
self.ptr
.pin_mut()
.set_guard_xfg_table_dispatch_function_pointer(value);
}
pub fn set_cast_guard_os_determined_failure_mode(&mut self, value: u64) {
self.ptr
.pin_mut()
.set_cast_guard_os_determined_failure_mode(value);
}
pub fn set_guard_memcpy_function_pointer(&mut self, value: u64) {
self.ptr.pin_mut().set_guard_memcpy_function_pointer(value);
}
pub fn set_uma_function_pointers(&mut self, value: u64) {
self.ptr.pin_mut().set_uma_function_pointers(value);
}
}
impl<'a> FromFFI<ffi::PE_LoadConfiguration> for LoadConfiguration<'a> {
fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_LoadConfiguration>) -> Self {
Self {
ptr,
_owner: PhantomData,
}
}
}
impl std::fmt::Debug for LoadConfiguration<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("LoadConfiguration")
.field("size", &self.size())
.field("timedatestamp", &self.timedatestamp())
.field("major_version", &self.major_version())
.field("minor_version", &self.minor_version())
.field("global_flags_clear", &self.global_flags_clear())
.field("global_flags_set", &self.global_flags_set())
.field(
"critical_section_default_timeout",
&self.critical_section_default_timeout(),
)
.field(
"decommit_free_block_threshold",
&self.decommit_free_block_threshold(),
)
.field(
"decommit_total_free_threshold",
&self.decommit_total_free_threshold(),
)
.field("lock_prefix_table", &self.lock_prefix_table())
.field("maximum_allocation_size", &self.maximum_allocation_size())
.field("virtual_memory_threshold", &self.virtual_memory_threshold())
.field("process_affinity_mask", &self.process_affinity_mask())
.field("process_heap_flags", &self.process_heap_flags())
.field("csd_version", &self.csd_version())
.field("reserved1", &self.reserved1())
.field("dependent_load_flags", &self.dependent_load_flags())
.field("editlist", &self.editlist())
.field("security_cookie", &self.security_cookie())
.field("se_handler_table", &self.se_handler_table())
.field("se_handler_count", &self.se_handler_count())
.field(
"guard_cf_check_function_pointer",
&self.guard_cf_check_function_pointer(),
)
.field(
"guard_cf_dispatch_function_pointer",
&self.guard_cf_dispatch_function_pointer(),
)
.field("guard_cf_function_table", &self.guard_cf_function_table())
.field("guard_cf_function_count", &self.guard_cf_function_count())
.field("guard_flags", &self.guard_flags())
.field(
"guard_address_taken_iat_entry_table",
&self.guard_address_taken_iat_entry_table(),
)
.field(
"guard_address_taken_iat_entry_count",
&self.guard_address_taken_iat_entry_count(),
)
.field(
"guard_long_jump_target_table",
&self.guard_long_jump_target_table(),
)
.field(
"guard_long_jump_target_count",
&self.guard_long_jump_target_count(),
)
.field(
"dynamic_value_reloc_table",
&self.dynamic_value_reloc_table(),
)
.field("hybrid_metadata_pointer", &self.hybrid_metadata_pointer())
.field("chpe_metadata_pointer", &self.chpe_metadata_pointer())
.field("guard_rf_failure_routine", &self.guard_rf_failure_routine())
.field(
"guard_rf_failure_routine_function_pointer",
&self.guard_rf_failure_routine_function_pointer(),
)
.field(
"dynamic_value_reloctable_offset",
&self.dynamic_value_reloctable_offset(),
)
.field(
"dynamic_value_reloctable_section",
&self.dynamic_value_reloctable_section(),
)
.field("reserved2", &self.reserved2())
.field(
"guard_rf_verify_stackpointer_function_pointer",
&self.guard_rf_verify_stackpointer_function_pointer(),
)
.field("hotpatch_table_offset", &self.hotpatch_table_offset())
.field("reserved3", &self.reserved3())
.field(
"enclave_configuration_ptr",
&self.enclave_configuration_ptr(),
)
.field(
"volatile_metadata_pointer",
&self.volatile_metadata_pointer(),
)
.field(
"guard_eh_continuation_table",
&self.guard_eh_continuation_table(),
)
.field(
"guard_eh_continuation_count",
&self.guard_eh_continuation_count(),
)
.field(
"guard_xfg_check_function_pointer",
&self.guard_xfg_check_function_pointer(),
)
.field(
"guard_xfg_dispatch_function_pointer",
&self.guard_xfg_dispatch_function_pointer(),
)
.field(
"guard_xfg_table_dispatch_function_pointer",
&self.guard_xfg_table_dispatch_function_pointer(),
)
.field(
"cast_guard_os_determined_failure_mode",
&self.cast_guard_os_determined_failure_mode(),
)
.field(
"guard_memcpy_function_pointer",
&self.guard_memcpy_function_pointer(),
)
.field("uma_function_pointers", &self.uma_function_pointers())
.finish()
}
}
pub struct GuardFunction<'a> {
ptr: cxx::UniquePtr<ffi::PE_LoadConfiguration_guard_function_t>,
_owner: PhantomData<&'a ffi::PE_LoadConfiguration>,
}
impl<'a> FromFFI<ffi::PE_LoadConfiguration_guard_function_t> for GuardFunction<'a> {
fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_LoadConfiguration_guard_function_t>) -> Self {
Self {
ptr,
_owner: PhantomData,
}
}
}
impl GuardFunction<'_> {
pub fn rva(&self) -> u32 {
self.ptr.rva()
}
pub fn extra(&self) -> u32 {
self.ptr.extra()
}
}
impl std::fmt::Debug for GuardFunction<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("GuardFunction")
.field("rva", &self.rva())
.field("extra", &self.extra())
.finish()
}
}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ImageGuardFlags: u32 {
const NONE = 0x0;
const CF_INSTRUMENTED = 0x100;
const CFW_INSTRUMENTED = 0x200;
const CF_FUNCTION_TABLE_PRESENT = 0x400;
const SECURITY_COOKIE_UNUSED = 0x800;
const PROTECT_DELAYLOAD_IAT = 0x1000;
const DELAYLOAD_IAT_IN_ITS_OWN_SECTION = 0x2000;
const CF_EXPORT_SUPPRESSION_INFO_PRESENT = 0x4000;
const CF_ENABLE_EXPORT_SUPPRESSION = 0x8000;
const CF_LONGJUMP_TABLE_PRESENT = 0x10000;
const RF_INSTRUMENTED = 0x20000;
const RF_ENABLE = 0x40000;
const RF_STRICT = 0x80000;
const RETPOLINE_PRESENT = 0x100000;
const EH_CONTINUATION_TABLE_PRESENT = 0x200000;
const XFG_ENABLED = 0x00800000;
const CASTGUARD_PRESENT = 0x01000000;
const MEMCPY_PRESENT = 0x02000000;
}
}
impl From<u32> for ImageGuardFlags {
fn from(value: u32) -> Self {
ImageGuardFlags::from_bits_truncate(value)
}
}
impl From<ImageGuardFlags> for u32 {
fn from(value: ImageGuardFlags) -> Self {
value.bits()
}
}
impl std::fmt::Display for ImageGuardFlags {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
bitflags::parser::to_writer(self, f)
}
}
#[derive(Debug)]
pub enum CHPEMetadata<'a> {
ARM64(chpe_metadata_arm64::CHPEMetadata<'a>),
X86(chpe_metadata_x86::CHPEMetadata<'a>),
}
impl<'a> FromFFI<ffi::PE_CHPEMetadata> for CHPEMetadata<'a> {
fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_CHPEMetadata>) -> Self {
unsafe {
let obj_ref = ffi_entry.as_ref().unwrap();
if ffi::PE_CHPEMetadataARM64::classof(obj_ref) {
let raw = {
type From = cxx::UniquePtr<ffi::PE_CHPEMetadata>;
type To = cxx::UniquePtr<ffi::PE_CHPEMetadataARM64>;
std::mem::transmute::<From, To>(ffi_entry)
};
CHPEMetadata::ARM64(chpe_metadata_arm64::CHPEMetadata::from_ffi(raw))
} else if ffi::PE_CHPEMetadataX86::classof(obj_ref) {
let raw = {
type From = cxx::UniquePtr<ffi::PE_CHPEMetadata>;
type To = cxx::UniquePtr<ffi::PE_CHPEMetadataX86>;
std::mem::transmute::<From, To>(ffi_entry)
};
CHPEMetadata::X86(chpe_metadata_x86::CHPEMetadata::from_ffi(raw))
} else {
panic!("unsupported architecture");
}
}
}
}
pub trait AsCHPEMetadata {
#[doc(hidden)]
fn as_generic(&self) -> &ffi::PE_CHPEMetadata;
fn version(&self) -> u32 {
self.as_generic().version()
}
}
impl std::fmt::Display for &dyn AsCHPEMetadata {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.as_generic().to_string())
}
}
impl AsCHPEMetadata for CHPEMetadata<'_> {
fn as_generic(&self) -> &ffi::PE_CHPEMetadata {
match &self {
CHPEMetadata::ARM64(entry) => entry.as_generic(),
CHPEMetadata::X86(entry) => entry.as_generic(),
}
}
}
declare_iterator!(
GuardCFFunctions,
GuardFunction<'a>,
ffi::PE_LoadConfiguration_guard_function_t,
ffi::PE_LoadConfiguration,
ffi::PE_LoadConfiguration_it_guard_cf_functions
);
declare_iterator!(
GuardAddressTakenIATEntries,
GuardFunction<'a>,
ffi::PE_LoadConfiguration_guard_function_t,
ffi::PE_LoadConfiguration,
ffi::PE_LoadConfiguration_it_guard_address_taken_iat_entries
);
declare_iterator!(
GuardLongJumpTargets,
GuardFunction<'a>,
ffi::PE_LoadConfiguration_guard_function_t,
ffi::PE_LoadConfiguration,
ffi::PE_LoadConfiguration_it_guard_long_jump_targets
);
declare_iterator!(
GuardEhContinuationFunctions,
GuardFunction<'a>,
ffi::PE_LoadConfiguration_guard_function_t,
ffi::PE_LoadConfiguration,
ffi::PE_LoadConfiguration_it_guard_eh_continuation
);
declare_iterator!(
DynamicRelocations,
DynamicRelocation<'a>,
ffi::PE_DynamicRelocation,
ffi::PE_LoadConfiguration,
ffi::PE_LoadConfiguration_it_dynamic_relocations
);