#!/usr/bin/env python3 """Scan ghidra/decomp.c (Ghidra decompiled C) for the PlainDamgeDealerComponent populate fingerprint: the same pointer var written at +0x10 (float, damageAmount), +0x14 (damageType) and +0x15 (isMelee). Also reports HitEventInfo (+0x30 damageAmount) and any function assigning a float constant to a +0x10 offset near those. """ import re, sys BLOCK = re.compile(r"^// ==== (.+?) @ \+0x([0-9a-f]+) ====$") def blocks(path): name = None addr = None buf = [] for line in open(path, errors="replace"): m = BLOCK.match(line.rstrip("\n")) if m: if name is not None: yield name, addr, "".join(buf) name, addr, buf = m.group(1), m.group(2), [] else: buf.append(line) if name is not None: yield name, addr, "".join(buf) # var written at a given byte offset: e.g. *(float *)(lVar5 + 0x10) = ... def vars_writing_offset(code, off): pat = re.compile(r"\*\([^)]*\)\(([A-Za-z_][A-Za-z0-9_]*) \+ 0x%x\) =" % off) return set(pat.findall(code)) def main(): path = sys.argv[1] if len(sys.argv) > 1 else "/home/downloadpizza/sand_tools/ghidra/decomp.c" hits = [] for name, addr, code in blocks(path): v10 = vars_writing_offset(code, 0x10) v14 = vars_writing_offset(code, 0x14) v15 = vars_writing_offset(code, 0x15) common = v10 & v14 & v15 if common: # confirm the +0x10 write is a float for v in common: if re.search(r"\*\(float \*\)\(%s \+ 0x10\) =" % re.escape(v), code): hits.append((name, addr, v)) break print("=== STRICT: +0x10 float, +0x14, +0x15 same ptr ===") for name, addr, v in hits: print(" +0x%s var %s %s" % (addr, v, name)) print("strict total:", len(hits)) # LOOSE: float@+0x10 and byte@+0x15 on same ptr (isMelee + damageAmount) loose = [] for name, addr, code in blocks(path): common = vars_writing_offset(code, 0x10) & vars_writing_offset(code, 0x15) for v in common: if re.search(r"\*\(float \*\)\(%s \+ 0x10\) =" % re.escape(v), code): loose.append((name, addr, v)); break print("\n=== LOOSE: +0x10 float & +0x15 same ptr ===") for name, addr, v in loose: print(" +0x%s var %s %s" % (addr, v, name)) print("loose total:", len(loose)) if __name__ == "__main__": main()