Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use crate::common::{into_optional, FromFFI};
4 : use crate::pe::Relocation;
5 : use crate::{declare_fwd_iterator, declare_iterator, to_slice};
6 : use std::marker::PhantomData;
7 :
8 : /// This enum wraps the different fixups that can be associated with a
9 : /// [`crate::pe::DynamicRelocation`]
10 0 : #[derive(Debug)]
11 : pub enum DynamicFixup<'a> {
12 : /// Entry when [`crate::pe::dynamic_relocation::AsDynamicRelocation::symbol`] is not
13 : /// a special value
14 : Generic(Generic<'a>),
15 :
16 : /// Entry when [`crate::pe::dynamic_relocation::AsDynamicRelocation::symbol`] is set
17 : /// to [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_ARM64X`]
18 : Arm64X(Arm64X<'a>),
19 :
20 : /// Entry when [`crate::pe::dynamic_relocation::AsDynamicRelocation::symbol`] is set
21 : /// to [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_FUNCTION_OVERRIDE`]
22 : FunctionOverride(FunctionOverride<'a>),
23 :
24 : /// Entry when [`crate::pe::dynamic_relocation::AsDynamicRelocation::symbol`] is set
25 : /// to [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_ARM64_KERNEL_IMPORT_CALL_TRANSFER`]
26 : ARM64Kernel(ARM64Kernel<'a>),
27 :
28 : /// Entry when [`crate::pe::dynamic_relocation::AsDynamicRelocation::symbol`] is set
29 : /// to [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_GUARD_IMPORT_CONTROL_TRANSFER`]
30 : ControlTransfer(ControlTransfer<'a>),
31 :
32 : /// Entry when [`crate::pe::dynamic_relocation::AsDynamicRelocation::symbol`] is set
33 : /// to a special value that is not supported by LIEF.
34 : Unknown(Unknown<'a>),
35 : }
36 :
37 : impl<'a> FromFFI<ffi::PE_DynamicFixup> for DynamicFixup<'a> {
38 0 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_DynamicFixup>) -> Self {
39 0 : unsafe {
40 0 : let obj_ref = ffi_entry.as_ref().unwrap();
41 0 : if ffi::PE_DynamicFixupARM64Kernel::classof(obj_ref) {
42 0 : let raw = {
43 0 : type From = cxx::UniquePtr<ffi::PE_DynamicFixup>;
44 0 : type To = cxx::UniquePtr<ffi::PE_DynamicFixupARM64Kernel>;
45 0 : std::mem::transmute::<From, To>(ffi_entry)
46 0 : };
47 0 : DynamicFixup::ARM64Kernel(ARM64Kernel::from_ffi(raw))
48 0 : } else if ffi::PE_DynamicFixupARM64X::classof(obj_ref) {
49 0 : let raw = {
50 0 : type From = cxx::UniquePtr<ffi::PE_DynamicFixup>;
51 0 : type To = cxx::UniquePtr<ffi::PE_DynamicFixupARM64X>;
52 0 : std::mem::transmute::<From, To>(ffi_entry)
53 0 : };
54 0 : DynamicFixup::Arm64X(Arm64X::from_ffi(raw))
55 0 : } else if ffi::PE_DynamicFixupControlTransfer::classof(obj_ref) {
56 0 : let raw = {
57 0 : type From = cxx::UniquePtr<ffi::PE_DynamicFixup>;
58 0 : type To = cxx::UniquePtr<ffi::PE_DynamicFixupControlTransfer>;
59 0 : std::mem::transmute::<From, To>(ffi_entry)
60 0 : };
61 0 : DynamicFixup::ControlTransfer(ControlTransfer::from_ffi(raw))
62 0 : } else if ffi::PE_DynamicFixupGeneric::classof(obj_ref) {
63 0 : let raw = {
64 0 : type From = cxx::UniquePtr<ffi::PE_DynamicFixup>;
65 0 : type To = cxx::UniquePtr<ffi::PE_DynamicFixupGeneric>;
66 0 : std::mem::transmute::<From, To>(ffi_entry)
67 0 : };
68 0 : DynamicFixup::Generic(Generic::from_ffi(raw))
69 0 : } else if ffi::PE_DynamicFixupUnknown::classof(obj_ref) {
70 0 : let raw = {
71 0 : type From = cxx::UniquePtr<ffi::PE_DynamicFixup>;
72 0 : type To = cxx::UniquePtr<ffi::PE_DynamicFixupUnknown>;
73 0 : std::mem::transmute::<From, To>(ffi_entry)
74 0 : };
75 0 : DynamicFixup::Unknown(Unknown::from_ffi(raw))
76 0 : } else if ffi::PE_FunctionOverride::classof(obj_ref) {
77 0 : let raw = {
78 0 : type From = cxx::UniquePtr<ffi::PE_DynamicFixup>;
79 0 : type To = cxx::UniquePtr<ffi::PE_FunctionOverride>;
80 0 : std::mem::transmute::<From, To>(ffi_entry)
81 0 : };
82 0 : DynamicFixup::FunctionOverride(FunctionOverride::from_ffi(raw))
83 : } else {
84 0 : panic!("unsupported version");
85 : }
86 : }
87 0 : }
88 : }
89 :
90 : pub trait AsDynamicFixup {
91 : #[doc(hidden)]
92 : fn as_generic(&self) -> &ffi::PE_DynamicFixup;
93 : }
94 :
95 : impl std::fmt::Display for DynamicFixup<'_> {
96 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
97 0 : match self {
98 0 : DynamicFixup::Generic(fixup) => {
99 0 : write!(f, "{}", fixup.as_generic().to_string())
100 : }
101 :
102 0 : DynamicFixup::Arm64X(fixup) => {
103 0 : write!(f, "{}", fixup.as_generic().to_string())
104 : }
105 :
106 0 : DynamicFixup::FunctionOverride(fixup) => {
107 0 : write!(f, "{}", fixup.as_generic().to_string())
108 : }
109 :
110 0 : DynamicFixup::ARM64Kernel(fixup) => {
111 0 : write!(f, "{}", fixup.as_generic().to_string())
112 : }
113 :
114 0 : DynamicFixup::ControlTransfer(fixup) => {
115 0 : write!(f, "{}", fixup.as_generic().to_string())
116 : }
117 :
118 0 : DynamicFixup::Unknown(fixup) => {
119 0 : write!(f, "{}", fixup.as_generic().to_string())
120 : }
121 : }
122 0 : }
123 : }
124 :
125 : /// This structure represents a generic entry where fixups are regular
126 : /// relocations: [`crate::pe::Relocation`]
127 : pub struct Generic<'a> {
128 : ptr: cxx::UniquePtr<ffi::PE_DynamicFixupGeneric>,
129 : _owner: PhantomData<&'a ffi::PE_DynamicRelocation>,
130 : }
131 :
132 : impl<'a> FromFFI<ffi::PE_DynamicFixupGeneric> for Generic<'a> {
133 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupGeneric>) -> Self {
134 0 : Self {
135 0 : ptr,
136 0 : _owner: PhantomData,
137 0 : }
138 0 : }
139 : }
140 :
141 : impl AsDynamicFixup for Generic<'_> {
142 0 : fn as_generic(&self) -> &ffi::PE_DynamicFixup {
143 0 : self.ptr.as_ref().unwrap().as_ref()
144 0 : }
145 : }
146 :
147 : impl std::fmt::Debug for Generic<'_> {
148 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
149 0 : f.debug_struct("Generic").finish()
150 0 : }
151 : }
152 :
153 : impl std::fmt::Display for Generic<'_> {
154 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
155 0 : write!(f, "{}", self.as_generic().to_string())
156 0 : }
157 : }
158 :
159 : impl Generic<'_> {
160 : /// Iterator over the (regular) relocations
161 0 : pub fn relocations(&self) -> GenericRelocations<'_> {
162 0 : GenericRelocations::new(self.ptr.relocations())
163 0 : }
164 : }
165 :
166 : /// This structure represents the [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_ARM64X`]
167 : /// special value
168 : pub struct Arm64X<'a> {
169 : ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64X>,
170 : _owner: PhantomData<&'a ffi::PE_DynamicRelocation>,
171 : }
172 :
173 : impl<'a> FromFFI<ffi::PE_DynamicFixupARM64X> for Arm64X<'a> {
174 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64X>) -> Self {
175 0 : Self {
176 0 : ptr,
177 0 : _owner: PhantomData,
178 0 : }
179 0 : }
180 : }
181 :
182 : impl AsDynamicFixup for Arm64X<'_> {
183 0 : fn as_generic(&self) -> &ffi::PE_DynamicFixup {
184 0 : self.ptr.as_ref().unwrap().as_ref()
185 0 : }
186 : }
187 :
188 : impl std::fmt::Debug for Arm64X<'_> {
189 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
190 0 : f.debug_struct("Arm64X").finish()
191 0 : }
192 : }
193 :
194 : impl std::fmt::Display for Arm64X<'_> {
195 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
196 0 : write!(f, "{}", self.as_generic().to_string())
197 0 : }
198 : }
199 :
200 : impl Arm64X<'_> {
201 : /// Iterator over the relocations
202 0 : pub fn relocations(&self) -> Arm64XRelocEntries<'_> {
203 0 : Arm64XRelocEntries::new(self.ptr.relocations())
204 0 : }
205 : }
206 :
207 : /// Structure that describes a relocation entry for [`Arm64X`]
208 : pub struct Arm64XRelocEntry<'a> {
209 : ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64X_entry>,
210 : _owner: PhantomData<&'a ffi::PE_DynamicFixupARM64X>,
211 : }
212 :
213 : impl<'a> FromFFI<ffi::PE_DynamicFixupARM64X_entry> for Arm64XRelocEntry<'a> {
214 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64X_entry>) -> Self {
215 0 : Self {
216 0 : ptr,
217 0 : _owner: PhantomData,
218 0 : }
219 0 : }
220 : }
221 :
222 : pub const ARM64X_RELOC_ZERO_FILL: u32 = 0;
223 :
224 : pub const ARM64X_RELOC_VALUE: u32 = 1;
225 :
226 : pub const ARM64X_RELOC_DELTA: u32 = 2;
227 :
228 : impl Arm64XRelocEntry<'_> {
229 : /// RVA where the fixup takes place
230 0 : pub fn rva(&self) -> u32 {
231 0 : self.ptr.rva()
232 0 : }
233 :
234 0 : pub fn size(&self) -> u32 {
235 0 : self.ptr.size()
236 0 : }
237 :
238 : /// If the fixup is [`ARM64X_RELOC_DELTA`], return the associated delta.
239 0 : pub fn value(&self) -> Option<i64> {
240 0 : if self.kind() != ARM64X_RELOC_DELTA {
241 0 : return None;
242 0 : }
243 0 : Some(self.ptr.value())
244 0 : }
245 :
246 : /// If the fixup is [`ARM64X_RELOC_VALUE`], return the associated bytes.
247 0 : pub fn bytes(&self) -> Option<&[u8]> {
248 0 : if self.kind() != ARM64X_RELOC_VALUE {
249 0 : return None;
250 0 : }
251 0 : unsafe {
252 0 : let raw = self.ptr.get_bytes();
253 0 : if raw.size > 0 {
254 0 : return Some(std::slice::from_raw_parts_mut(raw.ptr, raw.size as usize));
255 0 : }
256 0 : Some(&[])
257 : }
258 0 : }
259 :
260 : /// Fixup's kind can be either:
261 : ///
262 : /// - [`ARM64X_RELOC_ZERO_FILL`]
263 : /// - [`ARM64X_RELOC_VALUE`]
264 : /// - [`ARM64X_RELOC_DELTA`]
265 0 : pub fn kind(&self) -> u32 {
266 0 : self.ptr.get_type()
267 0 : }
268 : }
269 :
270 : /// This structure represents the
271 : /// [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_FUNCTION_OVERRIDE`] special value
272 : pub struct FunctionOverride<'a> {
273 : ptr: cxx::UniquePtr<ffi::PE_FunctionOverride>,
274 : _owner: PhantomData<&'a ffi::PE_DynamicRelocation>,
275 : }
276 :
277 : impl<'a> FromFFI<ffi::PE_FunctionOverride> for FunctionOverride<'a> {
278 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_FunctionOverride>) -> Self {
279 0 : Self {
280 0 : ptr,
281 0 : _owner: PhantomData,
282 0 : }
283 0 : }
284 : }
285 :
286 : impl AsDynamicFixup for FunctionOverride<'_> {
287 0 : fn as_generic(&self) -> &ffi::PE_DynamicFixup {
288 0 : self.ptr.as_ref().unwrap().as_ref()
289 0 : }
290 : }
291 :
292 : impl std::fmt::Debug for FunctionOverride<'_> {
293 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
294 0 : f.debug_struct("FunctionOverride").finish()
295 0 : }
296 : }
297 :
298 : impl std::fmt::Display for FunctionOverride<'_> {
299 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
300 0 : write!(f, "{}", self.as_generic().to_string())
301 0 : }
302 : }
303 :
304 : impl FunctionOverride<'_> {
305 : /// Iterator over the overriding info
306 0 : pub fn func_overriding_info(&self) -> ItFuncOverrideInfo<'_> {
307 0 : ItFuncOverrideInfo::new(self.ptr.func_overriding_info())
308 0 : }
309 :
310 : /// Find the `IMAGE_BDD_INFO` associated with the given info
311 0 : pub fn bdd_info(&self) -> ItImageBddInfo<'_> {
312 0 : ItImageBddInfo::new(self.ptr.bdd_info())
313 0 : }
314 :
315 : /// Find the `IMAGE_BDD_INFO` at the given offset
316 0 : pub fn bdd_info_at(&self, offset: u32) -> Option<ImageBddInfo<'_>> {
317 0 : into_optional(self.ptr.bdd_info_at(offset))
318 0 : }
319 :
320 : /// Find the `IMAGE_BDD_INFO` associated with the given info
321 0 : pub fn bdd_info_for(&self, info: &FunctionOverrideInfo) -> Option<ImageBddInfo<'_>> {
322 0 : into_optional(self.ptr.bdd_info_for(info.ptr.as_ref().unwrap()))
323 0 : }
324 : }
325 :
326 : /// Mirror `IMAGE_BDD_DYNAMIC_RELOCATION`
327 : pub struct ImageBddDynamicRelocation<'a> {
328 : ptr: cxx::UniquePtr<ffi::PE_FunctionOverride_image_bdd_dynamic_relocation_t>,
329 : _owner: PhantomData<&'a ffi::PE_FunctionOverride>,
330 : }
331 :
332 : impl<'a> FromFFI<ffi::PE_FunctionOverride_image_bdd_dynamic_relocation_t>
333 : for ImageBddDynamicRelocation<'a>
334 : {
335 0 : fn from_ffi(
336 0 : ptr: cxx::UniquePtr<ffi::PE_FunctionOverride_image_bdd_dynamic_relocation_t>,
337 0 : ) -> Self {
338 0 : Self {
339 0 : ptr,
340 0 : _owner: PhantomData,
341 0 : }
342 0 : }
343 : }
344 :
345 : impl ImageBddDynamicRelocation<'_> {
346 0 : pub fn left(&self) -> u16 {
347 0 : self.ptr.left()
348 0 : }
349 :
350 0 : pub fn right(&self) -> u16 {
351 0 : self.ptr.right()
352 0 : }
353 :
354 0 : pub fn value(&self) -> u32 {
355 0 : self.ptr.value()
356 0 : }
357 : }
358 :
359 : /// Mirror `IMAGE_BDD_INFO`
360 : pub struct ImageBddInfo<'a> {
361 : ptr: cxx::UniquePtr<ffi::PE_FunctionOverride_image_bdd_info_t>,
362 : _owner: PhantomData<&'a ffi::PE_FunctionOverride>,
363 : }
364 :
365 : impl<'a> FromFFI<ffi::PE_FunctionOverride_image_bdd_info_t> for ImageBddInfo<'a> {
366 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_FunctionOverride_image_bdd_info_t>) -> Self {
367 0 : Self {
368 0 : ptr,
369 0 : _owner: PhantomData,
370 0 : }
371 0 : }
372 : }
373 :
374 : impl ImageBddInfo<'_> {
375 0 : pub fn version(&self) -> u32 {
376 0 : self.ptr.version()
377 0 : }
378 :
379 0 : pub fn original_size(&self) -> u32 {
380 0 : self.ptr.original_size()
381 0 : }
382 :
383 0 : pub fn original_offset(&self) -> u32 {
384 0 : self.ptr.original_offset()
385 0 : }
386 :
387 : /// If [`ImageBddInfo::version`] is 1
388 0 : pub fn payload(&self) -> &[u8] {
389 0 : to_slice!(self.ptr.payload());
390 0 : }
391 :
392 : /// If [`ImageBddInfo::version`] is not 1
393 0 : pub fn relocations(&self) -> ImageBddDynRelocations<'_> {
394 0 : ImageBddDynRelocations::new(self.ptr.relocations())
395 0 : }
396 : }
397 :
398 : pub struct FunctionOverrideInfo<'a> {
399 : ptr: cxx::UniquePtr<ffi::PE_FunctionOverrideInfo>,
400 : _owner: PhantomData<&'a ffi::PE_FunctionOverride>,
401 : }
402 :
403 : impl<'a> FromFFI<ffi::PE_FunctionOverrideInfo> for FunctionOverrideInfo<'a> {
404 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_FunctionOverrideInfo>) -> Self {
405 0 : Self {
406 0 : ptr,
407 0 : _owner: PhantomData,
408 0 : }
409 0 : }
410 : }
411 :
412 : impl FunctionOverrideInfo<'_> {
413 : /// RVA of the original function
414 0 : pub fn original_rva(&self) -> u32 {
415 0 : self.ptr.original_rva()
416 0 : }
417 :
418 : /// Offset into the BDD region
419 0 : pub fn bdd_offset(&self) -> u32 {
420 0 : self.ptr.bdd_offset()
421 0 : }
422 :
423 : /// Size in bytes taken by RVAs
424 0 : pub fn rva_size(&self) -> u32 {
425 0 : self.ptr.rva_size()
426 0 : }
427 :
428 : /// Size in bytes taken by BaseRelocs
429 0 : pub fn base_reloc_size(&self) -> u32 {
430 0 : self.ptr.base_reloc_size()
431 0 : }
432 :
433 0 : pub fn functions_rva(&self) -> Vec<u32> {
434 0 : Vec::from(self.ptr.functions_rva().as_slice())
435 0 : }
436 :
437 0 : pub fn relocations(&self) -> FuncOverrideRelocations<'_> {
438 0 : FuncOverrideRelocations::new(self.ptr.relocations())
439 0 : }
440 : }
441 :
442 : /// This class wraps fixups associated with the (special) symbol value:
443 : /// [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_ARM64_KERNEL_IMPORT_CALL_TRANSFER`].
444 : pub struct ARM64Kernel<'a> {
445 : ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64Kernel>,
446 : _owner: PhantomData<&'a ffi::PE_DynamicRelocation>,
447 : }
448 :
449 : impl<'a> FromFFI<ffi::PE_DynamicFixupARM64Kernel> for ARM64Kernel<'a> {
450 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64Kernel>) -> Self {
451 0 : Self {
452 0 : ptr,
453 0 : _owner: PhantomData,
454 0 : }
455 0 : }
456 : }
457 :
458 : impl AsDynamicFixup for ARM64Kernel<'_> {
459 0 : fn as_generic(&self) -> &ffi::PE_DynamicFixup {
460 0 : self.ptr.as_ref().unwrap().as_ref()
461 0 : }
462 : }
463 :
464 : impl std::fmt::Debug for ARM64Kernel<'_> {
465 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
466 0 : f.debug_struct("ARM64Kernel").finish()
467 0 : }
468 : }
469 :
470 : impl std::fmt::Display for ARM64Kernel<'_> {
471 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
472 0 : write!(f, "{}", self.as_generic().to_string())
473 0 : }
474 : }
475 :
476 : impl ARM64Kernel<'_> {
477 : /// Iterator over the different relocations
478 0 : pub fn relocations(&self) -> ARM64KernelEntries<'_> {
479 0 : ARM64KernelEntries::new(self.ptr.relocations())
480 0 : }
481 : }
482 :
483 : /// Mirror `IMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION`
484 : pub struct ARM64KernelEntry<'a> {
485 : ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64Kernel_entry>,
486 : _owner: PhantomData<&'a ffi::PE_DynamicFixupARM64Kernel>,
487 : }
488 :
489 : impl<'a> FromFFI<ffi::PE_DynamicFixupARM64Kernel_entry> for ARM64KernelEntry<'a> {
490 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64Kernel_entry>) -> Self {
491 0 : Self {
492 0 : ptr,
493 0 : _owner: PhantomData,
494 0 : }
495 0 : }
496 : }
497 :
498 : impl ARM64KernelEntry<'_> {
499 : /// RVA to the call instruction
500 0 : pub fn rva(&self) -> u32 {
501 0 : self.ptr.rva()
502 0 : }
503 :
504 : /// True if target instruction is a `blr`, false if it's a `br`.
505 0 : pub fn indirect_call(&self) -> bool {
506 0 : self.ptr.indirect_call()
507 0 : }
508 :
509 : /// Register index used for the indirect call/jump.
510 : /// For instance, if the instruction is `br x3`, this index is set to `3`
511 0 : pub fn register_index(&self) -> u8 {
512 0 : self.ptr.register_index()
513 0 : }
514 :
515 : /// IAT index of the corresponding import. `0x7FFF` is a special value
516 : /// indicating no index.
517 0 : pub fn iat_index(&self) -> u16 {
518 0 : self.ptr.iat_index()
519 0 : }
520 : }
521 :
522 : /// This class wraps fixups associated with the (special) symbol value:
523 : /// [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_GUARD_IMPORT_CONTROL_TRANSFER`].
524 : pub struct ControlTransfer<'a> {
525 : ptr: cxx::UniquePtr<ffi::PE_DynamicFixupControlTransfer>,
526 : _owner: PhantomData<&'a ffi::PE_DynamicRelocation>,
527 : }
528 :
529 : impl<'a> FromFFI<ffi::PE_DynamicFixupControlTransfer> for ControlTransfer<'a> {
530 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupControlTransfer>) -> Self {
531 0 : Self {
532 0 : ptr,
533 0 : _owner: PhantomData,
534 0 : }
535 0 : }
536 : }
537 :
538 : impl AsDynamicFixup for ControlTransfer<'_> {
539 0 : fn as_generic(&self) -> &ffi::PE_DynamicFixup {
540 0 : self.ptr.as_ref().unwrap().as_ref()
541 0 : }
542 : }
543 :
544 : impl std::fmt::Debug for ControlTransfer<'_> {
545 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
546 0 : f.debug_struct("ControlTransfer").finish()
547 0 : }
548 : }
549 :
550 : impl std::fmt::Display for ControlTransfer<'_> {
551 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
552 0 : write!(f, "{}", self.as_generic().to_string())
553 0 : }
554 : }
555 :
556 : impl ControlTransfer<'_> {
557 : /// Iterator over the relocations
558 0 : pub fn relocations(&self) -> ControlTransferEntries<'_> {
559 0 : ControlTransferEntries::new(self.ptr.relocations())
560 0 : }
561 : }
562 :
563 : /// Mirror `IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION`
564 : pub struct ControlTransferEntry<'a> {
565 : ptr: cxx::UniquePtr<ffi::PE_DynamicFixupControlTransfer_entry>,
566 : _owner: PhantomData<&'a ffi::PE_DynamicFixupControlTransfer>,
567 : }
568 :
569 : impl<'a> FromFFI<ffi::PE_DynamicFixupControlTransfer_entry> for ControlTransferEntry<'a> {
570 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupControlTransfer_entry>) -> Self {
571 0 : Self {
572 0 : ptr,
573 0 : _owner: PhantomData,
574 0 : }
575 0 : }
576 : }
577 :
578 : impl ControlTransferEntry<'_> {
579 : /// RVA to the call instruction
580 0 : pub fn rva(&self) -> u32 {
581 0 : self.ptr.rva()
582 0 : }
583 :
584 : /// True if target instruction is a `call`, false otherwise.
585 0 : pub fn is_call(&self) -> bool {
586 0 : self.ptr.is_call()
587 0 : }
588 :
589 : /// IAT index of the corresponding import. `0x7FFF` is a special value
590 : /// indicating no index.
591 0 : pub fn iat_index(&self) -> u16 {
592 0 : self.ptr.iat_index()
593 0 : }
594 : }
595 :
596 : /// This class represents an special dynamic relocation where the format of the
597 : /// fixups is not supported by LIEF.
598 : pub struct Unknown<'a> {
599 : ptr: cxx::UniquePtr<ffi::PE_DynamicFixupUnknown>,
600 : _owner: PhantomData<&'a ffi::PE_DynamicRelocation>,
601 : }
602 :
603 : impl<'a> FromFFI<ffi::PE_DynamicFixupUnknown> for Unknown<'a> {
604 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupUnknown>) -> Self {
605 0 : Self {
606 0 : ptr,
607 0 : _owner: PhantomData,
608 0 : }
609 0 : }
610 : }
611 :
612 : impl AsDynamicFixup for Unknown<'_> {
613 0 : fn as_generic(&self) -> &ffi::PE_DynamicFixup {
614 0 : self.ptr.as_ref().unwrap().as_ref()
615 0 : }
616 : }
617 :
618 : impl std::fmt::Debug for Unknown<'_> {
619 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
620 0 : f.debug_struct("Unknown").finish()
621 0 : }
622 : }
623 :
624 : impl std::fmt::Display for Unknown<'_> {
625 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
626 0 : write!(f, "{}", self.as_generic().to_string())
627 0 : }
628 : }
629 :
630 : impl Unknown<'_> {
631 0 : pub fn payload(&self) -> &[u8] {
632 0 : to_slice!(self.ptr.payload());
633 0 : }
634 : }
635 :
636 0 : declare_iterator!(
637 0 : ARM64KernelEntries,
638 0 : ARM64KernelEntry<'a>,
639 0 : ffi::PE_DynamicFixupARM64Kernel_entry,
640 0 : ffi::PE_DynamicFixupARM64Kernel,
641 0 : ffi::PE_DynamicFixupARM64Kernel_it_relocations
642 0 : );
643 :
644 0 : declare_iterator!(
645 0 : Arm64XRelocEntries,
646 0 : Arm64XRelocEntry<'a>,
647 0 : ffi::PE_DynamicFixupARM64X_entry,
648 0 : ffi::PE_DynamicFixupARM64X,
649 0 : ffi::PE_DynamicFixupARM64X_it_relocations
650 0 : );
651 :
652 0 : declare_iterator!(
653 0 : ControlTransferEntries,
654 0 : ControlTransferEntry<'a>,
655 0 : ffi::PE_DynamicFixupControlTransfer_entry,
656 0 : ffi::PE_DynamicFixupControlTransfer,
657 0 : ffi::PE_DynamicFixupControlTransfer_it_relocations
658 0 : );
659 :
660 0 : declare_iterator!(
661 0 : GenericRelocations,
662 0 : Relocation<'a>,
663 0 : ffi::PE_Relocation,
664 0 : ffi::PE_DynamicFixupGeneric,
665 0 : ffi::PE_DynamicFixupGeneric_it_relocations
666 0 : );
667 :
668 0 : declare_fwd_iterator!(
669 0 : ImageBddDynRelocations,
670 0 : ImageBddDynamicRelocation<'a>,
671 0 : ffi::PE_FunctionOverride_image_bdd_dynamic_relocation_t,
672 0 : ffi::PE_FunctionOverride_image_bdd_info_t,
673 0 : ffi::PE_FunctionOverride_image_bdd_info_t_it_relocations
674 0 : );
675 :
676 0 : declare_iterator!(
677 0 : FuncOverrideRelocations,
678 0 : Relocation<'a>,
679 0 : ffi::PE_Relocation,
680 0 : ffi::PE_FunctionOverrideInfo,
681 0 : ffi::PE_FunctionOverrideInfo_it_relocations
682 0 : );
683 :
684 0 : declare_iterator!(
685 0 : ItFuncOverrideInfo,
686 0 : FunctionOverrideInfo<'a>,
687 0 : ffi::PE_FunctionOverrideInfo,
688 0 : ffi::PE_FunctionOverride,
689 0 : ffi::PE_FunctionOverride_it_func_overriding_info
690 0 : );
691 :
692 0 : declare_iterator!(
693 0 : ItImageBddInfo,
694 0 : ImageBddInfo<'a>,
695 0 : ffi::PE_FunctionOverride_image_bdd_info_t,
696 0 : ffi::PE_FunctionOverride,
697 0 : ffi::PE_FunctionOverride_it_bdd_info
698 0 : );
|