#!/usr/bin/env python3 """Find an APT/ActionScript symbol inside the FIFA 17 Frostbite .cas archives. Frosty is a GUI-only tool and its Legacy Explorer is the documented way to reach these assets, but the chunks holding APT ActionScript are stored plainly enough to grep — so a screen can be identified, and its whole symbol table recovered, without driving the GUI at all. ALWAYS passes a control first: `KitAssignmentPopup` is a string from an already-exported BIG, so if it misses, the archives are packed differently than assumed and no negative from this tool may be quoted. python3 find_apt_in_cas.py FUT_GET_MATCH_KITS_DP python3 find_apt_in_cas.py --dump 0x3707ecd7 fifa_installpackage_01/cas_01.cas """ import argparse import glob import os import re import sys ROOT = "/mnt/games/FIFA 17" CONTROL = b"KitAssignmentPopup" def cas_files(): return sorted(glob.glob(os.path.join(ROOT, "**", "*.cas"), recursive=True)) def find(needle: bytes): control_total = 0 hits = [] for p in cas_files(): d = open(p, "rb").read() control_total += d.count(CONTROL) start = 0 while True: i = d.find(needle, start) if i < 0: break hits.append((p, i)) start = i + 1 return control_total, hits def dump(path, off, span=90000): with open(path, "rb") as f: f.seek(max(0, off - span // 2)) d = f.read(span) seen = [] for m in re.finditer(rb"[ -~]{4,}", d): t = m.group().decode("latin1") if t not in seen: seen.append(t) return seen def main(): ap = argparse.ArgumentParser() ap.add_argument("needle", nargs="?") ap.add_argument("--dump", metavar="OFFSET") ap.add_argument("--file") args = ap.parse_args() if args.dump: path = args.file if os.path.isabs(args.file or "") else os.path.join( ROOT, "Data/Win32/superbundlelayout", args.file or "") for s in dump(path, int(args.dump, 0)): print(s) return 0 if not args.needle: ap.error("needle required") ctl, hits = find(args.needle.encode()) print(f"control {CONTROL.decode()}: {ctl} hit(s)") if ctl == 0: print("CONTROL FAILED — archives not greppable this way; no negative is valid.") return 1 print(f"{args.needle}: {len(hits)} hit(s)") for p, i in hits[:20]: print(f" {os.path.relpath(p, ROOT)} @ {i:#x}") return 0 if __name__ == "__main__": sys.exit(main())