
TRANSFORMERS: Forged to Fight è un gioco di combattimento 3D in cui prendi il controllo di alcuni dei più carismatici soldati direttamente dall'universo di Transformers. Parliamo di grandi nomi come Optimus Prime, Megatron, Bumblebee, Ratchet, Soundwave e Grindor–niente di meno. Sì, hai letto bene. I tuoi personaggi preferiti da qualsiasi Transformers
Questo pacchetto contiene un boot offline funzionante di Transformers: Forged to Fight, insieme a tutti gli strumenti, le patch e le note di reverse engineering utilizzati per arrivarci. È pensato per essere raccolto da qualcuno che abbia il tempo e l'energia per compiere il passo successivo, molto più grande, ovvero ricostruire da zero il contenuto lato server del gioco. Tutto qui è documentato in modo che tu non debba partire da zero come ho fatto io.
Leggi tutto questo file prima di toccare qualsiasi cosa. La sezione "Gotchas" in particolare ti farà risparmiare giorni.
Il gioco si avvia completamente offline e raggiunge la sua vera schermata principale interattiva senza alcun server live in funzione. Dalla schermata principale i menu navigano senza crash: la base, il roster dei bot (con un bot posseduto presente nell'account), la selezione della modalità di combattimento, la schermata dei cristalli e i soliti popup e suggerimenti. Il flusso di login completo viene eseguito, ogni sottosistema online si connette e l'esperienza iniziale e i gate del tutorial vengono superati. Il combattimento introduttivo scriptato (Optimus vs Starscream) arriva persino abbastanza avanti da iniziare a caricare la battaglia, e i modelli 3D dei personaggi vengono renderizzati e animati.
Questa era la parte difficile ed è risolta. Il client stesso è di nuovo vivo offline.
Il gameplay effettivo non funziona. La storia non mostra missioni e i combattimenti non possono caricarsi completamente. Questo non è un bug e non è qualcosa che una patch possa risolvere.
Forged to Fight era completamente server-authoritative. L'app sul telefono è essenzialmente uno schermo con controlli. Quasi nulla del gioco risiedeva nell'app. Ogni missione, ogni combattimento, ogni schieramento nemico, le statistiche e le abilità dell'intero roster, l'economia e tutto il bilanciamento vivevano sui server di Kabam e venivano trasmessi al dispositivo in ogni sessione. Quando i server sono stati spenti all'inizio del 2020, quel database di contenuti è scomparso con loro, e non è mai stato rilasciato o archiviato pubblicamente in nessun luogo che io possa raggiungere.
Quindi la situazione è nettamente divisa in due. L'arte e l'audio sono sopravvissuti, perché sono inclusi nell'app (vedi re_notes/ASSET_INVENTORY.txt). Ogni personaggio è un bundle di asset Unity completo che contiene modello, texture, rig, clip di animazione, controller di animazione, effetti e audio. Anche gli ambienti, gli edifici, l'interfaccia utente, i ritratti, le cutscene e i dialoghi sono tutti lì. Ciò che non è sopravvissuto sono i dati che dicevano al gioco quali asset utilizzare, come assemblarli in un combattimento o in una missione, e quali fossero i numeri effettivi di ogni bot. Tutti i pezzi sono presenti. Non è rimasto nulla che sappia come metterli insieme. Ricostruire quello è l'intero lavoro che rimane.
Ci sono quattro componenti mobili. Insieme fanno sì che il gioco non modificato pensi di parlare con Kabam.
Patch binarie native. Il gioco è Unity IL2CPP, quindi la logica risiede in una libreria ARM compilata, libil2cpp.so, non in file script modificabili. patches/patch_il2cpp.py riscrive sei funzioni in quella libreria per superare i controlli dei server morti: sconfigge due percorsi di certificate pinning in modo che il nostro certificato TLS sia accettato, forza il blocco di registrazione del manager a eseguirsi anche se la configurazione live è nulla, permette al login di riuscire con la nostra sessione del dispositivo locale e silenzia gli errori fatali dei sottosistemi che altrimenti farebbero apparire il dialogo "accesso fallito". Inietta anche una singola voce di dipendenza (vedi la sezione Gotchas) in modo che l'hook runtime venga effettivamente caricato. L'output è libil2cpp.patched.so.
Un finto server Sparx. server/fakeserver.py fa da backend per Kabam. Ascolta su TLS 443 e HTTP normale 80 e risponde alle chiamate API del gioco. Le risposte predefinite si trovano in server/responses/, un file per endpoint, nominato per metodo e percorso, ad esempio GET__account_data.json. Alcuni endpoint sono gestiti dinamicamente nel codice anziché da un file, perché il gioco si aspetta che echoino i valori della richiesta (gli endpoint del tutorial e l'endpoint dei dettagli dell'eroe). L'involucro della risposta è {"error":null,"result": ...}. Nota che all'interno dei payload di errore di Sparx il campo è scritto err, non error. Questo dettaglio è importante e facile da perdere.
Un hook runtime nativo. tools/nativehook/ costruisce libdothook.so, una piccola libreria caricata nel gioco all'avvio che registra ogni chiave di dati letta dal gioco, più un paio di suggerimenti comportamentali mirati. Questo è il ciclo di feedback che ha reso possibile tutto il resto: ti dice esattamente cosa sta chiedendo il gioco in modo da poter sintetizzare una risposta e verificarla. È un hook in-line puro con sovrascrittura di byte installato prima dell'esecuzione, perché lo strumento normale per questo (Frida) crasha sotto il layer di traduzione ARM dell'emulatore.
Cablaggio del dispositivo. L'emulatore deve inviare i domini di Kabam al PC e fidarsi del certificato falso. tools/provision_ldplayer.sh fa tutto in un colpo solo: carica la libreria patchata e l'hook, reindirizza gli hostname di Kabam all'indirizzo LAN del PC tramite il file hosts, monta la CA falsa nel trust store di sistema e rilassa SELinux. Eseguilo dopo ogni riavvio dell'emulatore, perché questi mount non sopravvivono a un riavvio.
Il flusso di dati in runtime è: il gioco effettua una chiamata HTTPS a un dominio Kabam, il file hosts la invia al PC, il finto server risponde con una risposta da server/responses/, la libreria patchata accetta il certificato e la risposta, e l'hook registra ciò che è stato letto. Quel ciclo è il modo in cui ogni schermata in questa build è stata attivata.
README.md questo file
TECHNICAL_NOTES.md il riferimento tecnico più approfondito: patch, forme dei dati recuperati, scoperte
patches/
patch_il2cpp.py le sei patch native più la re-iniezione delle dipendenze
disasm_fn.py helper: disassembla una funzione a un offset
find_callers.py helper: trova i chiamanti di una funzione
find_str_ref.py helper: trova i riferimenti a una stringa
server/
fakeserver.py il finto server Sparx
gen_certs.sh rigenera il certificato TLS e la CA (esegui questo, vedi sotto)
setup_device.sh riferimento per la configurazione di rete e trust lato dispositivo
iterate.sh ciclo rapido di riavvio e cattura
responses/ un file JSON per endpoint chiamato dal gioco
tools/
provision_ldplayer.sh ri-provisioning in un colpo solo dell'emulatore allo stato funzionante
setup_arm64.sh note di configurazione della toolchain
decompile_targets.py guida il decompilatore headless di Ghidra agli offset scelti
find_xrefs.py ricerca di riferimenti incrociati sul binario
apply_labels.py applica le etichette dei simboli IL2CPP
light_analyze.py helper leggeri di analisi statica
frida_attach.py helper Frida (tenuti per riferimento, vedi la nota libnb)
frida_run.py
hook_dot.js
nativehook/
hook.c sorgente di libdothook.so, l'hook runtime
libdothook.so hook precompilato, arm64
deploy.sh compila e distribuisci l'hook
relaunch_and_capture.sh rilancia il gioco e cattura i log
hook/dothook.c variante precedente dell'hook, tenuta per riferimento
re_notes/
dump.cs il dump IL2CPP completo: ogni classe, metodo e campo del gioco
decomp_out.c corpi decompilati delle funzioni chiave
decompile_targets.txt gli offset che vale la pena decompilare
ASSET_INVENTORY.txt quali arte e audio sono già inclusi nell'app
re_notes/dump.cs è il file più prezioso per il lavoro che rimane. È il modello completo dei tipi del gioco: ogni classe, ogni metodo e, cosa cruciale, ogni campo dati che il client legge dal server. È la tua mappa dell'intera API backend. Quando hai bisogno di sapere quale forma dovrebbe avere una risposta, la risposta è lì.
Questi sono stati esclusi appositamente, perché sono grandi, protetti da copyright, segreti, o dovresti generarli tu stesso.
com.kabam.bigrobot, versione 9.2.0). È circa 800 MB. Procurati la tua copia. Il nome del pacchetto e la versione sono in TECHNICAL_NOTES.md.libil2cpp.so originale e gli asset del gioco. Entrambi provengono direttamente dall'APK. Decomprimi l'APK, la libreria è in lib/arm64-v8a/, gli asset sono in assets/.server/gen_certs.sh per creare la tua coppia corrispondente, quindi punta il trust store del dispositivo alla nuova CA.patches/patch_il2cpp.py contro il libil2cpp.so originale dell'APK.re_notes/dump.cs dalla libreria dell'APK e dai metadati globali.Hai bisogno dell'APK installato su un emulatore in grado di tradurre ARM (è stato usato LDPlayer 9, con root e filesystem scrivibile), Python sul PC e gli elementi della sezione sopra.
bash server/gen_certs.sh.python patches/patch_il2cpp.py percorso/al/libil2cpp.so originale --apply.tools/nativehook/deploy.sh.python server/fakeserver.py. Deve essere raggiungibile sulle porte 443 e 80 dall'emulatore.bash tools/provision_ldplayer.sh <IP-LAN-del-tuo-PC>. Eseguilo di nuovo dopo ogni riavvio dell'emulatore.Se si blocca al login, controlla il primo elemento nella sezione Gotchas prima di qualsiasi altra cosa.
Questi sono quelli che mi sono costati ore. Sono scritti in modo che non ti costino lo stesso.
libdothook.so. I byte e gli offset esatti sono documentati nello script di patch e in TECHNICAL_NOTES.md.provision_ldplayer.sh o nulla si connetterà.err, non error. Usare quello sbagliato produce risposte che il client ignora silenziosamente o gestisce male.Questo è il vero lavoro, ed è grande. Ecco la sua forma e da dove iniziare.
L'obiettivo è ricreare a mano il contenuto lato server che veniva trasmesso al client: le missioni e le quest, le mappe e i loro schieramenti nemici, il roster completo con le statistiche e le abilità di ogni bot, le formule di combattimento e l'economia. Niente di tutto ciò esiste più, quindi tutto deve essere creato da zero, nelle forme esatte che il client si aspetta.
Il metodo che funziona è il ciclo su cui è costruito questo progetto. Esegui il gioco con l'hook attaccato. L'hook registra ogni chiave che il client legge. Quando il client chiede qualcosa che non hai fornito, vedi esattamente cosa voleva. Quindi sintetizzi una risposta nella forma giusta, la inserisci in server/responses/ o la aggiungi al gestore dinamico in fakeserver.py, riavvii e verifichi che il client la accetti e vada avanti. Ripeti. Ogni schermata nella build corrente è stata attivata esattamente in questo modo. re_notes/dump.cs ti dice la forma di ogni struttura prima ancora di eseguire, perché elenca ogni campo che il client legge.
Un ordine sensato per affrontarlo:
decompile_targets.py) e leggi i campi esatti.ASSET_INVENTORY.txt, quindi stai solo creando numeri e definizioni di abilità, non asset.TECHNICAL_NOTES.md per le chiavi.Sii realistico sulla scala. Anche per giochi in cui i fan hanno salvato i dati live del server prima dello spegnimento, allestire un server privato è un progetto lungo. Qui non ci sono dati salvati da cui partire, quindi ogni numero e ogni abilità devono essere ricercati o reinventati e poi verificati rispetto al client. Questo è uno sforzo multi-persona e multi-anno se l'obiettivo è il vero gioco. Detto questo, il percorso non è più un mistero. Il boot è risolto, il ciclo di feedback esiste, il modello di tipo è dumpato e gli asset sono intatti. Ciò che rimane è una grandissima quantità di attenta ricostruzione dei dati, non più reverse engineering dell'ignoto.
Inizia con TECHNICAL_NOTES.md. È il riferimento tecnico più approfondito, con le patch esatte, le forme dei dati recuperati e le scoperte specifiche, in maggiore dettaglio rispetto a questo README. Poi esegui il ciclo.
Buona fortuna. Ora è una macchina reale. Ha solo bisogno che i suoi contenuti vengano ricostruiti.