LIEF v0.14.0

ionicons-v5-k Romain Thomas January 21, 2024

LIEF v0.14.0 is out, here is an overview of the main changes!

What’s new?

Python Bindings

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
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)
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
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,
 5  ...
 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,
14    ...
15  };

As of LIEF v0.14.0, the PE format is mostly impacted by this refactoring and the other formats should be progressively updated accordingly.

On Going Work

As a reminder, LIEF is exclusively developed on my spare time, so some functionalities might take time to be completed and integrated

Rust Bindings

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.

Final Word

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.

Romain Thomas Posted on January 21, 2024