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