import re, struct, sys exe = open("HAVOC_NOCD.EXE", "rb").read() # ── 1. All NUL-terminated strings in rdata that look like paths/filenames ── print("=== Path/filename strings in rdata (0x067000+) ===") rdata = exe[0x067000:] base = 0x067000 seen = set() for m in re.finditer(rb'(?:[\x21-\x7e]{3,60})(?=\x00)', rdata): s = m.group().decode('latin1') fo = base + m.start() if s in seen: continue # keep only things that look like filenames or paths has_dot = '.' in s has_bs = chr(0x5c) in s # backslash has_colon = ':' in s if not (has_dot or has_bs or has_colon): continue # skip long prose strings if len(s) > 50: continue seen.add(s) print(f" 0x{fo:06x}: {s!r}") # ── 2. Find the IAT VA for every imported function ── # Scan the import descriptor table to map function name -> IAT file offset print("\n=== Imports (name -> IAT file offset -> VA) ===") iat_map = {} # name -> iat_va # The IAT in HAVOC.EXE is around 0x06ec00 based on prior analysis. # Scan 0x06ec00..0x06fd00 for hint+name entries and build a name->IAT map. # Actually easier: find all FF 15 (CALL [mem]) targets in .text, then resolve names. call_indirect = {} # iat_va -> [call_fo, ...] for m in re.finditer(b'\xff\x15', exe[0x400:0x067000]): call_fo = 0x400 + m.start() iat_va = struct.unpack_from(' iat_va for api in apis_of_interest: idx = exe.find(api) while idx != -1: # the hint is 2 bytes before the name; the IAT entry points here via the INT # Find which IAT entry references this (INT entry = &hint+name) hint_fo = idx - 2 int_rva = 0x400000 + hint_fo - 0x000400 + 0x001000 # VA of hint record needle = struct.pack('