Registry / serialization / lief
library1.0.0pypypi✓ verified 23d ago

LIEF (Library to Instrument Executable Formats) is a robust, cross-platform library designed to parse, modify, and abstract various executable formats, including ELF, PE, Mach-O, OAT, DEX, VDEX, and ART. It provides a comprehensive, user-friendly API for C++, Python, Rust, and C, enabling detailed analysis, manipulation, and reconstruction of binaries without relying on disassemblers. Currently at version 0.17.6, LIEF maintains an active development and release cadence, with frequent updates addressing new features and bug fixes.

pip install lief
INSTALL
IMPORT
SIG · LIEF
L
lief
serializationpythonv1.0.0
Install
1.8s avg
Import
887ms
Disk
28MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.0.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.996s · 30.6MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.8s · import 0.778s · 30MB
28MB installed
● package 28MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

lief
import lief
The primary import for accessing all LIEF functionalities.
lief.ELF
import lief elf_binary = lief.ELF.parse('/bin/ls')
Access specific format parsers directly for clarity or C++-like behavior.
lief.PE
import lief pe_binary = lief.PE.parse('C:\\Windows\\System32\\notepad.exe')
Access specific format parsers directly for clarity or C++-like behavior.

This quickstart demonstrates how to use `lief.parse()` to automatically detect and parse an executable file (ELF on Linux/macOS, PE on Windows). It then prints basic information about the binary, showcasing format-specific attributes like ELF machine type or number of PE imported libraries. Replace the default paths with your target binaries.

import lief import sys import os def analyze_binary(filepath): if not os.path.exists(filepath): print(f"Error: File not found at {filepath}") return binary = lief.parse(filepath) if binary is None: print(f"Could not parse {filepath} as an executable.") return print(f"\nAnalyzing: {filepath}") print(f" Format: {binary.format}") print(f" Entrypoint: {hex(binary.entrypoint)}") print(f" Number of sections: {len(binary.sections)}") # Example: Accessing ELF-specific features if binary.format == lief.Binary.FORMATS.ELF: elf_binary = binary.as_elf() if elf_binary and elf_binary.header: print(f" ELF Machine Type: {elf_binary.header.machine_type}") if elf_binary.dynamic_entries: print(f" Number of dynamic entries: {len(elf_binary.dynamic_entries)}") # Example: Accessing PE-specific features elif binary.format == lief.Binary.FORMATS.PE: pe_binary = binary.as_pe() if pe_binary and pe_binary.header: print(f" PE Machine Type: {pe_binary.header.machine_type}") if pe_binary.imports: print(f" Number of imported libraries: {len(pe_binary.imports)}") # Try to analyze common executables based on OS if sys.platform.startswith('linux'): analyze_binary('/bin/ls') elif sys.platform == 'win32': analyze_binary('C:\\Windows\\System32\\notepad.exe') elif sys.platform == 'darwin': analyze_binary('/bin/ls') # macOS also uses ELF/MachO, /bin/ls is a good example else: print("Unsupported OS for quickstart example.")
lief --version
Debug
Known issues
breakingLIEF v0.17.0 introduced a significant refactoring of the PE parser and builder API to align with ELF and Mach-O functionalities. Codebases processing PE binaries may require updates.
fix
Review the 'PE Changelog for LIEF 0.17.0' documentation for specific API changes and migration guidance. Functions returning references that previously threw exceptions now return pointers (or Python `None`) on failure.
affects: >=0.17.0
gotchaWhen parsing PE files (especially from v0.17.0 onwards), certain in-depth metadata (e.g., ARM64X binaries, exceptions, exports, imports, relocations, resources, signatures) might not be parsed by default. These options must be explicitly enabled.
fix
Use `lief.PE.ParserConfig` to enable desired parsing options. For example, `config = lief.PE.ParserConfig(); config.parse_exports = True; binary = lief.PE.parse('path/to/pe.exe', config)`. Review `lief.PE.ParserConfig` for available flags.
affects: >=0.17.0
breakingThe `create_pe_from_scratch` feature (for building PE files from zero) was deprecated and removed in LIEF 0.17.0 due to significant bugs that often led to corrupted binaries.
fix
Avoid using the `create_pe_from_scratch` functionality. Focus on modifying existing binaries, which has seen improvements in the builder engine.
affects: >=0.17.0
gotchaPrior to version 0.17.0, modifying PE files using the Python API was highly bugged and often resulted in unexpected file size increases or corrupted binaries, especially when modifying sections like `.rsrc`.
fix
Upgrade to LIEF 0.17.0 or newer, as the builder engine for PE files has been refactored to address these limitations and provide a more conservative approach to modifications.
affects: <0.17.0
deprecatedLIEF v0.14.0 moved from Pybind11 to nanobind for its Python bindings. While this improved performance and compilation, internal changes for `setuptools` (replaced by `scikit-build-core`) could affect custom build processes.
fix
Projects that compile LIEF from source or have custom build setups should review their build configurations, especially regarding `setuptools` and `scikit-build-core` as mentioned in the v0.14.0 changelog.
affects: >=0.14.0
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'lief'
This error typically occurs when the 'lief' package is not correctly installed in the Python environment, or the Python interpreter cannot find it in its path.
fix
Ensure LIEF is properly installed by running `pip install lief`. If using a specific Python version or virtual environment, activate it first. For installation issues like 'couldn't build wheel for lief', consider installing from a specific URL for nightly builds or tagged releases if PyPI wheels are not available for your platform or Python version.
AttributeError: module 'lief' has no attribute 'EXE_FORMATS'
This `AttributeError` is due to a breaking API change in LIEF (around version 0.14.0 and later), where `EXE_FORMATS` was moved from the top-level `lief` module to `lief.Binary.FORMATS` or specific format modules (e.g., `lief.ELF.FORMATS`, `lief.PE.FORMATS`).
fix
Update your code to use `lief.Binary.FORMATS.ELF`, `lief.Binary.FORMATS.PE`, or the specific format's `FORMATS` attribute (e.g., `lief.ELF.FORMATS.ELF`) instead of `lief.EXE_FORMATS`. Alternatively, for `lief.PE.get_type`, the result is now a `lief.PE.PE_TYPE` enum.
AttributeError: 'lief.PE.Binary' object has no attribute 'has_signature'
This error indicates that the `has_signature` attribute, previously available on `lief.PE.Binary` objects, has been renamed or removed in a newer version of LIEF (e.g., changed to `has_signatures`).
fix
Replace `binary.has_signature` with `binary.has_signatures` in your code to reflect the API update.
AttributeError: module 'lief._lief.ELF' has no attribute 'DYNAMIC_TAGS'
This error typically arises from API changes in LIEF, where the location or naming of `DYNAMIC_TAGS` within the `lief.ELF` module has changed in newer versions (e.g., in `lief` 0.15.x and later).
fix
Consult the LIEF documentation for your installed version to find the correct path for `DYNAMIC_TAGS` within the `lief.ELF` module. It might be directly under `lief.ELF.DYNAMIC_TAGS` or a similar path. Consider pinning your `lief` version if compatibility is critical.
Segfault when calling `list(lief.parse('/bin/ls').sections)`
This bug (reported in older LIEF versions, e.g., before 0.13.0) occurs because the temporary `Binary` object returned by `lief.parse()` is prematurely freed, leading to a dangling pointer when its properties (like `sections`) are accessed.
fix
Store the result of `lief.parse()` in a variable before accessing its attributes, like `p = lief.parse('/bin/ls'); list(p.sections)`. This ensures the `Binary` object's lifetime is managed correctly.
Upgrade
Version history
1.0.0latest on PyPI · released Jul 12, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
5 hits · last 30 days
node
4
Resources
lief — pip install lief · libregistry