use scroll::ctx;
use scroll::{Pread, Pwrite, SizeWith};
use crate::container::{Container, Ctx};
use crate::error;
use crate::pe::data_directories;
use crate::pe::options;
use crate::pe::section_table;
use crate::pe::utils;
use log;
pub const IMAGE_GUARD_CF_INSTRUMENTED: u32 = 0x0000_0100;
pub const IMAGE_GUARD_CFW_INSTRUMENTED: u32 = 0x0000_0200;
pub const IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT: u32 = 0x0000_0400;
pub const IMAGE_GUARD_SECURITY_COOKIE_UNUSED: u32 = 0x0000_0800;
pub const IMAGE_GUARD_PROTECT_DELAYLOAD_IAT: u32 = 0x0000_1000;
pub const IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION: u32 = 0x0000_2000;
pub const IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT: u32 = 0x0000_4000;
pub const IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION: u32 = 0x0000_8000;
pub const IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT: u32 = 0x0001_0000;
pub const IMAGE_GUARD_RF_INSTRUMENTED: u32 = 0x0002_0000;
pub const IMAGE_GUARD_RF_ENABLE: u32 = 0x0004_0000;
pub const IMAGE_GUARD_RF_STRICT: u32 = 0x0008_0000;
pub const IMAGE_GUARD_RETPOLINE_PRESENT: u32 = 0x0010_0000;
pub const IMAGE_GUARD_EH_CONTINUATION_TABLE_PRESENT: u32 = 0x0040_0000;
pub const IMAGE_GUARD_XFG_ENABLED: u32 = 0x0080_0000;
pub const IMAGE_GUARD_CASTGUARD_PRESENT: u32 = 0x0100_0000;
pub const IMAGE_GUARD_MEMCPY_PRESENT: u32 = 0x0200_0000;
pub const DONT_RESOLVE_DLL_REFERENCES: u32 = 0x0000_0001;
pub const LOAD_LIBRARY_AS_DATAFILE: u32 = 0x0000_0002;
pub const LOAD_PACKAGED_LIBRARY: u32 = 0x0000_0004;
pub const LOAD_WITH_ALTERED_SEARCH_PATH: u32 = 0x0000_0008;
pub const LOAD_IGNORE_CODE_AUTHZ_LEVEL: u32 = 0x0000_0010;
pub const LOAD_LIBRARY_AS_IMAGE_RESOURCE: u32 = 0x0000_0020;
pub const LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE: u32 = 0x0000_0040;
pub const LOAD_LIBRARY_REQUIRE_SIGNED_TARGET: u32 = 0x0000_0080;
pub const LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR: u32 = 0x0000_0100;
pub const LOAD_LIBRARY_SEARCH_APPLICATION_DIR: u32 = 0x0000_0200;
pub const LOAD_LIBRARY_SEARCH_USER_DIRS: u32 = 0x0000_0400;
pub const LOAD_LIBRARY_SEARCH_SYSTEM32: u32 = 0x0000_0800;
pub const LOAD_LIBRARY_SEARCH_DEFAULT_DIRS: u32 = 0x0000_1000;
pub const LOAD_LIBRARY_SAFE_CURRENT_DIRS: u32 = 0x0000_2000;
pub const LOAD_LIBRARY_SEARCH_SYSTEM32_NO_FORWARDER: u32 = 0x0000_4000;
pub const LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY: u32 = 0x0000_8000;
#[non_exhaustive]
#[derive(Debug, Clone, Default, Eq, PartialEq)]
pub struct LoadConfigDirectory {
pub size: u32,
pub time_stamp: Option<u32>,
pub major_version: Option<u16>,
pub minor_version: Option<u16>,
pub global_flags_clear: Option<u32>,
pub global_flags_set: Option<u32>,
pub critical_section_default_timeout: Option<u32>,
pub de_commit_free_block_threshold: Option<u64>,
pub de_commit_total_free_threshold: Option<u64>,
pub lock_prefix_table: Option<u64>,
pub maximum_allocation_size: Option<u64>,
pub virtual_memory_threshold: Option<u64>,
pub process_affinity_mask: Option<u64>,
pub process_heap_flags: Option<u32>,
pub csd_version: Option<u16>,
pub dependent_load_flags: Option<u16>,
pub edit_list: Option<u64>,
pub security_cookie: Option<u64>,
pub se_handler_table: Option<u64>,
pub se_handler_count: Option<u64>,
pub guard_cf_check_function_pointer: Option<u64>,
pub guard_cf_dispatch_function_pointer: Option<u64>,
pub guard_cf_function_table: Option<u64>,
pub guard_cf_function_count: Option<u64>,
pub guard_flags: Option<u32>,
pub code_integrity: Option<LoadConfigCodeIntegrity>,
pub guard_address_taken_iat_entry_table: Option<u64>,
pub guard_address_taken_iat_entry_count: Option<u64>,
pub guard_long_jump_target_table: Option<u64>,
pub guard_long_jump_target_count: Option<u64>,
pub dynamic_value_reloc_table: Option<u64>,
pub chpe_metadata_pointer: Option<u64>,
pub guard_rf_failure_routine: Option<u64>,
pub guard_rf_failure_routine_function_pointer: Option<u64>,
pub dynamic_value_reloc_table_offset: Option<u32>,
pub dynamic_value_reloc_table_section: Option<u16>,
pub reserved2: Option<u16>,
pub guard_rf_verify_stack_pointer_function_pointer: Option<u64>,
pub hot_patch_table_offset: Option<u32>,
pub reserved3: Option<u32>,
pub enclave_configuration_pointer: Option<u64>,
pub volatile_metadata_pointer: Option<u64>,
pub guard_eh_continuation_table: Option<u64>,
pub guard_eh_continuation_count: Option<u64>,
pub guard_xfg_check_function_pointer: Option<u64>,
pub guard_xfg_dispatch_function_pointer: Option<u64>,
pub guard_xfg_table_dispatch_function_pointer: Option<u64>,
pub cast_guard_os_determined_failure_mode: Option<u64>,
pub guard_memcpy_function_pointer: Option<u64>,
}
impl<'a> ctx::TryFromCtx<'a, Ctx> for LoadConfigDirectory {
type Error = crate::error::Error;
fn try_from_ctx(bytes: &'a [u8], ctx: Ctx) -> error::Result<(Self, usize)> {
if bytes.len() < 4 {
return Err(error::Error::Malformed(format!("Too small")));
}
let is_64 = ctx.is_big();
let mut offset = 0;
let read_arch_dependent_u64 = |offset: &mut usize| {
if is_64 {
bytes.gread_with(offset, scroll::LE).ok()
} else {
bytes
.gread_with::<u32>(offset, scroll::LE)
.map(Into::into)
.ok()
}
};
let out = Self {
size: bytes.gread_with(&mut offset, scroll::LE)?,
time_stamp: bytes.gread_with(&mut offset, scroll::LE).ok(),
major_version: bytes.gread_with(&mut offset, scroll::LE).ok(),
minor_version: bytes.gread_with(&mut offset, scroll::LE).ok(),
global_flags_clear: bytes.gread_with(&mut offset, scroll::LE).ok(),
global_flags_set: bytes.gread_with(&mut offset, scroll::LE).ok(),
critical_section_default_timeout: bytes.gread_with(&mut offset, scroll::LE).ok(),
de_commit_free_block_threshold: read_arch_dependent_u64(&mut offset),
de_commit_total_free_threshold: read_arch_dependent_u64(&mut offset),
lock_prefix_table: read_arch_dependent_u64(&mut offset),
maximum_allocation_size: read_arch_dependent_u64(&mut offset),
virtual_memory_threshold: read_arch_dependent_u64(&mut offset),
process_affinity_mask: read_arch_dependent_u64(&mut offset),
process_heap_flags: bytes.gread_with(&mut offset, scroll::LE).ok(),
csd_version: bytes.gread_with(&mut offset, scroll::LE).ok(),
dependent_load_flags: bytes.gread_with(&mut offset, scroll::LE).ok(),
edit_list: read_arch_dependent_u64(&mut offset),
security_cookie: read_arch_dependent_u64(&mut offset),
se_handler_table: read_arch_dependent_u64(&mut offset),
se_handler_count: read_arch_dependent_u64(&mut offset),
guard_cf_check_function_pointer: read_arch_dependent_u64(&mut offset),
guard_cf_dispatch_function_pointer: read_arch_dependent_u64(&mut offset),
guard_cf_function_table: read_arch_dependent_u64(&mut offset),
guard_cf_function_count: read_arch_dependent_u64(&mut offset),
guard_flags: bytes.gread_with(&mut offset, scroll::LE).ok(),
code_integrity: bytes.gread_with(&mut offset, scroll::LE).ok(),
guard_address_taken_iat_entry_table: read_arch_dependent_u64(&mut offset),
guard_address_taken_iat_entry_count: read_arch_dependent_u64(&mut offset),
guard_long_jump_target_table: read_arch_dependent_u64(&mut offset),
guard_long_jump_target_count: read_arch_dependent_u64(&mut offset),
dynamic_value_reloc_table: read_arch_dependent_u64(&mut offset),
chpe_metadata_pointer: read_arch_dependent_u64(&mut offset),
guard_rf_failure_routine: read_arch_dependent_u64(&mut offset),
guard_rf_failure_routine_function_pointer: read_arch_dependent_u64(&mut offset),
dynamic_value_reloc_table_offset: bytes.gread_with(&mut offset, scroll::LE).ok(),
dynamic_value_reloc_table_section: bytes.gread_with(&mut offset, scroll::LE).ok(),
reserved2: bytes.gread_with(&mut offset, scroll::LE).ok(),
guard_rf_verify_stack_pointer_function_pointer: read_arch_dependent_u64(&mut offset),
hot_patch_table_offset: bytes.gread_with(&mut offset, scroll::LE).ok(),
reserved3: bytes.gread_with(&mut offset, scroll::LE).ok(),
enclave_configuration_pointer: read_arch_dependent_u64(&mut offset),
volatile_metadata_pointer: read_arch_dependent_u64(&mut offset),
guard_eh_continuation_table: read_arch_dependent_u64(&mut offset),
guard_eh_continuation_count: read_arch_dependent_u64(&mut offset),
guard_xfg_check_function_pointer: read_arch_dependent_u64(&mut offset),
guard_xfg_dispatch_function_pointer: read_arch_dependent_u64(&mut offset),
guard_xfg_table_dispatch_function_pointer: read_arch_dependent_u64(&mut offset),
cast_guard_os_determined_failure_mode: read_arch_dependent_u64(&mut offset),
guard_memcpy_function_pointer: read_arch_dependent_u64(&mut offset),
};
Ok((out, offset))
}
}
#[repr(C)]
#[derive(Debug, Clone, Pread, Pwrite, SizeWith, Eq, PartialEq)]
pub struct LoadConfigCodeIntegrity {
pub flags: u16,
pub catalog: u16,
pub catalog_offset: u32,
pub reserved: u32,
}
#[derive(Debug, PartialEq, Clone, Default)]
pub struct LoadConfigData {
pub directory: LoadConfigDirectory,
}
impl LoadConfigData {
pub fn parse(
bytes: &[u8],
dd: data_directories::DataDirectory,
sections: &[section_table::SectionTable],
file_alignment: u32,
is_64: bool,
) -> error::Result<Self> {
Self::parse_with_opts(
bytes,
dd,
sections,
file_alignment,
&options::ParseOptions::default(),
is_64,
)
}
pub fn parse_with_opts(
bytes: &[u8],
dd: data_directories::DataDirectory,
sections: &[section_table::SectionTable],
file_alignment: u32,
opts: &options::ParseOptions,
is_64: bool,
) -> error::Result<Self> {
let offset =
utils::find_offset(dd.virtual_address as usize, sections, file_alignment, opts)
.ok_or_else(|| {
error::Error::Malformed(format!(
"Cannot map load config rva {:#x} into offset",
dd.virtual_address
))
})?;
log::debug!(
"LoadConfig parsing: offset={:#x}, dd.size={:#x}, total_bytes_len={:#x}, remaining_bytes_from_offset={:#x}",
offset,
dd.size,
bytes.len(),
bytes.len().saturating_sub(offset)
);
let bytes = bytes
.pread_with::<&[u8]>(offset, dd.size as usize)
.map_err(|_| {
error::Error::Malformed(format!(
"load config offset {:#x} and size {:#x} exceeds the bounds of the bytes size {:#x}",
offset,
dd.size,
bytes.len()
))
})?;
log::debug!(
"LoadConfig bytes slice created successfully, length={}",
bytes.len()
);
let ctx = Ctx::new(
if is_64 {
Container::Big
} else {
Container::Little
},
scroll::LE,
);
let directory = bytes.pread_with(0, ctx)?;
Ok(Self { directory })
}
}
#[cfg(test)]
mod tests {
use super::*;
const LOADCONFIG64_DATA0: &[u8; 320] = &[
0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x45,
0x1E, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x12, 0x1E, 0x80, 0x01, 0x00, 0x00, 0x00,
0x00, 0x50, 0x1E, 0x80, 0x01, 0x00, 0x00, 0x00, 0xA0, 0x02, 0x17, 0x80, 0x01, 0x00, 0x00,
0x00, 0x87, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x41, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0,
0x06, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xFF, 0x16, 0x80, 0x01, 0x00,
0x00, 0x00, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x50, 0x1E, 0x80, 0x01,
0x00, 0x00, 0x00, 0x10, 0x50, 0x1E, 0x80, 0x01, 0x00, 0x00, 0x00, 0x18, 0x50, 0x1E, 0x80,
0x01, 0x00, 0x00, 0x00, 0x20, 0x50, 0x1E, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
];
const LOADCONFIG32_DATA0: &[u8; 192] = &[
0xBC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0xD0, 0x41, 0x00, 0xD4, 0xB6, 0x41, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x51, 0x41,
0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x51, 0x41, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x75,
0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xD4, 0xDC, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00,
];
#[test]
fn parse_loadconfig64_data0() {
let ctx = Ctx::new(crate::container::Container::Big, scroll::LE);
let data = LOADCONFIG64_DATA0
.pread_with::<LoadConfigDirectory>(0, ctx)
.unwrap();
assert_eq!(data.size, 320);
assert_eq!(data.time_stamp, Some(0));
assert_eq!(data.major_version, Some(0));
assert_eq!(data.minor_version, Some(0));
assert_eq!(data.global_flags_clear, Some(0));
assert_eq!(data.global_flags_set, Some(0));
assert_eq!(data.critical_section_default_timeout, Some(0));
assert_eq!(data.de_commit_free_block_threshold, Some(0));
assert_eq!(data.de_commit_total_free_threshold, Some(0));
assert_eq!(data.lock_prefix_table, Some(0));
assert_eq!(data.maximum_allocation_size, Some(0));
assert_eq!(data.virtual_memory_threshold, Some(0));
assert_eq!(data.process_affinity_mask, Some(0));
assert_eq!(data.process_heap_flags, Some(0));
assert_eq!(data.csd_version, Some(0));
assert_eq!(
data.dependent_load_flags,
Some(LOAD_LIBRARY_SEARCH_SYSTEM32 as u16)
);
assert_eq!(data.edit_list, Some(0));
assert_eq!(data.security_cookie, Some(0x1801e4598));
assert_eq!(data.se_handler_table, Some(0));
assert_eq!(data.se_handler_count, Some(0));
assert_eq!(data.guard_cf_check_function_pointer, Some(0x1801e1218));
assert_eq!(data.guard_cf_dispatch_function_pointer, Some(0x1801e5000));
assert_eq!(data.guard_cf_function_table, Some(0x1801702a0));
assert_eq!(data.guard_cf_function_count, Some(2183));
assert_eq!(data.guard_flags, Some(0x10417500));
const FLAGS: u32 = IMAGE_GUARD_CF_INSTRUMENTED
| IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT
| IMAGE_GUARD_PROTECT_DELAYLOAD_IAT
| IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION
| IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT
| IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT
| IMAGE_GUARD_EH_CONTINUATION_TABLE_PRESENT;
assert_eq!(data.guard_flags.map(|x| x & FLAGS), Some(FLAGS));
assert_eq!(
data.code_integrity,
Some(LoadConfigCodeIntegrity {
flags: 0,
catalog: 0,
catalog_offset: 0,
reserved: 0
})
);
assert_eq!(data.guard_address_taken_iat_entry_table, Some(0));
assert_eq!(data.guard_address_taken_iat_entry_count, Some(0));
assert_eq!(data.guard_long_jump_target_table, Some(0));
assert_eq!(data.guard_long_jump_target_count, Some(0));
assert_eq!(data.dynamic_value_reloc_table, Some(0));
assert_eq!(data.chpe_metadata_pointer, Some(0));
assert_eq!(data.guard_rf_failure_routine, Some(0));
assert_eq!(data.guard_rf_failure_routine_function_pointer, Some(0));
assert_eq!(data.dynamic_value_reloc_table_offset, Some(0x6a0));
assert_eq!(data.dynamic_value_reloc_table_section, Some(15));
assert_eq!(data.reserved2, Some(0));
assert_eq!(data.guard_rf_verify_stack_pointer_function_pointer, Some(0));
assert_eq!(data.hot_patch_table_offset, Some(0));
assert_eq!(data.reserved3, Some(0));
assert_eq!(data.enclave_configuration_pointer, Some(0));
assert_eq!(data.volatile_metadata_pointer, Some(0));
assert_eq!(data.guard_eh_continuation_table, Some(0x18016ff38));
assert_eq!(data.guard_eh_continuation_count, Some(174));
assert_eq!(data.guard_xfg_check_function_pointer, Some(0x1801e5008));
assert_eq!(data.guard_xfg_dispatch_function_pointer, Some(0x1801e5010));
assert_eq!(
data.guard_xfg_table_dispatch_function_pointer,
Some(0x1801e5018)
);
assert_eq!(
data.cast_guard_os_determined_failure_mode,
Some(0x1801e5020)
);
assert_eq!(data.guard_memcpy_function_pointer, Some(0));
}
#[test]
fn parse_loadconfig32_data0() {
let ctx = Ctx::new(crate::container::Container::Little, scroll::LE);
let data = LOADCONFIG32_DATA0
.pread_with::<LoadConfigDirectory>(0, ctx)
.unwrap();
assert_eq!(data.size, 188);
assert_eq!(data.time_stamp, Some(0));
assert_eq!(data.major_version, Some(0));
assert_eq!(data.minor_version, Some(0));
assert_eq!(data.global_flags_clear, Some(0));
assert_eq!(data.global_flags_set, Some(0));
assert_eq!(data.critical_section_default_timeout, Some(0));
assert_eq!(data.de_commit_free_block_threshold, Some(0));
assert_eq!(data.de_commit_total_free_threshold, Some(0));
assert_eq!(data.lock_prefix_table, Some(0));
assert_eq!(data.maximum_allocation_size, Some(0));
assert_eq!(data.virtual_memory_threshold, Some(0));
assert_eq!(data.process_affinity_mask, Some(0));
assert_eq!(data.process_heap_flags, Some(0));
assert_eq!(data.csd_version, Some(0));
assert_eq!(data.dependent_load_flags, Some(0));
assert_eq!(data.edit_list, Some(0));
assert_eq!(data.security_cookie, Some(0x41d008));
assert_eq!(data.se_handler_table, Some(0x41b6d4));
assert_eq!(data.se_handler_count, Some(16));
assert_eq!(data.guard_cf_check_function_pointer, Some(0x415170));
assert_eq!(data.guard_cf_dispatch_function_pointer, Some(0));
assert_eq!(data.guard_cf_function_table, Some(0x4151bc));
assert_eq!(data.guard_cf_function_count, Some(63));
assert_eq!(data.guard_flags, Some(0x10017500));
const FLAGS: u32 = IMAGE_GUARD_CF_INSTRUMENTED
| IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT
| IMAGE_GUARD_PROTECT_DELAYLOAD_IAT
| IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION
| IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT
| IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT;
assert_eq!(data.guard_flags.map(|x| x & FLAGS), Some(FLAGS));
assert_eq!(
data.code_integrity,
Some(LoadConfigCodeIntegrity {
flags: 0,
catalog: 0,
catalog_offset: 0,
reserved: 0
})
);
assert_eq!(data.guard_address_taken_iat_entry_table, Some(0));
assert_eq!(data.guard_address_taken_iat_entry_count, Some(0));
assert_eq!(data.guard_long_jump_target_table, Some(0));
assert_eq!(data.guard_long_jump_target_count, Some(0));
assert_eq!(data.dynamic_value_reloc_table, Some(0));
assert_eq!(data.chpe_metadata_pointer, Some(0));
assert_eq!(data.guard_rf_failure_routine, Some(0));
assert_eq!(data.guard_rf_failure_routine_function_pointer, Some(0));
assert_eq!(data.dynamic_value_reloc_table_offset, Some(0));
assert_eq!(data.dynamic_value_reloc_table_section, Some(0));
assert_eq!(data.reserved2, Some(0));
assert_eq!(data.guard_rf_verify_stack_pointer_function_pointer, Some(0));
assert_eq!(data.hot_patch_table_offset, Some(0));
assert_eq!(data.reserved3, Some(0));
assert_eq!(data.enclave_configuration_pointer, Some(0));
assert_eq!(data.volatile_metadata_pointer, Some(0));
assert_eq!(data.guard_eh_continuation_table, Some(0));
assert_eq!(data.guard_eh_continuation_count, Some(0));
assert_eq!(data.guard_xfg_check_function_pointer, Some(0));
assert_eq!(data.guard_xfg_dispatch_function_pointer, Some(0));
assert_eq!(data.guard_xfg_table_dispatch_function_pointer, Some(0));
assert_eq!(data.cast_guard_os_determined_failure_mode, Some(0x41dcd4));
assert_eq!(data.guard_memcpy_function_pointer, Some(0));
}
}