Line data Source code
1 : //! This module includes the different structures related to the relocation process in a PE binary
2 :
3 : use std::marker::PhantomData;
4 :
5 : use lief_ffi as ffi;
6 :
7 : use crate::common::FromFFI;
8 : use crate::{declare_iterator, generic};
9 :
10 : /// Class which represents the *Base Relocation Block*
11 : /// We usually find this structure in the `.reloc` section
12 : pub struct Relocation<'a> {
13 : ptr: cxx::UniquePtr<ffi::PE_Relocation>,
14 : _owner: PhantomData<&'a ffi::PE_Binary>,
15 : }
16 :
17 : impl Relocation<'_> {
18 : /// The RVA for which the offset of the relocation entries is added
19 21830 : pub fn virtual_address(&self) -> u32 {
20 21830 : self.ptr.virtual_address()
21 21830 : }
22 :
23 : /// The total number of bytes in the base relocation block.
24 : /// `block_size = sizeof(BaseRelocationBlock) + nb_of_relocs * sizeof(uint16_t = RelocationEntry)`
25 21830 : pub fn block_size(&self) -> u32 {
26 21830 : self.ptr.block_size()
27 21830 : }
28 : /// Iterator over the Relocation [`Entry`]
29 21830 : pub fn entries(&self) -> RelocationEntries {
30 21830 : RelocationEntries::new(self.ptr.entries())
31 21830 : }
32 : }
33 :
34 : impl std::fmt::Debug for Relocation<'_> {
35 21830 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 21830 : f.debug_struct("Relocation")
37 21830 : .field("virtual_address", &self.virtual_address())
38 21830 : .field("block_size", &self.block_size())
39 21830 : .finish()
40 21830 : }
41 : }
42 :
43 : impl<'a> FromFFI<ffi::PE_Relocation> for Relocation<'a> {
44 21830 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_Relocation>) -> Self {
45 21830 : Relocation {
46 21830 : ptr,
47 21830 : _owner: PhantomData,
48 21830 : }
49 21830 : }
50 : }
51 :
52 :
53 : #[allow(non_camel_case_types)]
54 2247900 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
55 : pub enum BaseType {
56 : ABS,
57 : HIGH,
58 : LOW,
59 : HIGHLOW,
60 : HIGHADJ,
61 : MIPS_JMPADDR,
62 : ARM_MOV32,
63 : RISCV_HI20,
64 : SECTION,
65 : THUMB_MOV32,
66 : RISCV_LOW12I,
67 : RISCV_LOW12S,
68 : LOONARCH_MARK_LA,
69 : MIPS_JMPADDR16,
70 : DIR64,
71 : HIGH3ADJ,
72 : UNKNOWN(u32),
73 : }
74 :
75 : impl From<u32> for BaseType {
76 2247900 : fn from(value: u32) -> Self {
77 2247900 : match value {
78 10850 : 0x00000000 => BaseType::ABS,
79 0 : 0x00000001 => BaseType::HIGH,
80 0 : 0x00000002 => BaseType::LOW,
81 1224240 : 0x00000003 => BaseType::HIGHLOW,
82 0 : 0x00000004 => BaseType::HIGHADJ,
83 0 : 0x00000105 => BaseType::MIPS_JMPADDR,
84 0 : 0x00000205 => BaseType::ARM_MOV32,
85 0 : 0x00000405 => BaseType::RISCV_HI20,
86 0 : 0x00000006 => BaseType::SECTION,
87 0 : 0x00000807 => BaseType::THUMB_MOV32,
88 0 : 0x00001007 => BaseType::RISCV_LOW12I,
89 0 : 0x00002008 => BaseType::RISCV_LOW12S,
90 0 : 0x00004008 => BaseType::LOONARCH_MARK_LA,
91 0 : 0x00000009 => BaseType::MIPS_JMPADDR16,
92 1012810 : 0x0000000a => BaseType::DIR64,
93 0 : 0x0000000b => BaseType::HIGH3ADJ,
94 0 : _ => BaseType::UNKNOWN(value),
95 : }
96 2247900 : }
97 : }
98 : impl From<BaseType> for u32 {
99 0 : fn from(value: BaseType) -> u32 {
100 0 : match value {
101 0 : BaseType::ABS => 0x00000000,
102 0 : BaseType::HIGH => 0x00000001,
103 0 : BaseType::LOW => 0x00000002,
104 0 : BaseType::HIGHLOW => 0x00000003,
105 0 : BaseType::HIGHADJ => 0x00000004,
106 0 : BaseType::MIPS_JMPADDR => 0x00000105,
107 0 : BaseType::ARM_MOV32 => 0x00000205,
108 0 : BaseType::RISCV_HI20 => 0x00000405,
109 0 : BaseType::SECTION => 0x00000006,
110 0 : BaseType::THUMB_MOV32 => 0x00000807,
111 0 : BaseType::RISCV_LOW12I => 0x00001007,
112 0 : BaseType::RISCV_LOW12S => 0x00002008,
113 0 : BaseType::LOONARCH_MARK_LA => 0x00004008,
114 0 : BaseType::MIPS_JMPADDR16 => 0x00000009,
115 0 : BaseType::DIR64 => 0x0000000a,
116 0 : BaseType::HIGH3ADJ => 0x0000000b,
117 0 : BaseType::UNKNOWN(value) => value,
118 : }
119 0 : }
120 : }
121 :
122 : /// Class which represents an entry in the relocation table
123 : ///
124 : /// It implements the [`generic::Relocation`] trait which provides additional functions
125 : pub struct Entry<'a> {
126 : ptr: cxx::UniquePtr<ffi::PE_RelocationEntry>,
127 : _owner: PhantomData<&'a ffi::PE_Relocation>,
128 : }
129 :
130 : impl generic::Relocation for Entry<'_> {
131 4495800 : fn as_generic(&self) -> &ffi::AbstractRelocation {
132 4495800 : self.ptr.as_ref().unwrap().as_ref()
133 4495800 : }
134 : }
135 :
136 : impl Entry<'_> {
137 : /// Offset relative to [`Relocation::virtual_address`] where the relocation occurs.
138 2247900 : pub fn position(&self) -> u64 {
139 2247900 : self.ptr.position()
140 2247900 : }
141 :
142 : /// Type of the relocation
143 2247900 : pub fn get_type(&self) -> BaseType {
144 2247900 : BaseType::from(self.ptr.get_type())
145 2247900 : }
146 :
147 : /// Raw data of the relocation:
148 : /// - The **high** 4 bits store the relocation type
149 : /// - The **low** 12 bits store the relocation offset
150 2247900 : pub fn data(&self) -> u16 {
151 2247900 : self.ptr.data()
152 2247900 : }
153 : }
154 :
155 : impl std::fmt::Debug for Entry<'_> {
156 2247900 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
157 2247900 : let base = self as &dyn generic::Relocation;
158 2247900 : f.debug_struct("RelocationEntry")
159 2247900 : .field("base", &base)
160 2247900 : .field("type", &self.get_type())
161 2247900 : .field("data", &self.data())
162 2247900 : .field("position", &self.position())
163 2247900 : .finish()
164 2247900 : }
165 : }
166 :
167 : impl<'a> FromFFI<ffi::PE_RelocationEntry> for Entry<'a> {
168 2247900 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_RelocationEntry>) -> Self {
169 2247900 : Entry {
170 2247900 : ptr,
171 2247900 : _owner: PhantomData,
172 2247900 : }
173 2247900 : }
174 : }
175 :
176 2247900 : declare_iterator!(
177 2247900 : RelocationEntries,
178 2247900 : Entry<'a>,
179 2247900 : ffi::PE_RelocationEntry,
180 2247900 : ffi::PE_Relocation,
181 2247900 : ffi::PE_Relocation_it_entries
182 2247900 : );
183 21830 : declare_iterator!(
184 21830 : Relocations,
185 21830 : Relocation<'a>,
186 21830 : ffi::PE_Relocation,
187 21830 : ffi::PE_Binary,
188 21830 : ffi::PE_Binary_it_relocations
189 21830 : );
|