Hace poco decidi hacer por hobby algunos hacks para Argentum Online, un juego que jugaba mucho cuando era mas chico.
Arranque super basico con unos macros con sendkeys y leyendo pixeles de la pantalla para captar vida y mana y otras cosas por el estilo. Pero bueno llegue al punto que me gustaria leer memoria o packetes y llevar mis cheats al siguiente nivel.
Puntualmente creo q el primer paso seria, leer memoria(Vida y Mana) y en base a esas lecturas reaccionar y que se presione una tecla o algo por el estilo. Ese seria un paso menos radical desde donde estoy ahora.
Me mire los cursos de Blipi sobre hacking de juegos y consegui armarme un programa que lea memoria y la escriba( PERO HECHO EN C# ) hackeando el HackMe que blipi nos dejo para su cheat de c++, anda perfecto.
pero el problema esta ahora aplicarlo a un caso real.
Estoy intentando leer la vida de un Argentum Online(Tierras de lobos AO, Imperium AO)
y en base a esa vida ejecutar una accion pero no encuentro la direccion.
Link: Tierras de lobos AO
https://mega.co.nz/#!AtoSBJYK!PKoo2v...xETw5nxcQZCVvQ
Link: Imperium Ao
http://www.imperiumao.com.ar/
Puntualmente me pasa lo mismo que a esta persona http://foro.elhacker.net/ingenieria_inversa/cheat_engine_ayuda_con_la_busqueda_de_un_address_valor-t427968.0.html
Si alguien puede ayudarme seria ideal. O me recomiendan que me saltee esto y pase directamente a leer paquetes y enviar paquetes ( leer vida/mana , enviar pociones). El tema con leer paquetes es q lo veo dificil desde c# y la verdad que mi idea es practicar este lenguaje y no volver a c/c++ ya que ahora trabajo como desarrolador .net
Les dejo el codigo del programa que hice para el HackMe 1.6 por si a alguien le sirve
Program:
Código:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ReadMemory
{
class Program
{
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
static void Main(string[] args)
{
Process process = Process.GetProcessesByName("HackMe_0.1.6")[0];
IntPtr processHandle = OpenProcess(0x001F0FFF, false, process.Id);
int structAddress = 0x00DA544C; // 0x00DA544C; Pointer to the struct that holds all values.
int firstAddress = MemoryManagment.Read(processHandle, structAddress);
int life = MemoryManagment.Read(processHandle, firstAddress + 0);
int bullets = MemoryManagment.Read(processHandle, firstAddress + 4);
int mana = MemoryManagment.Read(processHandle, firstAddress + 8);
Console.WriteLine("----- Default Values -----");
Console.WriteLine("Vida= " + life );
Console.WriteLine("Balas= " + bullets);
Console.WriteLine("Mana= " + mana);
Console.WriteLine("----- Here it starts the Cheating -----");
bool writingCompleted = false;
while (MemoryManagment.IsProcessOpen("HackMe_0.1.6"))
{
writingCompleted = MemoryManagment.Write(processHandle, firstAddress + 0, 100);
writingCompleted = MemoryManagment.Write(processHandle, firstAddress + 4, 10);
writingCompleted = MemoryManagment.Write(processHandle, firstAddress + 8, 100);
}
Console.Clear();
Console.WriteLine("Game Closed!,Cheating Completed!");
Console.ReadKey();
}
}
}
Código:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ReadMemory
{
public static class MemoryManagment
{
//Read DLL
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead);
//Write DLL
[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(IntPtr hProcess,IntPtr lpBaseAddress,byte[] lpBuffer,int dwSize,out IntPtr lpNumberOfBytesWritten);
public static bool IsProcessOpen(string name)
{
foreach (Process clsProcess in Process.GetProcesses())
{
if (clsProcess.ProcessName.Contains(name))
{
return true;
}
}
return false;
}
public static int Read(IntPtr handle, int address)
{
//1. Prepare buffer and pointer
byte[] dataBuffer = new byte[4];
IntPtr bytesRead = IntPtr.Zero;
//2. Read
ReadProcessMemory(handle, (IntPtr)address, dataBuffer, dataBuffer.Length, out bytesRead);
//3. Error handling
if (bytesRead == IntPtr.Zero)
{
Console.WriteLine("No se leyo nada!");
Console.ReadKey();
return 0;
}
if (bytesRead.ToInt32() < dataBuffer.Length)
{
Console.WriteLine("Se leyeron {0} de un total de {1} bytes!", bytesRead.ToInt32(), dataBuffer.Length.ToString());
Console.ReadKey();
return 0;
}
//4. Convert the content of your buffer to int
return BitConverter.ToInt32(dataBuffer, 0);
}
//Writes the given int to memory and returns whether all (4) bytes were written or not
public static bool Write(IntPtr handle, int address, int value)
{
//1. Create buffer and pointer
byte[] dataBuffer = BitConverter.GetBytes(value);
IntPtr bytesWritten = IntPtr.Zero;
//2. Write
WriteProcessMemory(handle, (IntPtr)address, dataBuffer, dataBuffer.Length, out bytesWritten);
//3. Error handling
if (bytesWritten == IntPtr.Zero)
{
Console.WriteLine("We didn't write anything!");
return false;
}
if (bytesWritten.ToInt32() < dataBuffer.Length)
{
Console.WriteLine("We wrote {0} out of {1} bytes!", bytesWritten.ToInt32(), dataBuffer.Length.ToString());
return false;
}
return true;
}
}
}