LIEF v0.14.0 is out, here is an overview of the main changes!
LIEF v0.14.0 comes with some internal enhancements for the bindings.
First, LIEF now uses nanobind instead of Pybind11. This change is motivated
by the fact that nanobind
reduces the compilation time while also improving
the overall performances of the bindings1.
The typing stubs (.pyi
) are almost complete. This means that almost all the
functions and classes have accurate typing information that is not object
or Any
.
Finally, setuptools
has been replaced by scikit-build-core
as it provides a cleaner API to generate native wheels.
LIEF’s ELF module now supports the GNU properties notes and exposes a friendly API to access the underlying properties information. For instance, one can check if AArch64’s PAC is used by an ELF binary using the following API:
1import lief
2
3elf = lief.ELF.parse("aarch64-binary.elf")
4prop: lief.ELF.NoteGnuProperty = elf.get(lief.ELF.Note.TYPE.GNU_PROPERTY_TYPE_0)
5aarch64_feat: lief.ELF.AArch64Feature = prop.find(lief.ELF.NoteGnuProperty.Property.TYPE.AARCH64_FEATURES)
6
7if lief.ELF.AArch64Feature.FEATURE.PAC in aarch64_feat.features:
8 print("PAC is supported!")
In addition, the ELF parser can be tweaked to disable parsing some specific parts of an ELF file. For instance, one can skip parsing the relocations as follows:
1import lief
2config = lief.ELF.ParserConfig()
3config.parse_relocations = False
4
5# ELF object without relocations information
6elf = lief.ELF.parse("some-binary.elf", config)
As of now, one of the major design issues in LIEF is the enum API. Indeed, when I started to develop LIEF, I wanted to have class and enum names as close to their names mentioned in official documentation.
But it turned out that those names are – sometimes – already #define
in system headers. It means
that if we #include
a header that already defines one of these names, we have a compilation error:
1#include <um/winnt.h> // #define IMAGE_FILE_MACHINE_AM33 0x01d3
2#include <LIEF/PE/enums.hpp> // /!\ Compilation error on IMAGE_FILE_MACHINE_AM33
The current (hacky) workaround for this issue is a undef.h
file which #undef
the names that create conflict between system definition and LIEF (c.f. LIEF/PE/undef.h
).
Yes, it’s a hack and the current ongoing work to address this issue is a complete refactoring of the enums API which starts with a re-scoping. Currently, all the enums are defined in a single header file and some of them are used by only one class.
For instance, the enum LIEF::PE::SIG_ATTRIBUTE_TYPES
,
has been re-scoped in the LIEF::PE::Attribute
:
1// Before (v0.13.x): LIEF/PE/enums.hpp
2enum class SIG_ATTRIBUTE_TYPES {
3 UNKNOWN = 0,
4 CONTENT_TYPE,
5 ...
6};
7
8// Now (v0.14.0): LIEF/PE/signature/Attribute.hpp
9class LIEF_API Attribute : public Object {
10 public:
11 enum class TYPE {
12 UNKNOWN = 0,
13 CONTENT_TYPE,
14 ...
15 };
16}
As of LIEF v0.14.0
, the PE format is mostly impacted by this refactoring and
the other formats should be progressively updated accordingly.
As a reminder, LIEF is exclusively developed on my spare time, so some functionalities might take time to be completed and integrated
This is still ongoing and the bindings are almost completed for ELF, PE, and Mach-O.
I still need to create the bindings for the enums and figure out a way to reduce the compilation time but it keeps moving!
LIEF will welcome DWARF and PDB debug information support through an external extension. This module will provide a comprehensive API to iterate over DWARF & PDB information.
Compared to LIEF 0.13.2, this new version introduces 274 new commits, with 35 292 additions and 39 392 deletions thanks to 15 contributors!
The complete changelog is available here: lief-project.github.io/changelog.html#january-20-2024
Thank you also to F., antipatico, and MobSF for their sponsoring.