Files
OpenFUT/fifa17-recon/docker/fifa17-python/tools/atomdump.py
T
root 70a64e3709 fifa17-python: commit working FUT backend deployment (client/server split)
Freeze the running offline FUT backend into version control as
fifa17-recon/docker/fifa17-python/ - declarative and rebuildable from a
fresh checkout:

* OPENFUT_BIND / OPENFUT_ADVERTISE client/server split in the responders
  (lsx, blaze, roster, utas, pow) + entrypoint.sh; OPENFUT_ADVERTISE is
  required for remote mode (compose and entrypoint fail without it)
* docker-compose.yml reproducing the frozen baseline container exactly
  (env, ports incl. the 8085->8080 POW-content remap, /state bind, restart)
* .env.example / .env for site config - the LAN IP is never hardcoded in source
* tools/ + data/ staged from openfut-fut-backend:python-baseline-2026-08-10,
  verified byte-identical to the running container at freeze time
* client_arm.sh (the 105 client-side arming counterpart)
* Dockerfile bakes /app/SHA256SUMS.txt so any image is self-identifying
* docs/BASELINE-python-2026-08-10.md: frozen image/container/hash record,
  restore instructions and rebuild-equivalence procedure

Secrets (redir key/cert, .env) and runtime state (docker/state) stay gitignored.
The live container is untouched pending the .105 launcher audit.
2026-08-10 23:54:04 +00:00

54 lines
1.5 KiB
Python

#!/usr/bin/env python3
# Dump the FUT atom name table (atom index -> key string) from CardsDLL.
# Table at VA 0x1802d2760 is an array of char* pointers into .rdata.
import struct, sys
DLL = "/tmp/fut/cardsdll.dll"
data = open(DLL, "rb").read()
# (VA_start, size, file_off) from objdump -h
SECTIONS = [
(0x180001000, 0x1e3f62, 0x400), # .text
(0x1801e5000, 0xa4094, 0x1e4400), # .rdata
(0x18028a000, 0x54000, 0x288600), # .data
]
def va_to_off(va):
for start, size, off in SECTIONS:
if start <= va < start + size:
return off + (va - start)
return None
def read_cstr(va, maxlen=128):
off = va_to_off(va)
if off is None:
return None
end = data.find(b"\x00", off, off + maxlen)
if end < 0:
return None
try:
return data[off:end].decode("ascii")
except UnicodeDecodeError:
return None
TABLE_VA = 0x1802d2760
off = va_to_off(TABLE_VA)
atoms = {}
for i in range(0, 1200):
ptr = struct.unpack_from("<Q", data, off + i * 8)[0]
if ptr == 0:
s = None
else:
s = read_cstr(ptr)
if s is None:
# allow a few gaps then stop if we run off the end
if i > 40 and all(struct.unpack_from("<Q", data, off + (i + k) * 8)[0] == 0 for k in range(4)):
break
continue
if s.isprintable() and 1 <= len(s) <= 40:
atoms[i] = s
for i in sorted(atoms):
print(f"{i}\t0x{i:x}\t{atoms[i]}")
print(f"# total {len(atoms)} atoms", file=sys.stderr)