reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
#!/usr/bin/env python3
"""Deep PE static reverse without IDA: capstone linear+entry disasm, IAT thunk
resolution, call-site mapping to imports, and payload/container carving.
Usage: python pe_deep.py <path.exe> [--disasm-entry N] [--carve]
"""
from __future__ import annotations
import argparse, sys
import pefile
from capstone import Cs, CS_ARCH_X86, CS_MODE_64, CS_MODE_32
def rva_to_off(pe, rva):
return pe.get_offset_from_rva(rva)
def build_iat_map(pe):
"""Map IAT slot VA -> imported name (for call [rip+x] / call [iat] resolution)."""
m = {}
if not hasattr(pe, "DIRECTORY_ENTRY_IMPORT"):
return m
base = pe.OPTIONAL_HEADER.ImageBase
for entry in pe.DIRECTORY_ENTRY_IMPORT:
dll = entry.dll.decode("latin1", "replace")
for imp in entry.imports:
nm = imp.name.decode("latin1", "replace") if imp.name else f"{dll}#ord{imp.ordinal}"
if imp.address is not None:
m[imp.address] = f"{dll}!{nm}" # absolute VA of the IAT slot user
# imp.address is the VA where the pointer is used; also map the thunk RVA
return m
def main():
ap = argparse.ArgumentParser()
ap.add_argument("path")
ap.add_argument("--disasm-entry", type=int, default=120, help="instructions from entrypoint")
ap.add_argument("--carve", action="store_true")
args = ap.parse_args()
pe = pefile.PE(args.path, fast_load=False)
is64 = hex(pe.OPTIONAL_HEADER.Magic) == "0x20b"
md = Cs(CS_ARCH_X86, CS_MODE_64 if is64 else CS_MODE_32)
md.detail = True
base = pe.OPTIONAL_HEADER.ImageBase
ep_rva = pe.OPTIONAL_HEADER.AddressOfEntryPoint
ep_va = base + ep_rva
print(f"# {args.path}")
print(f"imagebase={hex(base)} entry_va={hex(ep_va)} bits={'64' if is64 else '32'}")
# Build a name map for IAT slots keyed by the pointer VA the code dereferences.
# pefile: imp.address = VA of the IAT entry (where the resolved pointer lives).
iat = {}
if hasattr(pe, "DIRECTORY_ENTRY_IMPORT"):
for entry in pe.DIRECTORY_ENTRY_IMPORT:
dll = entry.dll.decode("latin1", "replace")
for imp in entry.imports:
nm = imp.name.decode("latin1", "replace") if imp.name else f"ord{imp.ordinal}"
if imp.address:
iat[imp.address] = f"{dll}!{nm}"
# Disassemble from entrypoint.
ep_off = rva_to_off(pe, ep_rva)
code = pe.get_memory_mapped_image()[ep_rva: ep_rva + args.disasm_entry * 16]
print(f"\n== entrypoint disasm ({args.disasm_entry} insns) ==")
n = 0
for insn in md.disasm(code, ep_va):
annot = ""
# resolve call/jmp [rip+disp] against IAT
if insn.mnemonic in ("call", "jmp") and insn.operands:
op = insn.operands[-1]
try:
from capstone.x86 import X86_OP_MEM, X86_OP_IMM
if op.type == X86_OP_MEM and op.mem.base in (0,) and is64:
# rip-relative: target = next_insn + disp
tgt = insn.address + insn.size + op.mem.disp
if tgt in iat:
annot = f" ; -> {iat[tgt]}"
elif op.type == X86_OP_MEM:
if op.mem.disp in iat:
annot = f" ; -> {iat[op.mem.disp]}"
elif op.type == X86_OP_IMM and op.imm in iat:
annot = f" ; -> {iat[op.imm]}"
except Exception:
pass
print(f" {insn.address:#0x}: {insn.mnemonic:<7}{insn.op_str}{annot}")
n += 1
if n >= args.disasm_entry:
break
if args.carve:
print("\n== carve scan ==")
rd = [s for s in pe.sections if s.Name.rstrip(b'\x00') == b'.rdata']
if rd:
data = rd[0].get_data()
print(f".rdata off={hex(rd[0].PointerToRawData)} size={len(data)}")
# leading dword table
import struct
vals = struct.unpack_from("<8I", data, 0)
print("leading dwords:", [hex(v) for v in vals])
if __name__ == "__main__":
sys.exit(main())