Integración de motor mediante ingeniería inversa

Mina native mod menu

El menú no dibuja nada. Clona vtables vivas del motor y construye páginas con los controles del propio juego, así que se ve y se comporta como un menú vanilla porque lo es.

0direcciones hardcodeadas
8tipos de widget
Win + Linuxbuilds nativos

Problema

El juego incluye una API de mods con carga de código pero ninguna forma de configurarlos dentro del juego. Un overlay dibujado encima se sentiría ajeno y pelearía con la entrada, la fuente y el sonido del motor.

Enfoque de ingeniería

  • Localizar cada función del motor por firma de bytes y cada global de datos analizando desplazamientos rip-relativos: sin direcciones hardcodeadas, Windows y Linux compilan desde una sola fuente.
  • Recorrer la entidad raíz de menús del mundo para encontrar el menú de opciones, inyectar una entrada Mods y apilar objetos de menú clonados con slots de vtable de construcción de página y cursor sobrescritos.
  • Renderizar cada widget, sliders, toggles, enums, keybinds, etiquetas, botones, con la clase de control slider del propio motor; las ediciones escriben a través de punteros del mod y luego disparan callbacks para que cada mod persista sus ajustes.
  • Publicar un único header vendorizado para que cualquier mod obtenga una página de ajustes en unas quince líneas, con un handshake de ABI que omite de forma segura mods incompatibles.

Resultado

  • Funcionando y en uso activo en builds nativos de Windows y Linux, incluidos handhelds con Proton, con firmas y slots de vtable verificados contra cada binario objetivo.
  • Diseñado para degradar en vez de crashear: cuando una actualización rompe las firmas, el mod registra lo que no pudo resolver y simplemente no aparece en el menú.

El problema más difícil

El desafío

Un menú de ajustes que los jugadores no puedan distinguir de los del propio juego, en un motor sin API de UI.

La restricción

Cualquier cosa dibujada como overlay pelea con la fuente, el cursor, los sonidos y el timing de entrada del motor. La única forma de verse nativo es ser nativo, lo que implica depender de internas no documentadas que cualquier actualización puede romper.

La salida

Localizar todo por firma de bytes, clonar las vtables vivas del menú, construir páginas con el control slider del propio juego, y cuando las firmas dejen de coincidir tras una actualización, registrarlo y no aparecer en el menú en vez de crashear.

Cómo lo resolví

Los globales de datos fueron la mitad más difícil. Las funciones se encuentran por patrones de instrucciones, pero un global no tiene bytes que coincidir: se alcanza analizando el desplazamiento rip-relativo de una instrucción que una firma sí localizó. Cada firma y slot de vtable se verifica contra cada binario objetivo, incluida una comprobación a nivel de símbolos en Linux, así que un acierto erróneo desactiva el mod en vez de corromper memoria.

Los menús clonados mantienen intacto el slot RTTI en -8 de la clase original para que las consultas RTTI del motor sigan resolviendo, y la seguridad hacia los mods viene de un header vendorizado con handshake de ABI: el menú lee la versión de ABI y el tamaño del struct antes de confiar en cualquier otra cosa, y omite mods incompatibles en silencio.

Tecnologías

  • C++
  • Reverse engineering
  • Signature scanning
  • Vtable cloning
  • ABI design
  • CMake
  • Windows
  • Linux

Siguiente caso de estudio

TiP-Recomp input layer

Una capa nativa de teclado y mouse integrada a un proyecto de recompilación estática, incluyendo hooks de cámara, entrada cruda, zoom con rueda y limpieza de ciclo de vida.