This new version of LIEF introduces several improvements and features that
expand the scope of LIEF’s use cases.
Reverse Engineering Plugins
Reverse engineering frameworks like Binary Ninja and Ghidra provide excellent
support for analyzing instructions and functions. However, they might lack an
in-depth analysis of all structures associated with executable formats.
For example, the latest version of Ghidra (11.4.2) and Binary Ninja (5.1.8104)
are not able to accurately process Windows ARM64EC binaries, which combine ARM64 code
with x86_64. ARM64EC binaries use specific structures such as IMAGE_ARM64EC_METADATA, that
are not (yet) recognized by most of the reverse engineering frameworks:
This IMAGE_ARM64EC_METADATA structure contains the ExtraRFE attribute, which
is used to reference an exception table that is specific to the ARM64EC:
As for the x86_64 architecture, this table can be used to increase the coverage
of functions recognized by BinaryNinja:
The source code of these plugins is located in the main LIEF repository under
the following directories:
This new release of LIEF introduces official and maintained support for both
Binary Ninja and Ghidra, enhancing the analysis capabilities and type definitions
for these frameworks.
In this code snippet, we assume that the address of g_protections_conf is known.
With the latest release, the assembler engine has introduced support for dynamically
resolving symbols referenced in an assembly listing.
This functionality works by providing an additional configuration parameter:
The logic of the resolve_symbol function depends on DWARF information that is
generated by BinaryNinja (see: BinaryNinja - DWARF Plugin)
After patching, we can see the final results, which show that the adrp
instructions have been correctly generated to access the g_protections_conf.debug_check variable:
LIEF’s PE module has been significantly refactored, including improvements
to the parser, builder, and documentation. These improvements bring this format
to a level of maturity comparable to other formats (ELF/Mach-O).
The most notable enhancements involve the ability to modify TLS, as well as manage imports and exports.
It also provides support for ARM64EC and ARM64X binaries.
For this release, I started to bootstrap LIEF-based tools (mostly CLI) that aim to
provide specific functionalities using LIEF. The first tool of this bootstrap is
lief-patchelf, which provides a drop-in replacement for the well-known NixOS/patchelf.
The COFF format is now supported by LIEF, but it does not support modifications yet.
The API is really similar to the other formats and available in C++/Rust/Python:
1importlief 2coff: lief.COFF.Binary = lief.COFF.parse(r"C:\Users\romain\test.obj") 3 4# Access symbols and aux info 5for symbol in coff.symbols: 6print(symbol.name) 7for aux in symbol.auxiliary_symbols: 8assertstr(aux)=="""
9 AuxiliaryCLRToken {
10 Aux Type: 1
11 Reserved: 1
12 Symbol index: 10
13 Symbol: ??0CppInlineNamespaceAttribute@?A0xb81de522@vc.cppcli.attributes@@$$FQE$AAM@PE$[...]
14 Rgb reserved:
15 +---------------------------------------------------------------------+
16 | 00 00 00 00 00 00 00 00 00 00 00 00 | ............ |
17 +---------------------------------------------------------------------+
18 }
19 """2021# Disassembler support22for inst in coff.disassemble("?foo@@YAHHH@Z")23print(inst)
Version 0.17.0 is the latest release in the 0.X.Y series.
With significant improvements to the PE format and the global scale at which
LIEF is used, I believe the project is now ready for its upcoming 1.0 version.