The rust bindings for LIEF are getting more and more production-ready for the next
official release of LIEF (v0.15.0
). This blog post exposes the recent updates on
these bindings and some use cases.
The Rust documentation for the current bindings is now almost complete such as most of the functions and structures are documented:
One can access the nightly doc at this address: https://lief-rs.s3.fr-par.scw.cloud/doc/latest/lief/index.html
As mentioned in the previous blog post,
the Rust bindings work with a “pre-compilation” step. Since the previous blog post,
I added the support of iOS (i.e. aarch64-apple-ios
) and for Linux ARM64 (i.e. aarch64-unknown-linux-gnu
)
which gives us this support in LIEF compared to the Rust Platform Support
Triplet | Support | Comment |
---|---|---|
aarch64-unknown-linux-gnu | ✅ | |
i686-pc-windows-gnu | ❌ | |
i686-pc-windows-msvc | 🤷 | Could be supported if needed |
i686-unknown-linux-gnu | 🤷 | Could be supported if needed |
x86_64-apple-darwin | ✅ | |
x86_64-pc-windows-gnu | ❌ | |
x86_64-pc-windows-msvc | ✅ | |
x86_64-unknown-linux-gnu | ✅ |
Triplet | Support | Comment |
---|---|---|
aarch64-apple-ios | ✅ | |
aarch64-apple-ios-sim | 🤷 | Could be supported if needed |
aarch64-linux-android | ⏱️ | Planned |
aarch64-apple-darwin | ✅ | |
x86_64-unknown-linux-musl | ⏱️ | Planned |
The support for some triplets like i686-pc-windows-msvc
will be done on an as-needed
basis so feel free to reach out or to open an issue/discussion on GitHub if you need this
support.
1// This code checks the PE Authenticode
2
3let path = std::env::args().last().unwrap();
4let mut file = std::fs::File::open(path).expect("Can't open the file");
5
6if let Some(lief::Binary::PE(pe)) = lief::Binary::from(&mut file) {
7 let result = pe.verify_signature(pe::signature::VerificationChecks::DEFAULT);
8 if result.is_ok() {
9 println!("Valid signature!");
10 } else {
11 println!("Signature not valid: {}", result);
12 }
13 return ExitCode::SUCCESS;
14}
15ExitCode::FAILURE
1// This code list all the libraries needed by an ELF binary as well as
2// the versioning of the symbols.
3// Example of output:
4// Dependencies:
5// - libclang-cpp.so.17
6// - libLLVM-17.so
7// - libstdc++.so.6
8// - libc.so.6
9// Versions:
10// From libc.so.6
11// - GLIBC_ABI_DT_RELR
12// - GLIBC_2.14
13// - GLIBC_2.34
14// - GLIBC_2.32
15// From libstdc++.so.6
16// - GLIBCXX_3.4.29
17// - GLIBCXX_3.4.30
18// From libLLVM-17.so
19// - LLVM_17
20
21let mut args = std::env::args();
22if args.len() != 2 {
23 println!("Usage: {} <binary>", args.next().unwrap());
24 return ExitCode::FAILURE;
25}
26
27let path = std::env::args().last().unwrap();
28let mut file = std::fs::File::open(&path).expect("Can't open the file");
29if let Some(lief::Binary::ELF(elf)) = lief::Binary::from(&mut file) {
30 println!("Dependencies:");
31 for entry in elf.dynamic_entries() {
32 if let dynamic::Entries::Library(lib) = entry {
33 println!(" - {}", lib.name());
34 }
35 }
36 println!("Versions:");
37 for version in elf.symbols_version_requirement() {
38 println!(" From {}", version.name());
39 for aux in version.auxiliary_symbols() {
40 println!(" - {}", aux.name());
41 }
42 }
43
44 return ExitCode::SUCCESS;
45}
46println!("Can't process {}", path);
47ExitCode::FAILURE
1// Inspecting the PE rich header
2
3let path = std::env::args().last().unwrap();
4let mut file = std::fs::File::open(&path).expect("Can't open the file");
5
6if let Some(lief::Binary::PE(pe)) = lief::Binary::from(&mut file) {
7 let rich_header = pe.rich_header().unwrap_or_else(|| {
8 println!("Rich header not found!");
9 process::exit(0);
10 });
11
12 println!("Rich header key: 0x{:x}", rich_header.key());
13 for entry in rich_header.entries() {
14 println!("id: 0x{:04x} build_id: 0x{:04x} count: #{}",
15 entry.id(), entry.build_id(), entry.count());
16 }
17
18 return ExitCode::SUCCESS;
19}
20println!("Can't process {}", path);
21ExitCode::FAILURE
1// Dumping which section of an iOS app is encrypted
2
3let path = std::env::args().last().unwrap();
4let mut file = std::fs::File::open(&path).expect("Can't open the file");
5
6if let Some(lief::Binary::MachO(fat)) = lief::Binary::from(&mut file) {
7 for macho in fat.iter() {
8 for cmd in macho.commands() {
9 if let lief::macho::Commands::EncryptionInfo(info) = cmd {
10 println!("Encrypted area: 0x{:08x} - 0x{:08x} (id: {})",
11 info.crypt_offset(), info.crypt_offset() + info.crypt_size(),
12 info.crypt_id()
13 )
14 }
15 }
16 }
17 return ExitCode::SUCCESS;
18}