viernes, 2 de mayo de 2014

Hack en c++ para modificar la vida en un Juego Simple

Buenas. Os voy a hablar en esta entrada un poco de la pequeña 'investigación' que estoy haciendo. 
Mi objetivo es crear una IA que sea de capaz de jugar a un juego (cual, me lo reservo aún :p) sin que nadie se pueda dar cuenta de que es un bot. Para ello ahora mismo estoy empezando desde abajo, viendo como se relaciona un juego más básico con el pc. Aquí os esplicaré como crear un programa que te cambie la vida a la que tu quieras en el juego. El juego que voy a usar en esta prueba es el Hack, Slash, Loot (Versión 8), que es un pequeño juego de 8MB que podríais encontrar en la 'bahía del pirata' (por ejemplo xP) pero que no pondré enlaces porque tiene derechos de autor (está en Steam). Podría hacer publicidad y deciros que podeis conseguirlo gratis y original para Steam o Desura juntando puntos en ésta página. Si quisierais saber como conseguir puntos rápidos avisadme :p.

Bueno, voy a empezar consiguiendo lo primero que me hace falta... La dirección de memoria de la vida. Para ello necesitáis un programa llamado Cheat Engine, el cual podéis descargarlo de su página original o de Mega (me interesa más que lo descargueis de éste segundo :p).

Bueno. Primero abriremos el Juego. En mi caso lo he dejado como está todo y le he dado directamente a Start New Game (a la derecha del todo). Vemos que la vida comienza en 30. 

Abrimos Cheat Engine y clickeamos en el icono que hay arriba, debajo de 'File' y elegimos el juego que vamos a modificar. Escribimos un 30, seleccionamos 'Exact Value' y le damos a First Scan. Ésto buscará todos los registros que tengan un 30 como valor.
                    


A mi me han salido 665 resultados. Os aviso que las direcciones van a variar, no tiene que daros exactamente los mismos resultados que a mi.

Ahora vamos a movernos en el juego y perder algo de vida. Lo más fácil es (cuando haya un enemigo cerca) clickear en nosotros, pues esto hará pasar un turno. Cuando hayamos perdido vida, apuntamos en Value la nueva vida y le damos a Next Scan. Next Scan es una herramienta muy buena ya que lo que hace es buscar el valor entre los resultados que nos habían salido anteriormente. De ésta forma busca los resultados que antes eran 30 y ahora (en mi caso) 24. A mi solo me ha hecho falta hacer el Next Scan una vez. Si os han salido más solo debéis volver a perder vida y hacer otro Next Scan.

Hacemos doble click en la dirección y de esa forma la guardamos abajo. Ya tenemos la dirección dinámica (al final explicaré lo malo de éste tipo de direcciónes) de la vida.

Ahora vamos a ir a nuestro IDE de C++ (en mi caso Visual Studio 2013) y vamos a empezar a implementar el pequeño cheat, pero antes...
Un poco de información antes de comenzar
¿Qué son las direcciones de memoria dinámicas?
La memoria dinámica es un espacio de almacenamiento que se solicita en tiempo de ejecución. Esto quiere decir que estas direcciones, las cuales se solicitan "al momento" no siempre serán iguales. Varían, a diferencia de las direcciones de memoria estáticas (las que veremos en el próximo tutorial).
¿Qué es un puntero?
Un puntero o apuntador es una variable que referencia una región de memoria; en otras palabras es una variable cuyo valor es una dirección de memoria.Mas claro que eso, imposible.
¿Qué es un HANDLE?
Un handle (en español "manejador") es una referencia a un objeto. Wikipedia no podría ser mas claro :Los handles son usados cuando una aplicación hace referencia a bloques de memoria u objetos manejados por otro sistema.
HWND se usa para referenciar a una ventana (pertenece a user32)HANDLE para referenciar a un objeto. (pertenece a kernel32)
Fuente

El código es el siguiente:

#include <iostream>
#include <windows.h>

using namespace std;

int main()
{
 // Primero buscaremos la ventana activa.
 HWND hVentana;
 if (!(hVentana = FindWindow(NULL, "Hack, Slash, Loot.")))
 {
  MessageBox(NULL, "No se pudo encontrar la ventana", "Error", MB_OK);
  return -1;
 }
 
 system("echo Encuentra la Ventana :)");

 DWORD pid;
 if (!(GetWindowThreadProcessId(hVentana, &pid)))
 {
  MessageBox(NULL, "No se puede encontrar el ID del proceso", "Error", MB_OK);
  return -1;
 }
 system("echo Encuentra el pid :)");

 HANDLE hProcess;
 if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid)))
 {
  MessageBox(NULL, "No se pudo obtener el handle del proceso", "Error", MB_OK);
  return -1;
 }
 system("echo Encuentra el proceso :)");

 DWORD Buffer;
 DWORD BytesT;
        // Aqui debajo donde pone 0x108C76B0 teneis que poner 0x<vuestra direccion de memoria>
 ReadProcessMemory(hProcess, (LPCVOID)0x108C76B0, &Buffer, sizeof(Buffer), &BytesT);
 printf("\n La vida es de %d \n", Buffer);
 system("pause > nul");

 //Ya hemos leido la dirección. 
 //Ahora vamos a escribir en ella :p CRACKERS!!!!!
 long newBuffer;
 char *aux = "";
 cout << endl << "Introduce la nueva Vida : ";
 cin >> newBuffer;
 if (!WriteProcessMemory(hProcess, (LPVOID)0x108C76B0, &newBuffer, sizeof(newBuffer), &BytesT))
 {
  MessageBox(NULL, "No se pudo escribir la direccion de memoria", "Error", MB_OK);
  return -1;
 }
 cout << endl << "Vida Cambiada con Exito. =)" << endl;
 system("pause");
 return 0;
}

Ahora compilamos y... TACHAN!!


250 de vida, a ver quien se mete con nosotros. Ahora os diré una pequeña trampa. Si aún no habéis cerrado el Cheat Engine (no deberíais, pues no os he dado permiso :p) y clickeais abajo en la dirección guardada, en el campo value; podéis escribir un valor y se cambiará igual que como lo hemos hecho.
¿ENTONCES PARA QUÉ HEMOS HECHO TANTO LÍO DE CÓDIGO?
No me peguéis xD. Como ya he dicho, lo que quiero es crear un bot. Para ello el bot deberá leer una dirección de memoria y escribir en otras, ¿no? Pues al usar ReadProcessMemory y WriteProcessMemory ya hemos empezado a enterarnos de como vamos a poder hacer que nuestro bot se comunique con el entorno.

Ahora las malas noticias. Cuando cerremos el juego y lo volvamos a abrir la dirección de memoria habrá cambiado (eso significa que es dinámica). Por lo que (otro día cuando me entere yo mejor :p) subiré cómo arreglar esto.

Ya para acabar debo agradecer a Mad Antrax su tutorial que me ha venido de perlas. Os lo recomiendo.

Saludos ;)

No hay comentarios:

Publicar un comentario