I'm a beginner teaching myself systems programming and reverse engineering on Windows and Linux. I learn best by building things, so most of my projects are small tools that help me see what happens between source code and a running program: how compilers lay out objects and metadata, how linkers put a binary together, how loaders map it into memory, and how debuggers and unwinders read it back.
Something I've found fascinating so far is the metadata a compiler has to leave in a binary, such as RTTI, vtables, unwind tables and import tables. It survives stripping, and it can tell you a surprising amount about how a program is put together.
- Windows x64 internals: PE/COFF layout, the MSVC C++ ABI, RTTI and class hierarchies, vtables, imports and exports
- Linux internals: ELF, the System V AMD64 ABI, DWARF call frame information and
.eh_frame, program headers and the dynamic loader - Reverse engineering: reading stripped binaries with Ghidra, GDB, x64dbg and WinDbg, and writing small tools to help along the way
- Languages: C++ for my Windows tools, Rust for cross-platform command-line tools, C for the low-level parts, and Python for scripts and tests
- By building: I learn each file format by writing a tool that reads it, and test it on binaries I've built myself
- By checking my work: I compare my results with established tools like
readelfandllvm-readobj, so I find out when I've got something wrong - By keeping it small: each tool does one thing and has no third-party dependencies, so I can understand every line
- By writing it down: each README explains the format the tool reads, which helps me check that I really understand it
The languages and tools I've been learning with so far:
These are my learning projects: two small toolkits for taking binaries apart, one for each binary format. The PE tools are C++17 with CMake and build on Windows, Linux and macOS; the ELF tool is Rust. They're all MIT-licensed, tested in CI, and have no third-party dependencies.
|
My biggest project so far. It works out where functions start and end in stripped Linux ELF binaries by reading the
|
|
|
A command-line inspector I wrote to learn the Portable Executable format. It prints the DOS and NT headers, section layout, imports and exports. pe-walker --summary app.exe
|
Compares two PE files: headers, sections, imports and exports. It exits non-zero when something changed, so it can be used in a CI pipeline. pe-diff -T old.dll new.dll
|
|
Rebuilds class hierarchies from stripped MSVC x64 binaries by following the RTTI structures: Complete Object Locator → Class Hierarchy Descriptor → Base Class Array. rtti-dump --demangle app.exe
|
A companion to rtti-dump. It finds each class's vtable through its Complete Object Locator back-reference and lists the virtual function slots. vtable-dump -f exception app.exe
|
|
A single-header C++17 library for IDA-style byte signature scanning. It uses const auto sig = patscan::parse("48 8B ?? E8 ?? ?? ?? ?? 85 C0");
const auto* hit = patscan::find(data, size, sig);
|
|
I'm still a beginner, so if you spot something wrong or have tips, please open an issue. Every tool here is built and tested against my own test binaries.