Files
OpenMaidEngine/tools/pack_check.py
gamer147 463877773c chore: initialize age-reimpl repo
Reverse-engineering + open reimplementation workspace for Eushully's AGE/SYS4
engine (first target: Himegari). The repo root is age-reimpl/; the original game
install and the extracted ALF data are siblings outside the repo and are never
tracked. build/ (derived corpora) is gitignored and regenerated by the tools.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 12:58:30 -04:00

42 lines
1.6 KiB
Python

#!/usr/bin/env python3
import os, sys, struct, math, re
from pathlib import Path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import paths
data = paths.AGE_EXE.read_bytes()
pe = struct.unpack_from("<I", data, 0x3C)[0]
nsec = struct.unpack_from("<H", data, pe+6)[0]
opt = pe+24
nrva = struct.unpack_from("<I", data, opt+92)[0]
# data directories: index 1 = import, 12 = IAT
imp_rva, imp_sz = struct.unpack_from("<II", data, opt+96+1*8)
iat_rva, iat_sz = struct.unpack_from("<II", data, opt+96+12*8)
print(f"NumberOfRvaAndSizes {nrva}")
print(f"ImportDir rva {imp_rva:#x} size {imp_sz:#x}")
print(f"IAT rva {iat_rva:#x} size {iat_sz:#x}")
sec_off = opt + struct.unpack_from("<H", data, pe+20)[0]
print("\nsection entropy:")
for i in range(nsec):
o=sec_off+i*40
name=data[o:o+8].rstrip(b"\0").decode('ascii','replace') or f"<blank{i}>"
vsize,va,rsize,raw=struct.unpack_from("<IIII",data,o+8)
chunk=data[raw:raw+rsize]
if chunk:
freq=[0]*256
for b in chunk: freq[b]+=1
ent=-sum((c/len(chunk))*math.log2(c/len(chunk)) for c in freq if c)
else:
ent=0
print(f" {name:<10} va {va:#08x} vsize {vsize:#08x} raw {raw:#08x} rsize {rsize:#08x} entropy {ent:.2f}")
# UTF-16LE anchor search
print("\nUTF-16 anchors:")
for t in [b"SYS4422", b"DATA1", b"Eushully", b".BIN", b"AGE"]:
u = t.decode().encode("utf-16le")
n = data.count(u)
print(f" {t.decode():10} utf16 hits {n}")
# ascii import dll names still present?
print("\nDLL-name-ish ascii:")
for m in re.finditer(rb"[\x20-\x7e]{4,}\.dll", data, re.I):
print(" ", m.group().decode(errors='replace'))