LIEF: Library to Instrument Executable Formats Version 0.17.0
Loading...
Searching...
No Matches
Abstract/Binary.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_ABSTRACT_BINARY_H
17#define LIEF_ABSTRACT_BINARY_H
18
19#include <vector>
20#include <memory>
21#include <unordered_map>
22
23#include "LIEF/visibility.h"
24#include "LIEF/Object.hpp"
25#include "LIEF/iterators.hpp"
26#include "LIEF/errors.hpp"
27#include "LIEF/span.hpp"
28
31
33
34namespace llvm {
35class MCInst;
36}
37namespace LIEF {
40class Section;
41class Relocation;
42class Symbol;
43
44class DebugInfo;
45
46namespace assembly {
47class Engine;
48}
49class LIEF_API Binary : public Object {
53 public:
54 enum class VA_TYPES {
57 AUTO = 0,
58 RVA = 1,
59 VA = 2,
60 };
61
62 enum FORMATS {
63 UNKNOWN = 0,
64 ELF,
65 PE,
66 MACHO,
67 OAT,
68 };
69
70 using functions_t = std::vector<Function>;
71 using sections_t = std::vector<Section*>;
74 using it_sections = ref_iterator<sections_t>;
77 using it_const_sections = const_ref_iterator<sections_t>;
80 using symbols_t = std::vector<Symbol*>;
83 using it_symbols = ref_iterator<symbols_t>;
86 using it_const_symbols = const_ref_iterator<symbols_t>;
89 using relocations_t = std::vector<Relocation*>;
92 using it_relocations = ref_iterator<relocations_t>;
95 using it_const_relocations = const_ref_iterator<relocations_t>;
98 using instructions_it = iterator_range<assembly::Instruction::Iterator>;
101
102 public:
104 Binary(FORMATS fmt);
105
106 ~Binary() override;
107
108 Binary& operator=(const Binary&) = delete;
109 Binary(const Binary&) = delete;
110 FORMATS format() const {
113 return format_;
114 }
115 Header header() const {
118 return get_abstract_header();
119 }
120 it_symbols symbols() {
123 return get_abstract_symbols();
124 }
125 it_const_symbols symbols() const {
128 return const_cast<Binary*>(this)->get_abstract_symbols();
129 }
130 bool has_symbol(const std::string& name) const {
133 return get_symbol(name) != nullptr;
134 }
135 const Symbol* get_symbol(const std::string& name) const;
139
140 Symbol* get_symbol(const std::string& name) {
141 return const_cast<Symbol*>(static_cast<const Binary*>(this)->get_symbol(name));
142 }
143 it_sections sections() {
146 return get_abstract_sections();
147 }
148
149 it_const_sections sections() const {
150 return const_cast<Binary*>(this)->get_abstract_sections();
151 }
152 virtual void remove_section(const std::string& name, bool clear = false) = 0;
155 it_relocations relocations() {
158 return get_abstract_relocations();
159 }
160
161 it_const_relocations relocations() const {
162 return const_cast<Binary*>(this)->get_abstract_relocations();
163 }
164 virtual uint64_t entrypoint() const = 0;
167 uint64_t original_size() const {
170 return original_size_;
171 }
172 functions_t exported_functions() const {
175 return get_abstract_exported_functions();
176 }
177 std::vector<std::string> imported_libraries() const {
180 return get_abstract_imported_libraries();
181 }
182 functions_t imported_functions() const {
185 return get_abstract_imported_functions();
186 }
187 virtual result<uint64_t> get_function_address(const std::string& func_name) const;
190 void accept(Visitor& visitor) const override;
193
194 std::vector<uint64_t> xref(uint64_t address) const;
195 virtual void patch_address(uint64_t address, const std::vector<uint8_t>& patch_value,
203 VA_TYPES addr_type = VA_TYPES::AUTO) = 0;
204 virtual void patch_address(uint64_t address, uint64_t patch_value, size_t size = sizeof(uint64_t),
212 VA_TYPES addr_type = VA_TYPES::AUTO) = 0;
213 virtual span<const uint8_t>
216 get_content_from_virtual_address(uint64_t virtual_address, uint64_t size,
217 VA_TYPES addr_type = VA_TYPES::AUTO) const = 0;
218 template<class T>
221 LIEF::result<T> get_int_from_virtual_address(
222 uint64_t va, VA_TYPES addr_type = VA_TYPES::AUTO) const
223 {
224 T value;
225 static_assert(std::is_integral<T>::value, "Require an integral type");
226 span<const uint8_t> raw = get_content_from_virtual_address(va, sizeof(T), addr_type);
227 if (raw.empty() || raw.size() < sizeof(T)) {
228 return make_error_code(lief_errors::read_error);
229 }
230
231 std::copy(raw.data(), raw.data() + sizeof(T),
232 reinterpret_cast<uint8_t*>(&value));
233 return value;
234 }
235 void original_size(uint64_t size) {
242 original_size_ = size;
243 }
244 virtual bool is_pie() const = 0;
247 virtual bool has_nx() const = 0;
250 virtual uint64_t imagebase() const = 0;
253 virtual functions_t ctor_functions() const = 0;
256 virtual result<uint64_t> offset_to_virtual_address(uint64_t offset, uint64_t slide = 0) const = 0;
262
263 virtual std::ostream& print(std::ostream& os) const {
264 return os;
265 }
266
267 LIEF_API friend std::ostream& operator<<(std::ostream& os, const Binary& binary) {
268 binary.print(os);
269 return os;
270 }
271 DebugInfo* debug_info() const;
286 instructions_it disassemble(uint64_t address, size_t size) const;
299 instructions_it disassemble(uint64_t address) const;
311 instructions_it disassemble(const std::string& function) const;
323 instructions_it disassemble(const uint8_t* buffer, size_t size,
329 uint64_t address = 0) const;
330
331 instructions_it disassemble(const std::vector<uint8_t>& buffer,
337 uint64_t address = 0) const {
338 return disassemble(buffer.data(), buffer.size(), address);
339 }
340
341 instructions_it disassemble(LIEF::span<const uint8_t> buffer,
342 uint64_t address = 0) const {
343 return disassemble(buffer.data(), buffer.size(), address);
344 }
345
346 instructions_it disassemble(LIEF::span<uint8_t> buffer, uint64_t address = 0) const {
347 return disassemble(buffer.data(), buffer.size(), address);
348 }
349 std::vector<uint8_t> assemble(uint64_t address, const std::string& Asm);
361 std::vector<uint8_t> assemble(uint64_t address, const llvm::MCInst& inst);
367 std::vector<uint8_t> assemble(uint64_t address,
373 const std::vector<llvm::MCInst>& insts);
374
375 protected:
376 FORMATS format_ = FORMATS::UNKNOWN;
377 mutable std::unique_ptr<DebugInfo> debug_info_;
378 mutable std::unordered_map<uint32_t, std::unique_ptr<assembly::Engine>> engines_;
379 uint64_t original_size_ = 0;
380
381 assembly::Engine* get_engine(uint64_t address) const;
382
383 template<uint32_t Key, class F>
384 LIEF_LOCAL assembly::Engine* get_cache_engine(uint64_t address, F&& f) const;
385
386 // These functions need to be overloaded by the object that claims to extend this Abstract Binary
387 virtual Header get_abstract_header() const = 0;
388 virtual symbols_t get_abstract_symbols() = 0;
389 virtual sections_t get_abstract_sections() = 0;
390 virtual relocations_t get_abstract_relocations() = 0;
391
392 virtual functions_t get_abstract_exported_functions() const = 0;
393 virtual functions_t get_abstract_imported_functions() const = 0;
394 virtual std::vector<std::string> get_abstract_imported_libraries() const = 0;
395};
396
397LIEF_API const char* to_string(Binary::VA_TYPES e);
398LIEF_API const char* to_string(Binary::FORMATS e);
399
400}
401
402
403#endif
Function.hpp
Header.hpp
Instruction.hpp
Object.hpp
LIEF::Binary
Abstract binary that exposes an uniform API for the different executable file formats.
Definition Abstract/Binary.hpp:52
LIEF::Binary::header
Header header() const
Return the abstract header of the binary.
Definition Abstract/Binary.hpp:117
LIEF::Binary::patch_address
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.
LIEF::Binary::imported_functions
functions_t imported_functions() const
Return functions imported by the binary.
Definition Abstract/Binary.hpp:184
LIEF::Binary::entrypoint
virtual uint64_t entrypoint() const =0
Binary's entrypoint (if any)
LIEF::Binary::FORMATS
FORMATS
Definition Abstract/Binary.hpp:62
LIEF::Binary::offset_to_virtual_address
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.
LIEF::Binary::has_symbol
bool has_symbol(const std::string &name) const
Check if a Symbol with the given name exists.
Definition Abstract/Binary.hpp:132
LIEF::Binary::get_symbol
const Symbol * get_symbol(const std::string &name) const
Return the Symbol with the given name If the symbol does not exist, return a nullptr.
LIEF::Binary::get_symbol
Symbol * get_symbol(const std::string &name)
Definition Abstract/Binary.hpp:140
LIEF::Binary::get_int_from_virtual_address
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:221
LIEF::Binary::format
FORMATS format() const
Executable format (ELF, PE, Mach-O) of the underlying binary.
Definition Abstract/Binary.hpp:112
LIEF::Binary::operator<<
friend std::ostream & operator<<(std::ostream &os, const Binary &binary)
Definition Abstract/Binary.hpp:267
LIEF::Binary::sections
it_const_sections sections() const
Definition Abstract/Binary.hpp:149
LIEF::Binary::remove_section
virtual void remove_section(const std::string &name, bool clear=false)=0
Remove all the sections in the underlying binary.
LIEF::Binary::relocations
it_relocations relocations()
Return an iterator over the binary relocation (LIEF::Relocation)
Definition Abstract/Binary.hpp:157
LIEF::Binary::symbols
it_const_symbols symbols() const
Return an iterator over the abstracted symbols in which the elements can't be modified.
Definition Abstract/Binary.hpp:127
LIEF::Binary::~Binary
~Binary() override
LIEF::Binary::disassemble
instructions_it disassemble(uint64_t address, size_t size) const
Disassemble code starting a the given virtual address and with the given size.
LIEF::Binary::assemble
std::vector< uint8_t > assemble(uint64_t address, const std::string &Asm)
Assemble and patch the provided assembly code at the specified address.
LIEF::Binary::original_size
void original_size(uint64_t size)
Change binary's original size.
Definition Abstract/Binary.hpp:241
LIEF::Binary::VA_TYPES
VA_TYPES
Type of a virtual address.
Definition Abstract/Binary.hpp:56
LIEF::Binary::disassemble
instructions_it disassemble(const std::string &function) const
Disassemble code for the given symbol name.
LIEF::Binary::xref
std::vector< uint64_t > xref(uint64_t address) const
LIEF::Binary::is_pie
virtual bool is_pie() const =0
Check if the binary is position independent.
LIEF::Binary::exported_functions
functions_t exported_functions() const
Return the functions exported by the binary.
Definition Abstract/Binary.hpp:174
LIEF::Binary::get_content_from_virtual_address
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.
LIEF::Binary::print
virtual std::ostream & print(std::ostream &os) const
Definition Abstract/Binary.hpp:263
LIEF::Binary::patch_address
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.
LIEF::Binary::symbols
it_symbols symbols()
Return an iterator over the abstracted symbols in which the elements can be modified.
Definition Abstract/Binary.hpp:122
LIEF::Binary::get_function_address
virtual result< uint64_t > get_function_address(const std::string &func_name) const
Return the address of the given function name.
LIEF::Binary::assemble
std::vector< uint8_t > assemble(uint64_t address, const std::vector< llvm::MCInst > &insts)
Assemble and patch the address with the given LLVM MCInst.
LIEF::Binary::sections
it_sections sections()
Return an iterator over the binary's sections (LIEF::Section)
Definition Abstract/Binary.hpp:145
LIEF::Binary::ctor_functions
virtual functions_t ctor_functions() const =0
Constructor functions that are called prior any other functions.
LIEF::Binary::disassemble
instructions_it disassemble(uint64_t address) const
Disassemble code starting a the given virtual address.
LIEF::Binary::Binary
Binary()
LIEF::Binary::assemble
std::vector< uint8_t > assemble(uint64_t address, const llvm::MCInst &inst)
Assemble and patch the address with the given LLVM MCInst.
LIEF::Binary::operator=
Binary & operator=(const Binary &)=delete
LIEF::Binary::imagebase
virtual uint64_t imagebase() const =0
Default image base address if the ASLR is not enabled.
LIEF::Binary::imported_libraries
std::vector< std::string > imported_libraries() const
Return libraries which are imported by the binary.
Definition Abstract/Binary.hpp:179
LIEF::Binary::disassemble
instructions_it disassemble(const std::vector< uint8_t > &buffer, uint64_t address=0) const
Disassemble code provided by the given vector of bytes at the specified address parameter.
Definition Abstract/Binary.hpp:336
LIEF::Binary::Binary
Binary(FORMATS fmt)
LIEF::Binary::debug_info
DebugInfo * debug_info() const
Return the debug info if present. It can be either a LIEF::dwarf::DebugInfo or a LIEF::pdb::DebugInfo...
LIEF::Binary::original_size
uint64_t original_size() const
Binary's original size.
Definition Abstract/Binary.hpp:169
LIEF::Binary::accept
void accept(Visitor &visitor) const override
Method so that a visitor can visit us.
LIEF::Binary::relocations
it_const_relocations relocations() const
Definition Abstract/Binary.hpp:161
LIEF::Binary::disassemble
instructions_it disassemble(LIEF::span< uint8_t > buffer, uint64_t address=0) const
Definition Abstract/Binary.hpp:346
LIEF::Binary::Binary
Binary(const Binary &)=delete
LIEF::Binary::disassemble
instructions_it disassemble(LIEF::span< const uint8_t > buffer, uint64_t address=0) const
Definition Abstract/Binary.hpp:341
LIEF::Binary::disassemble
instructions_it disassemble(const uint8_t *buffer, size_t size, uint64_t address=0) const
Disassemble code provided by the given buffer at the specified address parameter.
LIEF::Binary::has_nx
virtual bool has_nx() const =0
Check if the binary uses NX protection.
LIEF::DebugInfo
Definition Abstract/DebugInfo.hpp:25
LIEF::Object
Definition Object.hpp:25
LIEF::Relocation
Class which represents an abstracted Relocation.
Definition Abstract/Relocation.hpp:27
LIEF::Section
Class which represents an abstracted section.
Definition Abstract/Section.hpp:29
LIEF::Symbol
This class represents a symbol in an executable format.
Definition Abstract/Symbol.hpp:28
LIEF::assembly::Engine
This class interfaces the assembler/disassembler support.
Definition Engine.hpp:34
errors.hpp
lief_errors::read_error
@ read_error
Definition errors.hpp:24
make_error_code
tl::unexpected< lief_errors > make_error_code(lief_errors e)
Create an standard error code from lief_errors.
Definition errors.hpp:52
iterators.hpp
LIEF::assembly
Namespace related to assembly/disassembly support.
Definition Abstract/Binary.hpp:46
LIEF
LIEF namespace.
Definition Abstract/Binary.hpp:39
LIEF::span
tcb::span< ElementType, Extent > span
Definition span.hpp:22
LIEF::to_string
const char * to_string(Binary::VA_TYPES e)
LIEF::result
tl::expected< T, lief_errors > result
Wrapper that contains an Object (T) or an error.
Definition errors.hpp:75
llvm
Definition Abstract/Binary.hpp:34
span.hpp
visibility.h
LIEF_API
#define LIEF_API
Definition visibility.h:41
LIEF_LOCAL
#define LIEF_LOCAL
Definition visibility.h:42