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 {namespace unwind_x64 {
29class LIEF_API Code {
32 public:
33 using OPCODE = RuntimeFunctionX64::UNWIND_OPCODES;
34 using REG = RuntimeFunctionX64::UNWIND_REG;
35 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
54 Code(OPCODE opcode) :
55 Code(opcode, 0)
56 {}
57 OPCODE opcode() const {
60 return opcode_;
61 }
62 uint32_t position() const {
65 return pos_;
66 }
67 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};
80class 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 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};
106class 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 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};
132class LIEF_API PushMachFrame : public Code {
135 public:
136 PushMachFrame() = delete;
137 PushMachFrame(uint8_t value, size_t pos) :
138 Code(OPCODE::PUSH_MACHFRAME, pos),
139 value_(value)
140 {}
141 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};
158class 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 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};
185class LIEF_API SaveNonVolatile : public Code {
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};
249class 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 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
RuntimeFunctionX64.hpp
LIEF::PE::unwind_x64::Alloc
This class represents a stack-allocation operation (UNWIND_OPCODES::ALLOC_SMALL or UNWIND_OPCODES::AL...
Definition UnwindCodeX64.hpp:83
LIEF::PE::unwind_x64::Alloc::to_string
std::string to_string() const override
Pretty representation.
LIEF::PE::unwind_x64::Alloc::classof
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:99
LIEF::PE::unwind_x64::Alloc::Alloc
Alloc(OPCODE op, size_t pos, uint32_t size)
Definition UnwindCodeX64.hpp:85
LIEF::PE::unwind_x64::Alloc::~Alloc
~Alloc() override=default
LIEF::PE::unwind_x64::Alloc::size
uint32_t size() const
The size allocated.
Definition UnwindCodeX64.hpp:91
LIEF::PE::unwind_x64::Code
Base class for all unwind operations.
Definition UnwindCodeX64.hpp:31
LIEF::PE::unwind_x64::Code::~Code
virtual ~Code()=default
LIEF::PE::unwind_x64::Code::opcode
OPCODE opcode() const
The original opcode.
Definition UnwindCodeX64.hpp:59
LIEF::PE::unwind_x64::Code::operator=
Code & operator=(const Code &)=default
LIEF::PE::unwind_x64::Code::operator=
Code & operator=(Code &&)=default
LIEF::PE::unwind_x64::Code::Code
Code(Code &&)=default
LIEF::PE::unwind_x64::Code::operator<<
friend std::ostream & operator<<(std::ostream &os, const Code &code)
Definition UnwindCodeX64.hpp:71
LIEF::PE::unwind_x64::Code::Code
Code(OPCODE opcode, uint32_t pos)
Definition UnwindCodeX64.hpp:49
LIEF::PE::unwind_x64::Code::Code
Code()=delete
LIEF::PE::unwind_x64::Code::position
uint32_t position() const
Offset in the prolog.
Definition UnwindCodeX64.hpp:64
LIEF::PE::unwind_x64::Code::Code
Code(OPCODE opcode)
Definition UnwindCodeX64.hpp:54
LIEF::PE::unwind_x64::Code::Code
Code(const Code &)=default
LIEF::PE::unwind_x64::Code::to_string
virtual std::string to_string() const
Pretty representation.
LIEF::PE::unwind_x64::Epilog
Describes the function's epilog.
Definition UnwindCodeX64.hpp:251
LIEF::PE::unwind_x64::Epilog::size
uint32_t size() const
Size of the epilog.
Definition UnwindCodeX64.hpp:266
LIEF::PE::unwind_x64::Epilog::Epilog
Epilog()=delete
LIEF::PE::unwind_x64::Epilog::to_string
std::string to_string() const override
Pretty representation.
LIEF::PE::unwind_x64::Epilog::Epilog
Epilog(uint8_t flags, uint8_t size)
Definition UnwindCodeX64.hpp:255
LIEF::PE::unwind_x64::Epilog::classof
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:274
LIEF::PE::unwind_x64::Epilog::flags
uint8_t flags() const
Definition UnwindCodeX64.hpp:261
LIEF::PE::unwind_x64::Epilog::~Epilog
~Epilog() override=default
LIEF::PE::unwind_x64::PushMachFrame
Push a machine frame.
Definition UnwindCodeX64.hpp:134
LIEF::PE::unwind_x64::PushMachFrame::to_string
std::string to_string() const override
Pretty representation.
LIEF::PE::unwind_x64::PushMachFrame::classof
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:151
LIEF::PE::unwind_x64::PushMachFrame::~PushMachFrame
~PushMachFrame() override=default
LIEF::PE::unwind_x64::PushMachFrame::value
uint8_t value() const
0 or 1
Definition UnwindCodeX64.hpp:143
LIEF::PE::unwind_x64::PushMachFrame::PushMachFrame
PushMachFrame()=delete
LIEF::PE::unwind_x64::PushMachFrame::PushMachFrame
PushMachFrame(uint8_t value, size_t pos)
Definition UnwindCodeX64.hpp:137
LIEF::PE::unwind_x64::PushNonVol
Push a nonvolatile integer register, decrementing RSP by 8.
Definition UnwindCodeX64.hpp:108
LIEF::PE::unwind_x64::PushNonVol::classof
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:125
LIEF::PE::unwind_x64::PushNonVol::PushNonVol
PushNonVol()=delete
LIEF::PE::unwind_x64::PushNonVol::to_string
std::string to_string() const override
Pretty representation.
LIEF::PE::unwind_x64::PushNonVol::PushNonVol
PushNonVol(REG reg, size_t pos)
Definition UnwindCodeX64.hpp:111
LIEF::PE::unwind_x64::PushNonVol::~PushNonVol
~PushNonVol() override=default
LIEF::PE::unwind_x64::PushNonVol::reg
REG reg() const
The register pushed.
Definition UnwindCodeX64.hpp:119
LIEF::PE::unwind_x64::SaveNonVolatile
Save a nonvolatile integer register on the stack using a MOV instead of a PUSH.
Definition UnwindCodeX64.hpp:188
LIEF::PE::unwind_x64::SaveNonVolatile::SaveNonVolatile
SaveNonVolatile()=delete
LIEF::PE::unwind_x64::SaveNonVolatile::~SaveNonVolatile
~SaveNonVolatile() override=default
LIEF::PE::unwind_x64::SaveNonVolatile::reg
REG reg() const
Definition UnwindCodeX64.hpp:197
LIEF::PE::unwind_x64::SaveNonVolatile::offset
uint32_t offset() const
Definition UnwindCodeX64.hpp:201
LIEF::PE::unwind_x64::SaveNonVolatile::SaveNonVolatile
SaveNonVolatile(OPCODE op, REG value, size_t pos, uint32_t offset)
Definition UnwindCodeX64.hpp:191
LIEF::PE::unwind_x64::SaveNonVolatile::classof
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:209
LIEF::PE::unwind_x64::SaveNonVolatile::to_string
std::string to_string() const override
Pretty representation.
LIEF::PE::unwind_x64::SaveXMM128
Definition UnwindCodeX64.hpp:219
LIEF::PE::unwind_x64::SaveXMM128::SaveXMM128
SaveXMM128()=delete
LIEF::PE::unwind_x64::SaveXMM128::SaveXMM128
SaveXMM128(OPCODE op, uint8_t num, size_t pos, uint32_t offset)
Definition UnwindCodeX64.hpp:222
LIEF::PE::unwind_x64::SaveXMM128::classof
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:240
LIEF::PE::unwind_x64::SaveXMM128::offset
uint32_t offset() const
Definition UnwindCodeX64.hpp:232
LIEF::PE::unwind_x64::SaveXMM128::num
uint8_t num() const
Definition UnwindCodeX64.hpp:228
LIEF::PE::unwind_x64::SaveXMM128::~SaveXMM128
~SaveXMM128() override=default
LIEF::PE::unwind_x64::SaveXMM128::to_string
std::string to_string() const override
Pretty representation.
LIEF::PE::unwind_x64::SetFPReg
Establish the frame pointer register by setting the register to some offset of the current RSP.
Definition UnwindCodeX64.hpp:161
LIEF::PE::unwind_x64::SetFPReg::classof
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:178
LIEF::PE::unwind_x64::SetFPReg::SetFPReg
SetFPReg()=delete
LIEF::PE::unwind_x64::SetFPReg::reg
REG reg() const
Frame pointer register.
Definition UnwindCodeX64.hpp:170
LIEF::PE::unwind_x64::SetFPReg::SetFPReg
SetFPReg(REG value, size_t pos)
Definition UnwindCodeX64.hpp:164
LIEF::PE::unwind_x64::SetFPReg::~SetFPReg
~SetFPReg() override=default
LIEF::PE::unwind_x64::SetFPReg::to_string
std::string to_string() const override
Pretty representation.
LIEF::PE::unwind_x64::Spare
Definition UnwindCodeX64.hpp:283
LIEF::PE::unwind_x64::Spare::classof
static bool classof(const Code *code)
Definition UnwindCodeX64.hpp:295
LIEF::PE::unwind_x64::Spare::Spare
Spare()
Definition UnwindCodeX64.hpp:285
LIEF::PE::unwind_x64::Spare::~Spare
~Spare() override=default
LIEF::PE::unwind_x64::Spare::to_string
std::string to_string() const override
Pretty representation.
Definition UnwindCodeX64.hpp:289
LIEF::SpanStream
Definition SpanStream.hpp:32
LIEF::PE::unwind_x64
This namespace wraps code related to PE-x64 unwinding code.
Definition RuntimeFunctionX64.hpp:34
LIEF::PE
Namespace related to the LIEF's PE module.
Definition Abstract/Header.hpp:32
LIEF
LIEF namespace.
Definition Abstract/Binary.hpp:36
LIEF_API
#define LIEF_API
Definition visibility.h:41