#!/usr/bin/env python3 """Inspect and realign a memory-dumped PE toward a loadable layout. `inspect` reports section raw-vs-virtual alignment and the entry point. `fix` rewrites each section's PointerToRawData/SizeOfRawData to match its virtual layout (the standard convention for files reconstructed from memory) and sets AddressOfEntryPoint to a supplied OEP. Operates on file bytes only; executes nothing. Import reconstruction is left to a dedicated tool. """ from __future__ import annotations import argparse import json import struct import sys from pathlib import Path def _pe_offsets(data: bytes): if data[:2] != b"MZ": raise ValueError("not a PE") e_lfanew = struct.unpack_from(" dict: data = Path(path).read_bytes() e_lfanew, opt_off, sect_off, num = _pe_offsets(data) aoep = struct.unpack_from(" dict: data = bytearray(Path(path).read_bytes()) e_lfanew, opt_off, sect_off, num = _pe_offsets(data) for i in range(num): base = sect_off + i * 40 vsize, vaddr = struct.unpack_from(" int: parser = argparse.ArgumentParser(description="Inspect/realign a dumped PE") sub = parser.add_subparsers(dest="cmd", required=True) pi = sub.add_parser("inspect") pi.add_argument("file") pf = sub.add_parser("fix") pf.add_argument("file") pf.add_argument("--oep", help="OEP RVA, e.g. 0x1234") pf.add_argument("-o", "--out", required=True) args = parser.parse_args(argv) if args.cmd == "inspect": print(json.dumps(inspect(args.file), indent=2)) else: oep = int(args.oep, 0) if args.oep else None print(json.dumps(fix(args.file, oep, args.out), indent=2)) return 0 if __name__ == "__main__": sys.exit(main())