C++
LIEF::Binary& bin;
uint16_t short_value = bin.get_int_from_virtual_address<uint16_>(0x140002CC8);
Python
some_bin: lief.Binary = ...
long_value = some_bin.get_int_from_virtual_address(0x140002CC8, 4)
# or
long_value = some_bin.get_int_from_virtual_address(0x140002CC8, ctypes.sizeof(ctypes.c_uint32))
Rust
elf: &lief::elf::Binary
let value: i16 = elf.get_int_from_virtual_address::<i16>(0x401126).unwrap();
lief.ARCHITECTURES
into lief.MODES
into lief.OBJECT_TYPES
into lief.ENDIANNESS
into Fix endianness support (#1110)
Add helpers to determine the platform targeted by a Mach-O binary:
Expose an iterator over the stub entries located in __stubs,__auth_stubs,__symbol_stub,__picsymbolstub4
:
LC_SUBCLIENT
command: LC_ROUTINE/LC_ROUTINE64
command: Fix authenticode error while reading RSA PKCS#1 1.5 padding
GNU_PROPERTY_AARCH64_FEATURE_PAUTH
GNU property note: .Fix a critical error when rewriting ELF file with DT_RELR
relocations. This error leads to a crash of the modified binary.
Fix error while (re)generating ELF’s RELR relocations (#1097)
Add support for RISC-V architecture
Fix bug when trying to remove a dynamic symbol that is associated with multiple relocations (#1089)
Thanks to Huntragon Rust bindings can be used without openssl (see: #1105)
Rust precompiled Linux packages are now supported for Debian 10 & Ubuntu 19.10. Before, they require at least Debian 11 & Ubuntu 20.04
Add support for the x86_64-unknown-linux-musl
target which allows to generate full static executable.
Before
@interface GCKUIImageHints<NSCopying,NSSecureCoding> {
long long _imageType;
NSObject<NSSecureCoding> * _customData;
struct CGSize _imageSize;
}
+ (bool)supportsSecureCoding:(GCKUIImageHints *)self :(SEL)id;
- (bool)isEqual:(GCKUIImageHints *)self :(SEL)id :(NSObject *)arg2;
After
@interface GCKUIImageHints<NSCopying,NSSecureCoding> {
long long _imageType;
NSObject<NSSecureCoding> * _customData;
struct CGSize _imageSize;
}
// Address: 0x00001aa448
+ (bool)supportsSecureCoding:(GCKUIImageHints *)self :(SEL)id;
// Address: 0x00001aa5ec
- (bool)isEqual:(GCKUIImageHints *)self :(SEL)id :(NSObject *)arg2;
Note
C++ SDK is now available
Rust package is now available
Initial disassembler support: Disassembler
Linux Python wheels are now manylinux_2_27
compliants. In other words, they are working with a glibc from at least 2018.
Support for Dyld shared cache
pe = lief.PE.parse("some.exe")
if exp := pe.get_export():
for entry in exp.entries:
# e.g.void __cdecl Platform::Details::EventSourceUninitialize(void **)
print(entry.demangled_name)
for imp in pe.imports:
for entry in imp.entries:
# e.g. void __cdecl std::_Xlength_error(char const *)
print(entry.demangled_name)
The extended version is now using a versioning matching LIEF regular version
Upgrade MbedTLS from 3.2.1
to 3.6.1
Global restructuring of the documentation
Add Sphinx cross-reference support for Rust. For instance, this link: lief::elf::Binary::debug_info
references the documentation of debug_info
in the Rust documentation page.
Fix missing commit for .hwx
support
Note
Add support for DWARF: DWARF
Add support for PDB: PDB
Add support for Objective-C: Objective-C
master
branch has been renamed main
First (beta) release of the bindings (c.f. Rust)
Add support to create custom notes (#1026):
elf: lief.ELF.Binary = ...
elf += lief.ELF.Note.create(
name="my-custom-note",
original_type=lief.ELF.Note.TYPE.UNKNOWN,
description=list(b"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed"),
section_name=".lief.note.custom"
)
config = lief.ELF.Builder.config_t()
config.notes = True
elf.write("/tmp/new-binary.elf", config)
Add lief.ELF.Binary.get_relocated_dynamic_array()
which allows to get a relocated view of the of init/fini entries. This function can handy ELF init array/fini array functions are defined through relocations. See: #1058, #626
Add support for QNX Stack note (#1065)
The static_symbols
API functions has been renamed in symtab_symbols
.
LIEF was naming symbols located in the .symtab
sections as static symbols in opposition to the .dynsym
symbols. This naming can be confusing since the concept of static symbol in a program is well defined (i.e. static bool my_var
) and not applicable in this case.
Therefore, the ``xxx_static_symbols`` API is has been renamed ``xxx_symtab_symbol``.
Re-scope DYNAMIC_TAGS
into lief.ELF.DynamicEntry.TAG
Re-scope E_TYPE
into lief.ELF.Header.FILE_TYPE
Re-scope VERSION
into lief.ELF.Header.VERSION
Re-scope ELF_CLASS
into lief.ELF.Header.CLASS
Re-scope ELF_DATA
into lief.ELF.Header.ELF_DATA
Re-scope OS_ABI
into lief.ELF.Header.OS_ABI
Re-scope ELF_SECTION_TYPES
into lief.ELF.Section.TYPE
Re-scope ELF_SECTION_FLAGS
into lief.ELF.Section.FLAGS
Re-scope SYMBOL_BINDINGS
into lief.ELF.Symbol.BINDING
Re-scope ELF_SYMBOL_TYPES
into lief.ELF.Symbol.TYPE
Re-scope ELF_SYMBOL_VISIBILITY
into lief.ELF.Symbol.VISIBILITY
Re-scope SEGMENT_TYPES
into lief.ELF.Segment.TYPE
Re-scope ELF_SEGMENT_FLAGS
into lief.ELF.Segment.FLAG
Re-scope DYNAMIC_FLAGS_1
into lief.ELF.DynamicEntryFlags.FLAG
Re-scope DYNAMIC_FLAGS
into lief.ELF.DynamicEntryFlags.FLAG
Re-scope DYNSYM_COUNT_METHODS
into lief.ELF.ParserConfig.DYNSYM_COUNT
Re-scope RELOCATION_PURPOSES
into lief.ELF.Relocation.PURPOSE
RELOC_x86_64
, RELOC_i386
, … have been re-scoped and merged into lief.ELF.Relocation.TYPE
Add support for Android packed relocation format (DT_ANDROID_REL{A}
)
Add support for relative relocation format (DT_RELR
)
Authenticode: Add partial support for the following PKCS #7 attributes:
1.3.6.1.4.1.311.3.3.1 - Ms-CounterSign
(lief.PE.MsCounterSign
)
1.3.6.1.4.1.311.10.3.28 - Ms-ManifestBinaryID
(lief.PE.MsManifestBinaryID
)
1.3.6.1.4.1.311.2.6.1 - SPC_RELAXED_PE_MARKER_CHECK_OBJID
(lief.PE.SpcRelaxedPeMarkerCheck
)
1.2.840.113549.1.9.16.2.47 - SIGNING_CERTIFICATE_V2
(lief.PE.SigningCertificateV2
)
1.2.840.113549.1.9.16.1.4 - PKCS#9 TSTInfo
(lief.PE.PKCS9TSTInfo
)
Add lief.PE.CodeViewPDB.guid
attribute (#480)
Move lief.PE.OptionalHeader.computed_checksum
to lief.PE.Binary.compute_checksum()
In previous versions of LIEF, lief.PE.OptionalHeader.checksum
was re-computed (on purpose) in the parsing phase. On large binaries, this re-computation can have a strong impact on the performances. Thus, this computation has been deferred to a dedicated method lief.PE.Binary.compute_checksum()
pe = lief.PE.parse("...")
# Before:
computed = pe.optional_header.computed_checksum
# Now:
computed = pe.compute_checksum()
Add support to modify Mach-O rpath (see: #1074)
Add helper lief.MachO.Binary.support_arm64_ptr_auth
to check if a Mach-O binary is supporting ARM64 pointer authentication (arm64e)
Fix major performance issue when processing Mach-O binaries on Windows & macOS
Add generic lief.MachO.UnknownCommand
to support Apple private Load commands not officially supported by LIEF.
Re-scope LOAD_COMMAND_TYPES
into lief.MachO.LoadCommand.TYPE
Re-scope FILE_TYPES
into lief.MachO.Header.FILE_TYPE
Re-scope HEADER_FLAGS
into lief.MachO.Header.FLAGS
Re-scope MACHO_SEGMENTS_FLAGS
into lief.MachO.SegmentCommand.FLAGS
Re-scope MACHO_SECTION_TYPES
into lief.MachO.Section.TYPE
Re-scope MACHO_SECTION_FLAGS
into lief.MachO.Section.FLAGS
Re-scope REBASE_TYPES
into lief.MachO.DyldInfo.REBASE_TYPE
Re-scope REBASE_OPCODES
into lief.MachO.DyldInfo.REBASE_OPCODES
Re-scope BIND_OPCODES
into lief.MachO.DyldInfo.BIND_OPCODES
Re-scope BINDING_CLASS
into lief.MachO.DyldBindingInfo.CLASS
Re-scope BIND_TYPES
into lief.MachO.DyldBindingInfo.TYPE
Re-scope EXPORT_SYMBOL_FLAGS
into lief.MachO.ExportInfo.FLAGS
Re-scope EXPORT_SYMBOL_KINDS
into lief.MachO.ExportInfo.KIND
Re-scope RELOCATION_ORIGINS
into lief.MachO.Relocation.ORIGIN
Re-scope SYMBOL_ORIGINS
into lief.MachO.Symbol.ORIGIN
Re-scope VM_PROTECTIONS
into lief.MachO.SegmentCommand.VM_PROTECTIONS
Re-scope CPU_TYPES
into lief.MachO.Header.CPU_TYPE
LIEFConfig.cmake
is now installed in <prefix>/lib/cmake/LIEF/
instead of <prefix>/share/LIEF/cmake/
Add lief.disable_leak_warning()
to disable Nanobind warning about “leaks”.
Warning
These warnings does not necessarily mean that LIEF leak objects. These warnings might happen in Cyclic garbage collection.
Add icons
Include inheritance diagram for Python API (e.g. lief.ELF.Note
)
Add support for the GNU note properies (#975).
elf = lief.ELF.parse("...")
note = elf.get(lief.ELF.Note.TYPE.GNU_PROPERTY_TYPE_0)
aarch64_feat: lief.ELF.AArch64Feature = note.find(lief.ELF.NoteGnuProperty.Property.TYPE.AARCH64_FEATURES)
if lief.ELF.AArch64Feature.FEATURE.BTI in aarch64_feat.features:
print("BTI supported")
See:
Refactoring of the ELF note processing
Fix relocation issue when using -Wl,--emit-relocs
(c.f. #897 / #898 by adamjseitz)
Improve the computation of the dynamic symbols thanks to adamjseitz (c.f. #922)
Add support for the LoongArch architecture thanks to loongson-zn (c.f. #921)
Add a lief.ELF.ParserConfig
interface that can be used to tweak which parts of the ELF format should be parsed.
config = lief.ELF.ParserConfig()
# Skip parsing static and dynamic symbols
config.parse_static_symbols = False
config.parse_dyn_symbols = False
elf = lief.ELF.parse("target.elf", config)
The fileset name is now stored in lief.MachO.Binary.fileset_name
(instead of lief.MachO.Binary.name)
RESOURCE_SUBLANGS
has been removed
RESOURCE_LANGS
is now defined in a dedicated header: LIEF/PE/resources/langs.hpp
RESOURCE_TYPES
is now scoped in ResourcesManager::TYPE
GUARD_CF_FLAGS
is now scoped as IMAGE_GUARD
in lief.PE.LoadConfigurationV1
SECTION_CHARACTERISTICS
is now scoped within the Section
class instead of being globally defined:
# Before
lief.PE.SECTION_CHARACTERISTICS.CNT_CODE
# Now:
lief.PE.Section.CHARACTERISTICS.CNT_CODE
DATA_DIRECTORY
is now scoped within the DataDirectory
class instead of being globally defined:
# Before
lief.PE.DATA_DIRECTORY.IAT
# Now:
lief.PE.DataDirectory.TYPES.IAT
MACHINE_TYPES
and HEADER_CHARACTERISTICS
are now scoped within the Header
class instead of being globally defined:
# Before
lief.PE.MACHINE_TYPES.AMD64
# Now:
lief.PE.Header.MACHINE_TYPES.AMD64
lief.PE.Header.characteristics
now returns a list/std::vector instead of a set
.
lief.PE.OptionalHeader.dll_characteristics_lists
now returns a list
/std::vector
instead of a set
.
SUBSYSTEM
and DLL_CHARACTERISTICS
are now scoped within the OptionalHeader
class instead of being globally defined:
# Before
lief.PE.SUBSYSTEM.NATIVE
# Now:
lief.PE.OptionalHeader.SUBSYSTEM.NATIVE
lief.PE.DosHeader.used_bytes_in_the_last_page
has been renamed in lief.PE.DosHeader.used_bytes_in_last_page
Refactoring of the Debug directory processing: lief.PE.Debug
is now the root class of: lief.PE.CodeView
/ lief.PE.CodeView
, lief.PE.Pogo
, lief.PE.Repro
.
The parsing logic has been cleaned and the tests updated.
Add a lief.PE.ParserConfig
interface that can be used to tweak which parts of the PE format should be parsed (#839).
config = lief.PE.ParserConfig()
# Skip parsing PE authenticode
config.parse_signature = False
pe = lief.PE.parse("pe.exe", config)
LIEF::EXE_FORMATS
is now scoped in LIEF::Binary::FORMATS
All the Binary classes now implement classof:
std::unique_ptr<LIEF::Binary> bin = LIEF::Parser::parse("...");
if (LIEF::PE::Binary::classof(bin.get())) {
auto& pe_file = static_cast<LIEF::PE::Binary&>(*bin);
}
Python parser functions (like: lief.PE.parse()
) now accept os.PathLike arguments like pathlib.Path (#974).
Remove the lief.Binary.name attribute
LIEF is now compiled with C++17 (the API remains C++11 compliant)
Switch to nanobind for the Python bindings.
CI are now more efficient.
The Python documentation for properties now contains the type of the property.
Fix overflow issue in segments (c.f. #845 found by liyansong2018)
Fix missing relationship between symbols and sections (c.f. #841)
Fix and (re)enable removing dynamic symbols (c.f. #828)
Add support for NT_GNU_BUILD_ATTRIBUTE_OPEN and NT_GNU_BUILD_ATTRIBUTE_FUNC (c.f. #816)
[CVE-2022-38497] Fix ELF core parsing issue (#766 found by CCWANG19)
[CVE-2022-38306] Fix a heap overflow found by CCWANG19 (#763)
aeflores fixed an issue when there are multiple versions associated with a symbol (see: #749 for the details).
Handle binaries compiled with the -static-pie flag correctly (see: #747)
Add support for modifying section-less binaries. The ELF Section
objects gain the lief.ELF.Section.as_frame()
method which defines the section as a framed section.
A framed section is a section that concretely does not wraps data and can be corrupted.
elf = lief.parse("/bin/ssh")
text = elf.get_section(".text").as_frame()
# We can now corrupt all the fields of the section
text.offset = 0xdeadc0de
text.size = 0xffffff
text.address = 0x123
elf.write("/tmp/out")
Add API to precisely define how the segments table should be relocated. One might want to enforce a certain ELF layout while adding sections/ segments. It is now possible to call the method: relocate_phdr_table()
to define how the segments table should be relocated for welcoming the new sections/segments:
elf = lief.parse("...")
# Enforce a specific relocation type:
# The new segments table will be shift at the end
# of the file
elf.relocate_phdr_table(Binary.PHDR_RELOC.FILE_END)
# Add sections/segments
# [...]
elf.write("out.elf")
See:
Add support for parsing Mach-O in memory
[CVE-2022-38307] Fix a segfault when the Mach-O binary does not have segments (found by CCWANG19 via #764)
Enable to create exports
Fix the layout of the binaries modified by LIEF such as they can be (re)signed.
Add support for LC_DYLD_CHAINED_FIXUPS and LC_DYLD_EXPORTS_TRIE
Global enhancement when modifying the __LINKEDIT content
Add API to get a Section
from a specified segment’s name and section’s name.
sec = bin.get_section("__DATA", "__objc_metadata")
Add API to remove a Section
from a specified segment’s name and section’s name.
sec = bin.remove_section("__DATA", "__objc_metadata")
The Python API now returns bytes objects instead of List[int]
Remove lief.PE.ResourceNode.sort_by_id()
Fix the ordering of children of ResourceNode
Remove deprecated functions related to PE hooking.
Add support for new PE LoadConfiguration structures.
Fix multiple parsing issues raised by bladchan
Move to a build system compliant with pyproject.toml
Provide typing stubs: #650
PyPI releases no longer provide source distribution (sdist)
Move to spdlog 1.11.0
Move to Pybind11 - 2.10.1
Move to nlohmann/json 3.11.2
Move to MbedTLS 3.2.1
Move to utfcpp 3.2.1
This release contains several security fixes:
ahaensler added the support to insert and assign a lief.ELF.SymbolVersionAuxRequirement
(see: #670)
Enhance the ELF parser to support corner cases described by netspooky in :
https://tmpout.sh/2/14.html (84 byte aarch64 ELF)
https://tmpout.sh/2/3.html (Some ELF Parser Bugs)
New ELF Builder which is more efficient in terms of speed and in terms of number of segments added when modifying binaries (see: https://lief-project.github.io/blog/2022-01-23-new-elf-builder/)
Clcanny improved (see #507 and #509) the reconstruction of the dynamic symbol table by sorting local symbols and non-exported symbols. It fixes the following warning when parsing a modified binary with readelf
Warning: local symbol 29 found at index >= .dynsym's sh_info value of 1
Change the layout of the binaries generated by LIEF such as they are compliant with codesign
checks
The API to configure the MachO parser has been redesigned to provide a better granularity
config = lief.MachO.ParserConfig()
config.parse_dyld_bindings = False
config.parse_dyld_exports = True
config.parse_dyld_rebases = False
lief.MachO.parse("/tmp/big.macho", config)
LucaMoroSyn added the support for the LC_FILESET_ENTRY
. This command is usually found in kernel cache files
LIEF::MachO::Binary::get_symbol
now returns a pointer (instead of a reference). If the symbol can’t be found, it returns a nullptr.
Add API to select a Binary
from a FatBinary
by its architecture. See: lief.MachO.FatBinary.take()
.
fat = lief.MachO.parse("/bin/ls")
fit = fat.take(lief.MachO.CPU_TYPES.x86_64)
Handle the 0x0D binding opcode (see: #524)
xhochy fixed performances issues in the Mach-O parser (see #579)
Adding lief.PE.OptionalHeader.computed_checksum
that re-computes the lief.PE.OptionalHeader.checksum
(c.f. issue #660)
Enable to recompute the RichHeader
(issue: #587)
Add support for PE’s delayed imports. see:
lief.PE.LoadConfiguration.reserved1
has been aliased to lief.PE.LoadConfiguration.dependent_load_flags
lief.PE.LoadConfiguration.characteristics
has been aliased to lief.PE.LoadConfiguration.size
Thanks to gdesmar, we updated the PE checks to support PE files that have a corrupted lief.PE.OptionalHeader.magic
(cf. #644)
Abstract binary imagebase for PE, ELF and Mach-O (lief.Binary.imagebase
)
Add PE imports/exports as abstracted symbols
ekilmer updated and modernized the CMake integration files through the PR: #674
Enable to use a pre-compiled version of spdlog. This feature aims at improving compilation time when developing on LIEF.
One can provide path to spdlog install through:
$ python ./setup.py --spdlog-dir=path/to/lib/cmake/spdlog [...]
# or
$ cmake -DLIEF_EXTERNAL_SPDLOG=ON -Dspdlog_DIR=path/to/lib/cmake/spdlog ...
Enable to feed LIEF’s dependencies externally (c.f. Third Party)
Replace the keywords and
, or
, not
with &&
, ||
and !
.
Upgrade to MbedTLS 3.1.0
Upgrade Catch2 to 2.13.8
The different dependencies can be linked externally (cf. above and Third Party)
New section about the errors handling ( Error Handling) and the upcoming deprecation of the exceptions.
New section about how to compile LIEF for debugging/developing. See: Debugging
LIEF now exposes Section/Segment’s data through a span interface. As std::span is available in the STL from C++20 and the LIEF public API aims at being C++11 compliant, we expose this span thanks to tcbrindle/span. This new interface enables to avoid copies of std::vector<uint8_t>
which can be costly. With this new interface, the original std::vector<uint8_t>
can be retrieved as follows:
auto bin = LIEF::ELF::Parser::parse("/bin/ls");
if (const auto* section = bin->get_section(".text")) {
LIEF::span<const uint8_t> text_ref = section->content();
std::vector<uint8_t> copy = {std::begin(text_ref), std::end(text_ref)};
}
In Python, span are wrapped by a read-only memory view. The original list of bytes can be retrieved as follows:
bin = lief.parse("/bin/ls")
section = bin.get_section(".text")
if section is not None:
memory_view = section.content
list_of_bytes = list(memory_view)
Warning
We started to refactor the API and the internal design to remove C++ exceptions. These changes are described a the dedicated blog (LIEF RTTI & Exceptions)
To highlighting the content of the blog for the end users, functions that returned a reference and which threw an exception in the case of a failure are now returning a pointer that is set to nullptr in the case of a failure.
If we consider this original code:
LIEF::MachO::Binary& bin = ...;
try {
LIEF::MachO::UUIDCommand& cmd = bin.uuid();
std::cout << cmd << "\n";
} catch (const LIEF::not_found&) {
// ... dedicated processing
}
// Other option with has_uuid()
if (bin.has_uuid()) {
LIEF::MachO::UUIDCommand& cmd = bin.uuid();
std::cout << cmd << "\n";
}
It can now be written as:
LIEF::MachO::Binary& bin = ...;
if (LIEF::MachO::UUIDCommand* cmd = bin.uuid();) {
std::cout << *cmd << "\n";
} else {
// ... dedicated processing as it is a nullptr
}
// Other option with has_uuid()
if (bin.has_uuid()) { // It ensures that it is not a nullptr
LIEF::MachO::UUIDCommand& cmd = *bin.uuid();
std::cout << cmd << "\n";
}
Remove usage of not
in public headers (b8e825b)
Fix issue when computing lief.PE.Binary.sizeof_headers
(ab3f073)
Fix error on property lief.MachO.BuildVersion.sdk
(see #533)
Fix missing bound check when computing the authentihash
Add sanity check on the signature’s length that could lead to a std::bad_alloc
exception
Fix regression in the behavior of the PE section’s name. One can now access the full section’s name (with trailing bytes) through lief.PE.Section.fullname
(see: #551)
lief.PE.x509.is_trusted_by()
and lief.PE.x509.verify()
now return a better lief.PE.x509.VERIFICATION_FLAGS
instead of just lief.PE.x509.VERIFICATION_FLAGS.BADCERT_NOT_TRUSTED
(see: #532)
Fix errors in the computation of the Authentihash
aeflores added MIPS relocations support in the ELF parser
Fix issue when exporting symbols on empty-gnu-hash ELF binary (1381f9a)
Fix reconstruction issue when the binary is prelinked (cf. issue #466)
Add DF_1_PIE
flag
Fix parsing issue of the .eh_frame
section when the base address is not 0.
JanuszL enhanced the algorithm that computes the string table. It moves from a N^2
algorithm to a Nlog(N)
(1e0c4e8).
Fix .eh_frame
parsing issue (b57f323)
Add PT_GNU_PROPERTY
enum
Bug fix in the symbols table reconstruction (ELF)
Enhance PE Authenticode. See PE Authenticode
get_imphash()
can now generate the same value as pefile and Virus Total (#299)
pe = lief.parse("example.exe")
vt_imphash = lief.PE.get_imphash(pe, lief.PE.IMPHASH_MODE.PEFILE)
lief_imphash = lief.PE.get_imphash(pe, lief.PE.IMPHASH_MODE.DEFAULT)
See also
Remove the padding entry (0) from the rich header
items
now returns a dictionary for which the values are bytes (instead of str
object). This change is related to utf-16
support.
kohnakagawa fixed wrong enums values: c031250, 6ee808a, cd05f34
kohnakagawa fixed a bug in the PE resources parser (a7254d1)
Handle PE forwarded exports (issue #307)
Replace easyloggingpp
with spdlog 1.8.1
Upgrade frozen
to 1.0.0
Upgrade json
to 3.7.3
Upgrade pybind11
to 2.6.0
Upgrade mbedtls
to 2.16.6
aguinet updated the bin2lib tutorial with the support of the new glibc versions (7884e57)
Global update and enable to build the documentation out-of-tree
Changing the theme
Add Python 3.9 support
FindLIEF.cmake
deprecates LIEF_ROOT
. You should use LIEF_DIR
instead.
We changed the logging interface. The following log levels have been removed:
LOG_GLOBAL
LOG_FATAL
LOG_VERBOSE
LOG_UNKNOWN
We also moved from an class-interface based to functions.
Example:
lief.logging.disable()
lief.logging.enable()
lief.logging.set_level(lief.logging.LEVEL.INFO)
Note
The log functions now output on stderr
instead of stdout
Fix regression in parsing Python bytes
Add Python API to demangle strings: lief.demangle
Add build support for ELF notes
Add coredump support (9fc3a8a)
Enable to bind a relocation with a symbol (a9f3cb8)
relocation = "..."
symbol = lief.ELF.Symbol()
symbol.name = "printf123"
relocation.symbol = symbol
Add constructors (67d924a)
Expose ELF destructors (957384c)
Add remove_static_symbol
(c677970)
Add support for static relocation writing (d1b98d6)
Expose function to get strings located in the .rodata
section (02f4851)
Export ELF ABI version (8d7ec26)
Enhance Mach-O modifications by exposing an API to:
Add load commands
Add sections
Add segments
See: 406115c
Enable write()
on FAT Mach-O (1659531)
Introduce Mach-O Build Version command (6f96723)
Enable to remove Mach-O symbols (616d739)
Add support for adding LC_UNIXTHREAD
commands in a MachO (by nezetic - 64d2597)
Add partial support for Android 9 (bce9ebe)
Many thanks to the contributors: recvfrom, pbrunet, mackncheesiest, wisk, nezetic, lkollar, jbremer, DaLynX, 1orenz0, breadchris, 0xbf00, unratito, strazzere, aguinetqb, mingwandroid, serge-sans-paille-qb, yrp604, majin42, KOLANICH
LIEF 0.9 comes with new formats related to Android: OAT, DEX, VDEX and ART. It also fixes bugs and thanks to yd0b0N, ELF parser now supports big and little endian binaries. We also completed the JSON serialization of LIEF objects. Enable to configure the Mach-O parser for quick parsing: 880b99a Add Add Add Add Add Add API to show export-trie, rebase and binding opcodes: 5d56141 Add PE Code View: eab4a76 Parser now returns a Use frozen for some internal Features¶
lief.MachO.EncryptionInfo
command: f4e2d81lief.MachO.RPathCommand
command: 196994dlief.MachO.DataInCode
command: a16e1c4lief.MachO.SubFramework
command: 9e3b5b4lief.MachO.SegmentSplitInfo
command: 9e3b5b4lief.MachO.DyldEnvironment
command: 9e3b5b4API¶
lief.breakp()
and lief.shell()
lief.parse()
now support io
streams as inputstd::unique_ptr
instead of a raw pointer: cd1cc45Misc¶
std::map
(If C++14 is supported by the compiler)Acknowledgements¶
[Mach-O] Fix typo on comparison operator - abbc264
[ELF] Increase the upper limit of relocation number - 077bc32
LIEF 0.8.0 mainly improves the MachO parser and the ELF builder. It comes with Dockerfiles for CentOS and Android.
LibFuzzer has also been integrated in the project to enhance the parsers Add the Handle relocations of object files ( Global enhancement of the ELF builder: One can now add multiple One can now add multiple entries in the dynamic table: b2d3694 enables modification of the ELF interpreter without length restriction Enhancement of the dynamic symbols counting - 985d124 Enable editing ELF’s notes: See commit 3be9dd0 for more details Add Parse the Load Config Table into For details, see commit: 0234e3b The Binding opcodes Rebases opcodes Export trie Section relocations are now parsed into Fix enums conflicts(#32) - 66b4cd4 Fix most of the memory leaks: 88dafa8, d9b1436, 554fa15, 3602643 In the C++ API Add [Python API] Enhance the access to the abstract layer through the One can now do: Add Add: To check if a given flag is set, one can do: [Python] Segment flags: Enhancement for Enhancement for Add some operators 5666351 Add some operators: cbe8354 Add an API to configure the logger - 4600c2b Example: See: Add FindLIEF.cmake - 6dd8b10 Add ASAN, TSAN, USAN, LSAN - 7f6aeb0 Add LibFuzzer - 7a0dc28 recomposer, bearparser, IAT_patcher, PEframe, Manalyze, MachOView, elf-dissectorFeatures¶
Relocation
are now abstracted from the 3 formats - 9503f2fPIE
and NX
are abstracted through the is_pie
and has_nx
propertieslief.Section.search()
and lief.Section.search_all()
methods to look for patterns in the section’s content.DT_FLAGS
and DT_FLAGS_1
are now parsed into DynamicEntryFlags
- 754b8af.o
) - 483b8dcSection
or Segment
into an ELF:elf = lief.parse("/bin/cat")
for i in range(3):
segment = Segment()
segment.type = SEGMENT_TYPES.LOAD
segment.content = [i & 0xFF] * 0x1000
elf += segment
for i in range(3):
section = Section("lief_{:02d}".format(i))
section.content = [i & 0xFF] * 0x1000
elf += section
elf.write("foo")
$ readelf -l ./foo
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x00000000000061f8 0x00000000000061f8 R E 0x8
INTERP 0x0000000000006238 0x0000000000006238 0x0000000000006238
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x000000000000d6d4 0x000000000000d6d4 R E 0x200000
LOAD 0x000000000000da90 0x000000000020da90 0x000000000020da90
0x0000000000000630 0x00000000000007d0 RW 0x200000
LOAD 0x000000000000f000 0x000000000040f000 0x000000000040f000
0x0000000000001000 0x0000000000001000 0x1000
LOAD 0x0000000000010000 0x0000000000810000 0x0000000000810000
0x0000000000001000 0x0000000000001000 0x1000
LOAD 0x0000000000011000 0x0000000001011000 0x0000000001011000
0x0000000000001000 0x0000000000001000 0x1000
....
$ readelf -S ./foo
...
[27] lief_00 PROGBITS 0000000002012000 00012000
0000000000001000 0000000000000000 0 0 4096
[28] lief_01 PROGBITS 0000000004013000 00013000
0000000000001000 0000000000000000 0 0 4096
[29] lief_02 PROGBITS 0000000008014000 00014000
0000000000001000 0000000000000000 0 0 4096
elf = lief.parse("/bin/cat")
elf.add_library("libfoo.so")
elf.add(DynamicEntryRunPath("$ORIGIN"))
elf.add(DynamicEntry(DYNAMIC_TAGS.INIT, 123))
elf.add(DynamicSharedObject("libbar.so"))
elf.write("foo")
$ readelf -d foo
0x0000000000000001 (NEEDED) Shared library: [libfoo.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000c (INIT) 0x7b
0x000000000000000c (INIT) 0x3600
...
0x000000000000001d (RUNPATH) Bibliothèque runpath:[$ORIGIN]
0x000000000000000e (SONAME) Bibliothèque soname: [libbar.so]
elf = lief.parse("/bin/cat")
elf.interpreter = "/a/very/long/path/to/another/interpreter"
elf.write("foo")
$ readelf -l foo
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x00000000000011f8 0x00000000000011f8 R E 0x8
INTERP 0x000000000000a000 0x000000000040a000 0x000000000040a000
0x0000000000001000 0x0000000000001000 R 0x1
[Requesting program interpreter: /a/very/long/path/to/another/interpreter]
....
elf = lief.parse("/bin/ls")
build_id = elf[NOTE_TYPES.BUILD_ID]
build_id.description = [0xFF] * 20
elf.write("foo")
$ readelf -n foo
Displaying notes found in: .note.gnu.build-id
Owner Data size Description
GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
Build ID: ffffffffffffffffffffffffffffffffffffffff
get_imphash()
and resolve_ordinals()
functions - a89bc6d, dfa8e98LoadConfiguration
(up to Windows 10 SDK 15002 with hotpatch_table_offset)from lief import to_json
import json
pe = lief.parse("some.exe")
loadconfig = to_json(pe.load_configuration)) # Using the lief.to_json function
pprint(json.loads(to_json(loadconfig)))
{'characteristics': 248,
'code_integrity': {'catalog': 0,
'catalog_offset': 0,
'flags': 0,
'reserved': 0},
'critical_section_default_timeout': 0,
'csd_version': 0,
'editlist': 0,
...
'guard_cf_check_function_pointer': 5368782848,
'guard_cf_dispatch_function_pointer': 5368782864,
'guard_cf_function_count': 15,
'guard_cf_function_table': 5368778752,
'guard_flags': 66816,
'guard_long_jump_target_count': 0,
'guard_long_jump_target_table': 0,
'guard_rf_failure_routine': 5368713280,
'guard_rf_failure_routine_function_pointer': 5368782880,
...
dyld
structure is parsed (deeply) into DyldInfo
. It includes:lief.MachO.Section.relocations
- 29c8157LC_FUNCTION_STARTS
is parsed into FunctionStarts
(18d8919)LC_SOURCE_VERSION
, LC_VERSION_MIN_MACOSX
and LC_VERSION_MIN_IPHONEOS
are parsed into SourceVersion
and VersionMin
(c359778, 0b4bb7d, 5b99311, #45)LC_THREAD
and LC_UNIXTHREAD
are now parsed into ThreadCommand
- 2325783Fixes¶
API¶
get_XXX()
getters have been renamed into XXX()
(e.g. get_header()
becomes header()
) - a4c69f7, e805669lief.Binary
gains the format
property - 9391238lief.parse()
can now takes a list of integers - f330fa8has_symbol()
and get_symbol()
to lief.Binary
- f121af5abstract
attribute - 0713854elf = lief.ELF.parse("/bin/ls") # Could be lief.MachO / lief.PE
abstract = elf.abstract # Return the lief.Binary object
lief.ELF.Binary.symbols
which return an iterator over all symbols (static and dynamic) - af6ab65Header.sizeof_section_header
has been renamed into section_header_size
- d96971barm_flags_list
,mips_flags_list
ppc64_flags_list
hexagon_flags_list
>>> if lief.ELF.ARM_EFLAGS.EABI_VER5 in lief.ELF.Header "yes" else "no"
PF_X
, PF_W
, PF_X
has been renamed into X
, W
, X
- d70ef9eDynamicEntryRpath
and DynamicEntryRunPath
: c375a47DynamicEntryArray
: 81440celief.MachO.parse()
can now takes a list of integers - f330fa8lief.MachO.parse()
now returns a FatBinary
instead of a list
of Binary
. FatBinary
has a similar API as a list - 3602643from lief import Logger
Logger.disable()
Logger.enable()
Logger.set_level(lief.LEVEL.INFO)
lief.Logger
Build system¶
Documentation¶
Acknowledgements¶
lief.ELF.Segment.data
has been renamed to lief.ELF.Segment.content
lief.ELF.parse()
takes an optional parameters: symbol counting - lief.ELF.DYNSYM_COUNT_METHODS
lief.ELF.Relocation.size
lief.PE.Binary.hook_function()
lief.PE.Binary.get_content_from_virtual_address()
takes either an Absolute virtual address or a Relative virtual address
lief.PE.Binary.section_from_virtual_address
has been renamed to lief.PE.Binary.section_from_rva()
.
lief.PE.parse_from_raw
has been removed. One can use lief.PE.parse()
.
lief.PE.Section.data
has been removed. Please use lief.PE.Section.content
elfsteem, pelook, PortEx, elfsharp, metasm, amoco, Goblin
Don’t rely on lief.ELF.Section.entry_size
to count symbols - 004c676
Philippe for the proofreading.
First public release