import lief
# Using filepath
pe: lief.PE.Binary = lief.PE.parse(r"C:\Users\test.exe")
# Using a Path from pathlib
pe: lief.PE.Binary = lief.PE.parse(pathlib.Path(r"C:\Users\test.exe"))
# Using an io object
with open(r"C:\Users\test.exe", 'rb') as f:
pe: lief.PE.Binary = lief.PE.parse(f)
#include <LIEF/PE.hpp>
// Using a file path as a std::string
std::unique_ptr<LIEF::PE::Binary> pe = LIEF::PE::Parser::parse("some.exe");
// Using a vector
std::vector<uint8_t> my_raw_pe;
std::unique_ptr<LIEF::PE::Binary> pe = LIEF::PE::Parser::parse(my_raw_pe);
let pe: lief::pe::Binary = lief::pe::Binary::parse("/bin/ls");
Note
In Python, you can also use lief.parse()
which returns a lief.PE.Binary
object.
pe: lief.PE.Binary = ...
print(pe.rich_header)
print(pe.authentihash_md5.hex(':'))
for section in pe.sections:
print(section.name, len(section.content))
std::unique_ptr<LIEF::PE::Binary> pe;
if (const LIEF::PE::RichHeader* rich = pe->rich_header()) {
std::cout << *rich << '\n';
}
for (const LIEF::PE::Section& section : pe->sections()) {
std::cout << section.name() << section.content().size() << '\n'
}
let pe: lief::pe::Binary;
println!("{:?}", pe.rich_header().expect("Missing Rich header"));
for section in pe.sections() {
println!("{} {}", section.name(), section.content().len());
}
pe: lief.PE.Binary = ...
section = lief.PE.Section(".hello")
section.content = [0xCC] * 0x100
pe.add_section(section)
pe.write("new.exe")
std::unique_ptr<LIEF::PE::Binary> pe;
LIEF::PE::Section section(".hello");
section.content = std::vector<uint8_t>(0x100, 0xCC);
pe->add_section(section);
pe->write("new.exe");
See also
Warning
parser_config = lief.PE.ParserConfig()
parser_config.parse_signature = False
pe: lief.PE.Binary = lief.PE.parse("some.exe", parser_config)
builder = lief.PE.Builder(pe)
builder.build_imports(False)
builder.patch_imports(False)
builder.build()
builder.write("new.exe")
LIEF::PE::ParserConfig parser_config;
parser_config.parse_signature = false;
auto pe = LIEF::PE::Parser::parse("some.exe", parser_config);
LIEF::PE::Builder builder(*pe);
builder.build_imports(false);
builder.patch_imports(false);
builder.build();
builder.write("new.exe");
For more the details about the PDB support, please check the PDB section.
LIEF supports PE authenticode by providing API to inspect and verify the signature of PE executables.
Note
import
pe = lief.PE.parse("signed.exe")
for signature in pe.signatures:
for crt in signature.certificates:
print(crt)
assert pe.verify_signature() == lief.PE.Signature.VERIFICATION_FLAGS.OK
auto pe = LIEF::PE::Parser::parse("signed.exe");
for (const LIEF::PE::Signature& sig : pe->signatures()) {
for (const LIEF::PE::X509& crt : sig.certificates()) {
std::cout << crt << '\n';
}
}
std::cout << pe->verify_signature() == LIEF::PE::Signature::VERIFICATION_FLAGS::OK;
if let Some(lief::Binary::PE(pe)) = lief::Binary::parse("signed.exe") {
for sig in pe.signatures() {
for crt in sig.certificates() {
println("{:?}", crt);
}
}
assert!(
pe.verify_signature(pe::signature::VerificationChecks::DEFAULT) ==
lief::pe::signature::VerificationFlags::OK
);
}
You can find additional details about the authenticode support in this tutorial: PE Authenticode