LIEF: Library to Instrument Executable Formats Version 2.0.0
Loading...
Searching...
No Matches
Abstract/Binary.hpp
Go to the documentation of this file.
1/* Copyright 2017 - 2026 R. Thomas
2 * Copyright 2017 - 2026 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_ABSTRACT_BINARY_H
17#define LIEF_ABSTRACT_BINARY_H
18
19#include <string_view>
20#include <unordered_map>
21#include <memory>
22#include <vector>
23
24#include "LIEF/Object.hpp"
26#include "LIEF/errors.hpp"
27#include "LIEF/iterators.hpp"
28#include "LIEF/span.hpp"
29#include "LIEF/visibility.h"
30
33
36
37namespace llvm {
38class MCInst;
39}
40
42namespace LIEF {
43class Section;
44class Relocation;
45class Symbol;
46
47class DebugInfo;
48
49namespace assembly {
50class Engine;
51}
52
61class LIEF_API Binary : public Object {
62 public:
64 enum class VA_TYPES {
67 AUTO = 0,
68
70 RVA = 1,
71
73 VA = 2,
74 };
75
83
84 using functions_t = std::vector<Function>;
85
87 using sections_t = std::vector<Section*>;
88
91
94
96 using symbols_t = std::vector<Symbol*>;
97
100
103
105 using relocations_t = std::vector<Relocation*>;
106
109
112
115
116 public:
119
120 ~Binary() override;
121
122 Binary& operator=(const Binary&) = delete;
123 Binary(const Binary&) = delete;
124
126 FORMATS format() const {
127 return format_;
128 }
129
131 Header header() const {
132 return get_abstract_header();
133 }
134
138 return get_abstract_symbols();
139 }
140
144 return const_cast<Binary*>(this)->get_abstract_symbols();
145 }
146
148 bool has_symbol(std::string_view name) const {
149 return get_symbol(name) != nullptr;
150 }
151
154 const Symbol* get_symbol(std::string_view name) const LIEF_LIFETIMEBOUND;
155
156 Symbol* get_symbol(std::string_view name) LIEF_LIFETIMEBOUND {
157 return const_cast<Symbol*>(static_cast<const Binary*>(this)->get_symbol(name));
158 }
159
162 return get_abstract_sections();
163 }
164
166 return const_cast<Binary*>(this)->get_abstract_sections();
167 }
168
170 virtual void remove_section(std::string_view name, bool clear = false) = 0;
171
174 return get_abstract_relocations();
175 }
176
178 return const_cast<Binary*>(this)->get_abstract_relocations();
179 }
180
182 virtual uint64_t entrypoint() const = 0;
183
185 uint64_t original_size() const {
186 return original_size_;
187 }
188
191 return get_abstract_exported_functions();
192 }
193
195 std::vector<std::string> imported_libraries() const {
196 return get_abstract_imported_libraries();
197 }
198
201 return get_abstract_imported_functions();
202 }
203
205 virtual result<uint64_t> get_function_address(std::string_view func_name) const;
206
208 void accept(Visitor& visitor) const override;
209
210 std::vector<uint64_t> xref(uint64_t address) const;
211
218 virtual void patch_address(uint64_t address,
219 const std::vector<uint8_t>& patch_value,
220 VA_TYPES addr_type = VA_TYPES::AUTO) = 0;
221
229 virtual void patch_address(uint64_t address, uint64_t patch_value,
230 size_t size = sizeof(uint64_t),
231 VA_TYPES addr_type = VA_TYPES::AUTO) = 0;
232
235 uint64_t virtual_address, uint64_t size, VA_TYPES addr_type = VA_TYPES::AUTO
236 ) const LIEF_LIFETIMEBOUND = 0;
237
239 template<class T>
242 VA_TYPES addr_type = VA_TYPES::AUTO) const {
243 T value;
244 static_assert(std::is_integral_v<T>, "Require an integral type");
246 get_content_from_virtual_address(va, sizeof(T), addr_type);
247 if (raw.empty() || raw.size() < sizeof(T)) {
249 }
250
251 std::copy(raw.data(), raw.data() + sizeof(T),
252 reinterpret_cast<uint8_t*>(&value));
253 return value;
254 }
255
261 void original_size(uint64_t size) {
262 original_size_ = size;
263 }
264
266 virtual bool is_pie() const = 0;
267
269 virtual bool has_nx() const = 0;
270
272 virtual uint64_t imagebase() const = 0;
273
275 virtual functions_t ctor_functions() const = 0;
276
283 uint64_t slide = 0) const = 0;
284
285 virtual std::ostream& print(std::ostream& os) const {
286 return os;
287 }
288
289 LIEF_API friend std::ostream& operator<<(std::ostream& os,
290 const Binary& binary) {
291 binary.print(os);
292 return os;
293 }
294
309
321 instructions_it disassemble(uint64_t address,
322 size_t size) const LIEF_LIFETIMEBOUND;
323
335
346 instructions_it disassemble(std::string_view function) const LIEF_LIFETIMEBOUND;
347
355 size_t size,
356 uint64_t address = 0) const LIEF_LIFETIMEBOUND;
357
358
364 disassemble(const std::vector<uint8_t>& buffer LIEF_LIFETIMEBOUND,
365 uint64_t address = 0) const LIEF_LIFETIMEBOUND {
366 return disassemble(buffer.data(), buffer.size(), address);
367 }
368
370 uint64_t address = 0) const LIEF_LIFETIMEBOUND {
371 return disassemble(buffer.data(), buffer.size(), address);
372 }
373
375 uint64_t address = 0) const LIEF_LIFETIMEBOUND {
376 return disassemble(buffer.data(), buffer.size(), address);
377 }
378
392 std::vector<uint8_t> assemble(uint64_t address, std::string_view Asm,
395
400 std::vector<uint8_t> assemble(uint64_t address, const llvm::MCInst& inst);
401
406 std::vector<uint8_t> assemble(uint64_t address,
407 const std::vector<llvm::MCInst>& insts);
408
411 virtual uint64_t page_size() const;
412
430 DebugInfo* load_debug_info(std::string_view path);
431
433 virtual uint64_t virtual_size() const {
434 return 0;
435 }
436
445 template<class T>
446 const T* cast() const LIEF_LIFETIMEBOUND {
447 static_assert(std::is_base_of_v<LIEF::Binary, T>,
448 "Require Abstract binary inheritance");
449 if (T::classof(this)) {
450 return static_cast<const T*>(this);
451 }
452 return nullptr;
453 }
454
455 template<class T>
457 return const_cast<T*>(static_cast<const Binary*>(this)->cast<T>());
458 }
459
460 protected:
461 FORMATS format_ = FORMATS::UNKNOWN;
462 mutable std::unique_ptr<DebugInfo> debug_info_;
463 mutable std::unordered_map<uint32_t, std::unique_ptr<assembly::Engine>> engines_;
464 uint64_t original_size_ = 0;
465
466 assembly::Engine* get_engine(uint64_t address) const;
467
468 template<uint32_t Key, class F>
469 LIEF_LOCAL assembly::Engine* get_cache_engine(uint64_t address, F&& f) const;
470
471 // These functions need to be overloaded by the object that claims to extend this
472 // Abstract Binary
473 virtual Header get_abstract_header() const = 0;
474 virtual symbols_t get_abstract_symbols() = 0;
475 virtual sections_t get_abstract_sections() = 0;
476 virtual relocations_t get_abstract_relocations() = 0;
477
478 virtual functions_t get_abstract_exported_functions() const = 0;
479 virtual functions_t get_abstract_imported_functions() const = 0;
480 virtual std::vector<std::string> get_abstract_imported_libraries() const = 0;
481};
482
485
486}
487
488
489#endif
Header header() const
Return the abstract header of the binary.
Definition Abstract/Binary.hpp:131
ref_iterator< symbols_t > it_symbols
Iterator that outputs LIEF::Symbol&.
Definition Abstract/Binary.hpp:99
virtual void patch_address(uint64_t address, const std::vector< uint8_t > &patch_value, VA_TYPES addr_type=VA_TYPES::AUTO)=0
Patch the content at virtual address address with patch_value.
std::vector< Function > functions_t
Definition Abstract/Binary.hpp:84
functions_t imported_functions() const
Return functions imported by the binary.
Definition Abstract/Binary.hpp:200
virtual uint64_t entrypoint() const =0
Binary's entrypoint (if any).
const_ref_iterator< relocations_t > it_const_relocations
Iterator that outputs const LIEF::Relocation&.
Definition Abstract/Binary.hpp:111
const Symbol * get_symbol(std::string_view name) const
Return the Symbol with the given name If the symbol does not exist, return a nullptr.
FORMATS
Definition Abstract/Binary.hpp:76
@ UNKNOWN
Definition Abstract/Binary.hpp:77
@ ELF
Definition Abstract/Binary.hpp:78
@ OAT
Definition Abstract/Binary.hpp:81
@ PE
Definition Abstract/Binary.hpp:79
@ MACHO
Definition Abstract/Binary.hpp:80
virtual result< uint64_t > offset_to_virtual_address(uint64_t offset, uint64_t slide=0) const =0
Convert the given offset into a virtual address.
Symbol * get_symbol(std::string_view name)
Definition Abstract/Binary.hpp:156
LIEF::result< T > get_int_from_virtual_address(uint64_t va, VA_TYPES addr_type=VA_TYPES::AUTO) const
Get the integer value at the given virtual address.
Definition Abstract/Binary.hpp:241
FORMATS format() const
Executable format (ELF, PE, Mach-O) of the underlying binary.
Definition Abstract/Binary.hpp:126
friend std::ostream & operator<<(std::ostream &os, const Binary &binary)
Definition Abstract/Binary.hpp:289
ref_iterator< sections_t > it_sections
Iterator that outputs LIEF::Section&.
Definition Abstract/Binary.hpp:90
it_const_sections sections() const
Definition Abstract/Binary.hpp:165
const_ref_iterator< sections_t > it_const_sections
Iterator that outputs const LIEF::Section&.
Definition Abstract/Binary.hpp:93
it_relocations relocations()
Return an iterator over the binary relocations (LIEF::Relocation).
Definition Abstract/Binary.hpp:173
it_const_symbols symbols() const
Return an iterator over the abstracted symbols in which the elements can't be modified.
Definition Abstract/Binary.hpp:143
std::vector< Symbol * > symbols_t
Internal container.
Definition Abstract/Binary.hpp:96
~Binary() override
instructions_it disassemble(uint64_t address, size_t size) const
Disassemble code starting at the given virtual address and with the given size.
virtual uint64_t virtual_size() const
Size of the binary when mapped in memory.
Definition Abstract/Binary.hpp:433
bool has_symbol(std::string_view name) const
Check if a Symbol with the given name exists.
Definition Abstract/Binary.hpp:148
virtual void remove_section(std::string_view name, bool clear=false)=0
Remove all the sections in the underlying binary.
void original_size(uint64_t size)
Change binary's original size.
Definition Abstract/Binary.hpp:261
const T * cast() const
This function can be used to down cast a Binary:
Definition Abstract/Binary.hpp:446
VA_TYPES
Enumeration of virtual address types used for patching and memory access.
Definition Abstract/Binary.hpp:64
@ AUTO
Automatically determine if the address is absolute or relative (default behavior).
Definition Abstract/Binary.hpp:67
std::vector< uint64_t > xref(uint64_t address) const
std::vector< Section * > sections_t
Internal container.
Definition Abstract/Binary.hpp:87
virtual bool is_pie() const =0
Check if the binary is position independent.
T * cast()
Definition Abstract/Binary.hpp:456
functions_t exported_functions() const
Return the functions exported by the binary.
Definition Abstract/Binary.hpp:190
virtual uint64_t page_size() const
Get the default memory page size according to the architecture and the format of the current binary.
virtual span< const uint8_t > get_content_from_virtual_address(uint64_t virtual_address, uint64_t size, VA_TYPES addr_type=VA_TYPES::AUTO) const =0
Return the content located at the given virtual address.
virtual std::ostream & print(std::ostream &os) const
Definition Abstract/Binary.hpp:285
const_ref_iterator< symbols_t > it_const_symbols
Iterator that outputs const LIEF::Symbol&.
Definition Abstract/Binary.hpp:102
virtual void patch_address(uint64_t address, uint64_t patch_value, size_t size=sizeof(uint64_t), VA_TYPES addr_type=VA_TYPES::AUTO)=0
Patch the address with the given value.
it_symbols symbols()
Return an iterator over the abstracted symbols in which the elements can be modified.
Definition Abstract/Binary.hpp:137
std::vector< uint8_t > assemble(uint64_t address, const std::vector< llvm::MCInst > &insts)
Assemble and patch the address with the given LLVM MCInst.
it_sections sections()
Return an iterator over the binary's sections (LIEF::Section).
Definition Abstract/Binary.hpp:161
virtual functions_t ctor_functions() const =0
Constructor functions that are called prior any other functions.
virtual result< uint64_t > get_function_address(std::string_view func_name) const
Return the address of the given function name.
std::vector< uint8_t > assemble(uint64_t address, std::string_view Asm, assembly::AssemblerConfig &config=assembly::AssemblerConfig::default_config())
Assemble and patch the provided assembly code at the specified address.
DebugInfo * load_debug_info(std::string_view path)
Load and associate an external debug file (e.g., DWARF or PDB) with this binary.
std::vector< uint8_t > assemble(uint64_t address, const llvm::MCInst &inst)
Assemble and patch the address with the given LLVM MCInst.
Binary & operator=(const Binary &)=delete
iterator_range< assembly::Instruction::Iterator > instructions_it
Instruction iterator.
Definition Abstract/Binary.hpp:114
virtual uint64_t imagebase() const =0
Default image base address if the ASLR is not enabled.
std::vector< std::string > imported_libraries() const
Return libraries which are imported by the binary.
Definition Abstract/Binary.hpp:195
Binary(FORMATS fmt)
DebugInfo * debug_info() const
Return the debug info if present. It can be either a LIEF::dwarf::DebugInfo or a LIEF::pdb::DebugInfo...
uint64_t original_size() const
Binary's original size.
Definition Abstract/Binary.hpp:185
void accept(Visitor &visitor) const override
Method so that a visitor can visit us.
it_const_relocations relocations() const
Definition Abstract/Binary.hpp:177
ref_iterator< relocations_t > it_relocations
Iterator that outputs LIEF::Relocation&.
Definition Abstract/Binary.hpp:108
std::vector< Relocation * > relocations_t
Internal container.
Definition Abstract/Binary.hpp:105
instructions_it disassemble(LIEF::span< uint8_t > buffer, uint64_t address=0) const
Definition Abstract/Binary.hpp:374
Binary(const Binary &)=delete
instructions_it disassemble(LIEF::span< const uint8_t > buffer, uint64_t address=0) const
Definition Abstract/Binary.hpp:369
virtual bool has_nx() const =0
Check if the binary uses NX protection.
This class provides a generic interface for accessing debug information from different formats such a...
Definition Abstract/DebugInfo.hpp:38
Definition Abstract/Header.hpp:40
Class which represents an abstracted Relocation.
Definition Abstract/Relocation.hpp:27
Class which represents an abstracted section.
Definition Abstract/Section.hpp:31
This class represents a symbol in an executable format.
Definition Abstract/Symbol.hpp:30
Definition Visitor.hpp:212
This class exposes the different elements that can be configured to assemble code.
Definition AssemblerConfig.hpp:29
static AssemblerConfig & default_config()
Default configuration.
Definition AssemblerConfig.hpp:50
This class interfaces the assembler/disassembler support.
Definition Engine.hpp:38
Definition iterators.hpp:681
Iterator which returns reference on container's values.
Definition iterators.hpp:121
Wrapper that contains an Object (T) or an error.
Definition errors.hpp:79
#define LIEF_LIFETIMEBOUND
Definition compiler_attributes.hpp:72
@ read_error
Definition errors.hpp:25
tl::unexpected< lief_errors > make_error_code(lief_errors e)
Create a standard error code from lief_errors.
Definition errors.hpp:55
Namespace related to assembly/disassembly support.
Definition Abstract/Binary.hpp:49
LIEF namespace.
Definition Abstract/Binary.hpp:42
tcb::span< ElementType, Extent > span
Definition span.hpp:22
ref_iterator< CT, U, typename decay_t< CT >::const_iterator > const_ref_iterator
Iterator which returns a const ref on container's values.
Definition iterators.hpp:386
const char * to_string(Binary::VA_TYPES e)
Definition Abstract/Binary.hpp:37
#define LIEF_API
Definition visibility.h:45
#define LIEF_LOCAL
Definition visibility.h:46