A robust, standard-compliant low-level C++ library designed for seamless parsing, modifying, and rebuilding of Portable Executable (PE32 and PE32+) binaries. Zero external dependencies, thread-safe MZ/PE header serialization, and robust resource directory parsing.
// Instantiate PeLib and build a PE binary
#include <PeLib.h>
int main() {
std::string file = "dummy.exe";
PeLib::PeFile f(file);
// Setup valid DOS header
f.mzHeader().makeValid();
f.mzHeader().write(file, 0);
// Inject functions into Import Directory
f.impDir().addFunction("User32.dll", "MessageBoxA");
f.writeSections();
}
Complete, robust interface to read, update, and write MS-DOS headers, PE headers, Optional headers, and Section headers with full specification compliance.
Programmatically append, inject, or rewrite imported libraries/functions in the IAT, construct export tables, and resolve relative virtual addresses (RVAs) easily.
Navigate, read, rebuild, and output the complex tree structure of resources (manifests, icons, strings) inside PE binaries with dedicated node and leaf wrappers.
Comes bundled with a fully compiled DLL export interface (`PeLibDll`), permitting painless use inside Delphi, Assembly, C#, or VB.NET environments.
#include <PeLib.h>
#include <iostream>
int main() {
// Instantiate PeFile with target file
PeLib::PeFile f("dummy.exe");
// Initialize and save a valid MZ header
f.mzHeader().makeValid();
f.mzHeader().write("dummy.exe", 0);
// Build and write the core PE structure
f.peHeader().setAddressOfEntryPoint(0x1000);
f.peHeader().makeValid(f.mzHeader().size());
f.peHeader().writeHeader("dummy.exe", f.mzHeader().size());
std::cout << "PE headers written successfully!" << std::endl;
}
#include <PeLib.h>
void injectDllCall() {
PeLib::PeFile f("dummy.exe");
unsigned int uiImpDirRva = 0x2100;
// Add Win32 MessageBox function to User32 imports
f.impDir().addFunction("User32.dll", "MessageBoxA");
// Register size and address in optional header
f.peHeader().setIdImportRva(uiImpDirRva);
f.peHeader().setIdImportSize(f.impDir().size());
// Commit raw structures to file
f.impDir().write("dummy.exe", f.peHeader().rvaToOffset(uiImpDirRva), uiImpDirRva);
}
#include <PeLib.h>
#include <iostream>
void dumpPEData() {
PeLib::PeFile f("explorer.exe");
f.readResources();
PeLib::ResourceDirectory& resDir = f.resDir();
std::cout << "Sub-Resource count: " << resDir.getNumberOfChildren() << std::endl;
for (unsigned int i = 0; i < resDir.getNumberOfChildren(); ++i) {
PeLib::ResourceChild* child = resDir.getChild(i);
std::cout << "Name: " << child->getName() << std::endl;
}
}
PeLib is a community-driven open source library. We welcome contributions of all forms, including bug fixes, performance optimizations, compiler compatibility adjustments, and documentation improvements.
PeLib is distributed under the highly permissive and business-friendly zlib/libpng License. This guarantees that you are free to: