Add enum for the latest dyld shared cache version introducing
changes in the header layout (dyld-1231.3 - 2024-09-24
)
uint64_t dynamicDataOffset;
uint64_t dynamicDataMaxSize;
+ uint32_t tproMappingsOffset;
+ uint32_t tproMappingsCount;
};
Fix symbol resolution issue: #1127
Please check LIEF 0.17.0 - PE changelog
LC_ATOM_INFO
)Fix issue when parsing the dynamic table with an invalid offset (bug found by lebr0nli)
Enhance support for IA64 architecture.
Introduce lief.ELF.Segment.raw_flags
to access the raw (integer)
value of the flag
LIEF extended can now process DWARF debug info in PE binaries
S_COMPILE3, S_COMPILE2, S_BUILDINFO, S_ENVBLOCK
.
These symbols are exposed through the interface ,
which can be accessed using .
This metadata provides build time information such as:Module Name : * Linker *
Build Metadata:
Frontend Version: 0.0.0.0
Backend Version : 14.37.32825.0
Tool Version : Microsoft (R) LINK
Language : LINK
Target : X64
Environment:
cwd: C:\Users\romai\dev\rust\ast-grep
exe: C:\Program Files\Microsoft Visual Studio\2022\Community\[...]
pdb: C:\Users\romai\dev\rust\ast-grep\target\debug\deps\ast_grep.pdb
cmd: /NOLOGO /LIBPATH:C:\Users\romai\dev\rust\ast-grep\target\[...]
Module Name : std-4ee9ee8805e6ac55.std.ddad90bab7781587-cgu.0.rcgu.o
Object : C:\Users\romai\scoop\persist\rustup\.rustup\toolchains\[...]
Build Metadata:
Frontend Version: 1.74.0.0
Backend Version : 17004.0.0.0
Tool Version : clang LLVM (rustc version 1.74.0 (79e9716c9 2023-11-13))
Language : RUST
Target : X64
Build Info:
Current directory: /rustc/79e9716c980570bfd1f666e3b16ac583f0168962
Build tool : C:\a\rust\rust\build\x86_64-pc-windows-msvc\stage1\bin\rustc.exe
Source file : library\std\src\lib.rs\@\std.ddad90bab7781587-cgu.0
Command line : "-cc1" "--crate-name" "std" "--edition=2021" [...]
Fix issue in the Python bindings while trying to access lief.__LIEF_MAIN_COMMIT__
Fix export forwarding issue (#1168)
Fix truncated nlist_t.n_type
when rewriting a Mach-O binary
Fix broken aarch64
Python wheel which is related to a toolchain issue
(#1146)
Various fixes from DzenIsRich & peledins-zimperium Thanks to them, Mach-O modification is more reliable.
Fix issue when building with -DLIEF_MACHO=ON
(see: #1138)
Fix min-rustc version issue (see: 75a27f0)
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
Fix issue when multiple empty strings are present in the .symtab
section
(#1124)
Add support for eBPF relocations.
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)
Mutable API are progressively introduced:
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;
Add DW_TAG_typedef
support
Note
LIEF extended is now open to everyone
C++ SDK is now available
Rust package is now available
Initial assembler support: Assembler
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 nanobind from 1.8.0
to 2.4.0
*.pyi
stubs are now generated by nanobind (replacing mypy’s stugen)
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
lief.PE.LangCodeItem.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 lief.MachO.EncryptionInfo
command: f4e2d81
Add lief.MachO.RPathCommand
command: 196994d
Add lief.MachO.DataInCode
command: a16e1c4
Add lief.MachO.SubFramework
command: 9e3b5b4
Add lief.MachO.SegmentSplitInfo
command: 9e3b5b4
Add lief.MachO.DyldEnvironment
command: 9e3b5b4
API to show export-trie, rebase and binding opcodes: 5d56141
Add PE Code View: eab4a76
lief.breakp()
andlief.shell()
lief.parse()
now supportio
streams as inputParser now returns a
std::unique_ptr
instead of a raw pointer: cd1cc45
Use frozen for some internal std::map
(If C++14 is supported by the compiler)
[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
Relocation
are now abstracted from the 3 formats - 9503f2f
PIE
and NX
are abstracted through the is_pie
and has_nx
properties
Add the lief.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
Handle relocations of object files (.o
) - 483b8dc
Global enhancement of the ELF builder:
One can now add multiple Section
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
One can now add multiple entries in the dynamic table:
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]
b2d3694 enables modification of the ELF interpreter without length restriction
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]
....
Enhancement of the dynamic symbols counting - 985d124
Enable editing ELF’s notes:
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
See commit 3be9dd0 for more details
Add get_imphash()
and resolve_ordinals()
functions - a89bc6d, dfa8e98
Parse the Load Config Table into LoadConfiguration
(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,
...
For details, see commit: 0234e3b
The dyld
structure is parsed (deeply) into DyldInfo
. It includes:
Binding opcodes
Rebases opcodes
Export trie
Section relocations are now parsed into lief.MachO.Section.relocations
- 29c8157
LC_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
- 2325783
Fix enums conflicts(#32) - 66b4cd4
Fix most of the memory leaks: 88dafa8, d9b1436, 554fa15, 3602643
In the C++ API get_XXX()
getters have been renamed into XXX()
(e.g. get_header()
becomes header()
) - a4c69f7, e805669
lief.Binary
gains the format
property - 9391238
lief.parse()
can now takes a list of integers - f330fa8
Add has_symbol()
and get_symbol()
to lief.Binary
- f121af5
[Python API] Enhance the access to the abstract layer through the abstract
attribute - 0713854
One can now do:
elf = lief.ELF.parse("/bin/ls") # Could be lief.MachO / lief.PE
abstract = elf.abstract # Return the lief.Binary object
Add lief.ELF.Binary.symbols
which return an iterator over all symbols (static and dynamic) - af6ab65
Header.sizeof_section_header
has been renamed into section_header_size
- d96971b
Add:
arm_flags_list
,
mips_flags_list
ppc64_flags_list
hexagon_flags_list
To check if a given flag is set, one can do:
>>> if lief.ELF.ARM_EFLAGS.EABI_VER5 in lief.ELF.Header "yes" else "no"
[Python] Segment flags: PF_X
, PF_W
, PF_X
has been renamed into X
, W
, X
- d70ef9e
Enhancement for DynamicEntryRpath
and DynamicEntryRunPath
: c375a47
Enhancement for DynamicEntryArray
: 81440ce
Add some operators 5666351
lief.MachO.parse()
can now takes a list of integers - f330fa8
lief.MachO.parse()
now returns a FatBinary
instead of a list
of Binary
. FatBinary
has a similar API as a list - 3602643
Add some operators: cbe8354
Add an API to configure the logger - 4600c2b
Example:
from lief import Logger
Logger.disable()
Logger.enable()
Logger.set_level(lief.LEVEL.INFO)
See: lief.Logger
Add FindLIEF.cmake - 6dd8b10
Add ASAN, TSAN, USAN, LSAN - 7f6aeb0
Add LibFuzzer - 7a0dc28
recomposer, bearparser, IAT_patcher, PEframe, Manalyze, MachOView, elf-dissector
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.Symbol.has_section
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
lief.PE.Builder.build_dos_stub
lief.PE.Builder.build_overlay
lief.PE.LangCodeItem
lief.PE.ResourceDialogItem
lief.PE.ResourceFixedFileInfo
lief.PE.ResourceStringFileInfo
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