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