Line data Source code
1 : use super::chpe_metadata_arm64;
2 : use super::chpe_metadata_x86;
3 : use super::dynamic_relocation::DynamicRelocation;
4 : use super::enclave_configuration::EnclaveConfiguration;
5 : use super::volatile_metadata::VolatileMetadata;
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 117 : pub fn size(&self) -> u32 {
32 117 : self.ptr.size()
33 117 : }
34 :
35 : /// The date and time stamp value
36 117 : pub fn timedatestamp(&self) -> u32 {
37 117 : self.ptr.timedatestamp()
38 117 : }
39 :
40 : /// Major version
41 117 : pub fn major_version(&self) -> u16 {
42 117 : self.ptr.major_version()
43 117 : }
44 :
45 : /// Minor version
46 117 : pub fn minor_version(&self) -> u16 {
47 117 : self.ptr.minor_version()
48 117 : }
49 :
50 : /// The global flags that control system behavior. For more information, see `Gflags.exe`.
51 117 : pub fn global_flags_clear(&self) -> u32 {
52 117 : self.ptr.global_flags_clear()
53 117 : }
54 :
55 : /// The global flags that control system behavior. For more information, see `Gflags.exe`.
56 117 : pub fn global_flags_set(&self) -> u32 {
57 117 : self.ptr.global_flags_set()
58 117 : }
59 :
60 : /// The critical section default time-out value.
61 117 : pub fn critical_section_default_timeout(&self) -> u32 {
62 117 : self.ptr.critical_section_default_timeout()
63 117 : }
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 117 : pub fn decommit_free_block_threshold(&self) -> u64 {
68 117 : self.ptr.decommit_free_block_threshold()
69 117 : }
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 117 : pub fn decommit_total_free_threshold(&self) -> u64 {
74 117 : self.ptr.decommit_total_free_threshold()
75 117 : }
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 117 : pub fn lock_prefix_table(&self) -> u64 {
80 117 : self.ptr.lock_prefix_table()
81 117 : }
82 :
83 : /// The maximum allocation size, in bytes. This member is obsolete and is used only for
84 : /// debugging purposes.
85 117 : pub fn maximum_allocation_size(&self) -> u64 {
86 117 : self.ptr.maximum_allocation_size()
87 117 : }
88 :
89 : /// The maximum block size that can be allocated from heap segments, in bytes.
90 117 : pub fn virtual_memory_threshold(&self) -> u64 {
91 117 : self.ptr.virtual_memory_threshold()
92 117 : }
93 :
94 : /// The process affinity mask. For more information, see `GetProcessAffinityMask`. This member
95 : /// is available only for `.exe` files.
96 117 : pub fn process_affinity_mask(&self) -> u64 {
97 117 : self.ptr.process_affinity_mask()
98 117 : }
99 :
100 : /// The process heap flags. For more information, see `HeapCreate`.
101 117 : pub fn process_heap_flags(&self) -> u32 {
102 117 : self.ptr.process_heap_flags()
103 117 : }
104 :
105 : /// The service pack version.
106 117 : pub fn csd_version(&self) -> u16 {
107 117 : self.ptr.csd_version()
108 117 : }
109 :
110 : /// See: [`LoadConfiguration::dependent_load_flags`]
111 117 : pub fn reserved1(&self) -> u16 {
112 117 : self.ptr.reserved1()
113 117 : }
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 117 : pub fn dependent_load_flags(&self) -> u16 {
121 117 : self.ptr.dependent_load_flags()
122 117 : }
123 :
124 : /// Reserved for use by the system.
125 117 : pub fn editlist(&self) -> u64 {
126 117 : self.ptr.editlist()
127 117 : }
128 :
129 : /// A pointer to a cookie that is used by Visual C++ or GS implementation.
130 117 : pub fn security_cookie(&self) -> u64 {
131 117 : self.ptr.security_cookie()
132 117 : }
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 117 : pub fn se_handler_table(&self) -> Option<u64> {
137 117 : to_opt!(&lief_ffi::PE_LoadConfiguration::se_handler_table, &self);
138 117 : }
139 :
140 : /// The count of unique handlers in the table. This member is available only for x86.
141 117 : pub fn se_handler_count(&self) -> Option<u64> {
142 117 : to_opt!(&lief_ffi::PE_LoadConfiguration::se_handler_count, &self);
143 117 : }
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 117 : pub fn guard_cf_check_function_pointer(&self) -> Option<u64> {
152 117 : to_opt!(
153 117 : &lief_ffi::PE_LoadConfiguration::guard_cf_check_function_pointer,
154 117 : &self
155 117 : );
156 117 : }
157 :
158 : /// The VA where Control Flow Guard dispatch-function pointer is stored.
159 117 : pub fn guard_cf_dispatch_function_pointer(&self) -> Option<u64> {
160 117 : to_opt!(
161 117 : &lief_ffi::PE_LoadConfiguration::guard_cf_dispatch_function_pointer,
162 117 : &self
163 117 : );
164 117 : }
165 :
166 : /// The VA of the sorted table of RVAs of each Control Flow Guard function in the image.
167 117 : pub fn guard_cf_function_table(&self) -> Option<u64> {
168 117 : to_opt!(
169 117 : &lief_ffi::PE_LoadConfiguration::guard_cf_function_table,
170 117 : &self
171 117 : );
172 117 : }
173 :
174 : /// The count of unique RVAs in the [`LoadConfiguration::guard_cf_function_table`] table.
175 117 : pub fn guard_cf_function_count(&self) -> Option<u64> {
176 117 : to_opt!(
177 117 : &lief_ffi::PE_LoadConfiguration::guard_cf_function_count,
178 117 : &self
179 117 : );
180 117 : }
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 117 : pub fn guard_flags(&self) -> Option<ImageGuardFlags> {
190 117 : to_conv_opt!(
191 117 : &lief_ffi::PE_LoadConfiguration::guard_flags,
192 117 : &self,
193 117 : |e: u32| ImageGuardFlags::from(e)
194 : );
195 117 : }
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 117 : pub fn guard_address_taken_iat_entry_table(&self) -> Option<u64> {
204 117 : to_opt!(
205 117 : &lief_ffi::PE_LoadConfiguration::guard_address_taken_iat_entry_table,
206 117 : &self
207 117 : );
208 117 : }
209 :
210 : /// The count of unique RVAs in the table pointed by
211 : /// [`LoadConfiguration::guard_address_taken_iat_entry_table`].
212 117 : pub fn guard_address_taken_iat_entry_count(&self) -> Option<u64> {
213 117 : to_opt!(
214 117 : &lief_ffi::PE_LoadConfiguration::guard_address_taken_iat_entry_count,
215 117 : &self
216 117 : );
217 117 : }
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 117 : pub fn guard_long_jump_target_table(&self) -> Option<u64> {
227 117 : to_opt!(
228 117 : &lief_ffi::PE_LoadConfiguration::guard_long_jump_target_table,
229 117 : &self
230 117 : );
231 117 : }
232 :
233 : /// The count of unique RVAs in the table pointed by
234 : /// [`LoadConfiguration::guard_long_jump_target_table`].
235 117 : pub fn guard_long_jump_target_count(&self) -> Option<u64> {
236 117 : to_opt!(
237 117 : &lief_ffi::PE_LoadConfiguration::guard_long_jump_target_count,
238 117 : &self
239 117 : );
240 117 : }
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 117 : pub fn dynamic_value_reloc_table(&self) -> Option<u64> {
250 117 : to_opt!(
251 117 : &lief_ffi::PE_LoadConfiguration::dynamic_value_reloc_table,
252 117 : &self
253 117 : );
254 117 : }
255 :
256 : /// Alias for [`LoadConfiguration::chpe_metadata_pointer`]
257 117 : pub fn hybrid_metadata_pointer(&self) -> Option<u64> {
258 117 : to_opt!(
259 117 : &lief_ffi::PE_LoadConfiguration::hybrid_metadata_pointer,
260 117 : &self
261 117 : );
262 117 : }
263 :
264 : /// VA to the extra Compiled Hybrid Portable Executable (CHPE) metadata.
265 117 : pub fn chpe_metadata_pointer(&self) -> Option<u64> {
266 117 : to_opt!(
267 117 : &lief_ffi::PE_LoadConfiguration::chpe_metadata_pointer,
268 117 : &self
269 117 : );
270 117 : }
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 117 : pub fn guard_rf_failure_routine(&self) -> Option<u64> {
279 117 : to_opt!(
280 117 : &lief_ffi::PE_LoadConfiguration::guard_rf_failure_routine,
281 117 : &self
282 117 : );
283 117 : }
284 :
285 : /// VA of the failure routine `fptr`.
286 117 : pub fn guard_rf_failure_routine_function_pointer(&self) -> Option<u64> {
287 117 : to_opt!(
288 117 : &lief_ffi::PE_LoadConfiguration::guard_rf_failure_routine_function_pointer,
289 117 : &self
290 117 : );
291 117 : }
292 :
293 : /// Offset of dynamic relocation table relative to the relocation table
294 117 : pub fn dynamic_value_reloctable_offset(&self) -> Option<u32> {
295 117 : to_opt!(
296 117 : &lief_ffi::PE_LoadConfiguration::dynamic_value_reloctable_offset,
297 117 : &self
298 117 : );
299 117 : }
300 :
301 : /// The section index of the dynamic value relocation table
302 117 : pub fn dynamic_value_reloctable_section(&self) -> Option<u16> {
303 117 : to_opt!(
304 117 : &lief_ffi::PE_LoadConfiguration::dynamic_value_reloctable_section,
305 117 : &self
306 117 : );
307 117 : }
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 117 : pub fn reserved2(&self) -> Option<u16> {
316 117 : to_opt!(&lief_ffi::PE_LoadConfiguration::reserved2, &self);
317 117 : }
318 :
319 : /// VA of the Function verifying the stack pointer
320 117 : pub fn guard_rf_verify_stackpointer_function_pointer(&self) -> Option<u64> {
321 117 : to_opt!(
322 117 : &lief_ffi::PE_LoadConfiguration::guard_rf_verify_stackpointer_function_pointer,
323 117 : &self
324 117 : );
325 117 : }
326 :
327 117 : pub fn hotpatch_table_offset(&self) -> Option<u32> {
328 117 : to_opt!(
329 117 : &lief_ffi::PE_LoadConfiguration::hotpatch_table_offset,
330 117 : &self
331 117 : );
332 117 : }
333 :
334 117 : pub fn reserved3(&self) -> Option<u32> {
335 117 : to_opt!(&lief_ffi::PE_LoadConfiguration::reserved3, &self);
336 117 : }
337 :
338 117 : pub fn enclave_config(&self) -> Option<EnclaveConfiguration<'_>> {
339 117 : into_optional(self.ptr.enclave_config())
340 117 : }
341 :
342 117 : pub fn enclave_configuration_ptr(&self) -> Option<u64> {
343 117 : to_opt!(
344 117 : &lief_ffi::PE_LoadConfiguration::enclave_configuration_ptr,
345 117 : &self
346 117 : );
347 117 : }
348 :
349 117 : pub fn volatile_metadata_pointer(&self) -> Option<u64> {
350 117 : to_opt!(
351 104 : &lief_ffi::PE_LoadConfiguration::volatile_metadata_pointer,
352 104 : &self
353 104 : );
354 117 : }
355 :
356 117 : pub fn volatile_metadata(&self) -> Option<VolatileMetadata<'_>> {
357 117 : into_optional(self.ptr.volatile_metadata())
358 117 : }
359 :
360 117 : pub fn guard_eh_continuation_table(&self) -> Option<u64> {
361 117 : to_opt!(
362 104 : &lief_ffi::PE_LoadConfiguration::guard_eh_continuation_table,
363 104 : &self
364 104 : );
365 117 : }
366 :
367 117 : pub fn guard_eh_continuation_count(&self) -> Option<u64> {
368 117 : to_opt!(
369 104 : &lief_ffi::PE_LoadConfiguration::guard_eh_continuation_count,
370 104 : &self
371 104 : );
372 117 : }
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 117 : pub fn guard_xfg_check_function_pointer(&self) -> Option<u64> {
381 117 : to_opt!(
382 104 : &lief_ffi::PE_LoadConfiguration::guard_xfg_check_function_pointer,
383 104 : &self
384 104 : );
385 117 : }
386 :
387 117 : pub fn guard_xfg_dispatch_function_pointer(&self) -> Option<u64> {
388 117 : to_opt!(
389 104 : &lief_ffi::PE_LoadConfiguration::guard_xfg_dispatch_function_pointer,
390 104 : &self
391 104 : );
392 117 : }
393 :
394 117 : pub fn guard_xfg_table_dispatch_function_pointer(&self) -> Option<u64> {
395 117 : to_opt!(
396 104 : &lief_ffi::PE_LoadConfiguration::guard_xfg_table_dispatch_function_pointer,
397 104 : &self
398 104 : );
399 117 : }
400 :
401 117 : pub fn cast_guard_os_determined_failure_mode(&self) -> Option<u64> {
402 117 : to_opt!(
403 104 : &lief_ffi::PE_LoadConfiguration::cast_guard_os_determined_failure_mode,
404 104 : &self
405 104 : );
406 117 : }
407 :
408 117 : pub fn guard_memcpy_function_pointer(&self) -> Option<u64> {
409 117 : to_opt!(
410 78 : &lief_ffi::PE_LoadConfiguration::guard_memcpy_function_pointer,
411 78 : &self
412 78 : );
413 117 : }
414 :
415 117 : pub fn uma_function_pointers(&self) -> Option<u64> {
416 117 : to_opt!(
417 0 : &lief_ffi::PE_LoadConfiguration::uma_function_pointers,
418 0 : &self
419 0 : );
420 117 : }
421 :
422 : /// Set the characteristics value
423 0 : pub fn set_characteristics(&mut self, value: u32) {
424 0 : self.ptr.pin_mut().set_characteristics(value);
425 0 : }
426 :
427 : /// Set the size value
428 0 : pub fn set_size(&mut self, value: u32) {
429 0 : self.ptr.pin_mut().set_size(value);
430 0 : }
431 :
432 : /// Set the timedatestamp value
433 0 : pub fn set_timedatestamp(&mut self, value: u32) {
434 0 : self.ptr.pin_mut().set_timedatestamp(value);
435 0 : }
436 :
437 : /// Set the major version
438 0 : pub fn set_major_version(&mut self, value: u16) {
439 0 : self.ptr.pin_mut().set_major_version(value);
440 0 : }
441 :
442 : /// Set the minor version
443 0 : pub fn set_minor_version(&mut self, value: u16) {
444 0 : self.ptr.pin_mut().set_minor_version(value);
445 0 : }
446 :
447 : /// Set the global flags to clear
448 0 : pub fn set_global_flags_clear(&mut self, value: u32) {
449 0 : self.ptr.pin_mut().set_global_flags_clear(value);
450 0 : }
451 :
452 : /// Set the global flags to set
453 0 : pub fn set_global_flags_set(&mut self, value: u32) {
454 0 : self.ptr.pin_mut().set_global_flags_set(value);
455 0 : }
456 :
457 : /// Set the critical section default timeout
458 0 : pub fn set_critical_section_default_timeout(&mut self, value: u32) {
459 0 : self.ptr
460 0 : .pin_mut()
461 0 : .set_critical_section_default_timeout(value);
462 0 : }
463 :
464 : /// Set the decommit free block threshold
465 0 : pub fn set_decommit_free_block_threshold(&mut self, value: u64) {
466 0 : self.ptr.pin_mut().set_decommit_free_block_threshold(value);
467 0 : }
468 :
469 : /// Set the decommit total free threshold
470 0 : pub fn set_decommit_total_free_threshold(&mut self, value: u64) {
471 0 : self.ptr.pin_mut().set_decommit_total_free_threshold(value);
472 0 : }
473 :
474 : /// Set the lock prefix table VA
475 0 : pub fn set_lock_prefix_table(&mut self, value: u64) {
476 0 : self.ptr.pin_mut().set_lock_prefix_table(value);
477 0 : }
478 :
479 : /// Set the maximum allocation size
480 0 : pub fn set_maximum_allocation_size(&mut self, value: u64) {
481 0 : self.ptr.pin_mut().set_maximum_allocation_size(value);
482 0 : }
483 :
484 : /// Set the virtual memory threshold
485 0 : pub fn set_virtual_memory_threshold(&mut self, value: u64) {
486 0 : self.ptr.pin_mut().set_virtual_memory_threshold(value);
487 0 : }
488 :
489 : /// Set the process affinity mask
490 0 : pub fn set_process_affinity_mask(&mut self, value: u64) {
491 0 : self.ptr.pin_mut().set_process_affinity_mask(value);
492 0 : }
493 :
494 : /// Set the process heap flags
495 0 : pub fn set_process_heap_flags(&mut self, value: u32) {
496 0 : self.ptr.pin_mut().set_process_heap_flags(value);
497 0 : }
498 :
499 : /// Set the CSD version
500 0 : pub fn set_csd_version(&mut self, value: u16) {
501 0 : self.ptr.pin_mut().set_csd_version(value);
502 0 : }
503 :
504 : /// Set reserved1
505 0 : pub fn set_reserved1(&mut self, value: u16) {
506 0 : self.ptr.pin_mut().set_reserved1(value);
507 0 : }
508 :
509 : /// Set the dependent load flags
510 0 : pub fn set_dependent_load_flags(&mut self, value: u16) {
511 0 : self.ptr.pin_mut().set_dependent_load_flags(value);
512 0 : }
513 :
514 : /// Set the editlist VA
515 0 : pub fn set_editlist(&mut self, value: u32) {
516 0 : self.ptr.pin_mut().set_editlist(value);
517 0 : }
518 :
519 : /// Set the security cookie VA
520 0 : pub fn set_security_cookie(&mut self, value: u64) {
521 0 : self.ptr.pin_mut().set_security_cookie(value);
522 0 : }
523 :
524 : /// Set the SE handler table VA
525 0 : pub fn set_se_handler_table(&mut self, value: u64) {
526 0 : self.ptr.pin_mut().set_se_handler_table(value);
527 0 : }
528 :
529 : /// Set the SE handler count
530 0 : pub fn set_se_handler_count(&mut self, value: u64) {
531 0 : self.ptr.pin_mut().set_se_handler_count(value);
532 0 : }
533 :
534 : /// Set the guard CF check function pointer VA
535 0 : pub fn set_guard_cf_check_function_pointer(&mut self, value: u64) {
536 0 : self.ptr
537 0 : .pin_mut()
538 0 : .set_guard_cf_check_function_pointer(value);
539 0 : }
540 :
541 : /// Set the guard CF dispatch function pointer VA
542 0 : pub fn set_guard_cf_dispatch_function_pointer(&mut self, value: u64) {
543 0 : self.ptr
544 0 : .pin_mut()
545 0 : .set_guard_cf_dispatch_function_pointer(value);
546 0 : }
547 :
548 : /// Set the guard CF function table VA
549 0 : pub fn set_guard_cf_function_table(&mut self, value: u64) {
550 0 : self.ptr.pin_mut().set_guard_cf_function_table(value);
551 0 : }
552 :
553 : /// Set the guard CF function count
554 0 : pub fn set_guard_cf_function_count(&mut self, value: u64) {
555 0 : self.ptr.pin_mut().set_guard_cf_function_count(value);
556 0 : }
557 :
558 : /// Set the guard flags
559 0 : pub fn set_guard_flags(&mut self, flags: ImageGuardFlags) {
560 0 : self.ptr.pin_mut().set_guard_flags(flags.bits());
561 0 : }
562 :
563 : /// Set the guard address taken IAT entry table VA
564 0 : pub fn set_guard_address_taken_iat_entry_table(&mut self, value: u64) {
565 0 : self.ptr
566 0 : .pin_mut()
567 0 : .set_guard_address_taken_iat_entry_table(value);
568 0 : }
569 :
570 : /// Set the guard address taken IAT entry count
571 0 : pub fn set_guard_address_taken_iat_entry_count(&mut self, value: u64) {
572 0 : self.ptr
573 0 : .pin_mut()
574 0 : .set_guard_address_taken_iat_entry_count(value);
575 0 : }
576 :
577 : /// Set the guard long jump target table VA
578 0 : pub fn set_guard_long_jump_target_table(&mut self, value: u64) {
579 0 : self.ptr.pin_mut().set_guard_long_jump_target_table(value);
580 0 : }
581 :
582 : /// Set the guard long jump target count
583 0 : pub fn set_guard_long_jump_target_count(&mut self, value: u64) {
584 0 : self.ptr.pin_mut().set_guard_long_jump_target_count(value);
585 0 : }
586 :
587 : /// Set the dynamic value relocation table VA
588 0 : pub fn set_dynamic_value_reloc_table(&mut self, value: u64) {
589 0 : self.ptr.pin_mut().set_dynamic_value_reloc_table(value);
590 0 : }
591 :
592 : /// Set the hybrid metadata pointer VA
593 0 : pub fn set_hybrid_metadata_pointer(&mut self, value: u64) {
594 0 : self.ptr.pin_mut().set_hybrid_metadata_pointer(value);
595 0 : }
596 :
597 : /// Set the guard RF failure routine VA
598 0 : pub fn set_guard_rf_failure_routine(&mut self, value: u64) {
599 0 : self.ptr.pin_mut().set_guard_rf_failure_routine(value);
600 0 : }
601 :
602 : /// Set the guard RF failure routine function pointer VA
603 0 : pub fn set_guard_rf_failure_routine_function_pointer(&mut self, value: u64) {
604 0 : self.ptr
605 0 : .pin_mut()
606 0 : .set_guard_rf_failure_routine_function_pointer(value);
607 0 : }
608 :
609 : /// Set the dynamic value relocation table offset
610 0 : pub fn set_dynamic_value_reloctable_offset(&mut self, value: u32) {
611 0 : self.ptr
612 0 : .pin_mut()
613 0 : .set_dynamic_value_reloctable_offset(value);
614 0 : }
615 :
616 : /// Set the dynamic value relocation table section
617 0 : pub fn set_dynamic_value_reloctable_section(&mut self, value: u16) {
618 0 : self.ptr
619 0 : .pin_mut()
620 0 : .set_dynamic_value_reloctable_section(value);
621 0 : }
622 :
623 : /// Set reserved2
624 0 : pub fn set_reserved2(&mut self, value: u16) {
625 0 : self.ptr.pin_mut().set_reserved2(value);
626 0 : }
627 :
628 : /// Set the guard RF verify stack pointer function pointer VA
629 0 : pub fn set_guard_rf_verify_stackpointer_function_pointer(&mut self, value: u64) {
630 0 : self.ptr
631 0 : .pin_mut()
632 0 : .set_guard_rf_verify_stackpointer_function_pointer(value);
633 0 : }
634 :
635 : /// Set the hotpatch table offset
636 0 : pub fn set_hotpatch_table_offset(&mut self, value: u32) {
637 0 : self.ptr.pin_mut().set_hotpatch_table_offset(value);
638 0 : }
639 :
640 : /// Set reserved3
641 0 : pub fn set_reserved3(&mut self, value: u32) {
642 0 : self.ptr.pin_mut().set_reserved3(value);
643 0 : }
644 :
645 : /// Set the enclave configuration pointer VA
646 0 : pub fn set_enclave_configuration_ptr(&mut self, value: u64) {
647 0 : self.ptr.pin_mut().set_enclave_configuration_ptr(value);
648 0 : }
649 :
650 : /// Set the volatile metadata pointer VA
651 0 : pub fn set_volatile_metadata_pointer(&mut self, value: u64) {
652 0 : self.ptr.pin_mut().set_volatile_metadata_pointer(value);
653 0 : }
654 :
655 : /// Set the guard EH continuation table VA
656 0 : pub fn set_guard_eh_continuation_table(&mut self, value: u64) {
657 0 : self.ptr.pin_mut().set_guard_eh_continuation_table(value);
658 0 : }
659 :
660 : /// Set the guard EH continuation count
661 0 : pub fn set_guard_eh_continuation_count(&mut self, value: u64) {
662 0 : self.ptr.pin_mut().set_guard_eh_continuation_count(value);
663 0 : }
664 :
665 : /// Set the guard XFG check function pointer VA
666 0 : pub fn set_guard_xfg_check_function_pointer(&mut self, value: u64) {
667 0 : self.ptr
668 0 : .pin_mut()
669 0 : .set_guard_xfg_check_function_pointer(value);
670 0 : }
671 :
672 : /// Set the guard XFG dispatch function pointer VA
673 0 : pub fn set_guard_xfg_dispatch_function_pointer(&mut self, value: u64) {
674 0 : self.ptr
675 0 : .pin_mut()
676 0 : .set_guard_xfg_dispatch_function_pointer(value);
677 0 : }
678 :
679 : /// Set the guard XFG table dispatch function pointer VA
680 0 : pub fn set_guard_xfg_table_dispatch_function_pointer(&mut self, value: u64) {
681 0 : self.ptr
682 0 : .pin_mut()
683 0 : .set_guard_xfg_table_dispatch_function_pointer(value);
684 0 : }
685 :
686 : /// Set the CastGuard OS determined failure mode VA
687 0 : pub fn set_cast_guard_os_determined_failure_mode(&mut self, value: u64) {
688 0 : self.ptr
689 0 : .pin_mut()
690 0 : .set_cast_guard_os_determined_failure_mode(value);
691 0 : }
692 :
693 : /// Set the guard memcpy function pointer VA
694 0 : pub fn set_guard_memcpy_function_pointer(&mut self, value: u64) {
695 0 : self.ptr.pin_mut().set_guard_memcpy_function_pointer(value);
696 0 : }
697 :
698 : /// Set the UMA function pointers VA
699 0 : pub fn set_uma_function_pointers(&mut self, value: u64) {
700 0 : self.ptr.pin_mut().set_uma_function_pointers(value);
701 0 : }
702 : }
703 :
704 : impl<'a> FromFFI<ffi::PE_LoadConfiguration> for LoadConfiguration<'a> {
705 117 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_LoadConfiguration>) -> Self {
706 117 : Self {
707 117 : ptr,
708 117 : _owner: PhantomData,
709 117 : }
710 117 : }
711 : }
712 :
713 : impl std::fmt::Debug for LoadConfiguration<'_> {
714 117 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
715 117 : f.debug_struct("LoadConfiguration")
716 117 : .field("size", &self.size())
717 117 : .field("timedatestamp", &self.timedatestamp())
718 117 : .field("major_version", &self.major_version())
719 117 : .field("minor_version", &self.minor_version())
720 117 : .field("global_flags_clear", &self.global_flags_clear())
721 117 : .field("global_flags_set", &self.global_flags_set())
722 117 : .field(
723 117 : "critical_section_default_timeout",
724 117 : &self.critical_section_default_timeout(),
725 117 : )
726 117 : .field(
727 117 : "decommit_free_block_threshold",
728 117 : &self.decommit_free_block_threshold(),
729 117 : )
730 117 : .field(
731 117 : "decommit_total_free_threshold",
732 117 : &self.decommit_total_free_threshold(),
733 117 : )
734 117 : .field("lock_prefix_table", &self.lock_prefix_table())
735 117 : .field("maximum_allocation_size", &self.maximum_allocation_size())
736 117 : .field("virtual_memory_threshold", &self.virtual_memory_threshold())
737 117 : .field("process_affinity_mask", &self.process_affinity_mask())
738 117 : .field("process_heap_flags", &self.process_heap_flags())
739 117 : .field("csd_version", &self.csd_version())
740 117 : .field("reserved1", &self.reserved1())
741 117 : .field("dependent_load_flags", &self.dependent_load_flags())
742 117 : .field("editlist", &self.editlist())
743 117 : .field("security_cookie", &self.security_cookie())
744 117 : .field("se_handler_table", &self.se_handler_table())
745 117 : .field("se_handler_count", &self.se_handler_count())
746 117 : .field(
747 117 : "guard_cf_check_function_pointer",
748 117 : &self.guard_cf_check_function_pointer(),
749 117 : )
750 117 : .field(
751 117 : "guard_cf_dispatch_function_pointer",
752 117 : &self.guard_cf_dispatch_function_pointer(),
753 117 : )
754 117 : .field("guard_cf_function_table", &self.guard_cf_function_table())
755 117 : .field("guard_cf_function_count", &self.guard_cf_function_count())
756 117 : .field("guard_flags", &self.guard_flags())
757 117 : .field(
758 117 : "guard_address_taken_iat_entry_table",
759 117 : &self.guard_address_taken_iat_entry_table(),
760 117 : )
761 117 : .field(
762 117 : "guard_address_taken_iat_entry_count",
763 117 : &self.guard_address_taken_iat_entry_count(),
764 117 : )
765 117 : .field(
766 117 : "guard_long_jump_target_table",
767 117 : &self.guard_long_jump_target_table(),
768 117 : )
769 117 : .field(
770 117 : "guard_long_jump_target_count",
771 117 : &self.guard_long_jump_target_count(),
772 117 : )
773 117 : .field(
774 117 : "dynamic_value_reloc_table",
775 117 : &self.dynamic_value_reloc_table(),
776 117 : )
777 117 : .field("hybrid_metadata_pointer", &self.hybrid_metadata_pointer())
778 117 : .field("chpe_metadata_pointer", &self.chpe_metadata_pointer())
779 117 : .field("guard_rf_failure_routine", &self.guard_rf_failure_routine())
780 117 : .field(
781 117 : "guard_rf_failure_routine_function_pointer",
782 117 : &self.guard_rf_failure_routine_function_pointer(),
783 117 : )
784 117 : .field(
785 117 : "dynamic_value_reloctable_offset",
786 117 : &self.dynamic_value_reloctable_offset(),
787 117 : )
788 117 : .field(
789 117 : "dynamic_value_reloctable_section",
790 117 : &self.dynamic_value_reloctable_section(),
791 117 : )
792 117 : .field("reserved2", &self.reserved2())
793 117 : .field(
794 117 : "guard_rf_verify_stackpointer_function_pointer",
795 117 : &self.guard_rf_verify_stackpointer_function_pointer(),
796 117 : )
797 117 : .field("hotpatch_table_offset", &self.hotpatch_table_offset())
798 117 : .field("reserved3", &self.reserved3())
799 117 : .field(
800 117 : "enclave_configuration_ptr",
801 117 : &self.enclave_configuration_ptr(),
802 117 : )
803 117 : .field(
804 117 : "volatile_metadata_pointer",
805 117 : &self.volatile_metadata_pointer(),
806 117 : )
807 117 : .field(
808 117 : "guard_eh_continuation_table",
809 117 : &self.guard_eh_continuation_table(),
810 117 : )
811 117 : .field(
812 117 : "guard_eh_continuation_count",
813 117 : &self.guard_eh_continuation_count(),
814 117 : )
815 117 : .field(
816 117 : "guard_xfg_check_function_pointer",
817 117 : &self.guard_xfg_check_function_pointer(),
818 117 : )
819 117 : .field(
820 117 : "guard_xfg_dispatch_function_pointer",
821 117 : &self.guard_xfg_dispatch_function_pointer(),
822 117 : )
823 117 : .field(
824 117 : "guard_xfg_table_dispatch_function_pointer",
825 117 : &self.guard_xfg_table_dispatch_function_pointer(),
826 117 : )
827 117 : .field(
828 117 : "cast_guard_os_determined_failure_mode",
829 117 : &self.cast_guard_os_determined_failure_mode(),
830 117 : )
831 117 : .field(
832 117 : "guard_memcpy_function_pointer",
833 117 : &self.guard_memcpy_function_pointer(),
834 117 : )
835 117 : .field("uma_function_pointers", &self.uma_function_pointers())
836 117 : .finish()
837 117 : }
838 : }
839 :
840 : pub struct GuardFunction<'a> {
841 : ptr: cxx::UniquePtr<ffi::PE_LoadConfiguration_guard_function_t>,
842 : _owner: PhantomData<&'a ffi::PE_LoadConfiguration>,
843 : }
844 :
845 : impl<'a> FromFFI<ffi::PE_LoadConfiguration_guard_function_t> for GuardFunction<'a> {
846 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_LoadConfiguration_guard_function_t>) -> Self {
847 0 : Self {
848 0 : ptr,
849 0 : _owner: PhantomData,
850 0 : }
851 0 : }
852 : }
853 :
854 : impl GuardFunction<'_> {
855 : /// RVA of the function
856 0 : pub fn rva(&self) -> u32 {
857 0 : self.ptr.rva()
858 0 : }
859 :
860 : /// Additional information whose meaning is not officially documented
861 0 : pub fn extra(&self) -> u32 {
862 0 : self.ptr.extra()
863 0 : }
864 : }
865 :
866 : impl std::fmt::Debug for GuardFunction<'_> {
867 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
868 0 : f.debug_struct("GuardFunction")
869 0 : .field("rva", &self.rva())
870 0 : .field("extra", &self.extra())
871 0 : .finish()
872 0 : }
873 : }
874 :
875 0 : bitflags! {
876 117 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
877 0 : pub struct ImageGuardFlags: u32 {
878 0 : const NONE = 0x0;
879 0 :
880 0 : /// Module performs control flow integrity checks using system-supplied
881 0 : /// support.
882 0 : const CF_INSTRUMENTED = 0x100;
883 0 :
884 0 : /// Module performs control flow and write integrity checks.
885 0 : const CFW_INSTRUMENTED = 0x200;
886 0 :
887 0 : /// Module contains valid control flow target metadata.
888 0 : const CF_FUNCTION_TABLE_PRESENT = 0x400;
889 0 :
890 0 : /// Module does not make use of the /GS security cookie.
891 0 : const SECURITY_COOKIE_UNUSED = 0x800;
892 0 :
893 0 : /// Module supports read only delay load IAT.
894 0 : const PROTECT_DELAYLOAD_IAT = 0x1000;
895 0 :
896 0 : /// Delayload import table in its own .didat section (with nothing else in it)
897 0 : /// that can be freely reprotected.
898 0 : const DELAYLOAD_IAT_IN_ITS_OWN_SECTION = 0x2000;
899 0 :
900 0 : /// Module contains suppressed export information. This also infers that the
901 0 : /// address taken IAT table is also present in the load config.
902 0 : const CF_EXPORT_SUPPRESSION_INFO_PRESENT = 0x4000;
903 0 :
904 0 : /// Module enables suppression of exports.
905 0 : const CF_ENABLE_EXPORT_SUPPRESSION = 0x8000;
906 0 :
907 0 : /// Module contains longjmp target information.
908 0 : const CF_LONGJUMP_TABLE_PRESENT = 0x10000;
909 0 :
910 0 : /// Module contains return flow instrumentation and metadata
911 0 : const RF_INSTRUMENTED = 0x20000;
912 0 :
913 0 : /// Module requests that the OS enable return flow protection
914 0 : const RF_ENABLE = 0x40000;
915 0 :
916 0 : /// Module requests that the OS enable return flow protection in strict mode
917 0 : const RF_STRICT = 0x80000;
918 0 :
919 0 : /// Module was built with retpoline support
920 0 : const RETPOLINE_PRESENT = 0x100000;
921 0 :
922 0 : /// Module contains EH continuation target information.
923 0 : const EH_CONTINUATION_TABLE_PRESENT = 0x200000;
924 0 :
925 0 : /// Module was built with xfg (deprecated)
926 0 : const XFG_ENABLED = 0x00800000;
927 0 :
928 0 : /// Module has CastGuard instrumentation present
929 0 : const CASTGUARD_PRESENT = 0x01000000;
930 0 :
931 0 : /// Module has Guarded Memcpy instrumentation present
932 0 : const MEMCPY_PRESENT = 0x02000000;
933 0 : }
934 0 : }
935 :
936 : impl From<u32> for ImageGuardFlags {
937 117 : fn from(value: u32) -> Self {
938 117 : ImageGuardFlags::from_bits_truncate(value)
939 117 : }
940 : }
941 : impl From<ImageGuardFlags> for u32 {
942 0 : fn from(value: ImageGuardFlags) -> Self {
943 0 : value.bits()
944 0 : }
945 : }
946 : impl std::fmt::Display for ImageGuardFlags {
947 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
948 0 : bitflags::parser::to_writer(self, f)
949 0 : }
950 : }
951 :
952 0 : #[derive(Debug)]
953 : pub enum CHPEMetadata<'a> {
954 : ARM64(chpe_metadata_arm64::CHPEMetadata<'a>),
955 : X86(chpe_metadata_x86::CHPEMetadata<'a>),
956 : }
957 :
958 : impl<'a> FromFFI<ffi::PE_CHPEMetadata> for CHPEMetadata<'a> {
959 0 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_CHPEMetadata>) -> Self {
960 0 : unsafe {
961 0 : let obj_ref = ffi_entry.as_ref().unwrap();
962 0 : if ffi::PE_CHPEMetadataARM64::classof(obj_ref) {
963 0 : let raw = {
964 0 : type From = cxx::UniquePtr<ffi::PE_CHPEMetadata>;
965 0 : type To = cxx::UniquePtr<ffi::PE_CHPEMetadataARM64>;
966 0 : std::mem::transmute::<From, To>(ffi_entry)
967 0 : };
968 0 : CHPEMetadata::ARM64(chpe_metadata_arm64::CHPEMetadata::from_ffi(raw))
969 0 : } else if ffi::PE_CHPEMetadataX86::classof(obj_ref) {
970 0 : let raw = {
971 0 : type From = cxx::UniquePtr<ffi::PE_CHPEMetadata>;
972 0 : type To = cxx::UniquePtr<ffi::PE_CHPEMetadataX86>;
973 0 : std::mem::transmute::<From, To>(ffi_entry)
974 0 : };
975 0 : CHPEMetadata::X86(chpe_metadata_x86::CHPEMetadata::from_ffi(raw))
976 : } else {
977 0 : panic!("unsupported architecture");
978 : }
979 : }
980 0 : }
981 : }
982 :
983 : /// Trait shared by all architecture-specific CHPEMetadata
984 : pub trait AsCHPEMetadata {
985 : #[doc(hidden)]
986 : fn as_generic(&self) -> &ffi::PE_CHPEMetadata;
987 :
988 : /// Version of the structure
989 0 : fn version(&self) -> u32 {
990 0 : self.as_generic().version()
991 0 : }
992 : }
993 :
994 : impl std::fmt::Display for &dyn AsCHPEMetadata {
995 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
996 0 : write!(f, "{}", self.as_generic().to_string())
997 0 : }
998 : }
999 :
1000 : impl AsCHPEMetadata for CHPEMetadata<'_> {
1001 0 : fn as_generic(&self) -> &ffi::PE_CHPEMetadata {
1002 0 : match &self {
1003 0 : CHPEMetadata::ARM64(entry) => entry.as_generic(),
1004 :
1005 0 : CHPEMetadata::X86(entry) => entry.as_generic(),
1006 : }
1007 0 : }
1008 : }
1009 :
1010 0 : declare_iterator!(
1011 0 : GuardCFFunctions,
1012 0 : GuardFunction<'a>,
1013 0 : ffi::PE_LoadConfiguration_guard_function_t,
1014 0 : ffi::PE_LoadConfiguration,
1015 0 : ffi::PE_LoadConfiguration_it_guard_cf_functions
1016 0 : );
1017 :
1018 0 : declare_iterator!(
1019 0 : GuardAddressTakenIATEntries,
1020 0 : GuardFunction<'a>,
1021 0 : ffi::PE_LoadConfiguration_guard_function_t,
1022 0 : ffi::PE_LoadConfiguration,
1023 0 : ffi::PE_LoadConfiguration_it_guard_address_taken_iat_entries
1024 0 : );
1025 :
1026 0 : declare_iterator!(
1027 0 : GuardLongJumpTargets,
1028 0 : GuardFunction<'a>,
1029 0 : ffi::PE_LoadConfiguration_guard_function_t,
1030 0 : ffi::PE_LoadConfiguration,
1031 0 : ffi::PE_LoadConfiguration_it_guard_long_jump_targets
1032 0 : );
1033 :
1034 0 : declare_iterator!(
1035 0 : GuardEhContinuationFunctions,
1036 0 : GuardFunction<'a>,
1037 0 : ffi::PE_LoadConfiguration_guard_function_t,
1038 0 : ffi::PE_LoadConfiguration,
1039 0 : ffi::PE_LoadConfiguration_it_guard_eh_continuation
1040 0 : );
1041 :
1042 0 : declare_iterator!(
1043 0 : DynamicRelocations,
1044 0 : DynamicRelocation<'a>,
1045 0 : ffi::PE_DynamicRelocation,
1046 0 : ffi::PE_LoadConfiguration,
1047 0 : ffi::PE_LoadConfiguration_it_dynamic_relocations
1048 0 : );
|