Bueno, llegados a éste punto, toca explicar uno de los puntos más divertidos de Cheat Engine, diseccionar estructuras.
El problema que comenta nuestro amigo nanduky por desgracia es muy común en los juegos actuales. Imaginemos que encontramos la dirección de memoria donde el juego almacena nuestra vida, usamos un "find out what writes to this address" y obtenemos una dirección similar a la siguiente:
SUB [EAX+10],1
Esa línea, cada vez que es ejecutada, resta 1 a la dirección de EAX+10. Una primera tentación que podemos tener es NOPEAR esa línea o cambiarla por un
ADD [EAX+10],1
Consiguiendo así que cada vez que nos golpeen en el juego, la vida aumentará. El problema viene cuando la línea de ADD [EAX+10],1 que has modificado también se ejecuta sobre las direcciones de memoria que almacenan la vida de los ENEMIGOS (que horror! hemos hecho un cheat que pone a nuestros enemigos invencibles!!)
Eso ocurre porque el programador del juego utiliza la misma función para modificar la vida tanto del PLAYER como de los ENEMIGOS, lo que hemos de hacer en éste caso es:
Como se hace? bueno, lo mejor es explicarlo con un ejemplo REAL. Iniciamos nuestro Cheat Engine 6.3, en la ventana principal pulsamos HELP -> TUTORIAL
Ésto cargará un tutorial la mar de chulo que sirve para practicar, tiene 9 pruebas (recomiendo hacerlas todas) pero como no tenemos tiempo, usaremos el botón SKIP para ir directo a la prueba número 9:
Como podéis ver, el tutorial simula un videojuego con 4 jugadores, 2 AMIGOS y 2 ENEMIGOS. Curiosamente la vida de los AMIGOS es 100 y los ENEMIGOS 500. Para completar el tutorial tenemos que pulsar el botón RESTAR GAME AND AUTOPLAY y conseguir que ganen los AMIGOS. El sistema de autoplay es una lucha por turnos, en cada turno se resta un punto. Si lo intentas a la primera, verás que nuestros jugadores (Player1 y Player 2) se quedan sin vida mientras los enemigos tienen 400 puntos restantes...
Lo primero que hay que hacer es obtener las 4 direcciones que corresponde a la VIDA de cada uno de los jugadores, ya os avanzo que la vida es del tipo FLOAT, aquí os dejo un pantallazo con mis 4 direcciones, he editado el nombre a p1, p2, p3, p4 para que se vea fácil:
Una vez que las tenemos, hacemos click derecho sobre la dirección p1 (Player 1) y seleccionamos "find out what writes to this address", aceptamos el mensaje del debugger y a continuación pulsamos en ATTACK del Player1 para que la vida disminuya, automáticamente el debugger nos soltará que instrucción ha modificado la vida de Player1:
Vamos a observar mi ejemplo:
3349BC = Dirección vida p1
EBX = 3349B8
La instrucción mov [ebx+04],eax mueve el contenido de EAX a la dirección 3349B8+04 (Esa dirección es igual a 3349BC, mi vida!).
Está clarisimo que esa instrucción es la que modifica la vida de p1. Si yo ahora nopeo esa instrucción o la modifico, conseguiré que p1 sea invencible, el problema es que esa misma instrucción tambien modifica las vidas de p2, p3 y p4, por lo que TODOS los 4 jugadores serían invencibles. Ahora la pregunta del día:
Como saber si una instrucción modifica más de una dirección de memoria?
Hay 2 respuestas, una sería modificando (o nopeando) la instrucción y probar a ver que ocurre, la otra es usar una herramienta de cheat engine que te avisa. Para ello pulsamos el botón SHOW DISSAMBLER, automáticamente se abre el código desensamblado y nos señala nuestra instrucción. Pulsamos botón derecho y seleccionamos: Find out what addresses this instruction accesses
Nos aparece una ventana pequeña vacía, seleccionar abajo del todo el tipo de dirección, en nuestro caso os recuerdo que son FLOAT, ahora volvemos al juego (tutorial) y pulsamos 1 vez sobre los 4 botones de ATTACK, para que la vida se modifique en los 4 Players, al volver a la ventanita nueva observaremos lo siguiente:
wooow! Que significa? Pues es sencillo, CE me ha dicho las direcciones de memoria que han sido modificadas por la instrucción mov [ebx+04],eax Bien, aquí tenemos un problema, como solucionamos ésto? Vamos a diseccionar las 4 estructuras:
Abrid un notepad o Bloc de Notas y apuntar el nombre de las 4 variables (p1, p2, p3, p4) y al lado la dirección de memoria de cada una de ellas. Ahora volvemos a la ventanita y pulsamos botón derecho en el primer registro, seleccionamos la primera opción SHOW REGISTER STATES (Ctrl+R), aparece la siguiente ventana:
Miramos la instrucción maldita mov [ebx+04],eax está claro que la estructura es EBX, copiamos el valor de EBX (puedes hacer click derecho y se copia), lo pegamos en el Bloc de Notas, al lado de p1
Repetimos el proceso para los 4 registros, en cada uno de ellos obtenemos el valor EBX y lo copiamos en el Bloc de Notas tal que así:
La primera columna es el nombre, la segunda es la dirección de cada jugador y la tercera columna es el valor EBX de cada jugador. Pulsamos en STOP y CLOSE para cerrar la ventanita, volveremos a la ventana grande de DISSEMBLER. Seleccionamos TOOLS -> DISSECT DATA / STRUCTURES
Aparece una ventana más grande, vacía con una dirección de ejemplo en la parte superior:
Utilizando el primer menú FILE, añadimos un GRUPO, en cada GRUPO añadimos 2 direcciones de memoria. Puedes asignar nombres a los grupos, así es más sencillo todo. Cada grupo representa los AMIGOS y ENEMIGOS, en total tenemos 4 direcciones, 2 direcciones de cada TIPO/GRUPO:
Ahora, en esas 4 cajas de texto, introducimos los valores del Bloc de Notas, introducimos los valores EBX. Los valores EBX de p1 y p2 los pones en el mismo grupo, y el resto (p3, p4) los pones en el segundo grupo, así:
Pulsamos menú STRUCTURE -> DEFINE NEW, puedes ponerle el nombre que quieras, en mi caso VIDA, el resto de opciones las he dejado por defecto:
Alaaaaaa, ésto que es? Bueno, ésta maravillosa herramienta nos ha diseccionado las 4 estructuras, el hecho de haber utilizado GRUPOS para separar los diferentes tipos de jugadores nos permite analizar la disección con algo de ventaja, miremos el código de colores:
Según la instrucción [ebx+04] es donde se guarda la vida. Si miramos en la disección, en la línea +0004 aparece la vida de los 4 jugadores. Si miramos más, en +0015 se almacena el nombre de cada uno. Bien!! Ahora miraremos los registros morados, ya que según el código de color, el morado diferencia los GRUPOS, curiosamente +0010 tiene el valor 1 si es AMIGO y el 2 si es ENEMIGO. Está claro que éste juego utiliza EBX+10 para saber si esa estructura (Player) es un jugador real o un Mob (enemigo). Ahora cerramos todo, generamos un AA Script y lo modificamos tal que así:
No voy a entrar a explicar ASM, pero el razonamiento es sencillo. Ejecuto un CMP para comparar EBX+10, si es 1 (significa que es una estructura de Player AMIGO) salto a la zona FRIEND (la zona friend establece la vida a 100 siempre), si EBX+10 no es 1, continuo hasta la zona ORIGINAL (restar vida). Guardo el script, lo activo, le doy a AUTOPLAY y compruebo que el cheat funciona a la perfección.
================================
Bueno, pues hasta aquí la explicación de hoy. Como podéis ver CE tiene herramientas MUY divertidas que permiten al cracker poder solventar los problemas más "raros" en un juego. Ésta teoría la he usado para hacer cheats en juegos como FTL y Roger Legacy, por ejemplo.
Por favor, intentad realizar el tutorial 9 tal y como he explicado, si algo no os sale o no se entiende me avisáis y lo explico de nuevo, me duelen ya los dedos después de picar todo éste texto, fotos y colores, pero si surgen dudas os las resolveré.
Saludos
El problema que comenta nuestro amigo nanduky por desgracia es muy común en los juegos actuales. Imaginemos que encontramos la dirección de memoria donde el juego almacena nuestra vida, usamos un "find out what writes to this address" y obtenemos una dirección similar a la siguiente:
SUB [EAX+10],1
Esa línea, cada vez que es ejecutada, resta 1 a la dirección de EAX+10. Una primera tentación que podemos tener es NOPEAR esa línea o cambiarla por un
ADD [EAX+10],1
Consiguiendo así que cada vez que nos golpeen en el juego, la vida aumentará. El problema viene cuando la línea de ADD [EAX+10],1 que has modificado también se ejecuta sobre las direcciones de memoria que almacenan la vida de los ENEMIGOS (que horror! hemos hecho un cheat que pone a nuestros enemigos invencibles!!)
Eso ocurre porque el programador del juego utiliza la misma función para modificar la vida tanto del PLAYER como de los ENEMIGOS, lo que hemos de hacer en éste caso es:
- Obtener los registros bases de las estructuras
- Diseccionar las estructuras
- Buscar un offset que identifique cada estructura
- Montar un script en ASM que me permita condicionar el cheat
Como se hace? bueno, lo mejor es explicarlo con un ejemplo REAL. Iniciamos nuestro Cheat Engine 6.3, en la ventana principal pulsamos HELP -> TUTORIAL
Ésto cargará un tutorial la mar de chulo que sirve para practicar, tiene 9 pruebas (recomiendo hacerlas todas) pero como no tenemos tiempo, usaremos el botón SKIP para ir directo a la prueba número 9:
Como podéis ver, el tutorial simula un videojuego con 4 jugadores, 2 AMIGOS y 2 ENEMIGOS. Curiosamente la vida de los AMIGOS es 100 y los ENEMIGOS 500. Para completar el tutorial tenemos que pulsar el botón RESTAR GAME AND AUTOPLAY y conseguir que ganen los AMIGOS. El sistema de autoplay es una lucha por turnos, en cada turno se resta un punto. Si lo intentas a la primera, verás que nuestros jugadores (Player1 y Player 2) se quedan sin vida mientras los enemigos tienen 400 puntos restantes...
Lo primero que hay que hacer es obtener las 4 direcciones que corresponde a la VIDA de cada uno de los jugadores, ya os avanzo que la vida es del tipo FLOAT, aquí os dejo un pantallazo con mis 4 direcciones, he editado el nombre a p1, p2, p3, p4 para que se vea fácil:
Una vez que las tenemos, hacemos click derecho sobre la dirección p1 (Player 1) y seleccionamos "find out what writes to this address", aceptamos el mensaje del debugger y a continuación pulsamos en ATTACK del Player1 para que la vida disminuya, automáticamente el debugger nos soltará que instrucción ha modificado la vida de Player1:
Vamos a observar mi ejemplo:
3349BC = Dirección vida p1
EBX = 3349B8
La instrucción mov [ebx+04],eax mueve el contenido de EAX a la dirección 3349B8+04 (Esa dirección es igual a 3349BC, mi vida!).
Está clarisimo que esa instrucción es la que modifica la vida de p1. Si yo ahora nopeo esa instrucción o la modifico, conseguiré que p1 sea invencible, el problema es que esa misma instrucción tambien modifica las vidas de p2, p3 y p4, por lo que TODOS los 4 jugadores serían invencibles. Ahora la pregunta del día:
Como saber si una instrucción modifica más de una dirección de memoria?
Hay 2 respuestas, una sería modificando (o nopeando) la instrucción y probar a ver que ocurre, la otra es usar una herramienta de cheat engine que te avisa. Para ello pulsamos el botón SHOW DISSAMBLER, automáticamente se abre el código desensamblado y nos señala nuestra instrucción. Pulsamos botón derecho y seleccionamos: Find out what addresses this instruction accesses
Nos aparece una ventana pequeña vacía, seleccionar abajo del todo el tipo de dirección, en nuestro caso os recuerdo que son FLOAT, ahora volvemos al juego (tutorial) y pulsamos 1 vez sobre los 4 botones de ATTACK, para que la vida se modifique en los 4 Players, al volver a la ventanita nueva observaremos lo siguiente:
wooow! Que significa? Pues es sencillo, CE me ha dicho las direcciones de memoria que han sido modificadas por la instrucción mov [ebx+04],eax Bien, aquí tenemos un problema, como solucionamos ésto? Vamos a diseccionar las 4 estructuras:
Abrid un notepad o Bloc de Notas y apuntar el nombre de las 4 variables (p1, p2, p3, p4) y al lado la dirección de memoria de cada una de ellas. Ahora volvemos a la ventanita y pulsamos botón derecho en el primer registro, seleccionamos la primera opción SHOW REGISTER STATES (Ctrl+R), aparece la siguiente ventana:
Miramos la instrucción maldita mov [ebx+04],eax está claro que la estructura es EBX, copiamos el valor de EBX (puedes hacer click derecho y se copia), lo pegamos en el Bloc de Notas, al lado de p1
Repetimos el proceso para los 4 registros, en cada uno de ellos obtenemos el valor EBX y lo copiamos en el Bloc de Notas tal que así:
La primera columna es el nombre, la segunda es la dirección de cada jugador y la tercera columna es el valor EBX de cada jugador. Pulsamos en STOP y CLOSE para cerrar la ventanita, volveremos a la ventana grande de DISSEMBLER. Seleccionamos TOOLS -> DISSECT DATA / STRUCTURES
Aparece una ventana más grande, vacía con una dirección de ejemplo en la parte superior:
Utilizando el primer menú FILE, añadimos un GRUPO, en cada GRUPO añadimos 2 direcciones de memoria. Puedes asignar nombres a los grupos, así es más sencillo todo. Cada grupo representa los AMIGOS y ENEMIGOS, en total tenemos 4 direcciones, 2 direcciones de cada TIPO/GRUPO:
Ahora, en esas 4 cajas de texto, introducimos los valores del Bloc de Notas, introducimos los valores EBX. Los valores EBX de p1 y p2 los pones en el mismo grupo, y el resto (p3, p4) los pones en el segundo grupo, así:
Pulsamos menú STRUCTURE -> DEFINE NEW, puedes ponerle el nombre que quieras, en mi caso VIDA, el resto de opciones las he dejado por defecto:
Alaaaaaa, ésto que es? Bueno, ésta maravillosa herramienta nos ha diseccionado las 4 estructuras, el hecho de haber utilizado GRUPOS para separar los diferentes tipos de jugadores nos permite analizar la disección con algo de ventaja, miremos el código de colores:
Según la instrucción [ebx+04] es donde se guarda la vida. Si miramos en la disección, en la línea +0004 aparece la vida de los 4 jugadores. Si miramos más, en +0015 se almacena el nombre de cada uno. Bien!! Ahora miraremos los registros morados, ya que según el código de color, el morado diferencia los GRUPOS, curiosamente +0010 tiene el valor 1 si es AMIGO y el 2 si es ENEMIGO. Está claro que éste juego utiliza EBX+10 para saber si esa estructura (Player) es un jugador real o un Mob (enemigo). Ahora cerramos todo, generamos un AA Script y lo modificamos tal que así:
No voy a entrar a explicar ASM, pero el razonamiento es sencillo. Ejecuto un CMP para comparar EBX+10, si es 1 (significa que es una estructura de Player AMIGO) salto a la zona FRIEND (la zona friend establece la vida a 100 siempre), si EBX+10 no es 1, continuo hasta la zona ORIGINAL (restar vida). Guardo el script, lo activo, le doy a AUTOPLAY y compruebo que el cheat funciona a la perfección.
================================
Bueno, pues hasta aquí la explicación de hoy. Como podéis ver CE tiene herramientas MUY divertidas que permiten al cracker poder solventar los problemas más "raros" en un juego. Ésta teoría la he usado para hacer cheats en juegos como FTL y Roger Legacy, por ejemplo.
Por favor, intentad realizar el tutorial 9 tal y como he explicado, si algo no os sale o no se entiende me avisáis y lo explico de nuevo, me duelen ya los dedos después de picar todo éste texto, fotos y colores, pero si surgen dudas os las resolveré.
Saludos