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