sots-re/tools/gen_addresses.py

20 lines
1.4 KiB
Python
Executable file

#!/usr/bin/env python3
"""Emit include/generated/sots_addresses.h for sots-engine from ghidra/addresses.json.
Only facts (name, RVA, convention, prototype, status) — never decompiler text."""
import json, os, subprocess, sys, datetime
root = os.path.join(os.path.dirname(__file__), "..")
j = json.load(open(os.path.join(root, "ghidra", "addresses.json")))
base = int(j["image_base"], 16)
try: rev = subprocess.check_output(["git","-C",root,"rev-parse","--short","HEAD"]).decode().strip()
except Exception: rev = "unknown"
out = [ "// GENERATED — do not edit. Facts about Sword of the Stars.exe (GOG 1.8.1).",
f"// Source: sots-re ghidra/addresses.json @ {rev}, generated {datetime.date.today()} by tools/gen_addresses.py",
"// Runtime address = (uintptr_t)GetModuleHandle(NULL) + RVA (the exe is ASLR-relocated).",
"#pragma once", "#include <cstdint>", "", "namespace sots::addr {", f"constexpr uint32_t IMAGE_BASE = 0x{base:08x};", "" ]
for e in j["entries"]:
rva = int(e["addr"],16) - base
out.append(f"// {e['convention']:8s} {e['prototype']} [{e['status']}]")
out.append(f"constexpr uint32_t {e['name']} = 0x{rva:08x};")
out += ["", "} // namespace sots::addr", ""]
dest = sys.argv[1] if len(sys.argv) > 1 else os.path.join(root, "ghidra", "generated", "sots_addresses.h")
os.makedirs(os.path.dirname(dest), exist_ok=True); open(dest, "w").write("\n".join(out)); print("wrote", dest, f"({len(j['entries'])} entries)")