Modifications
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 the generic 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");
let mut pe = lief::pe::Binary::parse("some.exe").unwrap();
let mut section = lief::pe::Section::new_with_name(".hello");
section.set_content(&[0xCC; 0x100]);
pe.add_section(section);
pe.write("new.exe");
See also
Modifications
Warning
parser_config = lief.PE.ParserConfig()
parser_config.parse_signature = False
pe: lief.PE.Binary = lief.PE.parse("some.exe", parser_config)
builder_config = lief.PE.Builder.config_t()
builder_config.imports = True
pe.write("new.exe", builder_config)
LIEF::PE::ParserConfig parser_config;
parser_config.parse_signature = false;
auto pe = LIEF::PE::Parser::parse("some.exe", parser_config);
LIEF::PE::Builder::config_t builder_config;
builder_config.imports = true;
pe->write("new.exe", builder_config);
let mut pe = ...;
let config = lief::pe::builder::Config::default();
pe.write_with_config("new.exe", config);
Note
pe: lief.PE.Binary = ...
new_pe: bytes = pe.write_to_bytes()
std::unique_ptr<LIEF::PE::Binary> pe;
std::ostringstream os;
pe->write(os);
std::string buffer = os.str();
const auto* start = reinterpret_cast<const uint8_t>(buffer.data());
size_t size = buffer.size();
For more details regarding PDB support, please refer to the PDB section.
LIEF supports PE Authenticode by providing an API for inspecting and verifying PE executable signatures.
Note
import lief
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 Authenticode support in this tutorial: PE Authenticode