Crear un trainer: Hackeando juegos para hacer trampa (I de II)

No soy muy jugón, pero cuando lo hago, me gusta jugar a mi manera. No quiero estar X tiempo en un nivel porque tal o cual enemigo resulta muy difícil o tener que rehacer un nivel porque olvidé recoger un objeto que ahora resulta vital para algo. Sí, uso trucos.

Algunos juegos incorporan un sistema de trucos integrado, cosa que se agradece, pero no son pocos los que no lo hacen. ¿Significa eso que debemos resignarnos? ¡Jamás! Lo que tenemos que hacer es tomárnoslo como un reto y… trucar el juego :D

En este caso usaré como ejemplo uno de los pocos juegos a los que realmente dediqué horas en su momento: Microsoft Fury3. Si no lo conoces, tranquilo, es de 1995 y poca gente ha oído hablar de él… eran otros tiempos. Seguro que te puedes hacer por ahí con una copia cuando Sinde no mire, pero te aviso, el instalador es de 16 bits (cosas de la época) así que si estás en 64, te toca saltarte el instalador. Afortunadamente con copiar la carpeta del ejecutable a cualquier otro sitio, sirve (ventajas de la época).

¿Qué vamos a hacer?

El objetivo es crear un “trainer”, un programa que nos permita modificar el comportamiento del juego para darnos “ventaja”. Una de las cosas que más nos van a importar son las armas y su munición y nuestra salud. Los juegos almacenan estos valores en posiciones de memoria… y por supuesto nosotros podemos modificarla a nuestro antojo. Así pues, tenemos dos tareas, encontrar las direcciones de memoria que nos interesen para más tarde parchearlas.

En este primer post, me centraré en cómo encontrar las direcciones de memoria que queremos parchear. En la siguiente entrega veremos cómo hacer un programa que modifique esas direcciones de memoria con los valores que nos interesen.

¿Cómo encontrar las direcciones de memoria?

Para esto usaremos CheatEngine, un programa que examina la memoria de un proceso y nos deja buscar entre sus valores. Puedes hacer lo mismo con cualquier debugger… pero CheatEngine es de lo más cómodo que conozco (con diferencia).

Imaginemos que queremos encontrar nuestra salud. CheatEngine nos permite varios métodos, pero para hacerlo simple, la idea es ir haciendo suposiciones lógicas sobre cómo podría estar implementado. Yo he hecho las siguientes suposiciones sobre el valor de la posición de memoria en la que se almacena la salud:

  • La salud se almacena en una posición de memoria (vale, esto era evidente).
  • A mayor salud, mayor valor.
  • A menor salud, menor valor.
  • Valores negativos no tienen sentido.

Así pues, iniciamos Fury y empezamos a jugar. Tan pronto veamos la nave, pausamos el juego, abrimos CheatEngine y le decimos que se “adjunte” a Fury:


No he hecho suposiciones sobre valores concretos de la salud, así que empezaremos diciéndole a CheatEngine que no tenemos ni idea del valor de la posición que buscamos:

Nos dice que ha encontrado 14.651.392 direcciones de memoria… sigamos refinando la búsqueda (el número de direcciones encontradas puede variar bastante, ya que depende del momento exacto en el que se tome la muestra). Volvemos al fury y nos pegamos un par de porrazos contra el suelo para disminuir la salud. Seguimos sin saber que valor tiene la salud, pero seguro que es menor que antes, así que le decimos a CheatEngine que realice una búsqueda sobre los resultados para mostrar únicamente aquellas que hayan reducido su valor:

Ahora hay 40.148. Son muchas menos, pero aún son demasiadas, así que repetimos la operación hasta que nos quedemos con un número manejable. En mi caso, tras unas cuantas veces, me he quedado con 7 direcciones. Examinando los valores, parece claro que sólo uno tiene sentido para la salud: 004EBCA9, con valor de 135.

¿Por qué digo que 135 tiene sentido para la salud? Sencillo, en un byte se puede guardar un valor entre 0 y 255, en el juego tengo la salud más o menos a la mitad, así que un valor de 135 cuadra con eso. Probemos la teoría, digámosle a CheatEngine que cambie el valor por 255, que debería ser salud máxima. Para esto no tenéis más que hacer doble clic en la dirección de memoria para que pase a edición, y una vez allí cambiáis su valor a 255:

Efectivamente la salud se restaura a su valor máximo. ¿Qué pasaría si nos equivocáramos? Cualquier cosa, desde que se cuelgue el programa, hasta que se pare la nave o vayamos a toda pastilla… simplemente es impredecible.

Con los mismos procedimientos podemos obtener también las direcciones de memoria que manejan el Turbo y cada una de las armas. Para dejaros practicar, pondré la tabla con los resultados, pero no el procedimiento, a ver si lo lográis :)

Objeto Dirección Tamaño Parcheo sugerido
Salud 004EBCA9 Byte Ponerlo a 255 y congelarlo
Turbo 0050E050 4 Bytes Darle un valor alto, 8000 por ejemplo
Arma Dom 0050E030 4 Bytes Darle valor -1, que Fury interpreta como infinito
Arma RFL20 0050DFB8 4 Bytes Darle valor -1, que Fury interpreta como infinito
Arma BFM 0050E040 4 Bytes Darle valor -1, que Fury interpreta como infinito
Arma DC14 0050DFB0 4 Bytes Darle valor -1, que Fury interpreta como infinito
Arma FFF 0050E048 4 Bytes Darle valor -1, que Fury interpreta como infinito

La segunda y última parte de este post ya está disponible

Por Carballude

Me llamo Pablo Carballude González, soy graduado en computación con master en HCI y Seguridad Informática. Actualmente trabajo para Amazon en Seattle como Software Developer Engineer. Soy de esas personas que no saben si los textos autobiográficos deben ser en primera o tercera persona. Lo intenté en segunda, pero no le entendí nada :P

7 comentarios

  1. Excelente articulo Pablo!!! que recuerdos me han venido, al leerte, de mis pinitos trucando juegos… joder, que mayor estoy! :)

    Un abrazote titan!

  2. Que bien me vino el tuto.
    Grácias a ti he resuelto en parte una duda muy importante con respecto al cheat engine.
    ¿Como diablos se detectan valores de memoria en videojuegos, que basan su funcionamiento en relatividades y no en valores absolutos?

    Vamos simplificado: Como saber cuanto vale la vida de determinado personaje en determinado juego, si por ejemplo la vida en ese determinado juego, se expresa con una barra de color verde, que no me dice nada. Simplemente es una barra que está más o menos llena pero no me dice ningún número exacto de la vida que tengo (una relatividad).
    Practicaré con algún juego, grácias.

    Yo quiero números, no barras en los juegos jejeje.

  3. muy facil e util gracias me sirvio para distintas aplicaciones no solo juegos es genial para programar tmb esto e.e abrazo

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *