Rust bindings for UEFITool with additional parsers for AMI PFAT and Dell PFS formats.
Parse UEFI firmware images to extract modules, NVRAM variables, microcode updates, buf sections, and Secure Boot signature databases.
The UEFITool sources are compiled automatically via build.rs.
git clone [email protected]:binarly-io/bias-loader-uefi.git
git submodule update --init
cargo build --releaseuse bias_loader_uefi::Uefi;
let bytes = std::fs::read("firmware.bin")?;
let fw = Uefi::new(&bytes)?;
// iterate over all modules
fw.for_each(|module| {
println!("{} [{}] {:?}", module.name(), module.guid(), module.module_type());
});
// count extracted components
println!("modules: {}", fw.count_modules());
println!("nvram vars: {}", fw.count_vars());
println!("microcode: {}", fw.count_microcode());fw.for_each_var(|var| {
println!("{} type={:?} valid={}", var.name(), var.var_type(), var.is_valid());
});fw.for_each_microcode(|mc| {
println!("{:?} date={} cpuid={:#x} rev={}", mc.vendor(), mc.date(), mc.cpu_signature(), mc.update_revision());
});use bias_loader_uefi::ContinueOrStop;
fw.for_each_until(|module| {
if module.guid() == "A2DF5376-C2ED-49C0-90FF-8B173B0FD066" {
// found it, stop iterating
return ContinueOrStop::Stop;
}
ContinueOrStop::Continue
});use bias_loader_uefi::depex::DepExOpcode;
use uuid::Uuid;
fw.for_each(|module| {
if !module.depex().is_empty() {
println!("{}:", module.name());
for op in module.depex() {
match op {
DepExOpcode::Push(guid) => println!(" Push({})", Uuid::from_bytes_le(*guid)),
DepExOpcode::Before(guid) => println!(" Before({})", Uuid::from_bytes_le(*guid)),
DepExOpcode::After(guid) => println!(" After({})", Uuid::from_bytes_le(*guid)),
other => println!(" {other:?}"),
}
}
}
});Auto-detect and unpack proprietary firmware containers before parsing:
use bias_loader_uefi::{try_unpack, Uefi};
let buf = std::fs::read("image.cap")?;
let unpacked = try_unpack(&buf)?;
let fw = Uefi::new(&unpacked)?;For firmware images containing multiple UEFI images (common with Dell PFS):
use bias_loader_uefi::UefiMulti;
let buf = std::fs::read("image.cap")?;
let multi = UefiMulti::new(&buf)?;
for (uefi, image) in multi.iter_full() {
println!("image: {} ({} modules)", image.name(), uefi.count_modules());
}use bias_loader_uefi::parsers::Hint;
match Hint::parse(&bytes) {
Hint::Pfat => println!("AMI PFAT"),
Hint::Pfs => println!("Dell PFS"),
Hint::Unknown => println!("Unknown"),
}use bias_loader_uefi::secureboot::extract_sb_signatures_from_nvram;
fw.for_each_var(|var| {
let sigs = extract_sb_signatures_from_nvram(var.name(), var.data());
for sig in sigs {
println!("{:?} owner={} type={}", sig.database_type, sig.signature_owner, sig.signature_type);
}
});Special thanks to:
- @NikolajSchlej and all UEFITool contributors for UEFITool
- @platomav for BIOSUtilities