LIEF: Library to Instrument Executable Formats Version 0.17.0
Loading...
Searching...
No Matches
UnwindCodeX64.hpp
Go to the documentation of this file.
1/* Copyright 2017 - 2025 R. Thomas
2 * Copyright 2017 - 2025 Quarkslab
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef LIEF_PE_UNWIND_CODE_X64_H
17#define LIEF_PE_UNWIND_CODE_X64_H
18#include <ostream>
19#include <memory>
20#include <string>
22
23namespace LIEF {
24class SpanStream;
25
26namespace PE {
28namespace unwind_x64 {
29
32 public:
35
37 static std::unique_ptr<Code>
38 create_from(const RuntimeFunctionX64::unwind_info_t& info, SpanStream& stream);
39
40 Code() = delete;
41 Code(const Code&) = default;
42 Code& operator=(const Code&) = default;
43
44 Code(Code&&) = default;
45 Code& operator=(Code&&) = default;
46
47 virtual ~Code() = default;
48
49 Code(OPCODE opcode, uint32_t pos) :
50 pos_(pos),
51 opcode_(opcode)
52 {}
53
55 Code(opcode, 0)
56 {}
57
59 OPCODE opcode() const {
60 return opcode_;
61 }
62
64 uint32_t position() const {
65 return pos_;
66 }
67
69 virtual std::string to_string() const;
70
71 LIEF_API friend std::ostream& operator<<(std::ostream& os, const Code& code) {
72 os << code.to_string();
73 return os;
74 }
75
76 protected:
77 uint32_t pos_ = 0;
78 OPCODE opcode_;
79};
80
83class LIEF_API Alloc : public Code {
84 public:
85 Alloc(OPCODE op, size_t pos, uint32_t size) :
86 Code(op, pos),
87 size_(size)
88 {}
89
91 uint32_t size() const {
92 return size_;
93 }
94
95 std::string to_string() const override;
96
97 ~Alloc() override = default;
98
99 static bool classof(const Code* code) {
100 return code->opcode() == OPCODE::ALLOC_LARGE ||
101 code->opcode() == OPCODE::ALLOC_SMALL;
102 }
103 protected:
104 uint32_t size_ = 0;
105};
106
108class LIEF_API PushNonVol : public Code {
109 public:
110 PushNonVol() = delete;
111 PushNonVol(REG reg, size_t pos) :
112 Code(OPCODE::PUSH_NONVOL, pos),
113 reg_(reg)
114 {}
115
116 std::string to_string() const override;
117
119 REG reg() const {
120 return reg_;
121 }
122
123 ~PushNonVol() override = default;
124
125 static bool classof(const Code* code) {
126 return code->opcode() == OPCODE::PUSH_NONVOL;
127 }
128
129 protected:
130 REG reg_;
131};
132
135 public:
136 PushMachFrame() = delete;
137 PushMachFrame(uint8_t value, size_t pos) :
138 Code(OPCODE::PUSH_MACHFRAME, pos),
139 value_(value)
140 {}
141
143 uint8_t value() const {
144 return value_;
145 }
146
147 std::string to_string() const override;
148
149 ~PushMachFrame() override = default;
150
151 static bool classof(const Code* code) {
152 return code->opcode() == OPCODE::PUSH_MACHFRAME;
153 }
154
155 protected:
156 uint8_t value_;
157};
158
161class LIEF_API SetFPReg : public Code {
162 public:
163 SetFPReg() = delete;
164 SetFPReg(REG value, size_t pos) :
165 Code(OPCODE::SET_FPREG, pos),
166 reg_(value)
167 {}
168
170 REG reg() const {
171 return reg_;
172 }
173
174 std::string to_string() const override;
175
176 ~SetFPReg() override = default;
177
178 static bool classof(const Code* code) {
179 return code->opcode() == OPCODE::SET_FPREG;
180 }
181
182 protected:
183 REG reg_;
184};
185
189 public:
190 SaveNonVolatile() = delete;
191 SaveNonVolatile(OPCODE op, REG value, size_t pos, uint32_t offset) :
192 Code(op, pos),
193 reg_(value),
194 offset_(offset)
195 {}
196
197 REG reg() const {
198 return reg_;
199 }
200
201 uint32_t offset() const {
202 return offset_;
203 }
204
205 std::string to_string() const override;
206
207 ~SaveNonVolatile() override = default;
208
209 static bool classof(const Code* code) {
210 return code->opcode() == OPCODE::SAVE_NONVOL ||
211 code->opcode() == OPCODE::SAVE_NONVOL_FAR;
212 }
213
214 protected:
215 REG reg_;
216 uint32_t offset_ = 0;
217};
218
219class LIEF_API SaveXMM128 : public Code {
220 public:
221 SaveXMM128() = delete;
222 SaveXMM128(OPCODE op, uint8_t num, size_t pos, uint32_t offset) :
223 Code(op, pos),
224 num_(num),
225 offset_(offset)
226 {}
227
228 uint8_t num() const {
229 return num_;
230 }
231
232 uint32_t offset() const {
233 return offset_;
234 }
235
236 std::string to_string() const override;
237
238 ~SaveXMM128() override = default;
239
240 static bool classof(const Code* code) {
241 return code->opcode() == OPCODE::SAVE_XMM128 ||
242 code->opcode() == OPCODE::SAVE_XMM128_FAR;
243 }
244
245 protected:
246 uint8_t num_ = 0;
247 uint32_t offset_ = 0;
248};
249
251class LIEF_API Epilog : public Code {
252 public:
253 Epilog() = delete;
254
255 Epilog(uint8_t flags, uint8_t size) :
256 Code(OPCODE::EPILOG, 0),
257 flags_(flags),
258 size_(size)
259 {}
260
261 uint8_t flags() const {
262 return flags_;
263 }
264
266 uint32_t size() const {
267 return size_;
268 }
269
270 std::string to_string() const override;
271
272 ~Epilog() override = default;
273
274 static bool classof(const Code* code) {
275 return code->opcode() == OPCODE::EPILOG;
276 }
277
278 protected:
279 uint8_t flags_ = 0;
280 uint8_t size_ = 0;
281};
282
283class LIEF_API Spare : public Code {
284 public:
286 Code(OPCODE::SPARE, 0)
287 {}
288
289 std::string to_string() const override {
290 return "Noop";
291 }
292
293 ~Spare() override = default;
294
295 static bool classof(const Code* code) {
296 return code->opcode() == OPCODE::SPARE;
297 }
298};
299
300}
301
302}
303}
304#endif
305
306
UNWIND_REG
Definition RuntimeFunctionX64.hpp:134
UNWIND_OPCODES
Definition RuntimeFunctionX64.hpp:65
std::string to_string() const override
Pretty representation.
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:99
Alloc(OPCODE op, size_t pos, uint32_t size)
Definition UnwindCodeX64.hpp:85
~Alloc() override=default
uint32_t size() const
The size allocated.
Definition UnwindCodeX64.hpp:91
virtual ~Code()=default
OPCODE opcode() const
The original opcode.
Definition UnwindCodeX64.hpp:59
Code & operator=(const Code &)=default
Code & operator=(Code &&)=default
RuntimeFunctionX64::UNWIND_REG REG
Definition UnwindCodeX64.hpp:34
friend std::ostream & operator<<(std::ostream &os, const Code &code)
Definition UnwindCodeX64.hpp:71
Code(OPCODE opcode, uint32_t pos)
Definition UnwindCodeX64.hpp:49
uint32_t position() const
Offset in the prolog.
Definition UnwindCodeX64.hpp:64
RuntimeFunctionX64::UNWIND_OPCODES OPCODE
Definition UnwindCodeX64.hpp:33
Code(OPCODE opcode)
Definition UnwindCodeX64.hpp:54
Code(const Code &)=default
virtual std::string to_string() const
Pretty representation.
uint32_t size() const
Size of the epilog.
Definition UnwindCodeX64.hpp:266
std::string to_string() const override
Pretty representation.
Epilog(uint8_t flags, uint8_t size)
Definition UnwindCodeX64.hpp:255
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:274
uint8_t flags() const
Definition UnwindCodeX64.hpp:261
~Epilog() override=default
std::string to_string() const override
Pretty representation.
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:151
uint8_t value() const
0 or 1
Definition UnwindCodeX64.hpp:143
PushMachFrame(uint8_t value, size_t pos)
Definition UnwindCodeX64.hpp:137
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:125
std::string to_string() const override
Pretty representation.
PushNonVol(REG reg, size_t pos)
Definition UnwindCodeX64.hpp:111
~PushNonVol() override=default
REG reg() const
The register pushed.
Definition UnwindCodeX64.hpp:119
REG reg() const
Definition UnwindCodeX64.hpp:197
uint32_t offset() const
Definition UnwindCodeX64.hpp:201
SaveNonVolatile(OPCODE op, REG value, size_t pos, uint32_t offset)
Definition UnwindCodeX64.hpp:191
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:209
std::string to_string() const override
Pretty representation.
SaveXMM128(OPCODE op, uint8_t num, size_t pos, uint32_t offset)
Definition UnwindCodeX64.hpp:222
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:240
uint32_t offset() const
Definition UnwindCodeX64.hpp:232
uint8_t num() const
Definition UnwindCodeX64.hpp:228
~SaveXMM128() override=default
std::string to_string() const override
Pretty representation.
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:178
REG reg() const
Frame pointer register.
Definition UnwindCodeX64.hpp:170
SetFPReg(REG value, size_t pos)
Definition UnwindCodeX64.hpp:164
~SetFPReg() override=default
std::string to_string() const override
Pretty representation.
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:295
Spare()
Definition UnwindCodeX64.hpp:285
~Spare() override=default
std::string to_string() const override
Pretty representation.
Definition UnwindCodeX64.hpp:289
Definition SpanStream.hpp:32
This namespace wraps code related to PE-x64 unwinding code.
Definition RuntimeFunctionX64.hpp:34
Namespace related to the LIEF's PE module.
Definition Abstract/Header.hpp:32
LIEF namespace.
Definition Abstract/Binary.hpp:40
This structure represents the UNWIND_INFO which records the effects a function has on the stack point...
Definition RuntimeFunctionX64.hpp:142
#define LIEF_API
Definition visibility.h:41