"""Static triage tren FILE vggame.exe (doc file tren dia, khong mo process, khong ghi).
Muc dich: thu thap bang chung doc lap - section, keyword NPC/object, dword giong con tro.
KHONG ket luan - chi dem va trich mau co gioi han.
"""
from __future__ import annotations

import collections
import math
import re

GAME = r"C:\JXVCTK\JxVoCongTruyenKy\vggame.exe"
KEYWORDS = [b"npc", b"Npc", b"NPC", b"object", b"Object", b"monster", b"Monster",
            b"actor", b"Actor", b"target", b"Target", b"enemy", b"Enemy"]

IMG_LO, IMG_HI = 0x400000, 0x800000  # vung image base pho bien cua client 32-bit


def entropy(buf: bytes) -> float:
    if not buf:
        return 0.0
    c = collections.Counter(buf)
    n = len(buf)
    return -sum((v / n) * math.log2(v / n) for v in c.values())


def main() -> None:
    data = open(GAME, "rb").read()
    print(f"file={GAME}")
    print(f"size={len(data)} ent_total={entropy(data[:1 << 20]):.3f}(1MB dau) "
          f"{entropy(data[len(data)//2:len(data)//2 + (1 << 20)]):.3f}(giua)")
    try:
        import pefile
        pe = pefile.PE(GAME, fast_load=True)
        print(f"machine={hex(pe.FILE_HEADER.Machine)} sections={len(pe.sections)}")
        for s in pe.sections:
            raw = s.get_data()[: 1 << 20]
            print(f"  sec name={s.Name!r} vsize=0x{s.Misc_VirtualSize:X} "
                  f"raw=0x{s.SizeOfRawData:X} ent={entropy(raw):.3f} chars=0x{s.Characteristics:08X}")
        pe.close()
    except Exception as ex:  # noqa: BLE001
        print(f"pefile: {ex}")
    print("== keyword strings (toi da 3 offset mau/keyword) ==")
    for kw in KEYWORDS:
        offs = [m.start() for m in re.finditer(re.escape(kw), data)][:3]
        total = len(re.findall(re.escape(kw), data))
        print(f"  {kw.decode()!r}: total={total} sample_offsets={[hex(o) for o in offs]}")
    print("== dword giong con tro image [0x400000,0x800000) ==")
    import struct
    hits = []
    for off in range(0, len(data) - 4, 4):
        v = struct.unpack_from("<I", data, off)[0]
        if IMG_LO <= v < IMG_HI:
            hits.append(off)
            if len(hits) >= 5:
                break
    print(f"  dword dau tien khop: {[hex(o) for o in hits]} (can dem full neu can)")


if __name__ == "__main__":
    main()
