TRANSFORMERS: Forged to Fight es un juego de combate en 3D donde tomas el control de algunos de los soldados más carismáticos del universo Transformers. Hablamos de grandes nombres como Optimus Prime, Megatron, Bumblebee, Ratchet, Soundwave y Grindor, ni más ni menos. Sí, leíste bien. Tus personajes favoritos de cualquier Transformers
Este paquete contiene un arranque offline funcional de Transformers: Forged to Fight, además de todas las herramientas, parches y notas de ingeniería inversa utilizadas para lograrlo. Está pensado para que lo tome alguien que tenga el tiempo y la energía para dar el siguiente paso, mucho más grande, que es reconstruir el contenido del lado del servidor del juego desde cero. Todo aquí está documentado para que no tengas que empezar desde cero como lo hice yo.
Lee este archivo completo antes de tocar nada. La sección "Gotchas" en particular te ahorrará días.
El juego arranca completamente offline y llega a su pantalla de inicio interactiva real sin ningún servidor en vivo. Desde la pantalla de inicio, los menús navegan sin fallos: la base, la lista de bots (con un bot presente en la cuenta), el selector de modo de combate, la pantalla de cristales y las ventanas emergentes y consejos habituales. El flujo completo de inicio de sesión se completa, cada subsistema en línea se conecta y se superan las puertas de la primera experiencia y el tutorial. La pelea introductoria con guion (Optimus vs Starscream) incluso avanza lo suficiente como para comenzar a cargar la batalla, y los modelos 3D de los personajes se renderizan y animan.
Esta era la parte difícil y está resuelta. El cliente en sí está vivo nuevamente offline.
El juego real no funciona. La historia no muestra misiones y las peleas no pueden cargarse por completo. Esto no es un error y no es algo que un parche pueda arreglar.
Forged to Fight era completamente autoritario del servidor. La aplicación en el teléfono es esencialmente una pantalla con controles. Casi nada del juego vivía en la aplicación. Cada misión, cada pelea, cada alineación enemiga, las estadísticas y habilidades de toda la lista, la economía y todo el equilibrio vivían en los servidores de Kabam y se transmitían al dispositivo en cada sesión. Cuando los servidores se cerraron a principios de 2020, esa base de datos de contenido se fue con ellos y nunca se publicó ni archivó públicamente en ningún lugar al que yo pueda acceder.
Por lo tanto, la situación se divide claramente en dos. El arte y el audio sobrevivieron porque se envían dentro de la aplicación (consulta re_notes/ASSET_INVENTORY.txt). Cada personaje es un paquete de activos completo de Unity que contiene el modelo, las texturas, el esqueleto, los clips de animación, los controladores de animación, los efectos y el audio. Los entornos, edificios, interfaz de usuario, retratos, escenas cinemáticas y diálogos también están allí. Lo que no sobrevivió son los datos que le decían al juego qué activos usar, cómo ensamblarlos en una pelea o misión y cuáles eran realmente los números de cada bot. Todas las piezas están presentes. Simplemente no queda nada que sepa cómo unirlas. Reconstruir eso es el único trabajo que queda.
Hay cuatro partes móviles. Juntas hacen que el juego sin modificar piense que está hablando con Kabam.
Parches binarios nativos. El juego es Unity IL2CPP, por lo que la lógica vive en una biblioteca ARM compilada, libil2cpp.so, no en archivos de script editables. patches/patch_il2cpp.py reescribe seis funciones en esa biblioteca para superar las comprobaciones de servidor muerto: derrota dos rutas de fijación de certificados para que se acepte nuestro propio certificado TLS, obliga a que se ejecute el bloque de registro del administrador aunque la configuración en vivo sea nula, permite que el inicio de sesión tenga éxito con nuestra sesión de dispositivo local y silencia los errores fatales del subsistema que de otro modo mostrarían el diálogo de "no se pudo iniciar sesión". También reinyecta una sola entrada de dependencia (consulta la sección Gotchas) para que el hook de tiempo de ejecución realmente se cargue. La salida es libil2cpp.patched.so.
Un servidor Sparx falso. server/fakeserver.py actúa como el backend de Kabam. Escucha en TLS 443 y HTTP plano 80 y responde a las llamadas API del juego. Las respuestas predefinidas están en server/responses/, un archivo por endpoint, nombrado por método y ruta, por ejemplo GET__account_data.json. Algunos endpoints se responden dinámicamente en código en lugar de desde un archivo, porque el juego espera que repitan valores de la solicitud (los endpoints del tutorial y el endpoint de detalle del héroe). El sobre de respuesta es {"error":null,"result": ...}. Ten en cuenta que dentro de los payloads de error de Sparx, el campo se escribe err, no error. Ese detalle importa y es fácil pasarlo por alto.
Un hook nativo en tiempo de ejecución. tools/nativehook/ construye libdothook.so, una biblioteca pequeña que se carga en el juego al inicio y registra cada clave de datos que el juego lee, además de un par de empujones de comportamiento específicos. Este es el bucle de retroalimentación que hizo posible todo lo demás: te dice exactamente lo que el juego está pidiendo para que puedas sintetizar una respuesta y verificarla. Es un hook inline de sobrescritura de bytes puro instalado antes de la ejecución, porque la herramienta normal para esto (Frida) falla bajo la capa de traducción ARM del emulador.
Cableado del dispositivo. El emulador debe enviar los dominios de Kabam a la PC y confiar en el certificado falso. tools/provision_ldplayer.sh hace esto de una sola vez: envía la biblioteca parcheada y el hook, redirige los nombres de host de Kabam a la dirección LAN de la PC mediante el archivo hosts, monta la CA falsa en el almacén de confianza del sistema y relaja SELinux. Ejecútalo después de cada reinicio del emulador, porque esos montajes no sobreviven a un reinicio.
El flujo de datos en tiempo de ejecución es: el juego realiza una llamada HTTPS a un dominio de Kabam, el archivo hosts lo envía a la PC, el servidor falso responde con una respuesta de server/responses/, la biblioteca parcheada acepta el certificado y la respuesta, y el hook registra lo que se leyó. Ese bucle es cómo se levantó cada pantalla en esta compilación.
README.md este archivo
TECHNICAL_NOTES.md la referencia técnica más profunda: parches, formas de datos recuperadas, hallazgos
patches/
patch_il2cpp.py los seis parches nativos más la reinyección de dependencia
disasm_fn.py helper: desensamblar una función en un desplazamiento
find_callers.py helper: encontrar llamadores de una función
find_str_ref.py helper: encontrar referencias a una cadena
server/
fakeserver.py el servidor Sparx falso
gen_certs.sh regenerar el certificado TLS y la CA (ejecutar esto, ver abajo)
setup_device.sh referencia de configuración de red y confianza del lado del dispositivo
iterate.sh bucle rápido de reinicio y captura
responses/ un archivo JSON por endpoint que llama el juego
tools/
provision_ldplayer.sh reaprovisionamiento único del emulador al estado de trabajo
setup_arm64.sh notas de configuración del toolchain
decompile_targets.py impulsar el descompilador headless de Ghidra en desplazamientos seleccionados
find_xrefs.py búsqueda de referencias cruzadas en el binario
apply_labels.py aplicar etiquetas de símbolos IL2CPP
light_analyze.py ayudantes de análisis estático ligero
frida_attach.py helpers de Frida (mantenidos como referencia, ver la nota sobre libdothook)
frida_run.py
hook_dot.js
nativehook/
hook.c fuente de libdothook.so, el hook de tiempo de ejecución
libdothook.so hook precompilado, arm64
deploy.sh compilar y desplegar el hook
relaunch_and_capture.sh reiniciar el juego y capturar registros
hook/dothook.c variante anterior del hook, mantenida como referencia
re_notes/
dump.cs el volcado IL2CPP completo: cada clase, método y campo en el juego
decomp_out.c cuerpos descompilados de funciones clave
decompile_targets.txt los desplazamientos que vale la pena descompilar
ASSET_INVENTORY.txt qué arte y audio ya se envían dentro de la aplicación
re_notes/dump.cs es el archivo más valioso para el trabajo que queda. Es el modelo de tipo completo del juego: cada clase, cada método y, crucialmente, cada campo de datos que el cliente lee del servidor. Es tu mapa de toda la API del backend. Cuando necesites saber qué forma debe tener una respuesta, la respuesta está ahí.
Estos se omitieron a propósito, porque son grandes, o tienen derechos de autor, o son secretos, o deberías generar los tuyos.
com.kabam.bigrobot, versión 9.2.0). Ocupa unos 800 MB. Consigue tu propia copia. El nombre del paquete y la versión están en TECHNICAL_NOTES.md.libil2cpp.so original y los activos del juego. Ambos salen directamente del APK. Descomprime el APK, la biblioteca está en lib/arm64-v8a/, los activos en assets/.server/gen_certs.sh para crear tu propio par correspondiente, luego apunta el almacén de confianza del dispositivo a la nueva CA.patches/patch_il2cpp.py contra el libil2cpp.so original del APK.re_notes/dump.cs a partir de la biblioteca del APK y los metadatos globales.Necesitas el APK instalado en un emulador con capacidad de traducción ARM (se usó LDPlayer 9, con root y sistema escribible), Python en la PC y los elementos de la sección anterior.
bash server/gen_certs.sh.python patches/patch_il2cpp.py ruta/al/libil2cpp.so/original --apply.tools/nativehook/deploy.sh.python server/fakeserver.py. Debe ser accesible en los puertos 443 y 80 desde el emulador.bash tools/provision_ldplayer.sh <tu-IP-LAN-PC>. Vuelve a ejecutarlo después de cada reinicio del emulador.Si se queda colgado en el inicio de sesión, verifica el primer elemento de la sección Gotchas antes que nada.
Estos son los que me costaron horas. Están escritos para que no te cuesten lo mismo.
libdothook.so. Los bytes exactos y los desplazamientos están documentados en el script de parche y en TECHNICAL_NOTES.md.provision_ldplayer.sh o nada se conectará.err, no error. Usar el incorrecto produce respuestas que el cliente ignora silenciosamente o maneja incorrectamente.Este es el trabajo real, y es grande. Aquí tienes la forma y por dónde empezar.
El objetivo es recrear, a mano, el contenido del lado del servidor que solía transmitirse al cliente: las misiones y tareas, los mapas y sus alineaciones enemigas, la lista completa con las estadísticas y habilidades de cada bot, las fórmulas de combate y la economía. Nada de esto existe ya, por lo que todo debe crearse desde cero, en las formas exactas que el cliente espera.
El método que funciona es el bucle en torno al cual se construyó este proyecto. Ejecuta el juego con el hook adjunto. El hook registra cada clave que el cliente lee. Cuando el cliente pide algo que no has proporcionado, ves exactamente lo que quería. Luego sintetizas una respuesta en la forma correcta, la colocas en server/responses/ o la agregas al manejador dinámico en fakeserver.py, reinicias y verificas que el cliente la acepte y avance. Repite. Cada pantalla en la compilación actual se levantó exactamente de esta manera. re_notes/dump.cs te indica la forma de cada estructura incluso antes de ejecutar, porque enumera cada campo que el cliente lee.
Un orden sensato para atacarlo:
decompile_targets.py) y lee los campos exactos.ASSET_INVENTORY.txt, por lo que solo estás creando números y definiciones de habilidades, no activos.TECHNICAL_NOTES.md para las claves.Sé realista sobre la escala. Incluso para juegos donde los fanáticos guardaron los datos del servidor en vivo antes del cierre, montar un servidor privado es un proyecto largo. Aquí no hay datos guardados para empezar, por lo que cada número y cada habilidad debe investigarse o reinventarse y luego verificarse contra el cliente. Esto es un esfuerzo de varias personas y varios años si el objetivo es el juego real. Dicho esto, el camino ya no es un misterio. El arranque está resuelto, el bucle de retroalimentación existe, el modelo de tipo está volcado y los activos están intactos. Lo que queda es una cantidad muy grande de reconstrucción cuidadosa de datos, no más ingeniería inversa de lo desconocido.
Comienza con TECHNICAL_NOTES.md. Es la referencia técnica más profunda, con los parches exactos, las formas de datos recuperadas y los hallazgos específicos, con más detalle que este README. Luego ejecuta el bucle.
Buena suerte. Ahora es una máquina real. Solo necesita que se reconstruya su contenido.