deps: update lief to 1.0.0

PR-URL: https://github.com/nodejs/node/pull/66345
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
Node.js GitHub Bot authored and GitHub committed 2026-09-29 08:57:54 +00:00
1 parent 5a271b3495
commit 691cf6245c
1477 files changed
+162690 -144617

No files matched your search

+2 -2
View File
@@ -186,8 +186,8 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2017 - 2025 R. Thomas
Copyright 2017 - 2025 Quarkslab
Copyright 2017 - 2026 R. Thomas
Copyright 2017 - 2026 Quarkslab
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
+40 -42
View File
@@ -17,28 +17,39 @@ modify and abstract ELF, PE and MachO formats.
**Main features**:
* **Parsing**: LIEF can parse [ELF](https://lief.re/doc/latest/formats/elf/index.html), [PE](https://lief.re/doc/latest/formats/pe/index.html), [MachO](https://lief.re/doc/latest/formats/macho/index.html), [COFF](https://lief.re/doc/latest/formats/coff/index.html), OAT, DEX, VDEX, ART and provides an user-friendly API to access to internals.
* **Modify**: LIEF can use to modify some parts of these formats (adding a section, changing a symbol's name, ...)
* **Parsing**: LIEF can parse [ELF](https://lief.re/doc/latest/formats/elf/index.html), [PE](https://lief.re/doc/latest/formats/pe/index.html), [MachO](https://lief.re/doc/latest/formats/macho/index.html), [COFF](https://lief.re/doc/latest/formats/coff/index.html), OAT, DEX, VDEX, ART and provides a user-friendly API to access their internals.
* **Modify**: LIEF can be used to modify some parts of these formats (adding a section, changing a symbol's name, ...)
* **Abstract**: Three formats have common features like sections, symbols, entry point... LIEF factors them.
* **API**: LIEF can be used in [C++](https://lief.re/doc/latest/doxygen/), Python, [Rust](https://lief-rs.s3.fr-par.scw.cloud/doc/latest/lief/index.html) and C
* **API**: You can use LIEF via [C++](https://lief.re/doc/latest/doxygen/), Python, [Rust](https://lief-rs.s3.fr-par.scw.cloud/doc/latest/lief/index.html), C and
[Node.js](https://github.com/Piebald-AI/node-lief) (unofficial, AI-generated)
**Extended features**:
* [**Runtime**](https://lief.re/doc/latest/runtime/intro.html)
* [**DWARF/PDB** Support](https://lief.re/doc/latest/extended/debug_info/index.html)
* [**Objective-C** Metadata](https://lief.re/doc/latest/extended/objc/index.html)
* [**Dyld Shared Cache**](https://lief.re/doc/latest/extended/dsc/index.html) with support for extracting Dylib
* [**Disassembler**](https://lief.re/doc/latest/extended/disassembler/index.html): AArch64, x86/x86-64, ARM, RISC-V, Mips, PowerPC, eBPF
* [**Assembler**](https://lief.re/doc/latest/extended/assembler/index.html): AArch64, x86/x86-64
* [**Assembler**](https://lief.re/doc/latest/extended/assembler/index.html): AArch64, x86/x86-64, RISC-V
**Plugins**:
* [**Ghidra**](https://lief.re/doc/latest/plugins/ghidra/index.html)
* [**BinaryNinja**](https://lief.re/doc/latest/plugins/binaryninja/index.html)
# Sponsors
<br />
<p align="center">
<a href="https://quansight.com/" target="_blank">
<img width="300px" src="https://lief.re/quansight_logo.jpg"/><br />
</a>
</p>
# Content
- [About](#about)
- [Download / Install](#downloads--install)
- [Downloads / Install](#downloads--install)
- [Getting started](#getting-started)
- [Blog](https://lief.re/blog/)
- [Documentation](#documentation)
@@ -56,21 +67,21 @@ modify and abstract ELF, PE and MachO formats.
- [ELF Coredump](https://lief.re/doc/latest/tutorials/12_elf_coredump.html)
- [PE Authenticode](https://lief.re/doc/latest/tutorials/13_pe_authenticode.html)
- [Contact](#contact)
- [About](#about)
- [About](#about-1)
- [Authors](#authors)
- [License](#license)
- [Bibtex](#bibtex)
## Downloads / Install
## C++
### C++
```cmake
find_package(LIEF REQUIRED)
target_link_libraries(my-project LIEF::LIEF)
```
## Rust
### Rust
```toml
[package]
@@ -79,10 +90,16 @@ version = "0.0.1"
edition = "2021"
[dependencies]
lief = "0.17.1"
lief = "1.0.0"
```
## Python
### Homebrew
```console
brew install lief
```
### Python
To install the latest **version** (release):
@@ -102,7 +119,7 @@ pip install [--user] --force-reinstall --index-url https://lief.s3-website.fr-pa
- **Nightly**:
* SDK: https://lief.s3-website.fr-par.scw.cloud/latest/sdk
* Python Wheels: https://lief.s3-website.fr-par.scw.cloud/latest/lief
- **v0.17.1**: https://github.com/lief-project/LIEF/releases/tag/0.17.1
- **v1.0.0**: https://github.com/lief-project/LIEF/releases/tag/1.0.0
Here are guides to install or integrate LIEF:
@@ -124,15 +141,14 @@ for section in binary.sections:
print(section.name, section.virtual_address)
# PE
binary = lief.parse("C:\\Windows\\explorer.exe")
if rheader := pe.rich_header:
binary = lief.parse(r"C:\Windows\explorer.exe")
if (rheader := binary.rich_header) is not None:
print(rheader.key)
# Mach-O
binary = lief.parse("/usr/bin/ls")
for fixup in binary.dyld_chained_fixups:
print(fixup)
if (fixups := binary.dyld_chained_fixups) is not None:
print(fixups)
```
### Rust
@@ -153,27 +169,30 @@ if let Some(Binary::PE(pe)) = Binary::parse(path.as_str()) {
### C++
```cpp
#include <iostream>
#include <LIEF/LIEF.hpp>
int main(int argc, char** argv) {
// ELF
if (std::unique_ptr<const LIEF::ELF::Binary> elf = LIEF::ELF::Parser::parse("/bin/ls")) {
for (const LIEF::ELF::Section& section : elf->sections()) {
std::cout << section->name() << ' ' << section->virtual_address() << '\n';
std::cout << section.name() << ' ' << section.virtual_address() << '\n';
}
}
// PE
if (std::unique_ptr<const LIEF::PE::Binary> pe = LIEF::PE::Parser::parse("C:\\Windows\\explorer.exe")) {
if (const LIEF::PE::RichHeader* rheader : pe->rich_header()) {
if (const LIEF::PE::RichHeader* rheader = pe->rich_header()) {
std::cout << rheader->key() << '\n';
}
}
// Mach-O
if (std::unique_ptr<LIEF::MachO::FatBinary> macho = LIEF::MachO::Parser::parse("/bin/ls")) {
for (const LIEF::MachO::DyldChainedFixups& fixup : macho->dyld_chained_fixups()) {
std::cout << fixup << '\n';
for (const LIEF::MachO::Binary& bin : *macho) {
if (const LIEF::MachO::DyldChainedFixups* fixups = bin.dyld_chained_fixups()) {
std::cout << *fixups << '\n';
}
}
}
@@ -182,25 +201,6 @@ int main(int argc, char** argv) {
```
### C (Limited API)
```cpp
#include <LIEF/LIEF.h>
int main(int argc, char** argv) {
Elf_Binary_t* elf = elf_parse("/usr/bin/ls");
Elf_Section_t** sections = elf->sections;
for (size_t i = 0; sections[i] != NULL; ++i) {
printf("%s\n", sections[i]->name);
}
elf_binary_destroy(elf);
return 0;
}
```
## Documentation
* [Main documentation](https://lief.re/doc/latest/index.html)
@@ -220,7 +220,7 @@ Romain Thomas ([@rh0main](https://www.romainthomas.fr/)) - Formerly at [Quarksla
### License
LIEF is provided under the [Apache 2.0 license](https://github.com/lief-project/LIEF/blob/0.17.1/LICENSE).
[Apache 2.0](https://github.com/lief-project/LIEF/blob/1.0.0/LICENSE).
### Bibtex
@@ -233,5 +233,3 @@ LIEF is provided under the [Apache 2.0 license](https://github.com/lief-project/
year = "2017"
}
```
+6 -2
View File
@@ -1,5 +1,9 @@
#include "mbedtls/mbedtls_config.h"
#if defined (MBEDTLS_ARCH_IS_X86)
#undef MBEDTLS_AESNI_C
#if defined(MBEDTLS_ARCH_IS_X86)
#undef MBEDTLS_AESNI_C
#endif
#if defined(MBEDTLS_DEBUG_C)
#undef MBEDTLS_DEBUG_C
#endif
+14
View File
@@ -0,0 +1,14 @@
// Disable MbedTLS options that are not thread-safe. See
// `tests/scripts/components-sanitizers.sh` in the MbedTLS tree: both options
// are unset there when building with MBEDTLS_THREADING_PTHREAD under TSan.
#if defined(MBEDTLS_THREADING_C)
// Self-tests do not currently use multiple threads.
#if defined(MBEDTLS_SELF_TEST)
#undef MBEDTLS_SELF_TEST
#endif
// Interruptible ECC operations are not thread-safe.
#if defined(MBEDTLS_ECP_RESTARTABLE)
#undef MBEDTLS_ECP_RESTARTABLE
#endif
#endif
+6 -6
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,10 +19,10 @@
#include "LIEF/config.h"
#if defined(LIEF_ART_SUPPORT)
#include "LIEF/ART/Parser.hpp"
#include "LIEF/ART/utils.hpp"
#include "LIEF/ART/File.hpp"
#include "LIEF/ART/EnumToString.hpp"
#include "LIEF/ART/Parser.hpp"
#include "LIEF/ART/utils.hpp"
#include "LIEF/ART/File.hpp"
#include "LIEF/ART/EnumToString.hpp"
#endif
#endif
+2 -3
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,4 +37,3 @@ LIEF_API const char* to_string(ART_44::IMAGE_ROOTS e);
} // namespace LIEF
#endif
+5 -5
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,10 +31,10 @@ class LIEF_API File : public Object {
public:
File& operator=(const File& copy) = delete;
File(const File& copy) = delete;
File(const File& copy) = delete;
const Header& header() const;
Header& header();
const Header& header() const LIEF_LIFETIMEBOUND;
Header& header() LIEF_LIFETIMEBOUND;
void accept(Visitor& visitor) const override;
+24 -24
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -85,43 +85,43 @@ class LIEF_API Header : public Object {
~Header() override;
private:
magic_t magic_;
art_version_t version_;
magic_t magic_{};
art_version_t version_ = 0;
uint32_t image_begin_;
uint32_t image_size_;
uint32_t image_begin_ = 0;
uint32_t image_size_ = 0;
uint32_t oat_checksum_;
uint32_t oat_checksum_ = 0;
uint32_t oat_file_begin_;
uint32_t oat_file_end_;
uint32_t oat_file_begin_ = 0;
uint32_t oat_file_end_ = 0;
uint32_t oat_data_begin_;
uint32_t oat_data_end_;
uint32_t oat_data_begin_ = 0;
uint32_t oat_data_end_ = 0;
int32_t patch_delta_;
uint32_t image_roots_;
int32_t patch_delta_ = 0;
uint32_t image_roots_ = 0;
uint32_t pointer_size_;
uint32_t pointer_size_ = 0;
bool compile_pic_;
bool compile_pic_ = false;
uint32_t nb_sections_;
uint32_t nb_methods_;
uint32_t nb_sections_ = 0;
uint32_t nb_methods_ = 0;
bool is_pic_;
bool is_pic_ = false;
// From ART 29
// ===========
uint32_t boot_image_begin_;
uint32_t boot_image_size_;
uint32_t boot_image_begin_ = 0;
uint32_t boot_image_size_ = 0;
uint32_t boot_oat_begin_;
uint32_t boot_oat_size_;
uint32_t boot_oat_begin_ = 0;
uint32_t boot_oat_size_ = 0;
STORAGE_MODES storage_mode_;
STORAGE_MODES storage_mode_ = STORAGE_MODES::STORAGE_UNCOMPRESSED;
uint32_t data_size_;
uint32_t data_size_ = 0;
};
} // Namespace ART
+8 -7
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,14 +28,15 @@ namespace ART {
class File;
/// Class which parses an ART file and transform into a ART::File object
/// Class which parses an ART file and transforms it into an ART::File object
class LIEF_API Parser {
public:
static std::unique_ptr<File> parse(const std::string& file);
static std::unique_ptr<File> parse(std::vector<uint8_t> data, const std::string& name = "");
static std::unique_ptr<File> parse(std::vector<uint8_t> data,
const std::string& name = "");
Parser& operator=(const Parser& copy) = delete;
Parser(const Parser& copy) = delete;
Parser(const Parser& copy) = delete;
private:
Parser();
@@ -95,8 +96,8 @@ class LIEF_API Parser {
//// Parse a **Single** java.lang.DexCache object
//template<typename ART_T, typename PTR_T>
//void parse_class_roots(size_t object_offset);
// template<typename ART_T, typename PTR_T>
// void parse_class_roots(size_t object_offset);
std::unique_ptr<File> file_;
std::unique_ptr<BinaryStream> stream_;
+43 -44
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,32 +21,32 @@ namespace ART {
enum STORAGE_MODES {
STORAGE_UNCOMPRESSED = 0,
STORAGE_LZ4 = 1,
STORAGE_LZ4HC = 2,
STORAGE_LZ4 = 1,
STORAGE_LZ4HC = 2,
};
namespace ART_17 {
enum IMAGE_METHODS {
RESOLUTION_METHOD = 0,
IMT_CONFLICT_METHOD = 1,
IMT_UNIMPLEMENTED_METHOD = 2,
CALLEE_SAVE_METHOD = 3,
REFS_ONLY_SAVE_METHOD = 4,
RESOLUTION_METHOD = 0,
IMT_CONFLICT_METHOD = 1,
IMT_UNIMPLEMENTED_METHOD = 2,
CALLEE_SAVE_METHOD = 3,
REFS_ONLY_SAVE_METHOD = 4,
REFS_AND_ARGS_SAVE_METHOD = 5,
};
enum IMAGE_SECTIONS {
SECTION_OBJECTS = 0,
SECTION_ART_FIELDS = 1,
SECTION_ART_METHODS = 2,
SECTION_INTERNED_STRINGS = 3,
SECTION_IMAGE_BITMAP = 4,
SECTION_OBJECTS = 0,
SECTION_ART_FIELDS = 1,
SECTION_ART_METHODS = 2,
SECTION_INTERNED_STRINGS = 3,
SECTION_IMAGE_BITMAP = 4,
};
enum IMAGE_ROOTS {
DEX_CACHES = 0,
CLASS_ROOTS = 1,
DEX_CACHES = 0,
CLASS_ROOTS = 1,
};
@@ -59,19 +59,18 @@ using ART_17::IMAGE_METHODS;
using ART_17::IMAGE_ROOTS;
enum IMAGE_SECTIONS {
SECTION_OBJECTS = 0,
SECTION_ART_FIELDS = 1,
SECTION_ART_METHODS = 2,
SECTION_RUNTIME_METHODS = 3, // New in ART 29
SECTION_IMT_CONFLICT_TABLES = 4, // New in ART 29
SECTION_DEX_CACHE_ARRAYS = 5, // New in ART 29
SECTION_INTERNED_STRINGS = 6,
SECTION_CLASS_TABLE = 7, // New in ART 29
SECTION_IMAGE_BITMAP = 8,
SECTION_OBJECTS = 0,
SECTION_ART_FIELDS = 1,
SECTION_ART_METHODS = 2,
SECTION_RUNTIME_METHODS = 3, // New in ART 29
SECTION_IMT_CONFLICT_TABLES = 4, // New in ART 29
SECTION_DEX_CACHE_ARRAYS = 5, // New in ART 29
SECTION_INTERNED_STRINGS = 6,
SECTION_CLASS_TABLE = 7, // New in ART 29
SECTION_IMAGE_BITMAP = 8,
};
} // Namespace ART_29
@@ -81,16 +80,16 @@ using ART_29::IMAGE_METHODS;
using ART_29::IMAGE_ROOTS;
enum IMAGE_SECTIONS {
SECTION_OBJECTS = 0,
SECTION_ART_FIELDS = 1,
SECTION_ART_METHODS = 2,
SECTION_RUNTIME_METHODS = 3,
SECTION_IM_TABLES = 4, // New in ART 30
SECTION_IMT_CONFLICT_TABLES = 5,
SECTION_DEX_CACHE_ARRAYS = 6,
SECTION_INTERNED_STRINGS = 7,
SECTION_CLASS_TABLE = 8,
SECTION_IMAGE_BITMAP = 9,
SECTION_OBJECTS = 0,
SECTION_ART_FIELDS = 1,
SECTION_ART_METHODS = 2,
SECTION_RUNTIME_METHODS = 3,
SECTION_IM_TABLES = 4, // New in ART 30
SECTION_IMT_CONFLICT_TABLES = 5,
SECTION_DEX_CACHE_ARRAYS = 6,
SECTION_INTERNED_STRINGS = 7,
SECTION_CLASS_TABLE = 8,
SECTION_IMAGE_BITMAP = 9,
};
} // Namespace ART_30
@@ -100,19 +99,19 @@ namespace ART_44 {
using ART_30::IMAGE_SECTIONS;
enum IMAGE_METHODS {
RESOLUTION_METHOD = 0,
IMT_CONFLICT_METHOD = 1,
IMT_UNIMPLEMENTED_METHOD = 2,
RESOLUTION_METHOD = 0,
IMT_CONFLICT_METHOD = 1,
IMT_UNIMPLEMENTED_METHOD = 2,
SAVE_ALL_CALLEE_SAVES_METHOD = 3, // New in ART 44
SAVE_REFS_ONLY_METHOD = 4, // New in ART 44
SAVE_REFS_AND_ARGS_METHOD = 5, // New in ART 44
SAVE_EVERYTHING_METHOD = 6, // New in ART 44
SAVE_REFS_ONLY_METHOD = 4, // New in ART 44
SAVE_REFS_AND_ARGS_METHOD = 5, // New in ART 44
SAVE_EVERYTHING_METHOD = 6, // New in ART 44
};
enum IMAGE_ROOTS {
DEX_CACHES = 0,
CLASS_ROOTS = 1,
DEX_CACHES = 0,
CLASS_ROOTS = 1,
CLASS_LOADER = 2, // New in ART 44
};
+4 -4
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,8 +35,8 @@ class LIEF_API Hash : public LIEF::Hash {
using LIEF::Hash::visit;
public:
void visit(const File& file) override;
void visit(const Header& header) override;
void visit(const File& file) override;
void visit(const Header& header) override;
~Hash() override;
};
+59 -62
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,25 +49,25 @@ struct brooks_read_barrier_t {
template<class T>
struct jobject_t {
heap_reference_t klass;
uint32_t monitor;
T brooks_read_barrier;
uint32_t monitor;
T brooks_read_barrier;
};
template<>
struct jobject_t<no_brooks_read_barrier_t> {
heap_reference_t klass;
uint32_t monitor;
uint32_t monitor;
};
template<class T = no_brooks_read_barrier_t>
struct ALIGNED_(4) jarray_t {
jobject_t<T> object;
int32_t length;
int32_t length;
uint32_t* elements;
};
template<class T = no_brooks_read_barrier_t>
struct ALIGNED_(4) jclass_t {
jobject_t<T> object;
jobject_t<T> object;
heap_reference_t class_loader;
heap_reference_t component_type;
@@ -86,8 +86,8 @@ struct ALIGNED_(4) jclass_t {
uint64_t virtual_methods;
uint32_t class_size;
uint32_t clinit_thread_id;
int32_t dex_class_def_idx;
int32_t dex_type_idx;
int32_t dex_class_def_idx;
int32_t dex_type_idx;
uint32_t num_direct_methods;
uint32_t num_instance_fields;
uint32_t num_reference_instance_fields;
@@ -97,15 +97,15 @@ struct ALIGNED_(4) jclass_t {
uint32_t object_size;
uint32_t primitive_type;
uint32_t reference_instance_offsets;
int32_t status;
int32_t status;
};
template<class T = no_brooks_read_barrier_t>
struct ALIGNED_(4) jstring_t {
jobject_t<T> object;
int32_t count;
uint32_t hash_code;
uint16_t* value;
int32_t count;
uint32_t hash_code;
uint16_t* value;
};
template<class T = no_brooks_read_barrier_t>
@@ -118,7 +118,7 @@ struct ALIGNED_(4) jdex_cache_t {
heap_reference_t resolved_methods;
heap_reference_t resolved_types;
heap_reference_t strings;
uint64_t dex_file;
uint64_t dex_file;
};
@@ -132,7 +132,7 @@ namespace ART_29 {
/// Namespace related to the Java part of ART 29
namespace Java {
using heap_reference_t = ART_17::Java::heap_reference_t;
using heap_reference_t = ART_17::Java::heap_reference_t;
using brooks_read_barrier_t = ART_17::Java::brooks_read_barrier_t;
template<class T = no_brooks_read_barrier_t>
@@ -143,9 +143,9 @@ using jarray_t = ART_17::Java::jarray_t<T>;
template<class T = no_brooks_read_barrier_t>
struct ALIGNED_(4) jclass_t {
jobject_t<T> object;
jobject_t<T> object;
heap_reference_t annotation_type; // ADDED in ART 29
heap_reference_t annotation_type; // ADDED in ART 29
heap_reference_t class_loader;
heap_reference_t component_type;
heap_reference_t dex_cache;
@@ -153,19 +153,19 @@ struct ALIGNED_(4) jclass_t {
heap_reference_t iftable;
heap_reference_t name;
heap_reference_t super_class;
heap_reference_t verify_error; // Type CHANGED from Class to Object
heap_reference_t verify_error; // Type CHANGED from Class to Object
heap_reference_t vtable;
uint32_t access_flags;
uint64_t dex_cache_strings; // direct_methods REPLACED with dex_cache_string
uint64_t dex_cache_strings; // direct_methods REPLACED with dex_cache_string
uint64_t ifields;
uint64_t methods; // ADDED in ART 29
uint64_t methods; // ADDED in ART 29
uint64_t sfields;
uint32_t class_flags; // virtual_methods REPLACED with class_flags
uint32_t class_flags; // virtual_methods REPLACED with class_flags
uint32_t class_size;
uint32_t clinit_thread_id;
int32_t dex_class_def_idx;
int32_t dex_type_idx;
int32_t dex_class_def_idx;
int32_t dex_type_idx;
// uint32_t num_direct_methods; // REMOVED in ART 29
// uint32_t num_instance_fields; // REMOVED in ART 29
uint32_t num_reference_instance_fields;
@@ -175,10 +175,10 @@ struct ALIGNED_(4) jclass_t {
uint32_t object_size;
uint32_t primitive_type;
uint32_t reference_instance_offsets;
int32_t status;
int32_t status;
uint16_t copied_methods_offset; // ADDED in ART 29
uint16_t virtual_methods_offset; // ADDED in ART 29
uint16_t copied_methods_offset; // ADDED in ART 29
uint16_t virtual_methods_offset; // ADDED in ART 29
};
@@ -192,20 +192,18 @@ struct ALIGNED_(4) jdex_cache_t {
heap_reference_t dex;
heap_reference_t location;
uint64_t dex_file; // LOCATION CHANGED
uint64_t resolved_fields; // TYPE CHANGED from heap_reference_t to uint64_t
uint64_t resolved_methods; // TYPE CHANGED from heap_reference_t to uint64_t
uint64_t resolved_types; // TYPE CHANGED from heap_reference_t to uint64_t
uint64_t strings; // TYPE CHANGED from heap_reference_t to uint64_t
uint32_t num_resolved_fields; // ADDED in ART 29
uint32_t num_resolved_methods; // ADDED in ART 29
uint32_t num_resolved_types; // ADDED in ART 29
uint32_t num_strings; // ADDED in ART 29
uint64_t dex_file; // LOCATION CHANGED
uint64_t resolved_fields; // TYPE CHANGED from heap_reference_t to uint64_t
uint64_t resolved_methods; // TYPE CHANGED from heap_reference_t to uint64_t
uint64_t resolved_types; // TYPE CHANGED from heap_reference_t to uint64_t
uint64_t strings; // TYPE CHANGED from heap_reference_t to uint64_t
uint32_t num_resolved_fields; // ADDED in ART 29
uint32_t num_resolved_methods; // ADDED in ART 29
uint32_t num_resolved_types; // ADDED in ART 29
uint32_t num_strings; // ADDED in ART 29
};
} // Namespace Java
} // Namespace ART_29
@@ -218,7 +216,7 @@ namespace ART_30 {
/// Namespace related to the Java part of ART 30
namespace Java {
using heap_reference_t = ART_29::Java::heap_reference_t;
using heap_reference_t = ART_29::Java::heap_reference_t;
using brooks_read_barrier_t = ART_29::Java::brooks_read_barrier_t;
template<class T = no_brooks_read_barrier_t>
@@ -250,7 +248,7 @@ namespace ART_44 {
namespace Java {
using heap_reference_t = ART_30::Java::heap_reference_t;
using heap_reference_t = ART_30::Java::heap_reference_t;
using brooks_read_barrier_t = ART_30::Java::brooks_read_barrier_t;
template<class T = no_brooks_read_barrier_t>
@@ -261,13 +259,13 @@ using jarray_t = ART_30::Java::jarray_t<T>;
template<class T = no_brooks_read_barrier_t>
struct ALIGNED_(4) jclass_t {
jobject_t<T> object;
jobject_t<T> object;
// heap_reference_t annotation_type; // REMOVED in ART 44
heap_reference_t class_loader;
heap_reference_t component_type;
heap_reference_t dex_cache;
heap_reference_t ext_data; // ADDED in ART 44
heap_reference_t ext_data; // ADDED in ART 44
heap_reference_t iftable;
heap_reference_t name;
heap_reference_t super_class;
@@ -279,19 +277,19 @@ struct ALIGNED_(4) jclass_t {
uint64_t ifields;
uint64_t methods;
uint64_t sfields;
uint32_t access_flags; // ADDED in ART 44
uint32_t access_flags; // ADDED in ART 44
uint32_t class_flags;
uint32_t class_size;
uint32_t clinit_thread_id;
int32_t dex_class_def_idx;
int32_t dex_type_idx;
int32_t dex_class_def_idx;
int32_t dex_type_idx;
uint32_t num_reference_instance_fields;
uint32_t num_reference_static_fields;
uint32_t object_size;
uint32_t object_size_alloc_fast_path; // ADDED in ART 44
uint32_t object_size_alloc_fast_path; // ADDED in ART 44
uint32_t primitive_type;
uint32_t reference_instance_offsets;
int32_t status;
int32_t status;
uint16_t copied_methods_offset;
uint16_t virtual_methods_offset;
};
@@ -310,19 +308,19 @@ struct ALIGNED_(4) jdex_cache_t {
// heap_reference_t dex; // REMOVED in ART 44
heap_reference_t location;
uint32_t num_resolved_call_sites; // ADDED in ART 44 (related to DEX38 format)
uint64_t dex_file;
uint64_t resolved_call_sites; // ADDED in ART 44 (related to DEX38 format)
uint64_t resolved_fields;
uint64_t resolved_method_types; // ADDED in ART 44
uint64_t resolved_methods;
uint64_t resolved_types;
uint64_t strings;
uint32_t num_resolved_fields;
uint32_t num_resolved_methods_types; // ADDED in ART 44
uint32_t num_resolved_methods;
uint32_t num_resolved_types;
uint32_t num_strings;
uint32_t num_resolved_call_sites; // ADDED in ART 44 (related to DEX38 format)
uint64_t dex_file;
uint64_t resolved_call_sites; // ADDED in ART 44 (related to DEX38 format)
uint64_t resolved_fields;
uint64_t resolved_method_types; // ADDED in ART 44
uint64_t resolved_methods;
uint64_t resolved_types;
uint64_t strings;
uint32_t num_resolved_fields;
uint32_t num_resolved_methods_types; // ADDED in ART 44
uint32_t num_resolved_methods;
uint32_t num_resolved_types;
uint32_t num_strings;
};
@@ -338,7 +336,7 @@ namespace ART_46 {
/// Namespace related to the Java part of ART 46
namespace Java {
using heap_reference_t = ART_44::Java::heap_reference_t;
using heap_reference_t = ART_44::Java::heap_reference_t;
using brooks_read_barrier_t = ART_44::Java::brooks_read_barrier_t;
template<class T = no_brooks_read_barrier_t>
@@ -367,7 +365,7 @@ namespace ART_56 {
/// Namespace related to the Java part of ART 46
namespace Java {
using heap_reference_t = ART_46::Java::heap_reference_t;
using heap_reference_t = ART_46::Java::heap_reference_t;
using brooks_read_barrier_t = ART_46::Java::brooks_read_barrier_t;
template<class T = no_brooks_read_barrier_t>
@@ -393,5 +391,4 @@ using jdex_cache_t = ART_46::Java::jdex_cache_t<T>;
} // Namespace LIEF
#endif
+2 -2
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+2 -2
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+2 -2
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+2 -2
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+2 -2
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+73 -53
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
#include <memory>
#include <unordered_map>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
#include "LIEF/Object.hpp"
#include "LIEF/iterators.hpp"
@@ -58,7 +59,6 @@ class Engine;
/// Subclasses like LIEF::PE::Binary implement format-specific API
class LIEF_API Binary : public Object {
public:
/// Enumeration of virtual address types used for patching and memory access.
enum class VA_TYPES {
/// Automatically determine if the address is absolute or relative
@@ -69,7 +69,7 @@ class LIEF_API Binary : public Object {
RVA = 1,
/// Absolute Virtual Address.
VA = 2
VA = 2,
};
enum FORMATS {
@@ -131,13 +131,15 @@ class LIEF_API Binary : public Object {
return get_abstract_header();
}
/// Return an iterator over the abstracted symbols in which the elements **can** be modified
it_symbols symbols() {
/// Return an iterator over the abstracted symbols in which the elements **can**
/// be modified
it_symbols symbols() LIEF_LIFETIMEBOUND {
return get_abstract_symbols();
}
/// Return an iterator over the abstracted symbols in which the elements **can't** be modified
it_const_symbols symbols() const {
/// Return an iterator over the abstracted symbols in which the elements
/// **can't** be modified
it_const_symbols symbols() const LIEF_LIFETIMEBOUND {
return const_cast<Binary*>(this)->get_abstract_symbols();
}
@@ -148,30 +150,30 @@ class LIEF_API Binary : public Object {
/// Return the Symbol with the given name
/// If the symbol does not exist, return a nullptr
const Symbol* get_symbol(const std::string& name) const;
const Symbol* get_symbol(const std::string& name) const LIEF_LIFETIMEBOUND;
Symbol* get_symbol(const std::string& name) {
Symbol* get_symbol(const std::string& name) LIEF_LIFETIMEBOUND {
return const_cast<Symbol*>(static_cast<const Binary*>(this)->get_symbol(name));
}
/// Return an iterator over the binary's sections (LIEF::Section)
it_sections sections() {
it_sections sections() LIEF_LIFETIMEBOUND {
return get_abstract_sections();
}
it_const_sections sections() const {
it_const_sections sections() const LIEF_LIFETIMEBOUND {
return const_cast<Binary*>(this)->get_abstract_sections();
}
/// Remove **all** the sections in the underlying binary
virtual void remove_section(const std::string& name, bool clear = false) = 0;
/// Return an iterator over the binary relocation (LIEF::Relocation)
it_relocations relocations() {
/// Return an iterator over the binary relocations (LIEF::Relocation)
it_relocations relocations() LIEF_LIFETIMEBOUND {
return get_abstract_relocations();
}
it_const_relocations relocations() const {
it_const_relocations relocations() const LIEF_LIFETIMEBOUND {
return const_cast<Binary*>(this)->get_abstract_relocations();
}
@@ -199,7 +201,8 @@ class LIEF_API Binary : public Object {
}
/// Return the address of the given function name
virtual result<uint64_t> get_function_address(const std::string& func_name) const;
virtual result<uint64_t>
get_function_address(const std::string& func_name) const;
/// Method so that a ``visitor`` can visit us
void accept(Visitor& visitor) const override;
@@ -212,7 +215,8 @@ class LIEF_API Binary : public Object {
/// @param[in] patch_value Patch to apply
/// @param[in] addr_type Specify if the address should be used as an
/// absolute virtual address or a RVA
virtual void patch_address(uint64_t address, const std::vector<uint8_t>& patch_value,
virtual void patch_address(uint64_t address,
const std::vector<uint8_t>& patch_value,
VA_TYPES addr_type = VA_TYPES::AUTO) = 0;
/// Patch the address with the given value
@@ -220,23 +224,26 @@ class LIEF_API Binary : public Object {
/// @param[in] address Address to patch
/// @param[in] patch_value Patch to apply
/// @param[in] size Size of the value in **bytes** (1, 2, ... 8)
/// @param[in] addr_type Specify if the address should be used as an absolute virtual address or an RVA
virtual void patch_address(uint64_t address, uint64_t patch_value, size_t size = sizeof(uint64_t),
/// @param[in] addr_type Specify if the address should be used as an absolute
/// virtual address or an RVA
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;
/// Return the content located at the given 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;
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 LIEF_LIFETIMEBOUND = 0;
/// Get the integer value at the given virtual address
template<class T>
LIEF::result<T> get_int_from_virtual_address(
uint64_t va, VA_TYPES addr_type = VA_TYPES::AUTO) const
{
LIEF::result<T>
get_int_from_virtual_address(uint64_t va,
VA_TYPES addr_type = VA_TYPES::AUTO) const {
T value;
static_assert(std::is_integral<T>::value, "Require an integral type");
span<const uint8_t> raw = get_content_from_virtual_address(va, sizeof(T), addr_type);
span<const uint8_t> raw =
get_content_from_virtual_address(va, sizeof(T), addr_type);
if (raw.empty() || raw.size() < sizeof(T)) {
return make_error_code(lief_errors::read_error);
}
@@ -270,14 +277,17 @@ class LIEF_API Binary : public Object {
/// Convert the given offset into a virtual address.
///
/// @param[in] offset The offset to convert.
/// @param[in] slide If not 0, it will replace the default base address (if any)
virtual result<uint64_t> offset_to_virtual_address(uint64_t offset, uint64_t slide = 0) const = 0;
/// @param[in] slide If not 0, it will replace the default base address (if
/// any)
virtual result<uint64_t> offset_to_virtual_address(uint64_t offset,
uint64_t slide = 0) const = 0;
virtual std::ostream& print(std::ostream& os) const {
return os;
}
LIEF_API friend std::ostream& operator<<(std::ostream& os, const Binary& binary) {
LIEF_API friend std::ostream& operator<<(std::ostream& os,
const Binary& binary) {
binary.print(os);
return os;
}
@@ -293,9 +303,9 @@ class LIEF_API Binary : public Object {
/// use LIEF::pdb::load() or LIEF::pdb::DebugInfo::from_file() to get PDB debug
/// info.
///
/// \warning This function requires LIEF's extended version otherwise it
/// **always** return a nullptr
DebugInfo* debug_info() const;
/// @warning This function requires LIEF's extended version otherwise it
/// **always** returns a nullptr
DebugInfo* debug_info() const LIEF_LIFETIMEBOUND;
/// Disassemble code starting at the given virtual address and with the given
/// size.
@@ -307,7 +317,7 @@ class LIEF_API Binary : public Object {
/// }
/// ```
///
/// \see LIEF::assembly::Instruction
/// @see LIEF::assembly::Instruction
instructions_it disassemble(uint64_t address, size_t size) const;
/// Disassemble code starting at the given virtual address
@@ -319,7 +329,7 @@ class LIEF_API Binary : public Object {
/// }
/// ```
///
/// \see LIEF::assembly::Instruction
/// @see LIEF::assembly::Instruction
instructions_it disassemble(uint64_t address) const;
/// Disassemble code for the given symbol name
@@ -331,13 +341,13 @@ class LIEF_API Binary : public Object {
/// }
/// ```
///
/// \see LIEF::assembly::Instruction
/// @see LIEF::assembly::Instruction
instructions_it disassemble(const std::string& function) const;
/// Disassemble code provided by the given buffer at the specified
/// `address` parameter.
///
/// \see LIEF::assembly::Instruction
/// @see LIEF::assembly::Instruction
instructions_it disassemble(const uint8_t* buffer, size_t size,
uint64_t address = 0) const;
@@ -345,7 +355,7 @@ class LIEF_API Binary : public Object {
/// Disassemble code provided by the given vector of bytes at the specified
/// `address` parameter.
///
/// \see LIEF::assembly::Instruction
/// @see LIEF::assembly::Instruction
instructions_it disassemble(const std::vector<uint8_t>& buffer,
uint64_t address = 0) const {
return disassemble(buffer.data(), buffer.size(), address);
@@ -356,7 +366,8 @@ class LIEF_API Binary : public Object {
return disassemble(buffer.data(), buffer.size(), address);
}
instructions_it disassemble(LIEF::span<uint8_t> buffer, uint64_t address = 0) const {
instructions_it disassemble(LIEF::span<uint8_t> buffer,
uint64_t address = 0) const {
return disassemble(buffer.data(), buffer.size(), address);
}
@@ -374,17 +385,18 @@ class LIEF_API Binary : public Object {
/// If you need to configure the assembly engine or to define addresses for
/// symbols, you can provide your own assembly::AssemblerConfig.
std::vector<uint8_t> assemble(uint64_t address, const std::string& Asm,
assembly::AssemblerConfig& config = assembly::AssemblerConfig::default_config());
assembly::AssemblerConfig& config =
assembly::AssemblerConfig::default_config());
/// Assemble **and patch** the address with the given LLVM MCInst.
///
/// \warning Because of ABI compatibility, this MCInst can **only be used**
/// @warning Because of ABI compatibility, this MCInst can **only be used**
/// with the **same** version of LLVM used by LIEF (see documentation)
std::vector<uint8_t> assemble(uint64_t address, const llvm::MCInst& inst);
/// Assemble **and patch** the address with the given LLVM MCInst.
///
/// \warning Because of ABI compatibility, this MCInst can **only be used**
/// @warning Because of ABI compatibility, this MCInst can **only be used**
/// with the **same** version of LLVM used by LIEF (see documentation)
std::vector<uint8_t> assemble(uint64_t address,
const std::vector<llvm::MCInst>& insts);
@@ -393,23 +405,30 @@ class LIEF_API Binary : public Object {
/// the format of the current binary
virtual uint64_t page_size() const;
/// Load and associate an external debug file (e.g., DWARF or PDB) with this binary.
/// Load and associate an external debug file (e.g., DWARF or PDB) with this
/// binary.
///
/// This method attempts to load the debug information from the file located at the given path,
/// and binds it to the current binary instance. If successful, it returns a pointer to the
/// loaded DebugInfo object.
/// This method attempts to load the debug information from the file located at
/// the given path, and binds it to the current binary instance. If successful,
/// it returns a pointer to the loaded DebugInfo object.
///
/// \param path Path to the external debug file (e.g., `.dwarf`, `.pdb`)
/// \return Pointer to the loaded DebugInfo object on success, or `nullptr` on failure.
/// @param path Path to the external debug file (e.g., `.dwarf`, `.pdb`)
/// @return Pointer to the loaded DebugInfo object on success, or `nullptr` on
/// failure.
///
/// \warning It is the caller's responsibility to ensure that the debug file is
/// @warning It is the caller's responsibility to ensure that the debug file is
/// compatible with the binary. Incorrect associations may lead to
/// inconsistent or invalid results.
///
/// \note This function does not verify that the debug file matches the binary's unique
/// identifier (e.g., build ID, GUID).
/// @note This function does not verify that the debug file matches the binary's
/// unique identifier (e.g., build ID, GUID).
DebugInfo* load_debug_info(const std::string& path);
/// Size of the binary when mapped in memory
virtual uint64_t virtual_size() const {
return 0;
}
protected:
FORMATS format_ = FORMATS::UNKNOWN;
mutable std::unique_ptr<DebugInfo> debug_info_;
@@ -421,14 +440,15 @@ class LIEF_API Binary : public Object {
template<uint32_t Key, class F>
LIEF_LOCAL assembly::Engine* get_cache_engine(uint64_t address, F&& f) const;
// These functions need to be overloaded by the object that claims to extend this Abstract Binary
// These functions need to be overloaded by the object that claims to extend this
// Abstract Binary
virtual Header get_abstract_header() const = 0;
virtual symbols_t get_abstract_symbols() = 0;
virtual sections_t get_abstract_sections() = 0;
virtual relocations_t get_abstract_relocations() = 0;
virtual functions_t get_abstract_exported_functions() const = 0;
virtual functions_t get_abstract_imported_functions() const = 0;
virtual functions_t get_abstract_exported_functions() const = 0;
virtual functions_t get_abstract_imported_functions() const = 0;
virtual std::vector<std::string> get_abstract_imported_libraries() const = 0;
};
+7 -5
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,13 +34,14 @@ class DebugInfo;
/// Users can use this interface to access high-level debug features like
/// resolving function addresses.
///
/// See: LIEF::pdb::DebugInfo, LIEF::dwarf::DebugInfo
/// @see LIEF::pdb::DebugInfo, LIEF::dwarf::DebugInfo
class LIEF_API DebugInfo {
public:
friend class Binary;
enum class FORMAT {
UNKNOWN = 0,
DWARF, PDB,
DWARF,
PDB,
};
DebugInfo(std::unique_ptr<details::DebugInfo> impl);
@@ -61,7 +62,7 @@ class LIEF_API DebugInfo {
template<class T>
const T* as() const {
static_assert(std::is_base_of<DebugInfo, T>::value,
"Require Instruction inheritance");
"Requires DebugInfo inheritance");
if (T::classof(this)) {
return static_cast<const T*>(this);
}
@@ -69,7 +70,8 @@ class LIEF_API DebugInfo {
}
/// Attempt to resolve the address of the function specified by `name`.
virtual optional<uint64_t> find_function_address(const std::string& name) const = 0;
virtual optional<uint64_t>
find_function_address(const std::string& name) const = 0;
protected:
std::unique_ptr<details::DebugInfo> impl_;
+12 -15
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,24 +50,21 @@ class LIEF_API Function : public Symbol {
/// returns its virtual address in the binary
EXPORTED = 1 << 3,
/// The function is **imported** by the binary and the address() should return 0
/// The function is **imported** by the binary and the address() should return
/// 0
IMPORTED = 1 << 4,
};
public:
Function() = default;
Function(const std::string& name) :
Symbol(name)
{}
Symbol(name) {}
Function(uint64_t address) :
Function("", address)
{}
Function("", address) {}
Function(const std::string& name, uint64_t address) :
Symbol(name, address)
{}
Symbol(name, address) {}
Function(const std::string& name, uint64_t address, FLAGS flags) :
Function(name, address)
{
Function(name, address) {
flags_ = flags;
}
@@ -94,8 +91,8 @@ class LIEF_API Function : public Symbol {
return ((uint32_t)flags_ & (uint32_t)f) != 0;
}
/// Address of the current function. For functions that are set with the FLAGS::IMPORTED flag,
/// this value is likely 0.
/// Address of the current function. For functions that are set with the
/// FLAGS::IMPORTED flag, this value is likely 0.
uint64_t address() const {
return value_;
}
@@ -106,7 +103,8 @@ class LIEF_API Function : public Symbol {
void accept(Visitor& visitor) const override;
LIEF_API friend std::ostream& operator<<(std::ostream& os, const Function& entry);
LIEF_API friend std::ostream& operator<<(std::ostream& os,
const Function& entry);
protected:
FLAGS flags_ = FLAGS::NONE;
@@ -118,4 +116,3 @@ LIEF_API const char* to_string(Function::FLAGS e);
ENABLE_BITMASK_OPERATORS(LIEF::Function::FLAGS);
#endif
+5 -5
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -67,9 +67,9 @@ class LIEF_API Header : public Object {
BITS_16 = 1LLU << 0, /// 16-bits architecture
BITS_32 = 1LLU << 1, /// 32-bits architecture
BITS_64 = 1LLU << 2, /// 64-bits architecture
THUMB = 1LLU << 3, /// Support ARM Thumb mode
THUMB = 1LLU << 3, /// Support ARM Thumb mode
ARM64E = 1LLU << 4, /// ARM64 with extended (security) features
ARM64E = 1LLU << 4, /// ARM64 with extended (security) features
};
enum class OBJECT_TYPES {
@@ -130,7 +130,7 @@ class LIEF_API Header : public Object {
protected:
ARCHITECTURES architecture_ = ARCHITECTURES::UNKNOWN;
OBJECT_TYPES object_type_ = OBJECT_TYPES::UNKNOWN;
OBJECT_TYPES object_type_ = OBJECT_TYPES::UNKNOWN;
uint64_t entrypoint_ = 0;
ENDIANNESS endianness_ = ENDIANNESS::UNKNOWN;
MODES modes_ = MODES::NONE;
+4 -3
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
#include <string>
#include <memory>
#include <cstdint>
#include <vector>
#include "LIEF/visibility.h"
@@ -50,7 +51,7 @@ class LIEF_API Parser {
protected:
Parser(const std::string& file);
uint64_t binary_size_ = 0;
uint64_t binary_size_ = 0;
virtual ~Parser();
Parser();
+11 -11
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,8 +32,7 @@ class LIEF_API Relocation : public Object {
/// Constructor from a relocation's address and size
Relocation(uint64_t address, uint8_t size) :
address_(address),
size_(size)
{}
size_(size) {}
~Relocation() override = default;
@@ -41,7 +40,7 @@ class LIEF_API Relocation : public Object {
Relocation(const Relocation&) = default;
void swap(Relocation& other) {
std::swap(address_, other.address_);
std::swap(size_, other.size_);
std::swap(size_, other.size_);
}
/// Relocation's address
@@ -66,31 +65,32 @@ class LIEF_API Relocation : public Object {
void accept(Visitor& visitor) const override;
/// Comparaison based on the Relocation's **address**
/// Comparison based on the Relocation's **address**
virtual bool operator<(const Relocation& rhs) const {
return address() < rhs.address();
}
/// Comparaison based on the Relocation's **address**
/// Comparison based on the Relocation's **address**
virtual bool operator<=(const Relocation& rhs) const {
return !(address() > rhs.address());
}
/// Comparaison based on the Relocation's **address**
/// Comparison based on the Relocation's **address**
virtual bool operator>(const Relocation& rhs) const {
return address() > rhs.address();
}
/// Comparaison based on the Relocation's **address**
/// Comparison based on the Relocation's **address**
virtual bool operator>=(const Relocation& rhs) const {
return !(address() < rhs.address());
}
LIEF_API friend std::ostream& operator<<(std::ostream& os, const Relocation& entry);
LIEF_API friend std::ostream& operator<<(std::ostream& os,
const Relocation& entry);
protected:
uint64_t address_ = 0;
uint8_t size_ = 0;
uint8_t size_ = 0;
};
+12 -12
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
#include "LIEF/span.hpp"
#include "LIEF/Object.hpp"
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
namespace LIEF {
@@ -32,27 +33,26 @@ class LIEF_API Section : public Object {
Section() = default;
Section(std::string name) :
name_(std::move(name))
{}
name_(std::move(name)) {}
~Section() override = default;
Section& operator=(const Section&) = default;
Section(const Section&) = default;
/// section's name
/// Section's name
virtual std::string name() const {
return name_.c_str();
}
/// Return the **complete** section's name which might
/// Return the **complete** section's name which might include
/// trailing (``0``) bytes
virtual const std::string& fullname() const {
return name_;
}
/// section's content
virtual span<const uint8_t> content() const {
/// Section's content
virtual span<const uint8_t> content() const LIEF_LIFETIMEBOUND {
return {};
}
@@ -61,7 +61,7 @@ class LIEF_API Section : public Object {
size_ = size;
}
/// section's size (size in the binary, not the virtual size)
/// Section's size (size in the binary, not the virtual size)
virtual uint64_t size() const {
return size_;
}
@@ -118,9 +118,9 @@ class LIEF_API Section : public Object {
protected:
std::string name_;
uint64_t virtual_address_ = 0;
uint64_t size_ = 0;
uint64_t offset_ = 0;
uint64_t virtual_address_ = 0;
uint64_t size_ = 0;
uint64_t offset_ = 0;
private:
template<typename T>
+10 -11
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,16 +29,16 @@ class LIEF_API Symbol : public Object {
public:
Symbol() = default;
Symbol(std::string name) :
name_(std::move(name))
{}
name_(std::move(name)) {}
Symbol(std::string name, uint64_t value) :
name_(std::move(name)), value_(value)
{}
name_(std::move(name)),
value_(value) {}
Symbol(std::string name, uint64_t value, uint64_t size) :
name_(std::move(name)), value_(value), size_(size)
{}
name_(std::move(name)),
value_(value),
size_(size) {}
Symbol(const Symbol&) = default;
Symbol& operator=(const Symbol&) = default;
@@ -64,7 +64,7 @@ class LIEF_API Symbol : public Object {
name_ = std::move(name);
}
// Symbol's value which is usually the **address** of the symbol
/// Symbol's value which is usually the **address** of the symbol
virtual uint64_t value() const {
return value_;
}
@@ -72,7 +72,7 @@ class LIEF_API Symbol : public Object {
value_ = value;
}
/// This size of the symbol (when applicable)
/// The size of the symbol (when applicable)
virtual uint64_t size() const {
return size_;
}
@@ -94,4 +94,3 @@ class LIEF_API Symbol : public Object {
}
#endif
+7 -7
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,12 +34,12 @@ class LIEF_API AbstractHash : public LIEF::Hash {
using LIEF::Hash::visit;
public:
void visit(const Binary& binary) override;
void visit(const Header& header) override;
void visit(const Section& section) override;
void visit(const Symbol& symbol) override;
void visit(const Binary& binary) override;
void visit(const Header& header) override;
void visit(const Section& section) override;
void visit(const Symbol& symbol) override;
void visit(const Relocation& relocation) override;
void visit(const Function& function) override;
void visit(const Function& function) override;
~AbstractHash() override;
};
+3 -4
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,5 +26,4 @@ LIEF_API std::string to_json_from_abstract(const Object& v);
}
#endif // LIEF_JSON_SUPPORT
#endif
+3 -4
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,8 +34,7 @@ class ASN1Reader {
ASN1Reader() = delete;
ASN1Reader(BinaryStream& stream) :
stream_(stream)
{}
stream_(stream) {}
ASN1Reader(const ASN1Reader&) = delete;
ASN1Reader& operator=(const ASN1Reader&) = delete;
+90 -46
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
#include <cstring>
#include <string>
#include <algorithm>
#include <utility>
#include "LIEF/endianness_support.hpp"
#include "LIEF/errors.hpp"
@@ -28,6 +29,7 @@
namespace LIEF {
class ASN1Reader;
class Binary;
/// Class that is used to a read stream of data from different sources
class LIEF_API BinaryStream {
@@ -40,13 +42,13 @@ class LIEF_API BinaryStream {
MEMORY,
SPAN,
FILE,
DUMP,
ELF_DATA_HANDLER,
};
BinaryStream(STREAM_TYPE type) :
stype_(type)
{}
stype_(type) {}
virtual ~BinaryStream() = default;
virtual uint64_t size() const = 0;
@@ -54,6 +56,18 @@ class LIEF_API BinaryStream {
return stype_;
}
bool is_memory_stream() const {
return type() == STREAM_TYPE::MEMORY;
}
bool is_dump_stream() const {
return type() == STREAM_TYPE::DUMP;
}
bool is_memory_view() const {
return is_memory_stream() || is_dump_stream();
}
result<uint64_t> read_uleb128(size_t* size = nullptr) const;
result<uint64_t> read_sleb128(size_t* size = nullptr) const;
@@ -61,7 +75,9 @@ class LIEF_API BinaryStream {
result<std::string> read_string(size_t maxsize = ~static_cast<size_t>(0)) const;
result<std::string> peek_string(size_t maxsize = ~static_cast<size_t>(0)) const;
result<std::string> peek_string_at(size_t offset, size_t maxsize = ~static_cast<size_t>(0)) const;
result<std::string>
peek_string_at(size_t offset,
size_t maxsize = ~static_cast<size_t>(0)) const;
result<std::u16string> read_u16string() const;
result<std::u16string> peek_u16string() const;
@@ -73,27 +89,31 @@ class LIEF_API BinaryStream {
result<std::u16string> peek_u16string_at(size_t offset, size_t length) const;
virtual ok_error_t peek_data(std::vector<uint8_t>& container,
uint64_t offset, uint64_t size,
uint64_t virtual_address = 0)
{
virtual ok_error_t peek_data(std::vector<uint8_t>& container, uint64_t offset,
uint64_t size, uint64_t virtual_address = 0) {
if (size == 0) {
return ok();
}
// Even though offset + size < ... => offset < ...
// the addition could overflow so it's worth checking both
const bool read_ok = offset <= this->size() && (offset + size) <= this->size()
/* Check for an overflow */
&& (static_cast<int64_t>(offset) >= 0 && static_cast<int64_t>(size) >= 0)
&& (static_cast<int64_t>(offset + size) >= 0);
const bool read_ok = offset <= this->size() &&
(offset + size) <= this->size()
/* Check for an overflow */
&& (static_cast<int64_t>(offset) >= 0 &&
static_cast<int64_t>(size) >= 0) &&
(static_cast<int64_t>(offset + size) >= 0);
if (!read_ok) {
return make_error_code(lief_errors::read_error);
}
container.resize(size);
if (peek_in(container.data(), offset, size, virtual_address)) {
return ok();
if (container.size() < size) {
std::vector<uint8_t> buffer(size);
const ok_error_t res = peek_in(buffer.data(), offset, size, virtual_address);
container = std::move(buffer);
return res;
}
return make_error_code(lief_errors::read_error);
return peek_in(container.data(), offset, size, virtual_address);
}
virtual ok_error_t read_data(std::vector<uint8_t>& container, uint64_t size) {
@@ -130,7 +150,8 @@ class LIEF_API BinaryStream {
}
template<class T>
ok_error_t peek_objects_at(uint64_t offset, std::vector<T>& container, uint64_t count) {
ok_error_t peek_objects_at(uint64_t offset, std::vector<T>& container,
uint64_t count) {
if (count == 0) {
return ok();
}
@@ -144,22 +165,25 @@ class LIEF_API BinaryStream {
return make_error_code(lief_errors::read_error);
}
container.resize(count);
ok_error_t res = make_error_code(lief_errors::inconsistent);
if (!peek_in(container.data(), pos(), size)) {
setpos(current_p);
return make_error_code(lief_errors::read_error);
if (container.size() < count) {
std::vector<T> buffer(count);
res = peek_in(buffer.data(), pos(), size);
container = std::move(buffer);
} else {
res = peek_in(container.data(), pos(), size);
}
setpos(current_p);
return ok();
return res;
}
void setpos(size_t pos) const {
pos_ = pos;
}
const BinaryStream& increment_pos(size_t value) const {
const BinaryStream& increment_pos(size_t value) const LIEF_LIFETIMEBOUND {
pos_ += value;
return *this;
}
@@ -176,10 +200,14 @@ class LIEF_API BinaryStream {
return pos_;
}
operator bool() const {
bool is_valid() const {
return pos_ < size();
}
operator bool() const {
return is_valid();
}
template<class T>
const T* read_array(size_t size) const;
@@ -190,10 +218,12 @@ class LIEF_API BinaryStream {
}
// Even though offset + size < ... => offset < ...
// the addition could overflow so it's worth checking both
const bool read_ok = pos_ <= size() && (pos_ + N) <= size()
/* Check for an overflow */
&& (static_cast<int64_t>(pos_) >= 0 && static_cast<int64_t>(N) >= 0)
&& (static_cast<int64_t>(pos_ + N) >= 0);
const bool read_ok =
pos_ <= size() &&
(pos_ + N) <= size()
/* Check for an overflow */
&& (static_cast<int64_t>(pos_) >= 0 && static_cast<int64_t>(N) >= 0) &&
(static_cast<int64_t>(pos_ + N) >= 0);
if (!read_ok) {
return make_error_code(lief_errors::read_error);
@@ -236,7 +266,8 @@ class LIEF_API BinaryStream {
bool can_read(size_t offset) const;
bool can_read(int64_t offset, int64_t size) const {
return offset < (int64_t)this->size() && (offset + size) < (int64_t)this->size();
return offset < (int64_t)this->size() &&
size < ((int64_t)this->size() - offset);
}
size_t align(size_t align_on) const;
@@ -247,16 +278,15 @@ class LIEF_API BinaryStream {
template<class T>
static bool is_all_zero(const T& buffer) {
const auto* ptr = reinterpret_cast<const uint8_t *const>(&buffer);
return std::all_of(ptr, ptr + sizeof(T),
[] (uint8_t x) { return x == 0; });
const auto* ptr = reinterpret_cast<const uint8_t* const>(&buffer);
return std::all_of(ptr, ptr + sizeof(T), [](uint8_t x) { return x == 0; });
}
bool should_swap() const {
return endian_swap_;
}
virtual const uint8_t* p() const {
virtual const uint8_t* p() const {
return nullptr;
}
@@ -284,11 +314,10 @@ class LIEF_API BinaryStream {
uint64_t virtual_address = 0) const = 0;
virtual ok_error_t peek_in(void* dst, uint64_t offset, uint64_t size,
uint64_t virtual_address = 0) const {
if (dst == nullptr) {
return make_error_code(lief_errors::read_error);
}
if (auto raw = read_at(offset, size, virtual_address)) {
if (dst == nullptr) {
return make_error_code(lief_errors::read_error);
}
const void* ptr = *raw;
if (ptr == nullptr) {
@@ -301,6 +330,25 @@ class LIEF_API BinaryStream {
return make_error_code(lief_errors::read_error);
}
template<class T>
const T* cast() const {
static_assert(std::is_base_of<BinaryStream, T>::value,
"Require BinaryStream inheritance");
if (T::classof(*this)) {
return static_cast<const T*>(this);
}
return nullptr;
}
template<class T>
T* cast() {
return const_cast<T*>(static_cast<const BinaryStream*>(this)->cast<T>());
}
virtual bool bind_binary(Binary& /*bin*/) {
return false;
}
protected:
BinaryStream() = default;
@@ -319,15 +367,13 @@ class ScopedStream {
explicit ScopedStream(BinaryStream& stream, uint64_t pos) :
pos_{stream.pos()},
stream_{stream}
{
stream_{stream} {
stream_.setpos(pos);
}
explicit ScopedStream(BinaryStream& stream) :
pos_{stream.pos()},
stream_{stream}
{}
stream_{stream} {}
~ScopedStream() {
stream_.setpos(pos_);
@@ -360,15 +406,13 @@ class ToggleEndianness {
explicit ToggleEndianness(BinaryStream& stream, bool value) :
endian_swap_(stream.should_swap()),
stream_{stream}
{
stream_{stream} {
stream.set_endian_swap(value);
}
explicit ToggleEndianness(BinaryStream& stream) :
endian_swap_(stream.should_swap()),
stream_{stream}
{
stream_{stream} {
stream.set_endian_swap(!stream_.should_swap());
}
+97
View File
@@ -0,0 +1,97 @@
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_DUMP_STREAM_H
#define LIEF_DUMP_STREAM_H
#include <memory>
#include <cstdint>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/errors.hpp"
#include "LIEF/visibility.h"
#include "LIEF/BinaryStream/BinaryStream.hpp"
namespace LIEF {
class Binary;
/// This stream interface provides facilities to parse a dumped binary.
///
/// A dump is a contiguous capture of a process memory that starts at a given
/// base address. This stream owns (or weakly references)
/// another BinaryStream that holds the raw dump and translates file offsets
/// into dump offsets according to this base address and the binary layout.
class LIEF_API DumpStream : public BinaryStream {
public:
DumpStream() = delete;
DumpStream(uintptr_t base_address, BinaryStream& ref) :
BinaryStream(BinaryStream::STREAM_TYPE::DUMP),
baseaddr_(base_address),
ref_(&ref) {}
DumpStream(uintptr_t base_address, std::unique_ptr<BinaryStream> owned) :
BinaryStream(BinaryStream::STREAM_TYPE::DUMP),
baseaddr_(base_address),
owned_(std::move(owned)),
ref_(owned_.get()) {}
DumpStream(const DumpStream&) = delete;
DumpStream& operator=(const DumpStream&) = delete;
DumpStream(DumpStream&&) noexcept = default;
DumpStream& operator=(DumpStream&&) noexcept = default;
uintptr_t base_address() const {
return baseaddr_;
}
Binary* binary() LIEF_LIFETIMEBOUND {
return binary_;
}
uint64_t size() const override {
return ref_->size();
}
bool bind_binary(Binary& bin) override {
binary_ = &bin;
return true;
}
std::vector<uint8_t> content() const;
result<const void*> read_at(uint64_t /*offset*/, uint64_t /*size*/,
uint64_t /*virtual_address*/ = 0) const override {
return make_error_code(lief_errors::not_supported);
}
ok_error_t peek_in(void* dst, uint64_t offset, uint64_t size,
uint64_t virtual_address = 0) const override;
~DumpStream() override = default;
static bool classof(const BinaryStream& stream) {
return stream.type() == BinaryStream::STREAM_TYPE::DUMP;
}
protected:
uintptr_t baseaddr_ = 0;
Binary* binary_ = nullptr;
std::unique_ptr<BinaryStream> owned_;
BinaryStream* ref_ = nullptr;
};
}
#endif
+4 -5
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,8 +33,7 @@ class LIEF_API FileStream : public BinaryStream {
FileStream(std::ifstream fs, uint64_t size) :
BinaryStream(STREAM_TYPE::FILE),
ifs_(std::move(fs)),
size_(size)
{}
size_(size) {}
FileStream() = delete;
@@ -56,7 +55,7 @@ class LIEF_API FileStream : public BinaryStream {
}
ok_error_t peek_in(void* dst, uint64_t offset, uint64_t size,
uint64_t /* virtual_address */= 0) const override {
uint64_t /* virtual_address */ = 0) const override {
if (offset > size_ || offset + size > size_) {
return make_error_code(lief_errors::read_error);
}
+12 -11
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,8 +35,7 @@ class LIEF_API MemoryStream : public BinaryStream {
MemoryStream(uintptr_t base_address, uint64_t size) :
BinaryStream(BinaryStream::STREAM_TYPE::MEMORY),
baseaddr_(base_address),
size_(size)
{}
size_(size) {}
MemoryStream(const MemoryStream&) = delete;
MemoryStream& operator=(const MemoryStream&) = delete;
@@ -45,7 +44,7 @@ class LIEF_API MemoryStream : public BinaryStream {
MemoryStream& operator=(MemoryStream&&) noexcept = default;
uintptr_t base_address() const {
return this->baseaddr_;
return baseaddr_;
}
const uint8_t* p() const override {
@@ -60,18 +59,19 @@ class LIEF_API MemoryStream : public BinaryStream {
return start() + size_;
}
void binary(Binary& bin) {
this->binary_ = &bin;
}
Binary* binary() {
return this->binary_;
return binary_;
}
uint64_t size() const override {
return size_;
}
bool bind_binary(Binary& bin) override {
binary_ = &bin;
return true;
}
~MemoryStream() override = default;
static bool classof(const BinaryStream& stream) {
@@ -79,7 +79,8 @@ class LIEF_API MemoryStream : public BinaryStream {
}
protected:
result<const void*> read_at(uint64_t offset, uint64_t size, uint64_t va) const override;
result<const void*> read_at(uint64_t offset, uint64_t size,
uint64_t va) const override;
uintptr_t baseaddr_ = 0;
uint64_t size_ = 0;
Binary* binary_ = nullptr;
+10 -13
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,21 +45,17 @@ class LIEF_API SpanStream : public BinaryStream {
}
SpanStream(span<const uint8_t> data) :
SpanStream(data.data(), data.size())
{}
SpanStream(data.data(), data.size()) {}
SpanStream(span<uint8_t> data) :
SpanStream(data.data(), data.size())
{}
SpanStream(data.data(), data.size()) {}
SpanStream(const uint8_t* p, size_t size) :
BinaryStream(BinaryStream::STREAM_TYPE::SPAN),
data_{p, p + size}
{}
data_{p, p + size} {}
SpanStream(const std::vector<uint8_t>& data) :
SpanStream(data.data(), data.size())
{}
SpanStream(data.data(), data.size()) {}
std::unique_ptr<SpanStream> clone() const {
return std::unique_ptr<SpanStream>(new SpanStream(*this));
@@ -94,7 +90,7 @@ class LIEF_API SpanStream : public BinaryStream {
}
result<SpanStream> slice(size_t offset, size_t size) const {
if (offset > data_.size() || (offset + size) > data_.size()) {
if (offset > data_.size() || size > data_.size() - offset) {
return make_error_code(lief_errors::read_out_of_bound);
}
return data_.subspan(offset, size);
@@ -115,9 +111,10 @@ class LIEF_API SpanStream : public BinaryStream {
~SpanStream() override = default;
protected:
result<const void*> read_at(uint64_t offset, uint64_t size, uint64_t /*va*/) const override {
result<const void*> read_at(uint64_t offset, uint64_t size,
uint64_t /*va*/) const override {
const uint64_t stream_size = this->size();
if (offset > stream_size || (offset + size) > stream_size) {
if (offset > stream_size || size > stream_size - offset) {
return make_error_code(lief_errors::read_error);
}
return data_.data() + offset;
+6 -6
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,8 +36,7 @@ class LIEF_API VectorStream : public BinaryStream {
VectorStream(std::vector<uint8_t> data) :
BinaryStream(BinaryStream::STREAM_TYPE::VECTOR),
binary_(std::move(data)),
size_(binary_.size())
{}
size_(binary_.size()) {}
VectorStream() = delete;
@@ -82,9 +81,10 @@ class LIEF_API VectorStream : public BinaryStream {
}
protected:
result<const void*> read_at(uint64_t offset, uint64_t size, uint64_t /*va*/) const override {
result<const void*> read_at(uint64_t offset, uint64_t size,
uint64_t /*va*/) const override {
const uint64_t stream_size = this->size();
if (offset > stream_size || (offset + size) > stream_size) {
if (offset > stream_size || size > stream_size - offset) {
return make_error_code(lief_errors::read_error);
}
return binary_.data() + offset;
+22 -22
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,30 +13,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_COFF_H
#define LIEF_COFF_H
#ifndef LIEF_COFF_H
#define LIEF_COFF_H
#include "LIEF/config.h"
#if defined(LIEF_COFF_SUPPORT)
#include "LIEF/COFF/Binary.hpp"
#include "LIEF/COFF/utils.hpp"
#include "LIEF/COFF/Parser.hpp"
#include "LIEF/COFF/Header.hpp"
#include "LIEF/COFF/BigObjHeader.hpp"
#include "LIEF/COFF/RegularHeader.hpp"
#include "LIEF/COFF/ParserConfig.hpp"
#include "LIEF/COFF/Section.hpp"
#include "LIEF/COFF/Relocation.hpp"
#include "LIEF/COFF/Symbol.hpp"
#include "LIEF/COFF/String.hpp"
#include "LIEF/COFF/Binary.hpp"
#include "LIEF/COFF/utils.hpp"
#include "LIEF/COFF/Parser.hpp"
#include "LIEF/COFF/Header.hpp"
#include "LIEF/COFF/BigObjHeader.hpp"
#include "LIEF/COFF/RegularHeader.hpp"
#include "LIEF/COFF/ParserConfig.hpp"
#include "LIEF/COFF/Section.hpp"
#include "LIEF/COFF/Relocation.hpp"
#include "LIEF/COFF/Symbol.hpp"
#include "LIEF/COFF/String.hpp"
#include "LIEF/COFF/AuxiliarySymbol.hpp"
#include "LIEF/COFF/AuxiliarySymbols/AuxiliarybfAndefSymbol.hpp"
#include "LIEF/COFF/AuxiliarySymbols/AuxiliaryCLRToken.hpp"
#include "LIEF/COFF/AuxiliarySymbols/AuxiliaryFile.hpp"
#include "LIEF/COFF/AuxiliarySymbols/AuxiliaryFunctionDefinition.hpp"
#include "LIEF/COFF/AuxiliarySymbols/AuxiliarySectionDefinition.hpp"
#include "LIEF/COFF/AuxiliarySymbols/AuxiliaryWeakExternal.hpp"
#include "LIEF/COFF/AuxiliarySymbol.hpp"
#include "LIEF/COFF/AuxiliarySymbols/AuxiliarybfAndefSymbol.hpp"
#include "LIEF/COFF/AuxiliarySymbols/AuxiliaryCLRToken.hpp"
#include "LIEF/COFF/AuxiliarySymbols/AuxiliaryFile.hpp"
#include "LIEF/COFF/AuxiliarySymbols/AuxiliaryFunctionDefinition.hpp"
#include "LIEF/COFF/AuxiliarySymbols/AuxiliarySectionDefinition.hpp"
#include "LIEF/COFF/AuxiliarySymbols/AuxiliaryWeakExternal.hpp"
#endif
#endif
+16 -15
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
#include <memory>
#include <vector>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
#include "LIEF/span.hpp"
@@ -32,14 +33,12 @@ class Symbol;
/// Class that represents an auxiliary symbol.
///
/// An auxiliary symbol has the same size as a regular LIEF::PE::Symbol (18
/// bytes) but its content depends on the the parent symbol.
/// bytes) but its content depends on the parent symbol.
class LIEF_API AuxiliarySymbol {
public:
AuxiliarySymbol() = default;
AuxiliarySymbol(std::vector<uint8_t> payload) :
type_(TYPE::UNKNOWN),
payload_(std::move(payload))
{}
payload_(std::move(payload)) {}
AuxiliarySymbol(const AuxiliarySymbol&) = default;
AuxiliarySymbol& operator=(const AuxiliarySymbol&) = default;
@@ -47,7 +46,7 @@ class LIEF_API AuxiliarySymbol {
AuxiliarySymbol& operator=(AuxiliarySymbol&&) = default;
LIEF_LOCAL static std::unique_ptr<AuxiliarySymbol>
parse(Symbol& sym, std::vector<uint8_t> payload);
parse(Symbol& sym, std::vector<uint8_t> payload);
virtual std::unique_ptr<AuxiliarySymbol> clone() const {
return std::unique_ptr<AuxiliarySymbol>(new AuxiliarySymbol(*this));
@@ -59,19 +58,22 @@ class LIEF_API AuxiliarySymbol {
CLR_TOKEN,
/// Auxiliary Format 1 from the PE-COFF documentation
FUNC_DEF,
/// Auxiliary Format 2: .bf and .ef Symbols from the PE-COFF documentation
BF_AND_EF,
/// Auxiliary Format 3: Weak Externals from the PE-COFF documentation
WEAK_EXTERNAL,
/// Auxiliary Format 4: Files from the PE-COFF documentation
FILE,
/// Auxiliary Format 5: Section Definitions from the PE-COFF documentation
SEC_DEF,
};
AuxiliarySymbol(TYPE ty) :
type_(ty)
{}
type_(ty) {}
static TYPE get_aux_type(const Symbol& sym);
@@ -80,11 +82,11 @@ class LIEF_API AuxiliarySymbol {
}
/// For unknown type **only**, return the raw representation of this symbol
span<const uint8_t> payload() const {
span<const uint8_t> payload() const LIEF_LIFETIMEBOUND {
return payload_;
}
span<uint8_t> payload() {
span<uint8_t> payload() LIEF_LIFETIMEBOUND {
return payload_;
}
@@ -92,7 +94,7 @@ class LIEF_API AuxiliarySymbol {
virtual ~AuxiliarySymbol() = default;
/// Helper to **downcast** a AuxiliarySymbol into a concrete implementation
/// Helper to **downcast** an AuxiliarySymbol into a concrete implementation
template<class T>
const T* as() const {
static_assert(std::is_base_of<AuxiliarySymbol, T>::value,
@@ -108,9 +110,8 @@ class LIEF_API AuxiliarySymbol {
return const_cast<T*>(static_cast<const AuxiliarySymbol*>(this)->as<T>());
}
LIEF_API friend
std::ostream& operator<<(std::ostream& os, const AuxiliarySymbol& aux)
{
LIEF_API friend std::ostream& operator<<(std::ostream& os,
const AuxiliarySymbol& aux) {
os << aux.to_string();
return os;
}
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
#include <memory>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
#include "LIEF/COFF/AuxiliarySymbol.hpp"
@@ -32,11 +33,10 @@ class LIEF_API AuxiliaryCLRToken : public AuxiliarySymbol {
friend class Parser;
LIEF_LOCAL static std::unique_ptr<AuxiliaryCLRToken>
parse(const std::vector<uint8_t>& payload);
parse(const std::vector<uint8_t>& payload);
AuxiliaryCLRToken() :
AuxiliarySymbol(AuxiliarySymbol::TYPE::CLR_TOKEN)
{}
AuxiliarySymbol(AuxiliarySymbol::TYPE::CLR_TOKEN) {}
AuxiliaryCLRToken(uint8_t aux_type, uint8_t reserved, uint32_t symbol_idx,
std::vector<uint8_t> rgb_reserved) :
@@ -44,8 +44,7 @@ class LIEF_API AuxiliaryCLRToken : public AuxiliarySymbol {
aux_type_(aux_type),
reserved_(reserved),
symbol_idx_(symbol_idx),
rgb_reserved_(std::move(rgb_reserved))
{}
rgb_reserved_(std::move(rgb_reserved)) {}
AuxiliaryCLRToken(const AuxiliaryCLRToken&) = default;
AuxiliaryCLRToken& operator=(const AuxiliaryCLRToken&) = default;
@@ -82,7 +81,7 @@ class LIEF_API AuxiliaryCLRToken : public AuxiliarySymbol {
}
/// Reserved (padding) values. Should be 0
span<const uint8_t> rgb_reserved() const {
span<const uint8_t> rgb_reserved() const LIEF_LIFETIMEBOUND {
return rgb_reserved_;
}
@@ -93,6 +92,7 @@ class LIEF_API AuxiliaryCLRToken : public AuxiliarySymbol {
}
~AuxiliaryCLRToken() override = default;
private:
uint8_t aux_type_ = 0;
uint8_t reserved_ = 0;
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,20 +29,19 @@ namespace COFF {
/// The Symbol::name itself should start with `.file`, and this auxiliary record
/// gives the name of a source-code file.
///
/// Reference: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-4-files
/// Reference:
/// https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-4-files
class LIEF_API AuxiliaryFile : public AuxiliarySymbol {
public:
LIEF_LOCAL static std::unique_ptr<AuxiliaryFile>
parse(const std::vector<uint8_t>& payload);
parse(const std::vector<uint8_t>& payload);
AuxiliaryFile() :
AuxiliarySymbol(AuxiliarySymbol::TYPE::FILE)
{}
AuxiliarySymbol(AuxiliarySymbol::TYPE::FILE) {}
AuxiliaryFile(std::string file) :
AuxiliarySymbol(AuxiliarySymbol::TYPE::FILE),
filename_(std::move(file))
{}
filename_(std::move(file)) {}
AuxiliaryFile(const AuxiliaryFile&) = default;
AuxiliaryFile& operator=(const AuxiliaryFile&) = default;
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,35 +26,36 @@ namespace COFF {
/// This auxiliary symbols marks the beginning of a function definition.
///
/// Reference: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-1-function-definitions
/// Reference:
/// https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-1-function-definitions
class LIEF_API AuxiliaryFunctionDefinition : public AuxiliarySymbol {
public:
LIEF_LOCAL static std::unique_ptr<AuxiliaryFunctionDefinition>
parse(const std::vector<uint8_t>& payload);
parse(const std::vector<uint8_t>& payload);
AuxiliaryFunctionDefinition() :
AuxiliarySymbol(AuxiliarySymbol::TYPE::FUNC_DEF)
{}
AuxiliarySymbol(AuxiliarySymbol::TYPE::FUNC_DEF) {}
AuxiliaryFunctionDefinition(uint32_t tagidx, uint32_t totalsz,
uint32_t ptr_line, uint32_t ptr_next_func,
uint16_t padding) :
AuxiliaryFunctionDefinition(uint32_t tagidx, uint32_t totalsz, uint32_t ptr_line,
uint32_t ptr_next_func, uint16_t padding) :
AuxiliarySymbol(AuxiliarySymbol::TYPE::FUNC_DEF),
tag_index_(tagidx),
total_size_(totalsz),
ptr_to_linenb_(ptr_line),
ptr_to_next_func_(ptr_next_func),
padding_(padding)
{}
padding_(padding) {}
AuxiliaryFunctionDefinition(const AuxiliaryFunctionDefinition&) = default;
AuxiliaryFunctionDefinition& operator=(const AuxiliaryFunctionDefinition&) = default;
AuxiliaryFunctionDefinition&
operator=(const AuxiliaryFunctionDefinition&) = default;
AuxiliaryFunctionDefinition(AuxiliaryFunctionDefinition&&) = default;
AuxiliaryFunctionDefinition& operator=(AuxiliaryFunctionDefinition&&) = default;
std::unique_ptr<AuxiliarySymbol> clone() const override {
return std::unique_ptr<AuxiliaryFunctionDefinition>(new AuxiliaryFunctionDefinition{*this});
return std::unique_ptr<AuxiliaryFunctionDefinition>(
new AuxiliaryFunctionDefinition{*this}
);
}
/// The symbol-table index of the corresponding `.bf` (begin function)
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,11 +30,10 @@ namespace COFF {
class LIEF_API AuxiliarySectionDefinition : public AuxiliarySymbol {
public:
LIEF_LOCAL static std::unique_ptr<AuxiliarySectionDefinition>
parse(const std::vector<uint8_t>& payload);
parse(const std::vector<uint8_t>& payload);
AuxiliarySectionDefinition() :
AuxiliarySymbol(AuxiliarySymbol::TYPE::SEC_DEF)
{}
AuxiliarySymbol(AuxiliarySymbol::TYPE::SEC_DEF) {}
AuxiliarySectionDefinition(uint32_t length, uint16_t nb_relocs,
uint16_t nb_lines, uint32_t checksum,
@@ -47,27 +46,30 @@ class LIEF_API AuxiliarySectionDefinition : public AuxiliarySymbol {
checksum_(checksum),
sec_idx_(sec_idx),
selection_((COMDAT_SELECTION)selection),
reserved_(reserved)
{}
reserved_(reserved) {}
AuxiliarySectionDefinition(const AuxiliarySectionDefinition&) = default;
AuxiliarySectionDefinition& operator=(const AuxiliarySectionDefinition&) = default;
AuxiliarySectionDefinition&
operator=(const AuxiliarySectionDefinition&) = default;
AuxiliarySectionDefinition(AuxiliarySectionDefinition&&) = default;
AuxiliarySectionDefinition& operator=(AuxiliarySectionDefinition&&) = default;
std::unique_ptr<AuxiliarySymbol> clone() const override {
return std::unique_ptr<AuxiliarySectionDefinition>(new AuxiliarySectionDefinition{*this});
return std::unique_ptr<AuxiliarySectionDefinition>(
new AuxiliarySectionDefinition{*this}
);
}
/// Values for the AuxiliarySectionDefinition::selection attribute
///
/// See: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#comdat-sections-object-only
/// See:
/// https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#comdat-sections-object-only
enum class COMDAT_SELECTION : uint8_t {
NONE = 0,
/// If this symbol is already defined, the linker issues a `multiply defined symbol`
/// error.
/// If this symbol is already defined, the linker issues a `multiply defined
/// symbol` error.
NODUPLICATES = 1,
/// Any section that defines the same COMDAT symbol can be linked; the rest
@@ -75,8 +77,8 @@ class LIEF_API AuxiliarySectionDefinition : public AuxiliarySymbol {
ANY,
/// The linker chooses an arbitrary section among the definitions for this
/// symbol. If all definitions are not the same size, a `multiply defined symbol`
/// error is issued.
/// symbol. If all definitions are not the same size, a `multiply defined
/// symbol` error is issued.
SAME_SIZE,
/// The linker chooses an arbitrary section among the definitions for this
@@ -100,7 +102,7 @@ class LIEF_API AuxiliarySectionDefinition : public AuxiliarySymbol {
/// The linker chooses the largest definition from among all of the definitions
/// for this symbol. If multiple definitions have this size, the choice
/// between them is arbitrary.
LARGEST
LARGEST,
};
/// The size of section data. The same as `SizeOfRawData` in the section header.
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
#include <memory>
#include <cassert>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
#include "LIEF/COFF/AuxiliarySymbol.hpp"
@@ -34,37 +35,39 @@ namespace COFF {
///
/// If a definition of `sym1` is linked, then an external reference to the
/// symbol is resolved normally. If a definition of `sym1` is not linked, then all
/// references to the weak external for `sym1` refer to `sym2` instead. The external
/// symbol, `sym2`, must always be linked; typically, it is defined in the module
/// that contains the weak reference to `sym1`.
/// references to the weak external for `sym1` refer to `sym2` instead. The
/// external symbol, `sym2`, must always be linked; typically, it is defined in the
/// module that contains the weak reference to `sym1`.
///
/// Reference: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-3-weak-externals
/// Reference:
/// https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-3-weak-externals
class LIEF_API AuxiliaryWeakExternal : public AuxiliarySymbol {
public:
enum class CHARACTERISTICS : uint32_t {
/// No library search for `sym1` should be performed.
SEARCH_NOLIBRARY = 1,
///A library search for `sym1` should be performed.
/// A library search for `sym1` should be performed.
SEARCH_LIBRARY = 2,
/// `sym1` is an alias for sym2
SEARCH_ALIAS = 3,
ANTI_DEPENDENCY = 4
ANTI_DEPENDENCY = 4,
};
LIEF_LOCAL static std::unique_ptr<AuxiliaryWeakExternal>
parse(const std::vector<uint8_t>& payload);
parse(const std::vector<uint8_t>& payload);
AuxiliaryWeakExternal() :
AuxiliarySymbol(AuxiliarySymbol::TYPE::WEAK_EXTERNAL)
{}
AuxiliarySymbol(AuxiliarySymbol::TYPE::WEAK_EXTERNAL) {}
AuxiliaryWeakExternal(uint32_t sym_idx, uint32_t characteristics,
std::vector<uint8_t> padding) :
AuxiliarySymbol(AuxiliarySymbol::TYPE::WEAK_EXTERNAL),
sym_idx_(sym_idx),
characteristics_(characteristics),
padding_(std::move(padding))
{
padding_(std::move(padding)) {
assert(padding_.size() == 10);
}
@@ -75,7 +78,9 @@ class LIEF_API AuxiliaryWeakExternal : public AuxiliarySymbol {
AuxiliaryWeakExternal& operator=(AuxiliaryWeakExternal&&) = default;
std::unique_ptr<AuxiliarySymbol> clone() const override {
return std::unique_ptr<AuxiliaryWeakExternal>(new AuxiliaryWeakExternal{*this});
return std::unique_ptr<AuxiliaryWeakExternal>(
new AuxiliaryWeakExternal{*this}
);
}
/// The symbol-table index of `sym2`, the symbol to be linked if `sym1` is not
@@ -88,7 +93,7 @@ class LIEF_API AuxiliaryWeakExternal : public AuxiliarySymbol {
return (CHARACTERISTICS)characteristics_;
}
span<const uint8_t> padding() const {
span<const uint8_t> padding() const LIEF_LIFETIMEBOUND {
return padding_;
}
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,11 +28,10 @@ namespace COFF {
class LIEF_API AuxiliarybfAndefSymbol : public AuxiliarySymbol {
public:
LIEF_LOCAL static std::unique_ptr<AuxiliarybfAndefSymbol>
parse(Symbol& sym, const std::vector<uint8_t>& payload);
parse(Symbol& sym, const std::vector<uint8_t>& payload);
AuxiliarybfAndefSymbol() :
AuxiliarySymbol(AuxiliarySymbol::TYPE::BF_AND_EF)
{}
AuxiliarySymbol(AuxiliarySymbol::TYPE::BF_AND_EF) {}
AuxiliarybfAndefSymbol(const AuxiliarybfAndefSymbol&) = default;
AuxiliarybfAndefSymbol& operator=(const AuxiliarybfAndefSymbol&) = default;
@@ -41,7 +40,9 @@ class LIEF_API AuxiliarybfAndefSymbol : public AuxiliarySymbol {
AuxiliarybfAndefSymbol& operator=(AuxiliarybfAndefSymbol&&) = default;
std::unique_ptr<AuxiliarySymbol> clone() const override {
return std::unique_ptr<AuxiliarybfAndefSymbol>(new AuxiliarybfAndefSymbol{*this});
return std::unique_ptr<AuxiliarybfAndefSymbol>(
new AuxiliarybfAndefSymbol{*this}
);
}
std::string to_string() const override {
+7 -6
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
#include "LIEF/COFF/Header.hpp"
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
#include "LIEF/span.hpp"
@@ -35,8 +36,7 @@ class LIEF_API BigObjHeader : public Header {
public:
static constexpr auto UUID_SZ = 16;
BigObjHeader() :
Header(KIND::BIGOBJ)
{}
Header(KIND::BIGOBJ) {}
static std::unique_ptr<BigObjHeader> create(BinaryStream& stream);
@@ -55,8 +55,9 @@ class LIEF_API BigObjHeader : public Header {
return version_;
}
/// Originally named `ClassID`, this uuid should match: `{D1BAA1C7-BAEE-4ba9-AF20-FAF66AA4DCB8}`
span<const uint8_t> uuid() const {
/// Originally named `ClassID`, this uuid should match:
/// `{D1BAA1C7-BAEE-4ba9-AF20-FAF66AA4DCB8}`
span<const uint8_t> uuid() const LIEF_LIFETIMEBOUND {
return uuid_;
}
+40 -34
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -61,7 +61,8 @@ class LIEF_API Binary {
using it_relocations = ref_iterator<relocations_t&, Relocation*>;
/// Iterator that outputs const Relocation& object
using it_const_relocations = const_ref_iterator<const relocations_t&, const Relocation*>;
using it_const_relocations =
const_ref_iterator<const relocations_t&, const Relocation*>;
/// Internal container used to store COFF's strings
using strings_table_t = std::vector<String>;
@@ -100,88 +101,92 @@ class LIEF_API Binary {
}
/// Iterator over the different sections located in this COFF binary
it_sections sections() {
it_sections sections() LIEF_LIFETIMEBOUND {
return sections_;
}
it_const_sections sections() const {
it_const_sections sections() const LIEF_LIFETIMEBOUND {
return sections_;
}
/// Iterator over **all** the relocations used by this COFF binary
it_relocations relocations() {
it_relocations relocations() LIEF_LIFETIMEBOUND {
return relocations_;
}
it_const_relocations relocations() const {
it_const_relocations relocations() const LIEF_LIFETIMEBOUND {
return relocations_;
}
/// Iterator over the COFF's symbols
it_symbols symbols() {
it_symbols symbols() LIEF_LIFETIMEBOUND {
return symbols_;
}
it_const_symbols symbols() const {
it_const_symbols symbols() const LIEF_LIFETIMEBOUND {
return symbols_;
}
/// Iterator over the COFF's strings
it_const_strings_table string_table() const {
it_const_strings_table string_table() const LIEF_LIFETIMEBOUND {
return strings_table_;
}
it_strings_table string_table() {
it_strings_table string_table() LIEF_LIFETIMEBOUND {
return strings_table_;
}
/// Try to find the COFF string at the given offset in the COFF string table.
///
/// \warning This offset must include the first 4 bytes holding the size of
/// @warning This offset must include the first 4 bytes holding the size of
/// the table. Hence, the first string starts a the offset 4.
String* find_string(uint32_t offset) {
String* find_string(uint32_t offset) LIEF_LIFETIMEBOUND {
auto it = std::find_if(strings_table_.begin(), strings_table_.end(),
[offset] (const String& item) {
return offset == item.offset();
}
);
[offset](const String& item) {
return offset == item.offset();
});
return it == strings_table_.end() ? nullptr : &*it;
}
const String* find_string(uint32_t offset) const {
const String* find_string(uint32_t offset) const LIEF_LIFETIMEBOUND {
return const_cast<Binary*>(this)->find_string(offset);
}
/// Iterator over the functions implemented in this COFF
it_const_function functions() const;
it_const_function functions() const LIEF_LIFETIMEBOUND;
it_functions functions();
it_functions functions() LIEF_LIFETIMEBOUND;
/// Try to find the function (symbol) with the given name
const Symbol* find_function(const std::string& name) const;
const Symbol* find_function(const std::string& name) const LIEF_LIFETIMEBOUND;
Symbol* find_function(const std::string& name) {
return const_cast<Symbol*>(static_cast<const Binary*>(this)->find_function(name));
Symbol* find_function(const std::string& name) LIEF_LIFETIMEBOUND {
return const_cast<Symbol*>(
static_cast<const Binary*>(this)->find_function(name)
);
}
/// Try to find the function (symbol) with the given **demangled** name
const Symbol* find_demangled_function(const std::string& name) const;
const Symbol*
find_demangled_function(const std::string& name) const LIEF_LIFETIMEBOUND;
Symbol* find_demangled_function(const std::string& name) {
return const_cast<Symbol*>(static_cast<const Binary*>(this)->find_demangled_function(name));
Symbol* find_demangled_function(const std::string& name) LIEF_LIFETIMEBOUND {
return const_cast<Symbol*>(
static_cast<const Binary*>(this)->find_demangled_function(name)
);
}
/// Disassemble code for the given symbol
///
/// ```cpp
/// const Symbol* func = binary->find_demangled_function("int __cdecl my_function(int, int)");
/// auto insts = binary->disassemble(*func);
/// for (std::unique_ptr<assembly::Instruction> inst : insts) {
/// const Symbol* func = binary->find_demangled_function("int __cdecl
/// my_function(int, int)"); auto insts = binary->disassemble(*func); for
/// (std::unique_ptr<assembly::Instruction> inst : insts) {
/// std::cout << inst->to_string() << '\n';
/// }
/// ```
///
/// \see LIEF::assembly::Instruction
/// @see LIEF::assembly::Instruction
instructions_it disassemble(const Symbol& symbol) const;
/// Disassemble code for the given symbol name
@@ -193,13 +198,13 @@ class LIEF_API Binary {
/// }
/// ```
///
/// \see LIEF::assembly::Instruction
/// @see LIEF::assembly::Instruction
instructions_it disassemble(const std::string& symbol) const;
/// Disassemble code provided by the given buffer at the specified
/// `address` parameter.
///
/// \see LIEF::assembly::Instruction
/// @see LIEF::assembly::Instruction
instructions_it disassemble(const uint8_t* buffer, size_t size,
uint64_t address = 0) const;
@@ -207,7 +212,7 @@ class LIEF_API Binary {
/// Disassemble code provided by the given vector of bytes at the specified
/// `address` parameter.
///
/// \see LIEF::assembly::Instruction
/// @see LIEF::assembly::Instruction
instructions_it disassemble(const std::vector<uint8_t>& buffer,
uint64_t address = 0) const {
return disassemble(buffer.data(), buffer.size(), address);
@@ -218,7 +223,8 @@ class LIEF_API Binary {
return disassemble(buffer.data(), buffer.size(), address);
}
instructions_it disassemble(LIEF::span<uint8_t> buffer, uint64_t address = 0) const {
instructions_it disassemble(LIEF::span<uint8_t> buffer,
uint64_t address = 0) const {
return disassemble(buffer.data(), buffer.size(), address);
}
+5 -8
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,11 +32,10 @@ namespace COFF {
/// `/bigobj` files
class LIEF_API Header {
public:
enum class KIND {
UNKNOWN = 0,
REGULAR,
BIGOBJ
BIGOBJ,
};
/// The different architectures (mirrored from PE)
@@ -48,8 +47,7 @@ class LIEF_API Header {
Header() = default;
Header(KIND kind) :
kind_(kind)
{}
kind_(kind) {}
Header& operator=(const Header&) = default;
Header(const Header&) = default;
@@ -119,8 +117,7 @@ class LIEF_API Header {
template<class T>
const T* as() const {
static_assert(std::is_base_of<Header, T>::value,
"Require Header inheritance");
static_assert(std::is_base_of<Header, T>::value, "Require Header inheritance");
if (T::classof(this)) {
return static_cast<const T*>(this);
}
+18 -25
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,10 +16,10 @@
#ifndef LIEF_COFF_PARSER_H
#define LIEF_COFF_PARSER_H
#include <map>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/BinaryStream/BinaryStream.hpp"
#include "LIEF/visibility.h"
#include "LIEF/BinaryStream/VectorStream.hpp"
#include "LIEF/BinaryStream/SpanStream.hpp"
#include "LIEF/errors.hpp"
#include "LIEF/COFF/ParserConfig.hpp"
#include "LIEF/COFF/Header.hpp"
@@ -33,23 +33,20 @@ class Symbol;
class Parser {
public:
static constexpr size_t MAX_NB_SECTIONS = 1 << 20;
/// Parse the COFF binary referenced by the `stream` argument with the
/// given config
static LIEF_API
std::unique_ptr<Binary> parse(std::unique_ptr<BinaryStream> stream,
const ParserConfig& config = ParserConfig::default_conf());
static LIEF_API std::unique_ptr<Binary>
parse(std::unique_ptr<BinaryStream> stream,
const ParserConfig& config = ParserConfig::default_conf());
/// Parse the COFF binary pointed by the `file` argument with the given config
static std::unique_ptr<Binary> parse(const std::string& file,
const ParserConfig& config = ParserConfig::default_conf())
{
if (auto strm = VectorStream::from_file(file)) {
return parse(std::unique_ptr<VectorStream>(new VectorStream(std::move(*strm))), config);
}
return nullptr;
}
static LIEF_API std::unique_ptr<Binary>
parse(const std::string& file,
const ParserConfig& config = ParserConfig::default_conf());
/// \private
/// @private
struct SymSec {
size_t sec_idx = 0;
Symbol* symbol = nullptr;
@@ -70,21 +67,17 @@ class Parser {
/// <=> std::unordered_multimap<section index, Symbol*>
using SymSecMap = std::vector<SymSec>;
/// \private
/// @private
LIEF_LOCAL void memoize(String str);
/// \private
/// @private
LIEF_LOCAL String* find_coff_string(uint32_t offset) const;
~Parser();
private:
Parser(std::unique_ptr<BinaryStream> stream, const ParserConfig& config,
Header::KIND kind) :
stream_(std::move(stream)),
kind_(kind),
config_(config)
{}
Header::KIND kind);
ok_error_t process();
ok_error_t parse_header();
@@ -102,7 +95,7 @@ class Parser {
std::map<size_t, Symbol*> symbol_idx_;
SymSecMap symsec_;
ParserConfig config_;
LIEF_MAYBE_UNUSED ParserConfig config_;
};
}
}
+3 -3
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ class LIEF_API ParserConfig {
}
static const ParserConfig& all() {
// To be updated when there is options that are off by default
// To be updated when there are options that are off by default
return default_conf();
}
};
+4 -5
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,8 +26,7 @@ namespace COFF {
class LIEF_API RegularHeader : public Header {
public:
RegularHeader() :
Header(KIND::REGULAR)
{}
Header(KIND::REGULAR) {}
/// Create a RegularHeader from the given stream
static std::unique_ptr<RegularHeader> create(BinaryStream& stream);
@@ -42,7 +41,7 @@ class LIEF_API RegularHeader : public Header {
return std::unique_ptr<Header>(new RegularHeader(*this));
}
/// The size of the optional header that follows this header (should be 0)
/// The size of the optional header which follows this header (should be 0)
uint16_t sizeof_optionalheader() const {
return sizeof_optionalheader_;
}
+81 -87
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,11 +35,11 @@ class LIEF_API Relocation : public LIEF::Relocation {
public:
friend class Parser;
static constexpr uint32_t I386 = 1 << 17;
static constexpr uint32_t X64 = 1 << 18;
static constexpr uint32_t ARM = 1 << 19;
static constexpr uint32_t I386 = 1 << 17;
static constexpr uint32_t X64 = 1 << 18;
static constexpr uint32_t ARM = 1 << 19;
static constexpr uint32_t ARM64 = 1 << 20;
static constexpr uint32_t MIPS = 1 << 21;
static constexpr uint32_t MIPS = 1 << 21;
/// The different relocation types.
///
@@ -48,87 +48,87 @@ class LIEF_API Relocation : public LIEF::Relocation {
enum class TYPE : uint32_t {
UNKNOWN = uint32_t(-1),
I386_ABSOLUTE = I386 + 0x0000,
I386_DIR16 = I386 + 0x0001,
I386_REL16 = I386 + 0x0002,
I386_DIR32 = I386 + 0x0006,
I386_DIR32NB = I386 + 0x0007,
I386_SEG12 = I386 + 0x0009,
I386_SECTION = I386 + 0x000A,
I386_SECREL = I386 + 0x000B,
I386_TOKEN = I386 + 0x000C,
I386_SECREL7 = I386 + 0x000D,
I386_REL32 = I386 + 0x0014,
I386_DIR16 = I386 + 0x0001,
I386_REL16 = I386 + 0x0002,
I386_DIR32 = I386 + 0x0006,
I386_DIR32NB = I386 + 0x0007,
I386_SEG12 = I386 + 0x0009,
I386_SECTION = I386 + 0x000A,
I386_SECREL = I386 + 0x000B,
I386_TOKEN = I386 + 0x000C,
I386_SECREL7 = I386 + 0x000D,
I386_REL32 = I386 + 0x0014,
AMD64_ABSOLUTE = X64 + 0x0000,
AMD64_ADDR64 = X64 + 0x0001,
AMD64_ADDR32 = X64 + 0x0002,
AMD64_ADDR64 = X64 + 0x0001,
AMD64_ADDR32 = X64 + 0x0002,
AMD64_ADDR32NB = X64 + 0x0003,
AMD64_REL32 = X64 + 0x0004,
AMD64_REL32_1 = X64 + 0x0005,
AMD64_REL32_2 = X64 + 0x0006,
AMD64_REL32_3 = X64 + 0x0007,
AMD64_REL32_4 = X64 + 0x0008,
AMD64_REL32_5 = X64 + 0x0009,
AMD64_SECTION = X64 + 0x000A,
AMD64_SECREL = X64 + 0x000B,
AMD64_SECREL7 = X64 + 0x000C,
AMD64_TOKEN = X64 + 0x000D,
AMD64_SREL32 = X64 + 0x000E,
AMD64_PAIR = X64 + 0x000F,
AMD64_SSPAN32 = X64 + 0x0010,
AMD64_REL32 = X64 + 0x0004,
AMD64_REL32_1 = X64 + 0x0005,
AMD64_REL32_2 = X64 + 0x0006,
AMD64_REL32_3 = X64 + 0x0007,
AMD64_REL32_4 = X64 + 0x0008,
AMD64_REL32_5 = X64 + 0x0009,
AMD64_SECTION = X64 + 0x000A,
AMD64_SECREL = X64 + 0x000B,
AMD64_SECREL7 = X64 + 0x000C,
AMD64_TOKEN = X64 + 0x000D,
AMD64_SREL32 = X64 + 0x000E,
AMD64_PAIR = X64 + 0x000F,
AMD64_SSPAN32 = X64 + 0x0010,
ARM_ABSOLUTE = ARM + 0x0000,
ARM_ADDR32 = ARM + 0x0001,
ARM_ADDR32NB = ARM + 0x0002,
ARM_BRANCH24 = ARM + 0x0003,
ARM_BRANCH11 = ARM + 0x0004,
ARM_TOKEN = ARM + 0x0005,
ARM_BLX24 = ARM + 0x0008,
ARM_BLX11 = ARM + 0x0009,
ARM_REL32 = ARM + 0x000A,
ARM_SECTION = ARM + 0x000E,
ARM_SECREL = ARM + 0x000F,
ARM_MOV32A = ARM + 0x0010,
ARM_MOV32T = ARM + 0x0011,
ARM_ABSOLUTE = ARM + 0x0000,
ARM_ADDR32 = ARM + 0x0001,
ARM_ADDR32NB = ARM + 0x0002,
ARM_BRANCH24 = ARM + 0x0003,
ARM_BRANCH11 = ARM + 0x0004,
ARM_TOKEN = ARM + 0x0005,
ARM_BLX24 = ARM + 0x0008,
ARM_BLX11 = ARM + 0x0009,
ARM_REL32 = ARM + 0x000A,
ARM_SECTION = ARM + 0x000E,
ARM_SECREL = ARM + 0x000F,
ARM_MOV32A = ARM + 0x0010,
ARM_MOV32T = ARM + 0x0011,
ARM_BRANCH20T = ARM + 0x0012,
ARM_BRANCH24T = ARM + 0x0014,
ARM_BLX23T = ARM + 0x0015,
ARM_PAIR = ARM + 0x0016,
ARM_BLX23T = ARM + 0x0015,
ARM_PAIR = ARM + 0x0016,
ARM64_ABSOLUTE = ARM64 + 0x0000,
ARM64_ADDR32 = ARM64 + 0x0001,
ARM64_ADDR32NB = ARM64 + 0x0002,
ARM64_BRANCH26 = ARM64 + 0x0003,
ARM64_ABSOLUTE = ARM64 + 0x0000,
ARM64_ADDR32 = ARM64 + 0x0001,
ARM64_ADDR32NB = ARM64 + 0x0002,
ARM64_BRANCH26 = ARM64 + 0x0003,
ARM64_PAGEBASE_REL21 = ARM64 + 0x0004,
ARM64_REL21 = ARM64 + 0x0005,
ARM64_REL21 = ARM64 + 0x0005,
ARM64_PAGEOFFSET_12A = ARM64 + 0x0006,
ARM64_PAGEOFFSET_12L = ARM64 + 0x0007,
ARM64_SECREL = ARM64 + 0x0008,
ARM64_SECREL_LOW12A = ARM64 + 0x0009,
ARM64_SECREL = ARM64 + 0x0008,
ARM64_SECREL_LOW12A = ARM64 + 0x0009,
ARM64_SECREL_HIGH12A = ARM64 + 0x000A,
ARM64_SECREL_LOW12L = ARM64 + 0x000B,
ARM64_TOKEN = ARM64 + 0x000C,
ARM64_SECTION = ARM64 + 0x000D,
ARM64_ADDR64 = ARM64 + 0x000E,
ARM64_BRANCH19 = ARM64 + 0x000F,
ARM64_BRANCH14 = ARM64 + 0x0010,
ARM64_REL32 = ARM64 + 0x0011,
ARM64_SECREL_LOW12L = ARM64 + 0x000B,
ARM64_TOKEN = ARM64 + 0x000C,
ARM64_SECTION = ARM64 + 0x000D,
ARM64_ADDR64 = ARM64 + 0x000E,
ARM64_BRANCH19 = ARM64 + 0x000F,
ARM64_BRANCH14 = ARM64 + 0x0010,
ARM64_REL32 = ARM64 + 0x0011,
MIPS_ABSOLUTE = MIPS + 0x0000,
MIPS_REFHALF = MIPS + 0x0001,
MIPS_REFWORD = MIPS + 0x0002,
MIPS_JMPADDR = MIPS + 0x0003,
MIPS_REFHI = MIPS + 0x0004,
MIPS_REFLO = MIPS + 0x0005,
MIPS_GPREL = MIPS + 0x0006,
MIPS_LITERAL = MIPS + 0x0007,
MIPS_SECTION = MIPS + 0x000A,
MIPS_SECREL = MIPS + 0x000B,
MIPS_SECRELLO = MIPS + 0x000C,
MIPS_SECRELHI = MIPS + 0x000D,
MIPS_ABSOLUTE = MIPS + 0x0000,
MIPS_REFHALF = MIPS + 0x0001,
MIPS_REFWORD = MIPS + 0x0002,
MIPS_JMPADDR = MIPS + 0x0003,
MIPS_REFHI = MIPS + 0x0004,
MIPS_REFLO = MIPS + 0x0005,
MIPS_GPREL = MIPS + 0x0006,
MIPS_LITERAL = MIPS + 0x0007,
MIPS_SECTION = MIPS + 0x000A,
MIPS_SECREL = MIPS + 0x000B,
MIPS_SECRELLO = MIPS + 0x000C,
MIPS_SECRELHI = MIPS + 0x000D,
MIPS_JMPADDR16 = MIPS + 0x0010,
MIPS_REFWORDNB = MIPS + 0x0022,
MIPS_PAIR = MIPS + 0x0025,
MIPS_PAIR = MIPS + 0x0025,
};
/// Convert a relocation enum type into a 16-bits value.
@@ -139,32 +139,26 @@ class LIEF_API Relocation : public LIEF::Relocation {
/// Create a relocation type from its raw value and the architecture
static TYPE from_value(uint16_t value, Header::MACHINE_TYPES arch) {
switch (arch) {
case Header::MACHINE_TYPES::ARM64:
return TYPE(value + ARM64);
case Header::MACHINE_TYPES::ARM64: return TYPE(value + ARM64);
case Header::MACHINE_TYPES::AMD64:
return TYPE(value + X64);
case Header::MACHINE_TYPES::AMD64: return TYPE(value + X64);
case Header::MACHINE_TYPES::I386:
return TYPE(value + I386);
case Header::MACHINE_TYPES::I386: return TYPE(value + I386);
case Header::MACHINE_TYPES::ARM:
case Header::MACHINE_TYPES::ARMNT:
case Header::MACHINE_TYPES::THUMB:
return TYPE(value + ARM);
case Header::MACHINE_TYPES::THUMB: return TYPE(value + ARM);
case Header::MACHINE_TYPES::R4000:
return TYPE(value + MIPS);
case Header::MACHINE_TYPES::R4000: return TYPE(value + MIPS);
default:
return TYPE::UNKNOWN;
default: return TYPE::UNKNOWN;
}
return TYPE::UNKNOWN;
}
/// Create a relocation from the given stream
static std::unique_ptr<Relocation> parse(
BinaryStream& stream, Header::MACHINE_TYPES arch);
static std::unique_ptr<Relocation> parse(BinaryStream& stream,
Header::MACHINE_TYPES arch);
/// Symbol index associated with this relocation
uint32_t symbol_idx() const {
+34 -16
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
#include <memory>
#include <ostream>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
#include "LIEF/Abstract/Section.hpp"
#include "LIEF/PE/Section.hpp"
@@ -60,9 +61,11 @@ class LIEF_API Section : public LIEF::Section {
using it_relocations = ref_iterator<relocations_t&, Relocation*>;
/// Iterator that outputs const Relocation&
using it_const_relocations = const_ref_iterator<const relocations_t&, const Relocation*>;
using it_const_relocations =
const_ref_iterator<const relocations_t&, const Relocation*>;
/// Container for the symbols associated with this section (owned by the Binary object)
/// Container for the symbols associated with this section (owned by the Binary
/// object)
using symbols_t = std::vector<Symbol*>;
/// Iterator that outputs Symbol&
@@ -85,7 +88,7 @@ class LIEF_API Section : public LIEF::Section {
}
/// Content wrapped by this section
span<const uint8_t> content() const override {
span<const uint8_t> content() const LIEF_LIFETIMEBOUND override {
return content_;
}
@@ -110,7 +113,7 @@ class LIEF_API Section : public LIEF::Section {
/// Number of relocations.
///
/// \warning If the number of relocations is greater than 0xFFFF (maximum
/// @warning If the number of relocations is greater than 0xFFFF (maximum
/// value for 16-bits integer), then the number of relocations is
/// stored in the virtual address of the **first** relocation.
uint16_t numberof_relocations() const {
@@ -151,32 +154,33 @@ class LIEF_API Section : public LIEF::Section {
}
/// Iterator over the relocations associated with this section
it_relocations relocations() {
it_relocations relocations() LIEF_LIFETIMEBOUND {
return relocations_;
}
it_const_relocations relocations() const {
it_const_relocations relocations() const LIEF_LIFETIMEBOUND {
return relocations_;
}
/// Iterator over the symbols associated with this section
it_symbols symbols() {
it_symbols symbols() LIEF_LIFETIMEBOUND {
return symbols_;
}
it_const_symbols symbols() const {
it_const_symbols symbols() const LIEF_LIFETIMEBOUND {
return symbols_;
}
/// Return comdat infomration (only if the section has the
/// Return comdat information (only if the section has the
/// CHARACTERISTICS::LNK_COMDAT characteristic)
optional<ComdatInfo> comdat_info() const;
/// Whether there is a large number of relocations whose number need
/// to be stored in the virtual address attribute
bool has_extended_relocations() const {
static constexpr auto MAX_RELOC = /*uint16_t::max*/ 65535;
return has_characteristic(CHARACTERISTICS::LNK_NRELOC_OVFL) &&
numberof_relocations() == std::numeric_limits<uint16_t>::max();
numberof_relocations() == MAX_RELOC;
}
void content(const std::vector<uint8_t>& data) override {
@@ -217,6 +221,18 @@ class LIEF_API Section : public LIEF::Section {
characteristics_ = characteristics;
}
/// Return the COFF string associated with the section's name (or a nullptr)
///
/// This coff string is usually present for long section names whose length
/// does not fit in the 8 bytes allocated by the COFF format.
String* coff_string() {
return coff_string_;
}
const String* coff_string() const {
return coff_string_;
}
std::string to_string() const;
LIEF_API friend std::ostream& operator<<(std::ostream& os, const Section& sec) {
@@ -230,15 +246,17 @@ class LIEF_API Section : public LIEF::Section {
Section() = default;
std::vector<uint8_t> content_;
uint32_t virtual_size_ = 0;
uint32_t virtual_size_ = 0;
uint32_t pointer_to_relocations_ = 0;
uint32_t pointer_to_linenumbers_ = 0;
uint16_t number_of_relocations_ = 0;
uint16_t number_of_linenumbers_ = 0;
uint32_t characteristics_ = 0;
uint16_t number_of_relocations_ = 0;
uint16_t number_of_linenumbers_ = 0;
uint32_t characteristics_ = 0;
relocations_t relocations_;
symbols_t symbols_;
String* coff_string_ = nullptr;
};
inline const char* to_string(Section::CHARACTERISTICS e) {
+9 -11
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,14 +29,14 @@ namespace COFF {
/// Some of these strings can be used for section names that are greater than 8
/// bytes. See: LIEF::PE::Section::coff_string()
///
/// Reference: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#coff-string-table
/// Reference:
/// https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#coff-string-table
class LIEF_API String {
public:
String() = default;
String(uint32_t offset, std::string str) :
str_(std::move(str)),
offset_(offset)
{}
offset_(offset) {}
String(const String&) = default;
String& operator=(const String&) = default;
@@ -47,7 +47,7 @@ class LIEF_API String {
~String() = default;
/// The actual string
const std::string& str() const {
const std::string& str() const LIEF_LIFETIMEBOUND {
return str_;
}
@@ -57,19 +57,17 @@ class LIEF_API String {
return offset_;
}
String& str(std::string str) {
String& str(std::string str) LIEF_LIFETIMEBOUND {
str_ = std::move(str);
return *this;
}
String& offset(uint32_t value) {
String& offset(uint32_t value) LIEF_LIFETIMEBOUND {
offset_ = value;
return *this;
}
friend LIEF_API
std::ostream& operator<<(std::ostream& os, const String& str)
{
friend LIEF_API std::ostream& operator<<(std::ostream& os, const String& str) {
os << str.str();
return os;
}
+45 -43
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,15 +37,17 @@ class LIEF_API Symbol : public LIEF::Symbol {
friend class Parser;
using auxiliary_symbols_t = std::vector<std::unique_ptr<AuxiliarySymbol>>;
using it_auxiliary_symbols_t = ref_iterator<auxiliary_symbols_t&, AuxiliarySymbol*>;
using it_const_auxiliary_symbols_t = const_ref_iterator<const auxiliary_symbols_t&, AuxiliarySymbol*>;
using it_auxiliary_symbols_t =
ref_iterator<auxiliary_symbols_t&, AuxiliarySymbol*>;
using it_const_auxiliary_symbols_t =
const_ref_iterator<const auxiliary_symbols_t&, AuxiliarySymbol*>;
struct parsing_context_t {
std::function<String*(uint32_t)> find_string;
bool is_bigobj;
};
static std::unique_ptr<Symbol> parse(
parsing_context_t& ctx, BinaryStream& stream, size_t* idx);
static std::unique_ptr<Symbol> parse(parsing_context_t& ctx,
BinaryStream& stream, size_t* idx);
Symbol();
Symbol(const Symbol&);
@@ -58,8 +60,10 @@ class LIEF_API Symbol : public LIEF::Symbol {
/// correspond to a section. Microsoft tools use this setting along with
/// `.file` records.
static constexpr auto SYM_SEC_IDX_DEBUG = -2;
/// The symbol has an absolute (non-relocatable) value and is not an address.
static constexpr auto SYM_SEC_IDX_ABS = -1;
/// The symbol record is not yet assigned a section. A value of zero indicates
/// that a reference to an external symbol is defined elsewhere. A value of
/// non-zero is a common symbol with a size that is specified by the value.
@@ -67,37 +71,38 @@ class LIEF_API Symbol : public LIEF::Symbol {
static constexpr auto SYM_COMPLEX_TYPE_SHIFT = 4;
/// Reference: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#storage-class
/// Reference:
/// https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#storage-class
enum class STORAGE_CLASS : int32_t {
INVALID = 0xFF,
END_OF_FUNCTION = -1, ///< Physical end of function
NONE = 0, ///< No symbol
AUTOMATIC = 1, ///< Stack variable
EXTERNAL = 2, ///< External symbol
STATIC = 3, ///< Static
REGISTER = 4, ///< Register variable
EXTERNAL_DEF = 5, ///< External definition
LABEL = 6, ///< Label
UNDEFINED_LABEL = 7, ///< Undefined label
MEMBER_OF_STRUCT = 8, ///< Member of structure
ARGUMENT = 9, ///< Function argument
STRUCT_TAG = 10, ///< Structure tag
MEMBER_OF_UNION = 11, ///< Member of union
UNION_TAG = 12, ///< Union tag
TYPE_DEFINITION = 13, ///< Type definition
UNDEFINED_STATIC = 14, ///< Undefined static
ENUM_TAG = 15, ///< Enumeration tag
MEMBER_OF_ENUM = 16, ///< Member of enumeration
REGISTER_PARAM = 17, ///< Register parameter
BIT_FIELD = 18, ///< Bit field
BLOCK = 100,
FUNCTION = 101,
END_OF_STRUCT = 102, ///< End of structure
FILE = 103, ///< File name
SECTION = 104,
WEAK_EXTERNAL = 105, ///< Duplicate tag
CLR_TOKEN = 107
END_OF_FUNCTION = -1, ///< Physical end of function
NONE = 0, ///< No symbol
AUTOMATIC = 1, ///< Stack variable
EXTERNAL = 2, ///< External symbol
STATIC = 3, ///< Static
REGISTER = 4, ///< Register variable
EXTERNAL_DEF = 5, ///< External definition
LABEL = 6, ///< Label
UNDEFINED_LABEL = 7, ///< Undefined label
MEMBER_OF_STRUCT = 8, ///< Member of structure
ARGUMENT = 9, ///< Function argument
STRUCT_TAG = 10, ///< Structure tag
MEMBER_OF_UNION = 11, ///< Member of union
UNION_TAG = 12, ///< Union tag
TYPE_DEFINITION = 13, ///< Type definition
UNDEFINED_STATIC = 14, ///< Undefined static
ENUM_TAG = 15, ///< Enumeration tag
MEMBER_OF_ENUM = 16, ///< Member of enumeration
REGISTER_PARAM = 17, ///< Register parameter
BIT_FIELD = 18, ///< Bit field
BLOCK = 100,
FUNCTION = 101,
END_OF_STRUCT = 102, ///< End of structure
FILE = 103, ///< File name
SECTION = 104,
WEAK_EXTERNAL = 105, ///< Duplicate tag
CLR_TOKEN = 107,
};
enum class BASE_TYPE : uint32_t {
@@ -116,7 +121,7 @@ class LIEF_API Symbol : public LIEF::Symbol {
TY_BYTE = 12, ///< A byte; unsigned 1-byte integer.
TY_WORD = 13, ///< A word; unsigned 2-byte integer.
TY_UINT = 14, ///< An unsigned integer of natural size.
TY_DWORD = 15 ///< An unsigned 4-byte integer.
TY_DWORD = 15, ///< An unsigned 4-byte integer.
};
enum class COMPLEX_TYPE : uint32_t {
@@ -192,8 +197,7 @@ class LIEF_API Symbol : public LIEF::Symbol {
}
bool is_undefined() const {
return is_external() && section_idx() == SYM_SEC_IDX_UNDEF &&
value() == 0;
return is_external() && section_idx() == SYM_SEC_IDX_UNDEF && value() == 0;
}
bool is_function_line_info() const {
@@ -223,7 +227,7 @@ class LIEF_API Symbol : public LIEF::Symbol {
std::string& name() override;
/// COFF string used to represents the (long) symbol name
/// COFF string used to represent the (long) symbol name
const String* coff_name() const {
return coff_name_;
}
@@ -256,9 +260,7 @@ class LIEF_API Symbol : public LIEF::Symbol {
std::string to_string() const;
LIEF_API friend
std::ostream& operator<<(std::ostream& os, const Symbol& entry)
{
LIEF_API friend std::ostream& operator<<(std::ostream& os, const Symbol& entry) {
os << entry.to_string();
return os;
}
@@ -267,8 +269,8 @@ class LIEF_API Symbol : public LIEF::Symbol {
private:
template<class T>
static std::unique_ptr<Symbol> parse_impl(
parsing_context_t& ctx, BinaryStream& stream, size_t* idx);
static std::unique_ptr<Symbol> parse_impl(parsing_context_t& ctx,
BinaryStream& stream, size_t* idx);
String* coff_name_ = nullptr;
uint16_t type_ = 0;
uint8_t storage_class_ = 0;
+2 -3
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
#define LIEF_COFF_UTILS_H
#include "LIEF/visibility.h"
#include "LIEF/COFF/Header.hpp"
#include "LIEF/BinaryStream/FileStream.hpp"
#include "LIEF/BinaryStream/SpanStream.hpp"
#include <string>
+11 -11
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,15 +18,15 @@
#include "LIEF/config.h"
#if defined(LIEF_DEX_SUPPORT)
#include "LIEF/DEX/Parser.hpp"
#include "LIEF/DEX/utils.hpp"
#include "LIEF/DEX/File.hpp"
#include "LIEF/DEX/Class.hpp"
#include "LIEF/DEX/Prototype.hpp"
#include "LIEF/DEX/Header.hpp"
#include "LIEF/DEX/Method.hpp"
#include "LIEF/DEX/Field.hpp"
#include "LIEF/DEX/EnumToString.hpp"
#include "LIEF/DEX/Parser.hpp"
#include "LIEF/DEX/utils.hpp"
#include "LIEF/DEX/File.hpp"
#include "LIEF/DEX/Class.hpp"
#include "LIEF/DEX/Prototype.hpp"
#include "LIEF/DEX/Header.hpp"
#include "LIEF/DEX/Method.hpp"
#include "LIEF/DEX/Field.hpp"
#include "LIEF/DEX/EnumToString.hpp"
#endif
#endif
+8 -7
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -56,7 +56,8 @@ class LIEF_API Class : public Object {
public:
static std::string package_normalized(const std::string& pkg_name);
static std::string fullname_normalized(const std::string& pkg_cls);
static std::string fullname_normalized(const std::string& pkg, const std::string& cls_name);
static std::string fullname_normalized(const std::string& pkg,
const std::string& cls_name);
Class();
Class(const Class&) = delete;
@@ -124,10 +125,10 @@ class LIEF_API Class : public Object {
private:
std::string fullname_;
uint32_t access_flags_ = ACCESS_FLAGS::ACC_UNKNOWN;
Class* parent_ = nullptr;
methods_t methods_;
fields_t fields_;
uint32_t access_flags_ = ACCESS_FLAGS::ACC_UNKNOWN;
Class* parent_ = nullptr;
methods_t methods_;
fields_t fields_;
std::string source_filename_;
uint32_t original_index_ = UINT_MAX;
+4 -4
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,13 +46,13 @@ class LIEF_API CodeInfo : public Object {
~CodeInfo() override;
LIEF_API friend std::ostream& operator<<(std::ostream& os, const CodeInfo& cinfo);
LIEF_API friend std::ostream& operator<<(std::ostream& os,
const CodeInfo& cinfo);
private:
uint16_t nb_registers_ = 0;
uint16_t args_input_sizes_ = 0;
uint16_t output_sizes_ = 0;
};
} // Namespace DEX
+2 -3
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,4 +32,3 @@ LIEF_API const char* to_string(Type::PRIMITIVES e);
} // namespace LIEF
#endif
+7 -6
View File
@@ -1,4 +1,4 @@
/* Copyright 2021 - 2025 R. Thomas
/* Copyright 2021 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,9 +30,10 @@ namespace DEX {
class Parser;
class Class;
/// Class which represent a DEX Field
/// Class which represents a DEX Field
class LIEF_API Field : public Object {
friend class Parser;
public:
using access_flags_list_t = std::vector<ACCESS_FLAGS>;
@@ -51,8 +52,8 @@ class LIEF_API Field : public Object {
bool has_class() const;
/// Class associated with this Field
const Class* cls() const;
Class* cls();
const Class* cls() const LIEF_LIFETIMEBOUND;
Class* cls() LIEF_LIFETIMEBOUND;
/// Index in the DEX Fields pool
size_t index() const;
@@ -61,8 +62,8 @@ class LIEF_API Field : public Object {
bool is_static() const;
/// Field's prototype
const Type* type() const;
Type* type();
const Type* type() const LIEF_LIFETIMEBOUND;
Type* type() LIEF_LIFETIMEBOUND;
void accept(Visitor& visitor) const override;
+46 -42
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,25 +49,27 @@ class LIEF_API File : public Object {
using it_methods = ref_iterator<methods_t&, Method*>;
using it_const_methods = const_ref_iterator<const methods_t&, const Method*>;
using strings_t = std::vector<std::unique_ptr<std::string>>;
using it_strings = ref_iterator<strings_t&, std::string*>;
using it_const_strings = const_ref_iterator<const strings_t&, const std::string*>;
using strings_t = std::vector<std::unique_ptr<std::string>>;
using it_strings = ref_iterator<strings_t&, std::string*>;
using it_const_strings =
const_ref_iterator<const strings_t&, const std::string*>;
using types_t = std::vector<std::unique_ptr<Type>>;
using it_types = ref_iterator<types_t&, Type*>;
using it_const_types = const_ref_iterator<const types_t&, const Type*>;
using types_t = std::vector<std::unique_ptr<Type>>;
using it_types = ref_iterator<types_t&, Type*>;
using it_const_types = const_ref_iterator<const types_t&, const Type*>;
using prototypes_t = std::vector<std::unique_ptr<Prototype>>;
using it_prototypes = ref_iterator<prototypes_t&, Prototype*>;
using it_const_prototypes = const_ref_iterator<const prototypes_t&, const Prototype*>;
using prototypes_t = std::vector<std::unique_ptr<Prototype>>;
using it_prototypes = ref_iterator<prototypes_t&, Prototype*>;
using it_const_prototypes =
const_ref_iterator<const prototypes_t&, const Prototype*>;
using fields_t = std::vector<std::unique_ptr<Field>>;
using it_fields = ref_iterator<fields_t&, Field*>;
using it_const_fields = const_ref_iterator<const fields_t&, const Field*>;
using fields_t = std::vector<std::unique_ptr<Field>>;
using it_fields = ref_iterator<fields_t&, Field*>;
using it_const_fields = const_ref_iterator<const fields_t&, const Field*>;
public:
File& operator=(const File& copy) = delete;
File(const File& copy) = delete;
File(const File& copy) = delete;
/// Version of the current DEX file
dex_version_t version() const;
@@ -82,25 +84,25 @@ class LIEF_API File : public Object {
void location(const std::string& location);
/// DEX header
const Header& header() const;
Header& header();
const Header& header() const LIEF_LIFETIMEBOUND;
Header& header() LIEF_LIFETIMEBOUND;
/// **All** classes used in the DEX file
it_const_classes classes() const;
it_classes classes();
it_const_classes classes() const LIEF_LIFETIMEBOUND;
it_classes classes() LIEF_LIFETIMEBOUND;
/// Check if the given class name exists
bool has_class(const std::string& class_name) const;
/// Return the DEX::Class object associated with the given name
const Class* get_class(const std::string& class_name) const;
const Class* get_class(const std::string& class_name) const LIEF_LIFETIMEBOUND;
Class* get_class(const std::string& class_name);
Class* get_class(const std::string& class_name) LIEF_LIFETIMEBOUND;
/// Return the DEX::Class object associated with the given index
const Class* get_class(size_t index) const;
const Class* get_class(size_t index) const LIEF_LIFETIMEBOUND;
Class* get_class(size_t index);
Class* get_class(size_t index) LIEF_LIFETIMEBOUND;
/// De-optimize information
dex2dex_info_t dex2dex_info() const;
@@ -109,24 +111,24 @@ class LIEF_API File : public Object {
std::string dex2dex_json_info() const;
/// Return an iterator over **all** the DEX::Method used in this DEX file
it_const_methods methods() const;
it_methods methods();
it_const_methods methods() const LIEF_LIFETIMEBOUND;
it_methods methods() LIEF_LIFETIMEBOUND;
/// Return an iterator over **all** the DEX::Field used in this DEX file
it_const_fields fields() const;
it_fields fields();
it_const_fields fields() const LIEF_LIFETIMEBOUND;
it_fields fields() LIEF_LIFETIMEBOUND;
/// String pool
it_const_strings strings() const;
it_strings strings();
it_const_strings strings() const LIEF_LIFETIMEBOUND;
it_strings strings() LIEF_LIFETIMEBOUND;
/// Type pool
it_const_types types() const;
it_types types();
it_const_types types() const LIEF_LIFETIMEBOUND;
it_types types() LIEF_LIFETIMEBOUND;
/// Prototype pool
it_prototypes prototypes();
it_const_prototypes prototypes() const;
it_prototypes prototypes() LIEF_LIFETIMEBOUND;
it_const_prototypes prototypes() const LIEF_LIFETIMEBOUND;
/// DEX Map
const MapList& map() const;
@@ -151,20 +153,22 @@ class LIEF_API File : public Object {
static void deoptimize_nop(uint8_t* inst_ptr, uint32_t value);
static void deoptimize_return(uint8_t* inst_ptr, uint32_t value);
static void deoptimize_invoke_virtual(uint8_t* inst_ptr, uint32_t value, OPCODES new_inst);
static void deoptimize_instance_field_access(uint8_t* inst_ptr, uint32_t value, OPCODES new_inst);
static void deoptimize_invoke_virtual(uint8_t* inst_ptr, uint32_t value,
OPCODES new_inst);
static void deoptimize_instance_field_access(uint8_t* inst_ptr, uint32_t value,
OPCODES new_inst);
std::string name_;
std::string location_;
Header header_;
classes_t classes_;
methods_t methods_;
fields_t fields_;
strings_t strings_;
types_t types_;
Header header_;
classes_t classes_;
methods_t methods_;
fields_t fields_;
strings_t strings_;
types_t types_;
prototypes_t prototypes_;
MapList map_;
MapList map_;
classes_list_t class_list_;
std::vector<uint8_t> original_data_;
+27 -27
View File
@@ -1,6 +1,6 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@ class LIEF_API Header : public Object {
public:
using location_t = std::pair<uint32_t, uint32_t>;
using magic_t = std::array<uint8_t, 8>;
using magic_t = std::array<uint8_t, 8>;
using signature_t = std::array<uint8_t, 20>;
Header();
@@ -67,7 +67,7 @@ class LIEF_API Header : public Object {
/// Size of this header. It should be 0x70
uint32_t header_size() const;
/// File endianess of the file
/// File endianness of the file
uint32_t endian_tag() const;
/// Offset from the start of the file to the map list (see: DEX::MapList)
@@ -95,39 +95,39 @@ class LIEF_API Header : public Object {
~Header() override;
private:
magic_t magic_;
uint32_t checksum_;
signature_t signature_;
uint32_t file_size_;
magic_t magic_{};
uint32_t checksum_ = 0;
signature_t signature_{};
uint32_t file_size_ = 0;
uint32_t header_size_;
uint32_t endian_tag_;
uint32_t header_size_ = 0;
uint32_t endian_tag_ = 0;
uint32_t link_size_;
uint32_t link_off_;
uint32_t link_size_ = 0;
uint32_t link_off_ = 0;
uint32_t map_off_;
uint32_t map_off_ = 0;
uint32_t string_ids_size_;
uint32_t string_ids_off_;
uint32_t string_ids_size_ = 0;
uint32_t string_ids_off_ = 0;
uint32_t type_ids_size_;
uint32_t type_ids_off_;
uint32_t type_ids_size_ = 0;
uint32_t type_ids_off_ = 0;
uint32_t proto_ids_size_;
uint32_t proto_ids_off_;
uint32_t proto_ids_size_ = 0;
uint32_t proto_ids_off_ = 0;
uint32_t field_ids_size_;
uint32_t field_ids_off_;
uint32_t field_ids_size_ = 0;
uint32_t field_ids_off_ = 0;
uint32_t method_ids_size_;
uint32_t method_ids_off_;
uint32_t method_ids_size_ = 0;
uint32_t method_ids_off_ = 0;
uint32_t class_defs_size_;
uint32_t class_defs_off_;
uint32_t class_defs_size_ = 0;
uint32_t class_defs_off_ = 0;
uint32_t data_size_;
uint32_t data_off_;
uint32_t data_size_ = 0;
uint32_t data_off_ = 0;
};
} // Namespace DEX
+26 -27
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,26 +33,26 @@ class LIEF_API MapItem : public Object {
public:
enum class TYPES : uint16_t {
HEADER = 0x0000,
STRING_ID = 0x0001,
TYPE_ID = 0x0002,
PROTO_ID = 0x0003,
FIELD_ID = 0x0004,
METHOD_ID = 0x0005,
CLASS_DEF = 0x0006,
CALL_SITE_ID = 0x0007,
METHOD_HANDLE = 0x0008,
MAP_LIST = 0x1000,
TYPE_LIST = 0x1001,
HEADER = 0x0000,
STRING_ID = 0x0001,
TYPE_ID = 0x0002,
PROTO_ID = 0x0003,
FIELD_ID = 0x0004,
METHOD_ID = 0x0005,
CLASS_DEF = 0x0006,
CALL_SITE_ID = 0x0007,
METHOD_HANDLE = 0x0008,
MAP_LIST = 0x1000,
TYPE_LIST = 0x1001,
ANNOTATION_SET_REF_LIST = 0x1002,
ANNOTATION_SET = 0x1003,
CLASS_DATA = 0x2000,
CODE = 0x2001,
STRING_DATA = 0x2002,
DEBUG_INFO = 0x2003,
ANNOTATION = 0x2004,
ENCODED_ARRAY = 0x2005,
ANNOTATIONS_DIRECTORY = 0x2006,
ANNOTATION_SET = 0x1003,
CLASS_DATA = 0x2000,
CODE = 0x2001,
STRING_DATA = 0x2002,
DEBUG_INFO = 0x2003,
ANNOTATION = 0x2004,
ENCODED_ARRAY = 0x2005,
ANNOTATIONS_DIRECTORY = 0x2006,
};
@@ -66,7 +66,7 @@ class LIEF_API MapItem : public Object {
/// The type of the item
TYPES type() const;
/// Reserved value (likely for alignment prupose)
/// Reserved value (likely for alignment purpose)
uint16_t reserved() const;
/// The number of elements (the real meaning depends on the type)
@@ -84,11 +84,10 @@ class LIEF_API MapItem : public Object {
~MapItem() override;
private:
TYPES type_;
uint16_t reserved_;
uint32_t size_;
uint32_t offset_;
TYPES type_ = TYPES::HEADER;
uint16_t reserved_ = 0;
uint32_t size_ = 0;
uint32_t offset_ = 0;
};
} // Namespace DEX
+7 -8
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,9 +38,9 @@ class LIEF_API MapList : public Object {
friend class Parser;
public:
using items_t = std::map<MapItem::TYPES, MapItem>;
using it_items_t = ref_iterator<std::vector<MapItem*>>;
using it_const_items_t = const_ref_iterator<std::vector<MapItem*>>;
using items_t = std::map<MapItem::TYPES, MapItem>;
using it_items_t = ref_iterator<std::vector<MapItem*>>;
using it_const_items_t = const_ref_iterator<std::vector<MapItem*>>;
public:
MapList();
@@ -56,10 +56,10 @@ class LIEF_API MapList : public Object {
bool has(MapItem::TYPES type) const;
/// Return the LIEF::DEX::MapItem associated with the given type
const MapItem& get(MapItem::TYPES type) const;
const MapItem& get(MapItem::TYPES type) const LIEF_LIFETIMEBOUND;
/// Return the LIEF::DEX::MapItem associated with the given type
MapItem& get(MapItem::TYPES type);
MapItem& get(MapItem::TYPES type) LIEF_LIFETIMEBOUND;
/// Return the LIEF::DEX::MapItem associated with the given type
const MapItem& operator[](MapItem::TYPES type) const;
@@ -76,7 +76,6 @@ class LIEF_API MapList : public Object {
private:
items_t items_;
};
} // Namespace DEX
+4 -4
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@ class Prototype;
/// Class which represents a DEX::Method
class LIEF_API Method : public Object {
friend class Parser;
public:
using access_flags_list_t = std::vector<ACCESS_FLAGS>;
@@ -67,7 +68,7 @@ class LIEF_API Method : public Object {
size_t index() const;
/// True if this method is a virtual one.
/// i.e. not **static**, **private**, **finale** or constructor
/// i.e. not **static**, **private**, **final** or constructor
bool is_virtual() const;
/// Method's prototype or a nullptr if it is not resolved
@@ -110,7 +111,6 @@ class LIEF_API Method : public Object {
CodeInfo code_info_;
dex2dex_method_info_t dex2dex_info_;
};
} // Namespace DEX
+5 -5
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,13 +37,13 @@ class Type;
/// Class which parses a DEX file to produce a DEX::File object
class LIEF_API Parser {
public:
/// Parse the DEX file from the file path given in parameter
static std::unique_ptr<File> parse(const std::string& file);
static std::unique_ptr<File> parse(std::vector<uint8_t> data, const std::string& name = "");
static std::unique_ptr<File> parse(std::vector<uint8_t> data,
const std::string& name = "");
Parser& operator=(const Parser& copy) = delete;
Parser(const Parser& copy) = delete;
Parser(const Parser& copy) = delete;
private:
Parser();
+8 -8
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,16 +31,16 @@ class LIEF_API Prototype : public Object {
public:
using parameters_type_t = std::vector<Type*>;
using it_params = ref_iterator<parameters_type_t>;
using it_const_params = const_ref_iterator<const parameters_type_t>;
using it_params = ref_iterator<parameters_type_t>;
using it_const_params = const_ref_iterator<const parameters_type_t>;
public:
Prototype();
Prototype(const Prototype& other);
/// Type returned or a nullptr if not resolved
const Type* return_type() const;
Type* return_type();
const Type* return_type() const LIEF_LIFETIMEBOUND;
Type* return_type() LIEF_LIFETIMEBOUND;
/// Types of the parameters
it_const_params parameters_type() const;
@@ -49,14 +49,14 @@ class LIEF_API Prototype : public Object {
void accept(Visitor& visitor) const override;
LIEF_API friend std::ostream& operator<<(std::ostream& os, const Prototype& type);
LIEF_API friend std::ostream& operator<<(std::ostream& os,
const Prototype& type);
~Prototype() override;
private:
Type* return_type_ = nullptr;
parameters_type_t params_;
};
} // Namespace DEX
+17 -16
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,28 +29,29 @@ class Parser;
class Class;
/// Class which represents a DEX type as described in the
/// format specifications: https://source.android.com/devices/tech/dalvik/dex-format#typedescriptor
/// format specifications:
/// https://source.android.com/devices/tech/dalvik/dex-format#typedescriptor
class LIEF_API Type : public Object {
friend class Parser;
public:
enum class TYPES {
UNKNOWN = 0,
UNKNOWN = 0,
PRIMITIVE = 1,
CLASS = 2,
ARRAY = 3,
CLASS = 2,
ARRAY = 3,
};
enum class PRIMITIVES {
VOID_T = 0x01,
VOID_T = 0x01,
BOOLEAN = 0x02,
BYTE = 0x03,
SHORT = 0x04,
CHAR = 0x05,
INT = 0x06,
LONG = 0x07,
FLOAT = 0x08,
DOUBLE = 0x09,
BYTE = 0x03,
SHORT = 0x04,
CHAR = 0x05,
INT = 0x06,
LONG = 0x07,
FLOAT = 0x08,
DOUBLE = 0x09,
};
using array_t = std::vector<Type>;
@@ -87,8 +88,8 @@ class LIEF_API Type : public Object {
size_t dim() const;
/// In the case of a TYPES::ARRAY, return the array's type
const Type& underlying_array_type() const;
Type& underlying_array_type();
const Type& underlying_array_type() const LIEF_LIFETIMEBOUND;
Type& underlying_array_type() LIEF_LIFETIMEBOUND;
void accept(Visitor& visitor) const override;
+4 -4
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,8 +25,8 @@ class Method;
// Method Index: {dex_pc: index, ...}
using dex2dex_method_info_t = std::unordered_map<uint32_t, uint32_t>;
using dex2dex_class_info_t = std::unordered_map<Method*, dex2dex_method_info_t>;
using dex2dex_info_t = std::unordered_map<Class*, dex2dex_class_info_t>;
using dex2dex_class_info_t = std::unordered_map<Method*, dex2dex_method_info_t>;
using dex2dex_info_t = std::unordered_map<Class*, dex2dex_class_info_t>;
}
}
+39 -49
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,61 +20,51 @@ namespace LIEF {
namespace DEX {
enum ACCESS_FLAGS {
ACC_UNKNOWN = 0x0,
ACC_PUBLIC = 0x1,
ACC_PRIVATE = 0x2,
ACC_PROTECTED = 0x4,
ACC_STATIC = 0x8,
ACC_FINAL = 0x10,
ACC_SYNCHRONIZED = 0x20,
ACC_VOLATILE = 0x40,
ACC_BRIDGE = 0x40,
ACC_TRANSIENT = 0x80,
ACC_VARARGS = 0x80,
ACC_NATIVE = 0x100,
ACC_INTERFACE = 0x200,
ACC_ABSTRACT = 0x400,
ACC_STRICT = 0x800,
ACC_SYNTHETIC = 0x1000,
ACC_ANNOTATION = 0x2000,
ACC_ENUM = 0x4000,
ACC_CONSTRUCTOR = 0x10000,
ACC_DECLARED_SYNCHRONIZED = 0x20000
ACC_UNKNOWN = 0x0,
ACC_PUBLIC = 0x1,
ACC_PRIVATE = 0x2,
ACC_PROTECTED = 0x4,
ACC_STATIC = 0x8,
ACC_FINAL = 0x10,
ACC_SYNCHRONIZED = 0x20,
ACC_VOLATILE = 0x40,
ACC_BRIDGE = 0x40,
ACC_TRANSIENT = 0x80,
ACC_VARARGS = 0x80,
ACC_NATIVE = 0x100,
ACC_INTERFACE = 0x200,
ACC_ABSTRACT = 0x400,
ACC_STRICT = 0x800,
ACC_SYNTHETIC = 0x1000,
ACC_ANNOTATION = 0x2000,
ACC_ENUM = 0x4000,
ACC_CONSTRUCTOR = 0x10000,
ACC_DECLARED_SYNCHRONIZED = 0x20000,
};
enum METHOD_TYPES {
METHOD_UNKNOWN = 0x00,
METHOD_VIRTUAL = 0x01,
METHOD_DIRECT = 0x02, // Deprecated
METHOD_UNKNOWN = 0x00,
METHOD_VIRTUAL = 0x01,
METHOD_DIRECT = 0x02, // Deprecated
METHOD_EXTERN = 0x03,
METHOD_CTOR = 0x04,
METHOD_STATIC = 0x05,
METHOD_STATIC_CTOR = 0x06,
METHOD_EXTERN = 0x03,
METHOD_CTOR = 0x04,
METHOD_STATIC = 0x05,
METHOD_STATIC_CTOR = 0x06,
};
static const ACCESS_FLAGS access_flags_list[] = {
ACCESS_FLAGS::ACC_UNKNOWN,
ACCESS_FLAGS::ACC_PUBLIC,
ACCESS_FLAGS::ACC_PRIVATE,
ACCESS_FLAGS::ACC_PROTECTED,
ACCESS_FLAGS::ACC_STATIC,
ACCESS_FLAGS::ACC_FINAL,
ACCESS_FLAGS::ACC_SYNCHRONIZED,
ACCESS_FLAGS::ACC_VOLATILE,
ACCESS_FLAGS::ACC_BRIDGE,
ACCESS_FLAGS::ACC_TRANSIENT,
ACCESS_FLAGS::ACC_VARARGS,
ACCESS_FLAGS::ACC_NATIVE,
ACCESS_FLAGS::ACC_INTERFACE,
ACCESS_FLAGS::ACC_ABSTRACT,
ACCESS_FLAGS::ACC_STRICT,
ACCESS_FLAGS::ACC_SYNTHETIC,
ACCESS_FLAGS::ACC_ANNOTATION,
ACCESS_FLAGS::ACC_ENUM,
ACCESS_FLAGS::ACC_CONSTRUCTOR,
ACCESS_FLAGS::ACC_DECLARED_SYNCHRONIZED,
ACCESS_FLAGS::ACC_UNKNOWN, ACCESS_FLAGS::ACC_PUBLIC,
ACCESS_FLAGS::ACC_PRIVATE, ACCESS_FLAGS::ACC_PROTECTED,
ACCESS_FLAGS::ACC_STATIC, ACCESS_FLAGS::ACC_FINAL,
ACCESS_FLAGS::ACC_SYNCHRONIZED, ACCESS_FLAGS::ACC_VOLATILE,
ACCESS_FLAGS::ACC_BRIDGE, ACCESS_FLAGS::ACC_TRANSIENT,
ACCESS_FLAGS::ACC_VARARGS, ACCESS_FLAGS::ACC_NATIVE,
ACCESS_FLAGS::ACC_INTERFACE, ACCESS_FLAGS::ACC_ABSTRACT,
ACCESS_FLAGS::ACC_STRICT, ACCESS_FLAGS::ACC_SYNTHETIC,
ACCESS_FLAGS::ACC_ANNOTATION, ACCESS_FLAGS::ACC_ENUM,
ACCESS_FLAGS::ACC_CONSTRUCTOR, ACCESS_FLAGS::ACC_DECLARED_SYNCHRONIZED,
};
}
+11 -11
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,16 +46,16 @@ class LIEF_API Hash : public LIEF::Hash {
using LIEF::Hash::visit;
public:
void visit(const File& file) override;
void visit(const Header& header) override;
void visit(const Class& cls) override;
void visit(const Field& field) override;
void visit(const Method& method) override;
void visit(const File& file) override;
void visit(const Header& header) override;
void visit(const Class& cls) override;
void visit(const Field& field) override;
void visit(const Method& method) override;
void visit(const CodeInfo& code_info) override;
void visit(const Type& type) override;
void visit(const Prototype& type) override;
void visit(const MapItem& item) override;
void visit(const MapList& list) override;
void visit(const Type& type) override;
void visit(const Prototype& type) override;
void visit(const MapItem& item) override;
void visit(const MapList& list) override;
~Hash() override;
};
+246 -242
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
#include "LIEF/visibility.h"
#include "LIEF/types.hpp"
#include <cstddef>
#include <cstdint>
namespace LIEF {
namespace DEX {
@@ -25,258 +26,258 @@ namespace DEX {
enum SWITCH_ARRAY_IDENT : uint16_t {
IDENT_PACKED_SWITCH = 0x0100,
IDENT_SPARSE_SWITCH = 0x0200,
IDENT_FILL_ARRAY = 0x0300,
IDENT_FILL_ARRAY = 0x0300,
};
/// The Dalvik Opcodes
enum OPCODES : uint8_t {
OP_NOP = 0x00,
OP_MOVE = 0x01,
OP_MOVE_FROM_16 = 0x02,
OP_MOVE_16 = 0x03,
OP_MOVE_WIDE = 0x04,
OP_MOVE_WIDE_FROM_16 = 0x05,
OP_MOVE_WIDE_16 = 0x06,
OP_MOVE_OBJECT = 0x07,
OP_MOVE_OBJECT_FROM_16 = 0x08,
OP_MOVE_OBJECT_16 = 0x09,
OP_MOVE_RESULT = 0x0a,
OP_MOVE_RESULT_WIDE = 0x0b,
OP_MOVE_RESULT_OBJECT = 0x0c,
OP_MOVE_EXCEPTION = 0x0d,
OP_RETURN_VOID = 0x0e,
OP_RETURN = 0x0f,
OP_RETURN_WIDE = 0x10,
OP_RETURN_OBJECT = 0x11,
OP_CONST_4 = 0x12,
OP_CONST_16 = 0x13,
OP_CONST = 0x14,
OP_CONST_HIGH_16 = 0x15,
OP_CONST_WIDE_16 = 0x16,
OP_CONST_WIDE_32 = 0x17,
OP_CONST_WIDE = 0x18,
OP_CONST_WIDE_HIGH_16 = 0x19,
OP_CONST_STRING = 0x1a,
OP_CONST_STRING_JUMBO = 0x1b,
OP_CONST_CLASS = 0x1c,
OP_MONITOR_ENTER = 0x1d,
OP_MONITOR_EXIT = 0x1e,
OP_CHECK_CAST = 0x1f,
OP_INSTANCE_OF = 0x20,
OP_ARRAY_LENGTH = 0x21,
OP_NEW_INSTANCE = 0x22,
OP_NEW_ARRAY = 0x23,
OP_FILLED_NEW_ARRAY = 0x24,
OP_NOP = 0x00,
OP_MOVE = 0x01,
OP_MOVE_FROM_16 = 0x02,
OP_MOVE_16 = 0x03,
OP_MOVE_WIDE = 0x04,
OP_MOVE_WIDE_FROM_16 = 0x05,
OP_MOVE_WIDE_16 = 0x06,
OP_MOVE_OBJECT = 0x07,
OP_MOVE_OBJECT_FROM_16 = 0x08,
OP_MOVE_OBJECT_16 = 0x09,
OP_MOVE_RESULT = 0x0a,
OP_MOVE_RESULT_WIDE = 0x0b,
OP_MOVE_RESULT_OBJECT = 0x0c,
OP_MOVE_EXCEPTION = 0x0d,
OP_RETURN_VOID = 0x0e,
OP_RETURN = 0x0f,
OP_RETURN_WIDE = 0x10,
OP_RETURN_OBJECT = 0x11,
OP_CONST_4 = 0x12,
OP_CONST_16 = 0x13,
OP_CONST = 0x14,
OP_CONST_HIGH_16 = 0x15,
OP_CONST_WIDE_16 = 0x16,
OP_CONST_WIDE_32 = 0x17,
OP_CONST_WIDE = 0x18,
OP_CONST_WIDE_HIGH_16 = 0x19,
OP_CONST_STRING = 0x1a,
OP_CONST_STRING_JUMBO = 0x1b,
OP_CONST_CLASS = 0x1c,
OP_MONITOR_ENTER = 0x1d,
OP_MONITOR_EXIT = 0x1e,
OP_CHECK_CAST = 0x1f,
OP_INSTANCE_OF = 0x20,
OP_ARRAY_LENGTH = 0x21,
OP_NEW_INSTANCE = 0x22,
OP_NEW_ARRAY = 0x23,
OP_FILLED_NEW_ARRAY = 0x24,
OP_FILLED_NEW_ARRAY_RANGE = 0x25,
OP_FILL_ARRAY_DATA = 0x26,
OP_THROW = 0x27,
OP_GOTO = 0x28,
OP_GOTO_16 = 0x29,
OP_GOTO_32 = 0x2a,
OP_PACKED_SWITCH = 0x2b,
OP_SPARSE_SWITCH = 0x2c,
OP_CMPL_FLOAT = 0x2d,
OP_CMPG_FLOAT = 0x2e,
OP_CMPL_DOUBLE = 0x2f,
OP_CMPG_DOUBLE = 0x30,
OP_CMP_LONG = 0x31,
OP_IF_EQ = 0x32,
OP_IF_NE = 0x33,
OP_IF_LT = 0x34,
OP_IF_GE = 0x35,
OP_IF_GT = 0x36,
OP_IF_LE = 0x37,
OP_IF_EQZ = 0x38,
OP_IF_NEZ = 0x39,
OP_IF_LTZ = 0x3a,
OP_IF_GEZ = 0x3b,
OP_IF_GTZ = 0x3c,
OP_IF_LEZ = 0x3d,
OP_AGET = 0x44,
OP_AGET_WIDE = 0x45,
OP_AGET_OBJECT = 0x46,
OP_AGET_BOOLEAN = 0x47,
OP_AGET_BYTE = 0x48,
OP_AGET_CHAR = 0x49,
OP_AGET_SHORT = 0x4a,
OP_APUT = 0x4b,
OP_APUT_WIDE = 0x4c,
OP_APUT_OBJECT = 0x4d,
OP_APUT_BOOLEAN = 0x4e,
OP_APUT_BYTE = 0x4f,
OP_APUT_CHAR = 0x50,
OP_APUT_SHORT = 0x51,
OP_IGET = 0x52,
OP_IGET_WIDE = 0x53,
OP_IGET_OBJECT = 0x54,
OP_IGET_BOOLEAN = 0x55,
OP_IGET_BYTE = 0x56,
OP_IGET_CHAR = 0x57,
OP_IGET_SHORT = 0x58,
OP_IPUT = 0x59,
OP_IPUT_WIDE = 0x5a,
OP_IPUT_OBJECT = 0x5b,
OP_IPUT_BOOLEAN = 0x5c,
OP_IPUT_BYTE = 0x5d,
OP_IPUT_CHAR = 0x5e,
OP_IPUT_SHORT = 0x5f,
OP_SGET = 0x60,
OP_SGET_WIDE = 0x61,
OP_SGET_OBJECT = 0x62,
OP_SGET_BOOLEAN = 0x63,
OP_SGET_BYTE = 0x64,
OP_SGET_CHAR = 0x65,
OP_SGET_SHORT = 0x66,
OP_SPUT = 0x67,
OP_SPUT_WIDE = 0x68,
OP_SPUT_OBJECT = 0x69,
OP_SPUT_BOOLEAN = 0x6a,
OP_SPUT_BYTE = 0x6b,
OP_SPUT_CHAR = 0x6c,
OP_SPUT_SHORT = 0x6d,
OP_INVOKE_VIRTUAL = 0x6e,
OP_INVOKE_SUPER = 0x6f,
OP_INVOKE_DIRECT = 0x70,
OP_INVOKE_STATIC = 0x71,
OP_INVOKE_INTERFACE = 0x72,
OP_FILL_ARRAY_DATA = 0x26,
OP_THROW = 0x27,
OP_GOTO = 0x28,
OP_GOTO_16 = 0x29,
OP_GOTO_32 = 0x2a,
OP_PACKED_SWITCH = 0x2b,
OP_SPARSE_SWITCH = 0x2c,
OP_CMPL_FLOAT = 0x2d,
OP_CMPG_FLOAT = 0x2e,
OP_CMPL_DOUBLE = 0x2f,
OP_CMPG_DOUBLE = 0x30,
OP_CMP_LONG = 0x31,
OP_IF_EQ = 0x32,
OP_IF_NE = 0x33,
OP_IF_LT = 0x34,
OP_IF_GE = 0x35,
OP_IF_GT = 0x36,
OP_IF_LE = 0x37,
OP_IF_EQZ = 0x38,
OP_IF_NEZ = 0x39,
OP_IF_LTZ = 0x3a,
OP_IF_GEZ = 0x3b,
OP_IF_GTZ = 0x3c,
OP_IF_LEZ = 0x3d,
OP_AGET = 0x44,
OP_AGET_WIDE = 0x45,
OP_AGET_OBJECT = 0x46,
OP_AGET_BOOLEAN = 0x47,
OP_AGET_BYTE = 0x48,
OP_AGET_CHAR = 0x49,
OP_AGET_SHORT = 0x4a,
OP_APUT = 0x4b,
OP_APUT_WIDE = 0x4c,
OP_APUT_OBJECT = 0x4d,
OP_APUT_BOOLEAN = 0x4e,
OP_APUT_BYTE = 0x4f,
OP_APUT_CHAR = 0x50,
OP_APUT_SHORT = 0x51,
OP_IGET = 0x52,
OP_IGET_WIDE = 0x53,
OP_IGET_OBJECT = 0x54,
OP_IGET_BOOLEAN = 0x55,
OP_IGET_BYTE = 0x56,
OP_IGET_CHAR = 0x57,
OP_IGET_SHORT = 0x58,
OP_IPUT = 0x59,
OP_IPUT_WIDE = 0x5a,
OP_IPUT_OBJECT = 0x5b,
OP_IPUT_BOOLEAN = 0x5c,
OP_IPUT_BYTE = 0x5d,
OP_IPUT_CHAR = 0x5e,
OP_IPUT_SHORT = 0x5f,
OP_SGET = 0x60,
OP_SGET_WIDE = 0x61,
OP_SGET_OBJECT = 0x62,
OP_SGET_BOOLEAN = 0x63,
OP_SGET_BYTE = 0x64,
OP_SGET_CHAR = 0x65,
OP_SGET_SHORT = 0x66,
OP_SPUT = 0x67,
OP_SPUT_WIDE = 0x68,
OP_SPUT_OBJECT = 0x69,
OP_SPUT_BOOLEAN = 0x6a,
OP_SPUT_BYTE = 0x6b,
OP_SPUT_CHAR = 0x6c,
OP_SPUT_SHORT = 0x6d,
OP_INVOKE_VIRTUAL = 0x6e,
OP_INVOKE_SUPER = 0x6f,
OP_INVOKE_DIRECT = 0x70,
OP_INVOKE_STATIC = 0x71,
OP_INVOKE_INTERFACE = 0x72,
OP_RETURN_VOID_NO_BARRIER = 0x73,
OP_INVOKE_VIRTUAL_RANGE = 0x74,
OP_INVOKE_SUPER_RANGE = 0x75,
OP_INVOKE_DIRECT_RANGE = 0x76,
OP_INVOKE_STATIC_RANGE = 0x77,
OP_INVOKE_VIRTUAL_RANGE = 0x74,
OP_INVOKE_SUPER_RANGE = 0x75,
OP_INVOKE_DIRECT_RANGE = 0x76,
OP_INVOKE_STATIC_RANGE = 0x77,
OP_INVOKE_INTERFACE_RANGE = 0x78,
OP_NEG_INT = 0x7b,
OP_NOT_INT = 0x7c,
OP_NEG_LONG = 0x7d,
OP_NOT_LONG = 0x7e,
OP_NEG_FLOAT = 0x7f,
OP_NEG_DOUBLE = 0x80,
OP_INT_TO_LONG = 0x81,
OP_INT_TO_FLOAT = 0x82,
OP_INT_TO_DOUBLE = 0x83,
OP_LONG_TO_INT = 0x84,
OP_LONG_TO_FLOAT = 0x85,
OP_LONG_TO_DOUBLE = 0x86,
OP_FLOAT_TO_INT = 0x87,
OP_FLOAT_TO_LONG = 0x88,
OP_FLOAT_TO_DOUBLE = 0x89,
OP_DOUBLE_TO_INT = 0x8a,
OP_DOUBLE_TO_LONG = 0x8b,
OP_DOUBLE_TO_FLOAT = 0x8c,
OP_INT_TO_BYTE = 0x8d,
OP_INT_TO_CHAR = 0x8e,
OP_INT_TO_SHORT = 0x8f,
OP_ADD_INT = 0x90,
OP_SUB_INT = 0x91,
OP_MUL_INT = 0x92,
OP_DIV_INT = 0x93,
OP_REM_INT = 0x94,
OP_AND_INT = 0x95,
OP_OR_INT = 0x96,
OP_XOR_INT = 0x97,
OP_SHL_INT = 0x98,
OP_SHR_INT = 0x99,
OP_USHR_INT = 0x9a,
OP_ADD_LONG = 0x9b,
OP_SUB_LONG = 0x9c,
OP_MUL_LONG = 0x9d,
OP_DIV_LONG = 0x9e,
OP_REM_LONG = 0x9f,
OP_AND_LONG = 0xa0,
OP_OR_LONG = 0xa1,
OP_XOR_LONG = 0xa2,
OP_SHL_LONG = 0xa3,
OP_SHR_LONG = 0xa4,
OP_USHR_LONG = 0xa5,
OP_ADD_FLOAT = 0xa6,
OP_SUB_FLOAT = 0xa7,
OP_MUL_FLOAT = 0xa8,
OP_DIV_FLOAT = 0xa9,
OP_REM_FLOAT = 0xaa,
OP_ADD_DOUBLE = 0xab,
OP_SUB_DOUBLE = 0xac,
OP_MUL_DOUBLE = 0xad,
OP_DIV_DOUBLE = 0xae,
OP_REM_DOUBLE = 0xaf,
OP_ADD_INT_2_ADDR = 0xb0,
OP_SUB_INT_2_ADDR = 0xb1,
OP_MUL_INT_2_ADDR = 0xb2,
OP_DIV_INT_2_ADDR = 0xb3,
OP_REM_INT_2_ADDR = 0xb4,
OP_AND_INT_2_ADDR = 0xb5,
OP_OR_INT_2_ADDR = 0xb6,
OP_XOR_INT_2_ADDR = 0xb7,
OP_SHL_INT_2_ADDR = 0xb8,
OP_SHR_INT_2_ADDR = 0xb9,
OP_USHR_INT_2_ADDR = 0xba,
OP_ADD_LONG_2_ADDR = 0xbb,
OP_SUB_LONG_2_ADDR = 0xbc,
OP_MUL_LONG_2_ADDR = 0xbd,
OP_DIV_LONG_2_ADDR = 0xbe,
OP_REM_LONG_2_ADDR = 0xbf,
OP_AND_LONG_2_ADDR = 0xc0,
OP_OR_LONG_2_ADDR = 0xc1,
OP_XOR_LONG_2_ADDR = 0xc2,
OP_SHL_LONG_2_ADDR = 0xc3,
OP_SHR_LONG_2_ADDR = 0xc4,
OP_USHR_LONG_2_ADDR = 0xc5,
OP_ADD_FLOAT_2_ADDR = 0xc6,
OP_SUB_FLOAT_2_ADDR = 0xc7,
OP_MUL_FLOAT_2_ADDR = 0xc8,
OP_DIV_FLOAT_2_ADDR = 0xc9,
OP_REM_FLOAT_2_ADDR = 0xca,
OP_ADD_DOUBLE_2_ADDR = 0xcb,
OP_SUB_DOUBLE_2_ADDR = 0xcc,
OP_MUL_DOUBLE_2_ADDR = 0xcd,
OP_DIV_DOUBLE_2_ADDR = 0xce,
OP_REM_DOUBLE_2_ADDR = 0xcf,
OP_ADD_INT_LIT_16 = 0xd0,
OP_RSUB_INT = 0xd1,
OP_MUL_INT_LIT_16 = 0xd2,
OP_DIV_INT_LIT_16 = 0xd3,
OP_REM_INT_LIT_16 = 0xd4,
OP_AND_INT_LIT_16 = 0xd5,
OP_OR_INT_LIT_16 = 0xd6,
OP_XOR_INT_LIT_16 = 0xd7,
OP_ADD_INT_LIT_8 = 0xd8,
OP_RSUB_INT_LIT_8 = 0xd9,
OP_MUL_INT_LIT_8 = 0xda,
OP_DIV_INT_LIT_8 = 0xdb,
OP_REM_INT_LIT_8 = 0xdc,
OP_AND_INT_LIT_8 = 0xdd,
OP_OR_INT_LIT_8 = 0xde,
OP_XOR_INT_LIT_8 = 0xdf,
OP_SHL_INT_LIT_8 = 0xe0,
OP_SHR_INT_LIT_8 = 0xe1,
OP_USHR_INT_LIT_8 = 0xe2,
OP_NEG_INT = 0x7b,
OP_NOT_INT = 0x7c,
OP_NEG_LONG = 0x7d,
OP_NOT_LONG = 0x7e,
OP_NEG_FLOAT = 0x7f,
OP_NEG_DOUBLE = 0x80,
OP_INT_TO_LONG = 0x81,
OP_INT_TO_FLOAT = 0x82,
OP_INT_TO_DOUBLE = 0x83,
OP_LONG_TO_INT = 0x84,
OP_LONG_TO_FLOAT = 0x85,
OP_LONG_TO_DOUBLE = 0x86,
OP_FLOAT_TO_INT = 0x87,
OP_FLOAT_TO_LONG = 0x88,
OP_FLOAT_TO_DOUBLE = 0x89,
OP_DOUBLE_TO_INT = 0x8a,
OP_DOUBLE_TO_LONG = 0x8b,
OP_DOUBLE_TO_FLOAT = 0x8c,
OP_INT_TO_BYTE = 0x8d,
OP_INT_TO_CHAR = 0x8e,
OP_INT_TO_SHORT = 0x8f,
OP_ADD_INT = 0x90,
OP_SUB_INT = 0x91,
OP_MUL_INT = 0x92,
OP_DIV_INT = 0x93,
OP_REM_INT = 0x94,
OP_AND_INT = 0x95,
OP_OR_INT = 0x96,
OP_XOR_INT = 0x97,
OP_SHL_INT = 0x98,
OP_SHR_INT = 0x99,
OP_USHR_INT = 0x9a,
OP_ADD_LONG = 0x9b,
OP_SUB_LONG = 0x9c,
OP_MUL_LONG = 0x9d,
OP_DIV_LONG = 0x9e,
OP_REM_LONG = 0x9f,
OP_AND_LONG = 0xa0,
OP_OR_LONG = 0xa1,
OP_XOR_LONG = 0xa2,
OP_SHL_LONG = 0xa3,
OP_SHR_LONG = 0xa4,
OP_USHR_LONG = 0xa5,
OP_ADD_FLOAT = 0xa6,
OP_SUB_FLOAT = 0xa7,
OP_MUL_FLOAT = 0xa8,
OP_DIV_FLOAT = 0xa9,
OP_REM_FLOAT = 0xaa,
OP_ADD_DOUBLE = 0xab,
OP_SUB_DOUBLE = 0xac,
OP_MUL_DOUBLE = 0xad,
OP_DIV_DOUBLE = 0xae,
OP_REM_DOUBLE = 0xaf,
OP_ADD_INT_2_ADDR = 0xb0,
OP_SUB_INT_2_ADDR = 0xb1,
OP_MUL_INT_2_ADDR = 0xb2,
OP_DIV_INT_2_ADDR = 0xb3,
OP_REM_INT_2_ADDR = 0xb4,
OP_AND_INT_2_ADDR = 0xb5,
OP_OR_INT_2_ADDR = 0xb6,
OP_XOR_INT_2_ADDR = 0xb7,
OP_SHL_INT_2_ADDR = 0xb8,
OP_SHR_INT_2_ADDR = 0xb9,
OP_USHR_INT_2_ADDR = 0xba,
OP_ADD_LONG_2_ADDR = 0xbb,
OP_SUB_LONG_2_ADDR = 0xbc,
OP_MUL_LONG_2_ADDR = 0xbd,
OP_DIV_LONG_2_ADDR = 0xbe,
OP_REM_LONG_2_ADDR = 0xbf,
OP_AND_LONG_2_ADDR = 0xc0,
OP_OR_LONG_2_ADDR = 0xc1,
OP_XOR_LONG_2_ADDR = 0xc2,
OP_SHL_LONG_2_ADDR = 0xc3,
OP_SHR_LONG_2_ADDR = 0xc4,
OP_USHR_LONG_2_ADDR = 0xc5,
OP_ADD_FLOAT_2_ADDR = 0xc6,
OP_SUB_FLOAT_2_ADDR = 0xc7,
OP_MUL_FLOAT_2_ADDR = 0xc8,
OP_DIV_FLOAT_2_ADDR = 0xc9,
OP_REM_FLOAT_2_ADDR = 0xca,
OP_ADD_DOUBLE_2_ADDR = 0xcb,
OP_SUB_DOUBLE_2_ADDR = 0xcc,
OP_MUL_DOUBLE_2_ADDR = 0xcd,
OP_DIV_DOUBLE_2_ADDR = 0xce,
OP_REM_DOUBLE_2_ADDR = 0xcf,
OP_ADD_INT_LIT_16 = 0xd0,
OP_RSUB_INT = 0xd1,
OP_MUL_INT_LIT_16 = 0xd2,
OP_DIV_INT_LIT_16 = 0xd3,
OP_REM_INT_LIT_16 = 0xd4,
OP_AND_INT_LIT_16 = 0xd5,
OP_OR_INT_LIT_16 = 0xd6,
OP_XOR_INT_LIT_16 = 0xd7,
OP_ADD_INT_LIT_8 = 0xd8,
OP_RSUB_INT_LIT_8 = 0xd9,
OP_MUL_INT_LIT_8 = 0xda,
OP_DIV_INT_LIT_8 = 0xdb,
OP_REM_INT_LIT_8 = 0xdc,
OP_AND_INT_LIT_8 = 0xdd,
OP_OR_INT_LIT_8 = 0xde,
OP_XOR_INT_LIT_8 = 0xdf,
OP_SHL_INT_LIT_8 = 0xe0,
OP_SHR_INT_LIT_8 = 0xe1,
OP_USHR_INT_LIT_8 = 0xe2,
// ODEX
OP_IGET_QUICK = 0xe3,
OP_IGET_WIDE_QUICK = 0xe4,
OP_IGET_OBJECT_QUICK = 0xe5,
OP_IPUT_QUICK = 0xe6,
OP_IPUT_WIDE_QUICK = 0xe7,
OP_IPUT_OBJECT_QUICK = 0xe8,
OP_INVOKE_VIRTUAL_QUICK = 0xe9,
OP_INVOKE_VIRTUAL_RANGE_QUICK = 0xea,
OP_IPUT_BOOLEAN_QUICK = 0xeb,
OP_IPUT_BYTE_QUICK = 0xec,
OP_IPUT_CHAR_QUICK = 0xed,
OP_IPUT_SHORT_QUICK = 0xee,
OP_IGET_BOOLEAN_QUICK = 0xef,
OP_IGET_BYTE_QUICK = 0xf0,
OP_IGET_CHAR_QUICK = 0xf1,
OP_IGET_SHORT_QUICK = 0xf2,
OP_IGET_QUICK = 0xe3,
OP_IGET_WIDE_QUICK = 0xe4,
OP_IGET_OBJECT_QUICK = 0xe5,
OP_IPUT_QUICK = 0xe6,
OP_IPUT_WIDE_QUICK = 0xe7,
OP_IPUT_OBJECT_QUICK = 0xe8,
OP_INVOKE_VIRTUAL_QUICK = 0xe9,
OP_INVOKE_VIRTUAL_RANGE_QUICK = 0xea,
OP_IPUT_BOOLEAN_QUICK = 0xeb,
OP_IPUT_BYTE_QUICK = 0xec,
OP_IPUT_CHAR_QUICK = 0xed,
OP_IPUT_SHORT_QUICK = 0xee,
OP_IGET_BOOLEAN_QUICK = 0xef,
OP_IGET_BYTE_QUICK = 0xf0,
OP_IGET_CHAR_QUICK = 0xf1,
OP_IGET_SHORT_QUICK = 0xf2,
// From DEX 38
OP_INVOKE_POLYMORPHIC = 0xfa,
OP_INVOKE_POLYMORPHIC = 0xfa,
OP_INVOKE_POLYMORPHIC_RANGE = 0xfb,
OP_INVOKE_CUSTOM = 0xfc,
OP_INVOKE_CUSTOM_RANGE = 0xfd,
OP_INVOKE_CUSTOM = 0xfc,
OP_INVOKE_CUSTOM_RANGE = 0xfd,
// From DEX 39
OP_CONST_METHOD_HANDLE = 0xfe,
OP_CONST_METHOD_TYPE = 0xff,
OP_CONST_METHOD_HANDLE = 0xfe,
OP_CONST_METHOD_TYPE = 0xff,
};
enum INST_FORMATS : uint8_t {
@@ -335,7 +336,7 @@ struct fill_array_data {
uint16_t ident;
uint16_t element_width;
uint32_t size;
//uint8_t data[size];
// uint8_t data[size];
};
@@ -349,8 +350,11 @@ LIEF_API bool is_switch_array(const uint8_t* ptr, const uint8_t* end);
LIEF_API size_t switch_array_size(const uint8_t* ptr, const uint8_t* end);
inline bool valid_inst_size(const uint8_t* ptr, const uint8_t* end, size_t size) {
return size != 0 && size != SIZE_MAX && (size_t)(end - ptr) >= size;
}
} // Namespace LIEF
} // Namespace DEX
#endif
+2 -2
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+2 -2
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+2 -2
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+3 -2
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
#include "LIEF/DWARF/types.hpp"
#include "LIEF/DWARF/Parameter.hpp"
#include "LIEF/DWARF/Editor.hpp"
#include "LIEF/DWARF/LexicalBlock.hpp"
#include "LIEF/DWARF/editor/CompilationUnit.hpp"
#include "LIEF/DWARF/editor/Function.hpp"
+51 -55
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,9 +18,11 @@
#include <string>
#include <vector>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
#include "LIEF/range.hpp"
#include "LIEF/iterators.hpp"
#include "LIEF/DebugDeclOpt.hpp"
#include "LIEF/DWARF/Function.hpp"
#include "LIEF/DWARF/Type.hpp"
@@ -35,61 +37,52 @@ class CompilationUnitIt;
/// This class represents a DWARF compilation unit
class LIEF_API CompilationUnit {
public:
class LIEF_API Iterator {
class Iterator final
: public iterator_facade_base<Iterator, std::bidirectional_iterator_tag,
CompilationUnit, std::ptrdiff_t,
const CompilationUnit*, const CompilationUnit&> {
public:
using iterator_category = std::bidirectional_iterator_tag;
using value_type = std::unique_ptr<CompilationUnit>;
using difference_type = std::ptrdiff_t;
using pointer = CompilationUnit*;
using reference = std::unique_ptr<CompilationUnit>&;
using implementation = details::CompilationUnitIt;
using iterator_facade_base::operator++;
using iterator_facade_base::operator--;
class LIEF_API PointerProxy {
// Inspired from LLVM's iterator_facade_base
friend class Iterator;
public:
pointer operator->() const { return R.get(); }
LIEF_API Iterator();
private:
value_type R;
LIEF_API Iterator(std::unique_ptr<details::CompilationUnitIt> impl);
template <typename RefT>
PointerProxy(RefT &&R) : R(std::forward<RefT>(R)) {} // NOLINT(bugprone-forwarding-reference-overload)
};
LIEF_API Iterator(const Iterator&);
LIEF_API Iterator& operator=(const Iterator&);
Iterator(const Iterator&);
Iterator(Iterator&&) noexcept;
Iterator(std::unique_ptr<details::CompilationUnitIt> impl);
~Iterator();
LIEF_API Iterator(Iterator&&) noexcept;
LIEF_API Iterator& operator=(Iterator&&) noexcept;
LIEF_API ~Iterator();
friend LIEF_API bool operator==(const Iterator& LHS, const Iterator& RHS);
friend LIEF_API bool operator!=(const Iterator& LHS, const Iterator& RHS) {
friend bool operator!=(const Iterator& LHS, const Iterator& RHS) {
return !(LHS == RHS);
}
Iterator& operator++();
Iterator& operator--();
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API Iterator& operator++();
Iterator operator--(int) {
Iterator tmp = *static_cast<Iterator*>(this);
--*static_cast<Iterator *>(this);
return tmp;
}
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API Iterator& operator--();
Iterator operator++(int) {
Iterator tmp = *static_cast<Iterator*>(this);
++*static_cast<Iterator *>(this);
return tmp;
}
LIEF_API const CompilationUnit& operator*() const LIEF_LIFETIMEBOUND;
std::unique_ptr<CompilationUnit> operator*() const;
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API const CompilationUnit* operator->() const LIEF_LIFETIMEBOUND;
PointerProxy operator->() const {
return static_cast<const Iterator*>(this)->operator*();
}
/// Transfer ownership of the compilation unit at the current position
/// to the caller. Returns `nullptr` if the iterator is past-the-end.
LIEF_API std::unique_ptr<CompilationUnit> yield();
private:
void load() const;
std::unique_ptr<details::CompilationUnitIt> impl_;
mutable std::unique_ptr<CompilationUnit> cached_;
};
/// Iterator over the dwarf::Function
@@ -130,11 +123,10 @@ class LIEF_API CompilationUnit {
Language() = default;
Language(LANG lang, uint32_t version) :
lang(lang), version(version)
{}
lang(lang),
version(version) {}
Language(LANG lang) :
Language(lang, 0)
{}
Language(lang, 0) {}
Language(const Language&) = default;
Language& operator=(const Language&) = default;
@@ -169,7 +161,7 @@ class LIEF_API CompilationUnit {
/// This value matches the `DW_AT_comp_dir` attribute
std::string compilation_dir() const;
/// Original Language of this compilation unit.
/// Original language of this compilation unit.
///
/// This value matches the `DW_AT_language` attribute.
Language language() const;
@@ -186,7 +178,7 @@ class LIEF_API CompilationUnit {
/// between the lowest address and the highest that are not owned by the CU),
/// then it returns the sum of **all** the address ranges owned by this CU.
///
/// If the compilation unit is **not** fragmented, then is basically returns
/// If the compilation unit is **not** fragmented, then it basically returns
/// `high_address - low_address`.
uint64_t size() const;
@@ -199,16 +191,18 @@ class LIEF_API CompilationUnit {
/// Try to find the function whose name is given in parameter.
///
/// The provided name can be demangled
std::unique_ptr<Function> find_function(const std::string& name) const;
std::unique_ptr<Function>
find_function(const std::string& name) const LIEF_LIFETIMEBOUND;
/// Try to find the function at the given address
std::unique_ptr<Function> find_function(uint64_t addr) const;
std::unique_ptr<Function> find_function(uint64_t addr) const LIEF_LIFETIMEBOUND;
/// Try to find the Variable at the given address
std::unique_ptr<Variable> find_variable(uint64_t addr) const;
std::unique_ptr<Variable> find_variable(uint64_t addr) const LIEF_LIFETIMEBOUND;
/// Try to find the Variable with the given name
std::unique_ptr<Variable> find_variable(const std::string& name) const;
std::unique_ptr<Variable>
find_variable(const std::string& name) const LIEF_LIFETIMEBOUND;
/// Return an iterator over the functions implemented in this compilation
/// unit.
@@ -232,7 +226,7 @@ class LIEF_API CompilationUnit {
/// The iterator will only return **one function** for `main` since
/// `get_secret_env` is inlined and thus, its implementation is located in
/// `main`.
functions_it functions() const;
functions_it functions() const LIEF_LIFETIMEBOUND;
/// Return an iterator over the functions **imported** in this compilation
/// unit **but not** implemented.
@@ -251,14 +245,13 @@ class LIEF_API CompilationUnit {
/// the iterator. On the other hand, `main()` is implemented in this
/// compilation unit so it is not returned by imported_function() but
/// functions().
functions_it imported_functions() const;
functions_it imported_functions() const LIEF_LIFETIMEBOUND;
/// Return an iterator over the different types defined in this
/// compilation unit.
types_it types() const;
types_it types() const LIEF_LIFETIMEBOUND;
/// Return an iterator over all the variables defined in the this compilation
/// Return an iterator over all the variables defined in this compilation
/// unit:
///
/// ```cpp
@@ -270,7 +263,11 @@ class LIEF_API CompilationUnit {
/// return C;
/// }
/// ```
vars_it variables() const;
vars_it variables() const LIEF_LIFETIMEBOUND;
/// Generate a C/C++ definition for the functions defined in this
/// compilation unit.
std::string to_decl(const DeclOpt& opt = DeclOpt()) const;
private:
std::unique_ptr<details::CompilationUnit> impl_;
@@ -279,4 +276,3 @@ class LIEF_API CompilationUnit {
}
}
#endif
+11 -7
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
#include <memory>
#include <string>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/iterators.hpp"
#include "LIEF/Abstract/DebugInfo.hpp"
#include "LIEF/DWARF/CompilationUnit.hpp"
@@ -53,23 +54,26 @@ class LIEF_API DebugInfo : public LIEF::DebugInfo {
/// // Found
/// }
/// ```
std::unique_ptr<Function> find_function(const std::string& name) const;
std::unique_ptr<Function>
find_function(const std::string& name) const LIEF_LIFETIMEBOUND;
/// Try to find the function at the given **virtual** address
std::unique_ptr<Function> find_function(uint64_t addr) const;
std::unique_ptr<Function> find_function(uint64_t addr) const LIEF_LIFETIMEBOUND;
/// Try to find the variable with the given name. This name can be mangled or
/// not.
std::unique_ptr<Variable> find_variable(const std::string& name) const;
std::unique_ptr<Variable>
find_variable(const std::string& name) const LIEF_LIFETIMEBOUND;
/// Try to find the variable at the given **virtual** address
std::unique_ptr<Variable> find_variable(uint64_t addr) const;
std::unique_ptr<Variable> find_variable(uint64_t addr) const LIEF_LIFETIMEBOUND;
/// Try to find the type with the given name
std::unique_ptr<Type> find_type(const std::string& name) const;
std::unique_ptr<Type>
find_type(const std::string& name) const LIEF_LIFETIMEBOUND;
/// Iterator on the CompilationUnit embedded in this dwarf
compilation_units_it compilation_units() const;
compilation_units_it compilation_units() const LIEF_LIFETIMEBOUND;
/// Attempt to resolve the address of the function specified by `name`.
optional<uint64_t> find_function_address(const std::string& name) const override;
+22 -3
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,9 @@
#define LIEF_DWARF_EDITOR_H
#include <memory>
#include <string>
#include <cstdint>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
namespace LIEF {
@@ -37,11 +39,29 @@ class LIEF_API Editor {
Editor() = delete;
Editor(std::unique_ptr<details::Editor> impl);
enum class FORMAT : uint32_t {
ELF,
MACHO,
PE,
};
enum class ARCH : uint32_t {
UNKNOWN,
X64,
X86,
AARCH64,
ARM,
};
/// Instantiate an editor for the given binary object
static std::unique_ptr<Editor> from_binary(LIEF::Binary& bin);
/// Instantiate an editor for the given format and arch
static std::unique_ptr<Editor> create(FORMAT fmt, ARCH arch);
/// Create a new compilation unit
std::unique_ptr<editor::CompilationUnit> create_compilation_unit();
std::unique_ptr<editor::CompilationUnit>
create_compilation_unit() LIEF_LIFETIMEBOUND;
/// Write the DWARF file to the specified output
void write(const std::string& output);
@@ -50,7 +70,6 @@ class LIEF_API Editor {
private:
std::unique_ptr<details::Editor> impl_;
};
}
+51 -45
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,9 +21,12 @@
#include "LIEF/visibility.h"
#include "LIEF/errors.hpp"
#include "LIEF/iterators.hpp"
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/range.hpp"
#include "LIEF/DWARF/Variable.hpp"
#include "LIEF/DWARF/Type.hpp"
#include "LIEF/DWARF/LexicalBlock.hpp"
#include "LIEF/asm/Instruction.hpp"
namespace LIEF {
@@ -41,62 +44,53 @@ class FunctionIt;
/// `DW_TAG_subprogram` or `DW_TAG_inlined_subroutine`.
class LIEF_API Function {
public:
class LIEF_API Iterator {
class Iterator final
: public iterator_facade_base<Iterator, std::bidirectional_iterator_tag,
Function, std::ptrdiff_t, const Function*,
const Function&> {
public:
using iterator_category = std::bidirectional_iterator_tag;
using value_type = std::unique_ptr<Function>;
using difference_type = std::ptrdiff_t;
using pointer = Function*;
using reference = std::unique_ptr<Function>&;
using implementation = details::FunctionIt;
using iterator_facade_base::operator++;
using iterator_facade_base::operator--;
class LIEF_API PointerProxy {
// Inspired from LLVM's iterator_facade_base
friend class Iterator;
public:
pointer operator->() const { return R.get(); }
LIEF_API Iterator();
private:
value_type R;
LIEF_API Iterator(std::unique_ptr<details::FunctionIt> impl);
template <typename RefT>
PointerProxy(RefT &&R) : R(std::forward<RefT>(R)) {} // NOLINT(bugprone-forwarding-reference-overload)
};
LIEF_API Iterator(const Iterator&);
LIEF_API Iterator& operator=(const Iterator&);
Iterator(const Iterator&);
Iterator(Iterator&&) noexcept;
Iterator(std::unique_ptr<details::FunctionIt> impl);
~Iterator();
LIEF_API Iterator(Iterator&&) noexcept;
LIEF_API Iterator& operator=(Iterator&&) noexcept;
LIEF_API ~Iterator();
friend LIEF_API bool operator==(const Iterator& LHS, const Iterator& RHS);
friend LIEF_API bool operator!=(const Iterator& LHS, const Iterator& RHS) {
friend bool operator!=(const Iterator& LHS, const Iterator& RHS) {
return !(LHS == RHS);
}
Iterator& operator++();
Iterator& operator--();
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API Iterator& operator++();
Iterator operator--(int) {
Iterator tmp = *static_cast<Iterator*>(this);
--*static_cast<Iterator *>(this);
return tmp;
}
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API Iterator& operator--();
Iterator operator++(int) {
Iterator tmp = *static_cast<Iterator*>(this);
++*static_cast<Iterator *>(this);
return tmp;
}
LIEF_API const Function& operator*() const LIEF_LIFETIMEBOUND;
std::unique_ptr<Function> operator*() const;
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API const Function* operator->() const LIEF_LIFETIMEBOUND;
PointerProxy operator->() const {
return static_cast<const Iterator*>(this)->operator*();
}
/// Transfer ownership of the function at the current position to the
/// caller. Returns `nullptr` if the iterator is past-the-end.
LIEF_API std::unique_ptr<Function> yield();
private:
void load() const;
std::unique_ptr<details::FunctionIt> impl_;
mutable std::unique_ptr<Function> cached_;
};
/// Iterator over the variables defined in the scope of this function
@@ -104,6 +98,8 @@ class LIEF_API Function {
using parameters_t = std::vector<std::unique_ptr<Parameter>>;
using thrown_types_t = std::vector<std::unique_ptr<Type>>;
using lexical_blocks_it = iterator_range<LexicalBlock::Iterator>;
using instructions_it = iterator_range<assembly::Instruction::Iterator>;
Function(std::unique_ptr<details::Function> impl);
@@ -114,7 +110,7 @@ class LIEF_API Function {
/// The name of the function which is used for linking (`DW_AT_linkage_name`).
///
/// This name differs from name() as it is usually mangled. The function
/// return an empty string if the linkage name is not available.
/// returns an empty string if the linkage name is not available.
std::string linkage_name() const;
/// Return the address of the function (`DW_AT_entry_pc` or `DW_AT_low_pc`).
@@ -123,7 +119,7 @@ class LIEF_API Function {
/// Return an iterator of variables (`DW_TAG_variable`) defined within the
/// scope of this function. This includes regular stack-based variables as
/// well as static ones.
vars_it variables() const;
vars_it variables() const LIEF_LIFETIMEBOUND;
/// Whether this function is created by the compiler and not
/// present in the original source code
@@ -144,10 +140,10 @@ class LIEF_API Function {
/// Return the dwarf::Type associated with the **return type** of this
/// function
std::unique_ptr<Type> type() const;
std::unique_ptr<Type> type() const LIEF_LIFETIMEBOUND;
/// Return the function's parameters (including any template parameter)
parameters_t parameters() const;
parameters_t parameters() const LIEF_LIFETIMEBOUND;
/// List of exceptions (types) that can be thrown by the function.
///
@@ -161,16 +157,26 @@ class LIEF_API Function {
///
/// thrown_types() returns one element associated with the Type:
/// `StatisticsError`.
thrown_types_t thrown_types() const;
thrown_types_t thrown_types() const LIEF_LIFETIMEBOUND;
/// Return the scope in which this function is defined
std::unique_ptr<Scope> scope() const;
std::unique_ptr<Scope> scope() const LIEF_LIFETIMEBOUND;
/// Disassemble the current function by returning an iterator over
/// the assembly::Instruction
instructions_it instructions() const;
instructions_it instructions() const LIEF_LIFETIMEBOUND;
/// Iterator over the LexicalBlock owned by this function
lexical_blocks_it lexical_blocks() const LIEF_LIFETIMEBOUND;
/// Description (`DW_AT_description`) of this function or an empty string
std::string description() const;
/// Generates a C/C++ definition for this function
std::string to_decl(const DeclOpt& opt = DeclOpt()) const;
~Function();
private:
std::unique_ptr<details::Function> impl_;
};
+135
View File
@@ -0,0 +1,135 @@
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_DWARF_LEXICAL_BLOCK_H
#define LIEF_DWARF_LEXICAL_BLOCK_H
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
#include "LIEF/iterators.hpp"
#include "LIEF/optional.hpp"
#include "LIEF/range.hpp"
#include <memory>
#include <string>
#include <cstdint>
namespace LIEF {
namespace dwarf {
namespace details {
class LexicalBlock;
class LexicalBlockIt;
}
/// This class represents a DWARF lexical block (`DW_TAG_lexical_block`)
class LIEF_API LexicalBlock {
public:
class Iterator final
: public iterator_facade_base<Iterator, std::bidirectional_iterator_tag,
LexicalBlock, std::ptrdiff_t,
const LexicalBlock*, const LexicalBlock&> {
public:
using implementation = details::LexicalBlockIt;
using iterator_facade_base::operator++;
using iterator_facade_base::operator--;
LIEF_API Iterator();
LIEF_API Iterator(std::unique_ptr<details::LexicalBlockIt> impl);
LIEF_API Iterator(const Iterator&);
LIEF_API Iterator& operator=(const Iterator&);
LIEF_API Iterator(Iterator&&) noexcept;
LIEF_API Iterator& operator=(Iterator&&) noexcept;
LIEF_API ~Iterator();
friend LIEF_API bool operator==(const Iterator& LHS, const Iterator& RHS);
friend bool operator!=(const Iterator& LHS, const Iterator& RHS) {
return !(LHS == RHS);
}
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API Iterator& operator++();
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API Iterator& operator--();
LIEF_API const LexicalBlock& operator*() const LIEF_LIFETIMEBOUND;
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API const LexicalBlock* operator->() const LIEF_LIFETIMEBOUND;
/// Transfer ownership of the lexical block at the current position
/// to the caller. Returns `nullptr` if the iterator is past-the-end.
LIEF_API std::unique_ptr<LexicalBlock> yield();
private:
void load() const;
std::unique_ptr<details::LexicalBlockIt> impl_;
mutable std::unique_ptr<LexicalBlock> cached_;
};
using sub_blocks_it = iterator_range<Iterator>;
LexicalBlock(std::unique_ptr<details::LexicalBlock> impl);
LexicalBlock() = delete;
LexicalBlock& operator=(const LexicalBlock&) = delete;
LexicalBlock(const LexicalBlock&) = delete;
/// Return the *name* associated with this lexical block or an
/// empty string
std::string name() const;
/// Return the description associated with this lexical block or an
/// empty string
std::string description() const;
/// Return an iterator over the sub-LexicalBlock owned by this block.
sub_blocks_it sub_blocks() const LIEF_LIFETIMEBOUND;
/// Return the start address of this block
optional<uint64_t> addr() const;
/// Return the size of this block as the difference of the highest address and
/// the lowest address.
uint64_t size() const;
/// Return the lowest virtual address owned by this block.
optional<uint64_t> low_pc() const;
/// Return the highest virtual address owned by this block.
optional<uint64_t> high_pc() const;
/// Return a list of address ranges owned by this block.
///
/// If the lexical block owns a contiguous range, it should return
/// **a single** range.
std::vector<range_t> ranges() const;
~LexicalBlock();
LIEF_LOCAL static std::unique_ptr<LexicalBlock>
create(std::unique_ptr<details::LexicalBlock> impl);
protected:
std::unique_ptr<details::LexicalBlock> impl_;
};
}
}
#endif
+51 -7
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,11 @@
#define LIEF_DWARF_PARAMETER_H
#include "LIEF/visibility.h"
#include "LIEF/compiler_attributes.hpp"
#include <memory>
#include <string>
#include <cstdint>
namespace LIEF {
namespace dwarf {
@@ -41,19 +43,61 @@ class LIEF_API Parameter {
TEMPLATE_VALUE, ///< DW_TAG_template_value_parameter
FORMAL, ///< DW_TAG_formal_parameter
};
/// This class exposes information about the location of a parameter
class LIEF_API Location {
public:
enum class Type : uint8_t {
UNKNOWN = 0,
REG,
};
Location(Type ty) :
type(ty) {}
template<class T>
const T* as() const {
if (T::classof(this)) {
return static_cast<const T*>(this);
}
return nullptr;
}
Type type = Type::UNKNOWN;
};
/// This class represents a register location
class LIEF_API RegisterLoc : public Location {
public:
RegisterLoc(uint64_t reg_id) :
Location(Type::REG),
id(reg_id) {}
static bool classof(const Location* loc) {
return loc->type == Type::REG;
}
/// DWARF id of the register
uint64_t id = 0;
};
Parameter() = delete;
Parameter(Parameter&& other);
Parameter& operator=(Parameter&& other);
Parameter(Parameter&& other) noexcept;
Parameter& operator=(Parameter&& other) noexcept;
Parameter& operator=(const Parameter&) = delete;
Parameter(const Parameter&) = delete;
KIND kind() const;
/// Name of the parameter
std::string name() const;
/// Type of this parameter
std::unique_ptr<Type> type() const;
std::unique_ptr<Type> type() const LIEF_LIFETIMEBOUND;
/// Location of this parameter. For instance it can be a specific register
/// that is not following the calling convention.
std::unique_ptr<Location> location() const LIEF_LIFETIMEBOUND;
template<class T>
const T* as() const {
@@ -65,8 +109,8 @@ class LIEF_API Parameter {
virtual ~Parameter();
LIEF_LOCAL static
std::unique_ptr<Parameter> create(std::unique_ptr<details::Parameter> impl);
LIEF_LOCAL static std::unique_ptr<Parameter>
create(std::unique_ptr<details::Parameter> impl);
protected:
Parameter(std::unique_ptr<details::Parameter> impl);
@@ -130,7 +174,7 @@ class LIEF_API TemplateValue : public Parameter {
///
/// The function `generic` has one parameters::TemplateType parameter: `Y`.
class LIEF_API TemplateType : public Parameter {
public:
public:
using Parameter::Parameter;
static bool classof(const Parameter* P) {
return P->kind() == Parameter::KIND::TEMPLATE_TYPE;
+2 -1
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -57,6 +57,7 @@ class LIEF_API Scope {
std::string chained(const std::string& sep = "::") const;
~Scope();
private:
std::unique_ptr<details::Scope> impl_;
};
+45 -42
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,10 +17,13 @@
#include <memory>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/iterators.hpp"
#include "LIEF/visibility.h"
#include "LIEF/errors.hpp"
#include "LIEF/debug_loc.hpp"
#include "LIEF/canbe_unique.hpp"
#include "LIEF/DebugDeclOpt.hpp"
namespace LIEF {
namespace dwarf {
@@ -63,63 +66,62 @@ class TypeIt;
/// - `DW_TAG_volatile_type`
class LIEF_API Type {
public:
class LIEF_API Iterator {
class Iterator final
: public iterator_facade_base<Iterator, std::bidirectional_iterator_tag, Type,
std::ptrdiff_t, const Type*, const Type&> {
public:
using iterator_category = std::bidirectional_iterator_tag;
using value_type = std::unique_ptr<Type>;
using difference_type = std::ptrdiff_t;
using pointer = Type*;
using reference = std::unique_ptr<Type>&;
using implementation = details::TypeIt;
using iterator_facade_base::operator++;
using iterator_facade_base::operator--;
class LIEF_API PointerProxy {
// Inspired from LLVM's iterator_facade_base
friend class Iterator;
public:
pointer operator->() const { return R.get(); }
LIEF_API Iterator();
private:
value_type R;
LIEF_API Iterator(std::unique_ptr<details::TypeIt> impl);
template <typename RefT>
PointerProxy(RefT &&R) : R(std::forward<RefT>(R)) {} // NOLINT(bugprone-forwarding-reference-overload)
};
LIEF_API Iterator(const Iterator&);
LIEF_API Iterator& operator=(const Iterator&);
Iterator(const Iterator&);
Iterator(Iterator&&) noexcept;
Iterator(std::unique_ptr<details::TypeIt> impl);
~Iterator();
LIEF_API Iterator(Iterator&&) noexcept;
LIEF_API Iterator& operator=(Iterator&&) noexcept;
LIEF_API ~Iterator();
friend LIEF_API bool operator==(const Iterator& LHS, const Iterator& RHS);
friend LIEF_API bool operator!=(const Iterator& LHS, const Iterator& RHS) {
friend bool operator!=(const Iterator& LHS, const Iterator& RHS) {
return !(LHS == RHS);
}
Iterator& operator++();
Iterator& operator--();
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API Iterator& operator++();
Iterator operator--(int) {
Iterator tmp = *static_cast<Iterator*>(this);
--*static_cast<Iterator *>(this);
return tmp;
}
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API Iterator& operator--();
Iterator operator++(int) {
Iterator tmp = *static_cast<Iterator*>(this);
++*static_cast<Iterator *>(this);
return tmp;
}
LIEF_API const Type& operator*() const LIEF_LIFETIMEBOUND;
std::unique_ptr<Type> operator*() const;
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API const Type* operator->() const LIEF_LIFETIMEBOUND;
PointerProxy operator->() const {
return static_cast<const Iterator*>(this)->operator*();
}
/// Transfer ownership of the type at the current position to the
/// caller. Returns `nullptr` if the iterator is past-the-end.
LIEF_API std::unique_ptr<Type> yield();
private:
void load() const;
std::unique_ptr<details::TypeIt> impl_;
mutable std::unique_ptr<Type> cached_;
};
LIEF_LOCAL Type(std::unique_ptr<details::Type> impl);
LIEF_LOCAL Type(details::Type& impl);
Type(const Type&) = delete;
Type& operator=(const Type&) = delete;
Type(Type&&) noexcept;
Type& operator=(Type&&) noexcept;
virtual ~Type();
enum class KIND {
@@ -176,6 +178,9 @@ class LIEF_API Type {
/// Return the scope in which this type is defined
std::unique_ptr<Scope> scope() const;
/// Generates a C/C++ definition for this type
std::string to_decl(const DeclOpt& opt = DeclOpt()) const;
template<class T>
const T* as() const {
if (T::classof(this)) {
@@ -184,12 +189,10 @@ class LIEF_API Type {
return nullptr;
}
static std::unique_ptr<Type> create(std::unique_ptr<details::Type> impl);
static std::unique_ptr<Type>
create(std::unique_ptr<details::Type> impl LIEF_LIFETIMEBOUND);
protected:
Type(std::unique_ptr<details::Type> impl);
Type(details::Type& impl);
LIEF::details::canbe_unique<details::Type> impl_;
};
+44 -41
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,9 @@
#include <memory>
#include "LIEF/iterators.hpp"
#include "LIEF/visibility.h"
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/errors.hpp"
#include "LIEF/debug_loc.hpp"
#include "LIEF/DWARF/Type.hpp"
@@ -35,61 +37,52 @@ class VariableIt;
/// dwarf::Function or a dwarf::CompilationUnit
class LIEF_API Variable {
public:
class LIEF_API Iterator {
class Iterator final
: public iterator_facade_base<Iterator, std::bidirectional_iterator_tag,
Variable, std::ptrdiff_t, const Variable*,
const Variable&> {
public:
using iterator_category = std::bidirectional_iterator_tag;
using value_type = std::unique_ptr<Variable>;
using difference_type = std::ptrdiff_t;
using pointer = Variable*;
using reference = std::unique_ptr<Variable>&;
using implementation = details::VariableIt;
using iterator_facade_base::operator++;
using iterator_facade_base::operator--;
class LIEF_API PointerProxy {
// Inspired from LLVM's iterator_facade_base
friend class Iterator;
public:
pointer operator->() const { return R.get(); }
LIEF_API Iterator();
private:
value_type R;
LIEF_API Iterator(std::unique_ptr<details::VariableIt> impl);
template <typename RefT>
PointerProxy(RefT &&R) : R(std::forward<RefT>(R)) {} // NOLINT(bugprone-forwarding-reference-overload)
};
LIEF_API Iterator(const Iterator&);
LIEF_API Iterator& operator=(const Iterator&);
Iterator(const Iterator&);
Iterator(Iterator&&) noexcept;
Iterator(std::unique_ptr<details::VariableIt> impl);
~Iterator();
LIEF_API Iterator(Iterator&&) noexcept;
LIEF_API Iterator& operator=(Iterator&&) noexcept;
LIEF_API ~Iterator();
friend LIEF_API bool operator==(const Iterator& LHS, const Iterator& RHS);
friend LIEF_API bool operator!=(const Iterator& LHS, const Iterator& RHS) {
friend bool operator!=(const Iterator& LHS, const Iterator& RHS) {
return !(LHS == RHS);
}
Iterator& operator++();
Iterator& operator--();
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API Iterator& operator++();
Iterator operator--(int) {
Iterator tmp = *static_cast<Iterator*>(this);
--*static_cast<Iterator *>(this);
return tmp;
}
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API Iterator& operator--();
Iterator operator++(int) {
Iterator tmp = *static_cast<Iterator*>(this);
++*static_cast<Iterator *>(this);
return tmp;
}
LIEF_API const Variable& operator*() const LIEF_LIFETIMEBOUND;
std::unique_ptr<Variable> operator*() const;
// NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
LIEF_API const Variable* operator->() const LIEF_LIFETIMEBOUND;
PointerProxy operator->() const {
return static_cast<const Iterator*>(this)->operator*();
}
/// Transfer ownership of the variable at the current position to the
/// caller. Returns `nullptr` if the iterator is past-the-end.
LIEF_API std::unique_ptr<Variable> yield();
private:
void load() const;
std::unique_ptr<details::VariableIt> impl_;
mutable std::unique_ptr<Variable> cached_;
};
Variable(std::unique_ptr<details::Variable> impl);
@@ -100,7 +93,7 @@ class LIEF_API Variable {
/// The name of the variable which is used for linking (`DW_AT_linkage_name`).
///
/// This name differs from name() as it is usually mangled. The function
/// return an empty string if the linkage name is not available.
/// returns an empty string if the linkage name is not available.
std::string linkage_name() const;
/// Address of the variable.
@@ -122,16 +115,26 @@ class LIEF_API Variable {
/// Whether it's a `constexpr` variable
bool is_constexpr() const;
/// Whether this variable is allocated on the stack
bool is_stack_based() const;
/// The original source location where the variable is defined.
debug_location_t debug_location() const;
/// Return the type of this variable
std::unique_ptr<Type> type() const;
std::unique_ptr<Type> type() const LIEF_LIFETIMEBOUND;
/// Return the scope in which this variable is defined
std::unique_ptr<Scope> scope() const;
std::unique_ptr<Scope> scope() const LIEF_LIFETIMEBOUND;
/// Description (`DW_AT_description`) of the variable or an empty string
std::string description() const;
/// Generates a C/C++ definition for this variable
std::string to_decl(const DeclOpt& opt = DeclOpt()) const;
~Variable();
private:
std::unique_ptr<details::Variable> impl_;
};
+6 -2
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,11 @@ namespace editor {
/// This class represents an array type (`DW_TAG_array_type`).
class LIEF_API ArrayType : public Type {
public:
using Type::Type;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<Type, Args&&...>::value>::type>
ArrayType(Args&&... args) :
Type(std::forward<Args>(args)...) {}
static bool classof(const Type* type);
+7 -3
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,11 @@ namespace editor {
/// This class represents a primitive type like `int, char`.
class LIEF_API BaseType : public Type {
public:
using Type::Type;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<Type, Args&&...>::value>::type>
BaseType(Args&&... args) :
Type(std::forward<Args>(args)...) {}
enum class ENCODING : uint32_t {
NONE = 0,
@@ -36,7 +40,7 @@ class LIEF_API BaseType : public Type {
UNSIGNED,
UNSIGNED_CHAR,
BOOLEAN,
FLOAT
FLOAT,
};
static bool classof(const Type* type);
+29 -16
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@
#include <string>
#include "LIEF/visibility.h"
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/DWARF/editor/StructType.hpp"
#include "LIEF/DWARF/editor/BaseType.hpp"
#include "LIEF/DWARF/editor/FunctionType.hpp"
@@ -47,46 +49,57 @@ class LIEF_API CompilationUnit {
///
/// This attribute aims to inform about the program that generated this
/// compilation unit (e.g. `LIEF Extended`)
CompilationUnit& set_producer(const std::string& producer);
CompilationUnit& set_producer(const std::string& producer) LIEF_LIFETIMEBOUND;
/// Create a new function owned by this compilation unit
std::unique_ptr<Function> create_function(const std::string& name);
std::unique_ptr<Function>
create_function(const std::string& name) LIEF_LIFETIMEBOUND;
/// Create a new **global** variable owned by this compilation unit
std::unique_ptr<Variable> create_variable(const std::string& name);
std::unique_ptr<Variable>
create_variable(const std::string& name) LIEF_LIFETIMEBOUND;
/// Create a `DW_TAG_unspecified_type` type with the given name
std::unique_ptr<Type> create_generic_type(const std::string& name);
std::unique_ptr<Type>
create_generic_type(const std::string& name) LIEF_LIFETIMEBOUND;
/// Create an enum type (`DW_TAG_enumeration_type`)
std::unique_ptr<EnumType> create_enum(const std::string& name);
std::unique_ptr<EnumType>
create_enum(const std::string& name) LIEF_LIFETIMEBOUND;
/// Create a typdef with the name provided in the first parameter which aliases
/// Create a typedef with the name provided in the first parameter which aliases
/// the type provided in the second parameter
std::unique_ptr<TypeDef> create_typedef(const std::string& name, const Type& type);
std::unique_ptr<TypeDef> create_typedef(const std::string& name,
const Type& type) LIEF_LIFETIMEBOUND;
/// Create a struct-like type (struct, class, union) with the given name.
std::unique_ptr<StructType> create_structure(
const std::string& name, StructType::TYPE kind = StructType::TYPE::STRUCT);
const std::string& name, StructType::TYPE kind = StructType::TYPE::STRUCT
) LIEF_LIFETIMEBOUND;
/// Create a primitive type with the given name and size.
std::unique_ptr<BaseType> create_base_type(const std::string& name, size_t size,
BaseType::ENCODING encoding = BaseType::ENCODING::NONE);
std::unique_ptr<BaseType> create_base_type(
const std::string& name, size_t size,
BaseType::ENCODING encoding = BaseType::ENCODING::NONE
) LIEF_LIFETIMEBOUND;
/// Create a function type with the given name.
std::unique_ptr<FunctionType> create_function_type(const std::string& name);
std::unique_ptr<FunctionType>
create_function_type(const std::string& name) LIEF_LIFETIMEBOUND;
/// Create a pointer on the provided type
std::unique_ptr<PointerType> create_pointer_type(const Type& ty) {
std::unique_ptr<PointerType>
create_pointer_type(const Type& ty) LIEF_LIFETIMEBOUND {
return ty.pointer_to();
}
/// Create a `void` type
std::unique_ptr<Type> create_void_type();
std::unique_ptr<Type> create_void_type() LIEF_LIFETIMEBOUND;
/// Create an array type with the given name, type and size.
std::unique_ptr<ArrayType>
create_array(const std::string& name, const Type& type, size_t count);
std::unique_ptr<ArrayType> create_array(const std::string& name,
const Type& type,
size_t count) LIEF_LIFETIMEBOUND;
~CompilationUnit();
+14 -4
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
#include <cstdint>
#include <string>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
#include "LIEF/DWARF/editor/Type.hpp"
@@ -31,7 +32,11 @@ class EnumValue;
/// This class represents an editable enum type (`DW_TAG_enumeration_type`)
class LIEF_API EnumType : public Type {
public:
using Type::Type;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<Type, Args&&...>::value>::type>
EnumType(Args&&... args) :
Type(std::forward<Args>(args)...) {}
/// This class represents an enum value
class LIEF_API Value {
@@ -40,16 +45,21 @@ class LIEF_API EnumType : public Type {
Value(std::unique_ptr<details::EnumValue> impl);
~Value();
private:
std::unique_ptr<details::EnumValue> impl_;
};
/// Define the number of bytes required to hold an instance of the
/// enumeration (`DW_AT_byte_size`).
EnumType& set_size(uint64_t size);
EnumType& set_size(uint64_t size) LIEF_LIFETIMEBOUND;
/// Set the underlying type that is used to encode this enum
EnumType& set_underlying_type(const Type& type) LIEF_LIFETIMEBOUND;
/// Add an enum value by specifying its name and its integer value
std::unique_ptr<Value> add_value(const std::string& name, int64_t value);
std::unique_ptr<Value> add_value(const std::string& name,
int64_t value) LIEF_LIFETIMEBOUND;
static bool classof(const Type* type);
+49 -14
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
#include <vector>
#include <string>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
namespace LIEF {
@@ -40,19 +41,27 @@ class LIEF_API Function {
struct LIEF_API range_t {
range_t() = default;
range_t(uint64_t start, uint64_t end) :
start(start), end(end)
{}
start(start),
end(end) {}
uint64_t start = 0;
uint64_t end = 0;
};
/// This class represents a parameter of the current function (`DW_TAG_formal_parameter`)
/// This class represents a parameter of the current function
/// (`DW_TAG_formal_parameter`)
class LIEF_API Parameter {
public:
Parameter() = delete;
Parameter(std::unique_ptr<details::FunctionParameter> impl);
~Parameter();
/// Assign this parameter to a specific named register.
Parameter& assign_register(const std::string& name) LIEF_LIFETIMEBOUND;
/// Assign this parameter to the given DWARF register id (e.g. `DW_OP_reg0`).
Parameter& assign_register(uint64_t reg) LIEF_LIFETIMEBOUND;
private:
std::unique_ptr<details::FunctionParameter> impl_;
};
@@ -63,7 +72,24 @@ class LIEF_API Function {
LexicalBlock() = delete;
LexicalBlock(std::unique_ptr<details::FunctionLexicalBlock> impl);
/// Create a sub-block with the given low/high addresses.
std::unique_ptr<LexicalBlock> add_block(uint64_t start,
uint64_t end) LIEF_LIFETIMEBOUND;
/// Create a sub-block with the given range of addresses.
std::unique_ptr<LexicalBlock>
add_block(const std::vector<range_t>& range) LIEF_LIFETIMEBOUND;
/// Create a `DW_AT_description` entry with the description
/// provided in parameter.
LexicalBlock&
add_description(const std::string& description) LIEF_LIFETIMEBOUND;
/// Create a `DW_AT_name` entry to associate a name to this entry
LexicalBlock& add_name(const std::string& name) LIEF_LIFETIMEBOUND;
~LexicalBlock();
private:
std::unique_ptr<details::FunctionLexicalBlock> impl_;
};
@@ -75,6 +101,7 @@ class LIEF_API Function {
Label(std::unique_ptr<details::FunctionLabel> impl);
~Label();
private:
std::unique_ptr<details::FunctionLabel> impl_;
};
@@ -83,39 +110,47 @@ class LIEF_API Function {
Function(std::unique_ptr<details::Function> impl);
/// Set the address of this function by defining `DW_AT_entry_pc`
Function& set_address(uint64_t addr);
Function& set_address(uint64_t addr) LIEF_LIFETIMEBOUND;
/// Set the upper and lower bound addresses for this function. This assumes
/// that the function is contiguous between `low` and `high`.
///
/// Underneath, the function defines `DW_AT_low_pc` and `DW_AT_high_pc`
Function& set_low_high(uint64_t low, uint64_t high);
Function& set_low_high(uint64_t low, uint64_t high) LIEF_LIFETIMEBOUND;
/// Set the ranges of addresses owned by the implementation of this function
/// by setting the `DW_AT_ranges` attribute.
///
/// This setter should be used for non-contiguous function.
Function& set_ranges(const std::vector<range_t>& ranges);
/// This setter should be used for non-contiguous functions.
Function& set_ranges(const std::vector<range_t>& ranges) LIEF_LIFETIMEBOUND;
/// Set the function as external by defining `DW_AT_external` to true.
/// This means that the function is **imported** by the current compilation
/// unit.
Function& set_external();
Function& set_external() LIEF_LIFETIMEBOUND;
/// Set the return type of this function
Function& set_return_type(const Type& type);
Function& set_return_type(const Type& type) LIEF_LIFETIMEBOUND;
/// Add a parameter to the current function
std::unique_ptr<Parameter> add_parameter(const std::string& name, const Type& type);
std::unique_ptr<Parameter> add_parameter(const std::string& name,
const Type& type) LIEF_LIFETIMEBOUND;
/// Create a stack-based variable owned by the current function
std::unique_ptr<Variable> create_stack_variable(const std::string& name);
std::unique_ptr<Variable>
create_stack_variable(const std::string& name) LIEF_LIFETIMEBOUND;
/// Add a lexical block with the given range
std::unique_ptr<LexicalBlock> add_lexical_block(uint64_t start, uint64_t end);
std::unique_ptr<LexicalBlock> add_lexical_block(uint64_t start,
uint64_t end) LIEF_LIFETIMEBOUND;
/// Add a label at the given address
std::unique_ptr<Label> add_label(uint64_t addr, const std::string& label);
std::unique_ptr<Label> add_label(uint64_t addr,
const std::string& label) LIEF_LIFETIMEBOUND;
/// Create a `DW_AT_description` entry with the description
/// provided in parameter.
Function& add_description(const std::string& description) LIEF_LIFETIMEBOUND;
~Function();
+10 -4
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
*/
#ifndef LIEF_DWARF_EDITOR_FUNCTION_TYPE_H
#define LIEF_DWARF_EDITOR_FUNCTION_TYPE_H
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
#include "LIEF/DWARF/editor/Type.hpp"
@@ -28,7 +29,11 @@ class FunctionTyParameter;
/// This class represents a function type (`DW_TAG_subroutine_type`)
class LIEF_API FunctionType : public Type {
public:
using Type::Type;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<Type, Args&&...>::value>::type>
FunctionType(Args&&... args) :
Type(std::forward<Args>(args)...) {}
/// This class represents a function's parameter
class LIEF_API Parameter {
@@ -37,15 +42,16 @@ class LIEF_API FunctionType : public Type {
Parameter(std::unique_ptr<details::FunctionTyParameter> impl);
~Parameter();
private:
std::unique_ptr<details::FunctionTyParameter> impl_;
};
/// Set the return type of this function
FunctionType& set_return_type(const Type& type);
FunctionType& set_return_type(const Type& type) LIEF_LIFETIMEBOUND;
/// Add a parameter
std::unique_ptr<Parameter> add_parameter(const Type& type);
std::unique_ptr<Parameter> add_parameter(const Type& type) LIEF_LIFETIMEBOUND;
static bool classof(const Type* type);
+6 -2
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,11 @@ namespace editor {
/// This class represents a pointer to another type.
class LIEF_API PointerType : public Type {
public:
using Type::Type;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<Type, Args&&...>::value>::type>
PointerType(Args&&... args) :
Type(std::forward<Args>(args)...) {}
static bool classof(const Type* type);
+18 -7
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
#include <string>
#include "LIEF/visibility.h"
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/DWARF/editor/Type.hpp"
namespace LIEF {
@@ -36,12 +37,16 @@ class StructMember;
/// - `DW_TAG_union_type`
class LIEF_API StructType : public Type {
public:
using Type::Type;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<Type, Args&&...>::value>::type>
StructType(Args&&... args) :
Type(std::forward<Args>(args)...) {}
enum class TYPE : uint32_t {
CLASS, /// Discriminant for `DW_TAG_class_type`
CLASS, /// Discriminant for `DW_TAG_class_type`
STRUCT, /// Discriminant for `DW_TAG_structure_type`
UNION, /// Discriminant for `DW_TAG_union_type`
UNION, /// Discriminant for `DW_TAG_union_type`
};
/// This class represents a member of the struct-like
@@ -51,6 +56,7 @@ class LIEF_API StructType : public Type {
Member(std::unique_ptr<details::StructMember> impl);
~Member();
private:
std::unique_ptr<details::StructMember> impl_;
};
@@ -59,11 +65,16 @@ class LIEF_API StructType : public Type {
/// type.
///
/// This function defines the `DW_AT_byte_size` attribute
StructType& set_size(uint64_t size);
StructType& set_size(uint64_t size) LIEF_LIFETIMEBOUND;
/// Add a member to the current struct-like
/// Adds a member to the current struct-like
std::unique_ptr<Member> add_member(const std::string& name, const Type& type,
int64_t offset = -1);
int64_t offset = -1) LIEF_LIFETIMEBOUND;
/// Adds a bitfield member to the current structure.
std::unique_ptr<Member> add_bitfield(const std::string& name, const Type& type,
uint64_t bitsize,
int64_t bitoffset = -1) LIEF_LIFETIMEBOUND;
static bool classof(const Type* type);
+7 -6
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
#include <memory>
#include <cassert>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
namespace LIEF {
@@ -39,20 +40,20 @@ class LIEF_API Type {
Type(std::unique_ptr<details::Type> impl);
/// Create a pointer type pointing to this type
std::unique_ptr<PointerType> pointer_to() const;
std::unique_ptr<PointerType> pointer_to() const LIEF_LIFETIMEBOUND;
virtual ~Type();
/// \private
/// @private
static std::unique_ptr<Type> create(std::unique_ptr<details::Type> impl);
/// \private
details::Type& impl() {
/// @private
details::Type& impl() LIEF_LIFETIMEBOUND {
assert(impl_ != nullptr);
return *impl_;
}
const details::Type& impl() const {
const details::Type& impl() const LIEF_LIFETIMEBOUND {
assert(impl_ != nullptr);
return *impl_;
}
+6 -2
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,11 @@ namespace editor {
/// This class represents a typedef (`DW_TAG_typedef`).
class LIEF_API TypeDef : public Type {
public:
using Type::Type;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<Type, Args&&...>::value>::type>
TypeDef(Args&&... args) :
Type(std::forward<Args>(args)...) {}
static bool classof(const Type* type);
+14 -8
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,9 @@
#define LIEF_DWARF_EDITOR_VARIABLE_H
#include <cstdint>
#include <memory>
#include <string>
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
namespace LIEF {
@@ -36,22 +38,26 @@ class LIEF_API Variable {
Variable(std::unique_ptr<details::Variable> impl);
/// Set the global address of this variable. Setting this address is only
/// revelant in the case of a static global variable. For stack variable, you
/// relevant in the case of a static global variable. For stack variable, you
/// should use set_stack_offset.
///
/// This function set the `DW_AT_location` attribute
Variable& set_addr(uint64_t address);
/// This function sets the `DW_AT_location` attribute
Variable& set_addr(uint64_t address) LIEF_LIFETIMEBOUND;
/// Set the stack offset of this variable.
///
/// This function set the `DW_AT_location` attribute
Variable& set_stack_offset(uint64_t offset);
/// This function sets the `DW_AT_location` attribute
Variable& set_stack_offset(uint64_t offset) LIEF_LIFETIMEBOUND;
/// Mark this variable as **imported**
Variable& set_external();
Variable& set_external() LIEF_LIFETIMEBOUND;
/// Set the type of the current variable
Variable& set_type(const Type& type);
Variable& set_type(const Type& type) LIEF_LIFETIMEBOUND;
/// Create a `DW_AT_description` entry with the description
/// provided in parameter.
Variable& add_description(const std::string& description) LIEF_LIFETIMEBOUND;
~Variable();
+21 -21
View File
@@ -1,5 +1,5 @@
/* Copyright 2017 - 2025 R. Thomas
* Copyright 2017 - 2025 Quarkslab
/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,26 +19,26 @@
namespace LIEF {
namespace dwarf {
enum class EH_ENCODING {
ABSPTR = 0x00,
OMIT = 0xff,
ULEB128 = 0x01,
UDATA2 = 0x02,
UDATA4 = 0x03,
UDATA8 = 0x04,
SLEB128 = 0x09,
SDATA2 = 0x0a,
SDATA4 = 0x0b,
SDATA8 = 0x0c,
SIGNED = 0x09,
enum class EH_ENCODING {
ABSPTR = 0x00,
OMIT = 0xff,
ULEB128 = 0x01,
UDATA2 = 0x02,
UDATA4 = 0x03,
UDATA8 = 0x04,
SLEB128 = 0x09,
SDATA2 = 0x0a,
SDATA4 = 0x0b,
SDATA8 = 0x0c,
SIGNED = 0x09,
PCREL = 0x10,
INDIRECT = 0x80,
TEXTREL = 0x20,
DATAREL = 0x30,
FUNCREL = 0x40,
ALIGNED = 0x50,
};
PCREL = 0x10,
INDIRECT = 0x80,
TEXTREL = 0x20,
DATAREL = 0x30,
FUNCREL = 0x40,
ALIGNED = 0x50,
};
} // dwarf
} // LIEF
+1 -1
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+16 -5
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
#ifndef LIEF_DWARF_TYPE_ARRAY_H
#define LIEF_DWARF_TYPE_ARRAY_H
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
#include "LIEF/DWARF/Type.hpp"
@@ -25,7 +26,17 @@ namespace types {
/// This class represents a `DW_TAG_array_type`
class LIEF_API Array : public Type {
public:
using Type::Type;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<Type, Args&&...>::value>::type>
Array(Args&&... args) :
Type(std::forward<Args>(args)...) {}
Array(const Array&) = delete;
Array& operator=(const Array&) = delete;
Array(Array&&) noexcept = default;
Array& operator=(Array&&) noexcept = default;
/// Structure that wraps information about the dimension of this array
struct size_info_t {
@@ -50,13 +61,13 @@ class LIEF_API Array : public Type {
}
/// The underlying type of this array
const Type* underlying_type() const;
const Type* underlying_type() const LIEF_LIFETIMEBOUND;
const Type* operator->() const {
const Type* operator->() const LIEF_LIFETIMEBOUND {
return underlying_type();
}
const Type& operator*() const {
const Type& operator*() const LIEF_LIFETIMEBOUND {
return *underlying_type();
}
+16 -5
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
#ifndef LIEF_DWARF_TYPE_ATOMIC_H
#define LIEF_DWARF_TYPE_ATOMIC_H
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/visibility.h"
#include "LIEF/DWARF/Type.hpp"
@@ -25,20 +26,30 @@ namespace types {
/// This class represents a `DW_TAG_atomic_type`
class LIEF_API Atomic : public Type {
public:
using Type::Type;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<Type, Args&&...>::value>::type>
Atomic(Args&&... args) :
Type(std::forward<Args>(args)...) {}
Atomic(const Atomic&) = delete;
Atomic& operator=(const Atomic&) = delete;
Atomic(Atomic&&) noexcept = default;
Atomic& operator=(Atomic&&) noexcept = default;
static bool classof(const Type* type) {
return type->kind() == Type::KIND::ATOMIC;
}
/// The underlying type being atomic
const Type* underlying_type() const;
const Type* underlying_type() const LIEF_LIFETIMEBOUND;
const Type* operator->() const {
const Type* operator->() const LIEF_LIFETIMEBOUND {
return underlying_type();
}
const Type& operator*() const {
const Type& operator*() const LIEF_LIFETIMEBOUND {
return *underlying_type();
}
+12 -4
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,11 @@ namespace types {
/// instance -- to represent integers or primitive types.
class LIEF_API Base : public Type {
public:
using Type::Type;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<Type, Args&&...>::value>::type>
Base(Args&&... args) :
Type(std::forward<Args>(args)...) {}
enum class ENCODING {
NONE = 0,
@@ -53,6 +57,12 @@ class LIEF_API Base : public Type {
ADDRESS,
};
Base(const Base&) = delete;
Base& operator=(const Base&) = delete;
Base(Base&&) noexcept = default;
Base& operator=(Base&&) noexcept = default;
static bool classof(const Type* type) {
return type->kind() == Type::KIND::BASE;
}
@@ -67,5 +77,3 @@ class LIEF_API Base : public Type {
}
}
#endif
+73 -17
View File
@@ -1,4 +1,4 @@
/* Copyright 2022 - 2025 R. Thomas
/* Copyright 2022 - 2026 R. Thomas
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
#define LIEF_DWARF_TYPE_STRUCTURE_H
#include "LIEF/visibility.h"
#include "LIEF/compiler_attributes.hpp"
#include "LIEF/DWARF/Type.hpp"
#include "LIEF/DWARF/Function.hpp"
@@ -31,7 +32,11 @@ class Member;
/// `DW_TAG_class_type`, `DW_TAG_union_type`.
class LIEF_API ClassLike : public Type {
public:
using Type::Type;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<Type, Args&&...>::value>::type>
ClassLike(Args&&... args) :
Type(std::forward<Args>(args)...) {}
/// This represents a class/struct/union attribute
class LIEF_API Member {
@@ -40,6 +45,9 @@ class LIEF_API ClassLike : public Type {
Member(Member&& other) noexcept;
Member& operator=(Member&& other) noexcept;
Member(const Member&) = delete;
Member& operator=(const Member&) = delete;
/// Name of the member
std::string name() const;
@@ -48,7 +56,7 @@ class LIEF_API ClassLike : public Type {
/// If the offset can't be resolved it returns a lief_errors
result<uint64_t> offset() const;
/// Offset of the current member in **bits** the struct/union/class
/// Offset of the current member in **bits** in the struct/union/class
///
/// This function differs from offset() for aggregates using bit-field
/// declaration:
@@ -65,35 +73,45 @@ class LIEF_API ClassLike : public Type {
/// If the offset can't be resolved it returns a lief_errors
result<uint64_t> bit_offset() const;
/// If the current member is a bit-field, this function returns its size in
/// bits.
result<uint64_t> bit_size() const;
/// Type of the current member
std::unique_ptr<Type> type() const;
std::unique_ptr<Type> type() const LIEF_LIFETIMEBOUND;
bool is_external() const;
bool is_declaration() const;
~Member();
private:
std::unique_ptr<details::Member> impl_;
};
ClassLike(const ClassLike&) = delete;
ClassLike& operator=(const ClassLike&) = delete;
ClassLike(ClassLike&&) noexcept = default;
ClassLike& operator=(ClassLike&&) noexcept = default;
using functions_it = iterator_range<Function::Iterator>;
static bool classof(const Type* type) {
const auto kind = type->kind();
return kind == Type::KIND::CLASS || kind == Type::KIND::STRUCT || kind == Type::KIND::UNION;
return kind == Type::KIND::CLASS || kind == Type::KIND::STRUCT ||
kind == Type::KIND::UNION;
}
/// Return the list of all the attributes defined in this class-like type
std::vector<Member> members() const;
std::vector<Member> members() const LIEF_LIFETIMEBOUND;
/// Try to find the attribute at the given offset
std::unique_ptr<Member> find_member(uint64_t offset) const;
std::unique_ptr<Member> find_member(uint64_t offset) const LIEF_LIFETIMEBOUND;
/// Iterator over the functions defined by the class-like.
functions_it functions() const;
functions_it functions() const LIEF_LIFETIMEBOUND;
~ClassLike() override;
};
@@ -101,7 +119,17 @@ class LIEF_API ClassLike : public Type {
/// This class represents a DWARF `struct` type (`DW_TAG_structure_type`)
class LIEF_API Structure : public ClassLike {
public:
using ClassLike::ClassLike;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<ClassLike, Args&&...>::value>::type>
Structure(Args&&... args) :
ClassLike(std::forward<Args>(args)...) {}
Structure(const Structure&) = delete;
Structure& operator=(const Structure&) = delete;
Structure(Structure&&) noexcept = default;
Structure& operator=(Structure&&) noexcept = default;
static bool classof(const Type* type) {
return type->kind() == Type::KIND::STRUCT;
@@ -113,7 +141,17 @@ class LIEF_API Structure : public ClassLike {
/// This class represents a DWARF `class` type (`DW_TAG_class_type`)
class LIEF_API Class : public ClassLike {
public:
using ClassLike::ClassLike;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<ClassLike, Args&&...>::value>::type>
Class(Args&&... args) :
ClassLike(std::forward<Args>(args)...) {}
Class(const Class&) = delete;
Class& operator=(const Class&) = delete;
Class(Class&&) noexcept = default;
Class& operator=(Class&&) noexcept = default;
static bool classof(const Type* type) {
return type->kind() == Type::KIND::CLASS;
@@ -122,10 +160,20 @@ class LIEF_API Class : public ClassLike {
~Class() override;
};
/// This class represents a DWARF `class` type (`DW_TAG_union_type`)
/// This class represents a DWARF `union` type (`DW_TAG_union_type`)
class LIEF_API Union : public ClassLike {
public:
using ClassLike::ClassLike;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<ClassLike, Args&&...>::value>::type>
Union(Args&&... args) :
ClassLike(std::forward<Args>(args)...) {}
Union(const Union&) = delete;
Union& operator=(const Union&) = delete;
Union(Union&&) noexcept = default;
Union& operator=(Union&&) noexcept = default;
static bool classof(const Type* type) {
return type->kind() == Type::KIND::UNION;
@@ -137,7 +185,17 @@ class LIEF_API Union : public ClassLike {
/// This class represents a DWARF `packed` type (`DW_TAG_packed_type`)
class LIEF_API Packed : public ClassLike {
public:
using ClassLike::ClassLike;
template<typename... Args,
typename = typename std::
enable_if<std::is_constructible<ClassLike, Args&&...>::value>::type>
Packed(Args&&... args) :
ClassLike(std::forward<Args>(args)...) {}
Packed(const Packed&) = delete;
Packed& operator=(const Packed&) = delete;
Packed(Packed&&) noexcept = default;
Packed& operator=(Packed&&) noexcept = default;
static bool classof(const Type* type) {
return type->kind() == Type::KIND::PACKED;
@@ -150,5 +208,3 @@ class LIEF_API Packed : public ClassLike {
}
}
#endif
Loaded 100 of 1477 files, more files were not shown because too many files have changed in this diff. Show more