The purpose of this project is to provide a cross-platform library to parse, modify, and abstract ELF, PE, and Mach-O formats.
From a technical standpoint, the library is written in C++ with a C++11 public interface and exposes bindings for Python and Rust.
Hence, you can use LIEF with an idiomatic API in these languages:
import lief
elf: lief.ELF.Binary = lief.ELF.parse("libc.so")
for symbol in elf.symbols:
print(symbol.address, symbol.name)
print(elf.header)
for entry in elf.dynamic_entries:
if isinstance(entry, lief.ELF.DynamicEntryLibrary):
entry.name = "libhello.so"
elf.write("modified.elf")
#include <LIEF/LIEF.hpp>
std::unique_ptr<LIEF::MachO::FatBinary> fat =
LIEF::MachO::Parser::parse("libobjc.dylib");
for (const LIEF::MachO::Binary& macho : fat) {
for (const LIEF::MachO::BindingInfo& binding : macho.bindings()) {
std::cout << binding.address() << ' ' << bindings.symbol()->name() << '\n';
}
if (macho.is_ios()) {
if (const LIEF::MachO::EncryptionInfo* info = macho.encryption_info())
{
std::cout << info->crypt_id() << '\n';
}
}
}
let mut file = std::fs::File::open(path).expect("Can't open the file");
if let Some(lief::Binary::PE(pe)) = lief::Binary::from(&mut file) {
let rich_header = pe.rich_header().unwrap_or_else(|| {
println!("Rich header not found!");
process::exit(0);
});
println!("Rich header key: 0x{:x}", rich_header.key());
for entry in rich_header.entries() {
println!("id: 0x{:04x} build_id: 0x{:04x} count: #{}",
entry.id(), entry.build_id(), entry.count());
}
let result = pe.verify_signature(pe::signature::VerificationChecks::DEFAULT);
if result.is_ok() {
println!("Valid signature!");
} else {
println!("Signature not valid: {}", result);
}
}
This project is also attached to provide comprehensive documentation as well as development best practices:
A regular test suite associated with test coverage and non-regression testing
Address sanitizer checks (ASAN)
CI for testing and releasing packages
Dockerization of the different CI steps
A comprehensive changelog
Nightly builds
To get started with LIEF functionalities, you can check the documentation of one of these formats: ELF, PE, or Mach-O and to start integrating LIEF in your project it should be pretty straightforward:
With pip
$ pip install lief
Using a requirement.txt file
lief==0.16.0
Compiler command line
$ clang++ -lLIEF -I<LIEF_INSTALL>/include/ ...
CMake
find_package(LIEF)
target_link_libraries(my-project LIEF::LIEF)
Nightly version
# For nightly build
[dependencies]
lief = { git = "https://github.com/lief-project/LIEF", branch = "main" }
Released version
# For a tagged release
[dependencies]
lief = "0.16.0"
You can also find additional content in the LIEF’s blog post among those:
As well as in the examples/ directory For those who seek for enhanced support for PDB, DWARF or Objective-C (and more), you can check the extended section. Rust documentation: Extended Version¶
Additional Documentation¶