Aquaria 1.1.2
Posted: Fri Jun 08, 2018 9:10 am
by Slade
I'm happy to provide you with some help if you want to learn. It's not as hard as you'd think.
Non displayed values are a bit of a pain, but you can learn a few tricks that might help.
Often in these cases, the health is stored as a float, not an integer. So that helps narrow down the search. That's my usual starting point, floats, then doubles, then 4 byte integers. Just keep getting hurt and do a decrease, then find health and do an increase, until you narrow it down to a few results. Then freeze them and see what happens.
Once you've found the location, attach the debugger (new window opens), get hit and select the code in the new window, choose disassemble and stuff like below is shown. The "fsub dword ptr [esp+28]" is interesting, and using "Replace with code that does nothing" on it (right click the instruction) means you don't die - but neither does the enemy.
[CODE]"Aquaria.exe"+B710D: EB 0C - jmp Aquaria.exe+B711B
"Aquaria.exe"+B710F: DD D8 - fstp st(0)
"Aquaria.exe"+B7111: D9 86 E4 1A 00 00 - fld dword ptr [esi+00001AE4]
// ---------- INJECTING HERE ----------
"Aquaria.exe"+B7117: D8 64 24 28 - fsub dword ptr [esp+28]
"Aquaria.exe"+B711B: D9 9E E4 1A 00 00 - fstp dword ptr [esi+00001AE4]
// ---------- DONE INJECTING ----------
"Aquaria.exe"+B7121: D8 9E E4 1A 00 00 - fcomp dword ptr [esi+00001AE4]
"Aquaria.exe"+B7127: DF E0 - fnstsw ax
"Aquaria.exe"+B7129: F6 C4 01 - test ah,01[/CODE]
So restore the code, use the "Find out what addresses this instruction access" menu item (right click) and shoot / get hit - I usually freeze my health so I can't die. A bunch of addresses will show in the new window that opened. Select 3-4 including your own health, and use the data dissector and click OK on all the options. Scroll through that looking for something unique to the player. In this case it's the players name. Using that we can filter out the player hits against the enemies every time.
So instead of our code being this:
[code]
code:
fsub dword ptr [esp+28] // take one health off the player or enemy
fstp dword ptr [esi+00001AE4] // write the health back to the memory location
jmp return[/code]
We can add:
[code]
newmem:
cmp dword ptr [esi+1994], 'Naij' //compare the location at esi + 1944 with the characters name
jne code //if not correct, jump to the code portion
fstp dword ptr [esi+00001AE4] //otherwise write the health back to the memory location (skipping the fsub dword ptr [esp+28], thus not reducing our health)
jmp return //return back the the original code in the game.
[/code]
I know it isn't much, but it gives you some insight as to how the cheats are written.
I'll keep working on the table now. Health is working, food is working too, both ingredients and full recipes :)
Aquaria 1.1.2
Posted: Fri Jun 08, 2018 10:38 pm
by SunBeam
Want my old trainer source? :p
[code]
#include "stdafx.h"
#include "Resource.h"
#include
#include "cMemory.h"
#include "cProcess.h"
#include "cSigScan.h"
#define _WIN32_WINNT 0x0501
#include "commctrl.h"
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"extaLib.lib")
using namespace cMemory;
using namespace cProcess;
using namespace cSigScan;
cMemory Mem;
cProcess Proc;
cSigScan Sig;
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK IdProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
void KeyCheck();
HINSTANCE mInst;
HWND tDlg;
HWND hMsgBox;
HICON Icon;
WNDPROC OldIdProc;
HCURSOR hIdCursor = LoadCursor(NULL,IDC_HAND);
char* TrainerTitle = "Extalia presents..";
char* game = "aquaria.exe";
char* About =
"Aquaria v1.0.3 - Trainer +5
"
"Powered by extaLibâ„¢
";
//God Mode
DWORD dwGodCave = NULL;
BYTE bGodMod[] = { 0x3B, 0x05, 0x0C, 0xBA, 0x5E, 0x00, 0x75, 0x0E, 0x53,
0x8B, 0x98, 0x3C, 0x1C, 0x00, 0x00, 0x89, 0x98, 0x38,
0x1C, 0x00, 0x00, 0x5B, 0xD9, 0x80, 0x38, 0x1C, 0x00,
0x00};
BYTE bGodOrig[] = { 0xD9, 0x80, 0x38, 0x1C, 0x00, 0x00 };
//Inventory Items
BYTE bInvOrig[] = { 0x83, 0x40, 0x3C, 0xFF };
/*//Speed
DWORD dwSpdCave = NULL;
BYTE bSpdMod[] = { 0x3B, 0x35, 0x0C, 0xBA, 0x5E, 0x00, 0x75, 0x0E,
0xB8, 0xD0, 0x07, 0x00, 0x00, 0xEB, 0x15, 0x80,
0x3D, 0x14, 0xBA, 0x5E, 0x00, 0x01, 0x75, 0x09,
0xB8, 0x00, 0x00, 0x00, 0x00, 0x89, 0x86, 0xC4,
0x44, 0x00, 0x00 };
BYTE bSpdOrig[] = { 0x89, 0x86, 0xC4, 0x44, 0x00, 0x00 };
//Save Position
DWORD dwSvCave = NULL;
BYTE bSvMod[] = { };
BYTE bSvOrig = { };
//Load Position
//Magnify Naija*/
BOOL CheckProc()
{
DWORD dwProcId = NULL;
dwProcId = cProcess::ProcIdByProcName( game );
if( dwProcId == 0 )
{
MessageBox( tDlg, "Game is not running!", "Error", MB_OK );
return FALSE;
}
else
return TRUE;
}
void KeyCheck()
{
static BOOL b1Enabled = FALSE;
static BOOL b2Enabled = FALSE;
/* static BOOL b3Enabled = FALSE;
static BOOL b4Enabled = FALSE;
static BOOL b5Enabled = FALSE;
static BOOL b6Enabled = FALSE;*/
BYTE* pBaseAddress = NULL;
if (GetAsyncKeyState(VK_F1))
{
if( !CheckProc() ) return;
if( !b1Enabled )
{
//Mem.GetModBase( game, &pBaseAddress );
//dwGodCave = Mem.MakeJump( (pBaseAddress+0xF5316), 1, &bGodMod, sizeof(bGodMod) );
dwGodCave = cMemory::MakeJump(
cProcess::ProcIdByProcName(game),
(cProcess::ModBaseFromProcName( game, module ) + 0xF5316),
1,
&bGodMod,
sizeof(bGodMod) );
SetDlgItemText( tDlg, IDC_F1, "ON" );
}
else
{
Mem.GetModBase( game, &pBaseAddress );
Mem.WriteMem( (pBaseAddress+0xF5316), &bGodOrig, sizeof(bGodOrig) );
Mem.DeleteCave( (BYTE *)dwGodCave, sizeof(bGodMod) );
SetDlgItemText( tDlg, IDC_F1, "OFF" );
}
b1Enabled = !b1Enabled;
}
if (GetAsyncKeyState(VK_F2))
{
if( !CheckProc() ) return;
if( !b2Enabled )
{
Mem.GetModBase( game, &pBaseAddress );
Mem.WriteNops( (pBaseAddress+0xBF390), 4 );
SetDlgItemText( tDlg, IDC_F2, "ON" );
}
else
{
Mem.GetModBase( game, &pBaseAddress );
Mem.WriteMem( (pBaseAddress+0xBF390), &bInvOrig, sizeof(bInvOrig) );
SetDlgItemText( tDlg, IDC_F2, "OFF" );
}
b2Enabled = !b2Enabled;
}
/* if (GetAsyncKeyState(VK_F3))
{
if( !CheckProc() ) return;
if( !b3Enabled )
{
Mem.GetModBase( game, &pBaseAddress );
dwSpdCave = Mem.MakeJump( (pBaseAddress+0xAB734), 1, &bSpdMod, sizeof(bSpdMod) );
SetDlgItemText( tDlg, IDC_F3, "ON" );
}
else
{
Mem.GetModBase( game, &pBaseAddress );
Mem.WriteMem( (pBaseAddress+0xAB734), &bSpdOrig, sizeof(bSpdOrig) );
Mem.DeleteCave( (BYTE *)dwSpdCave, sizeof(bSpdMod) );
SetDlgItemText( tDlg, IDC_F3, "OFF" );
}
b3Enabled = !b3Enabled;
}
if (GetAsyncKeyState(VK_F4))
{
if( !CheckProc() ) return;
if( !b4Enabled )
{
Mem.GetModBase( game, &pBaseAddress );
Mem.WriteMem( (pBaseAddress+0x2B9E5), &bInvisMod, sizeof(bInvisMod) );
// SetDlgItemText( tDlg, IDC_INVIS, "ON");
}
else
{
Mem.GetModBase( game, &pBaseAddress );
Mem.WriteMem( (pBaseAddress+0x2B9E5), &bInvisOrig, sizeof(bInvisOrig) );
// SetDlgItemText( tDlg, IDC_INVIS, "OFF");
}
b4Enabled = !b4Enabled;
}
if( GetAsyncKeyState(VK_F5) )
{
if( !CheckProc() ) return;
if( !b5Enabled )
{
Mem.GetModBase( game, &pBaseAddress );
dwSpeedCaveAddr = Mem.MakeCave( &pSpeedCave, sizeof(pSpeedCave) );
Mem.WriteMem( (pBaseAddress+0x14BCBB), &bSpeedChange, sizeof(bSpeedChange) );
Mem.WriteMem( (pBaseAddress+0x14BCBC), &dwSpeedCaveAddr, 4 );
// SetDlgItemText( tDlg, IDC_SPEED, "ON");
}
else
{
Mem.GetModBase( game, &pBaseAddress );
Mem.WriteMem( (pBaseAddress+0x14BCBA), &bSpeedOrig, sizeof(bSpeedOrig) );
Mem.DeleteCave( (PBYTE)dwSpeedCaveAddr, sizeof(pSpeedCave) );
// SetDlgItemText( tDlg, IDC_SPEED, "OFF");
}
b5Enabled = !b5Enabled;
}
if (GetAsyncKeyState(VK_F6))
{
if( !CheckProc() ) return;
if( !b6Enabled )
{
Mem.GetModBase( game, &pBaseAddress );
Mem.WriteMem( (pBaseAddress+0x447924), &szJumpModEnabled, sizeof(szJumpModEnabled) );
// SetDlgItemText( tDlg, IDC_JUMP, "ON");
}
else
{
Mem.GetModBase( game, &pBaseAddress );
Mem.WriteMem( (PBYTE)(pBaseAddress+0x447924), &szJumpModDisabled, sizeof(szJumpModDisabled) );
// SetDlgItemText( tDlg, IDC_JUMP, "OFF");
}
b6Enabled = !b6Enabled;
}*/
Proc.CloseProc();
}
BOOL CALLBACK DialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg){
case WM_INITDIALOG:
tDlg = hwndDlg;
SetWindowSubclass(GetDlgItem(hwndDlg,IDC_LOGO), IdProc, 0, 0);
SetWindowSubclass(GetDlgItem(hwndDlg,IDC_ABOUT), IdProc, 0, 0);
SetWindowSubclass(GetDlgItem(hwndDlg,IDC_EXIT), IdProc, 0, 0);
SetWindowText(hwndDlg,TrainerTitle);
SendMessage(hwndDlg, WM_SETICON,ICON_BIG,(LPARAM)Icon);
SetTimer(hwndDlg,1,255,0);
return FALSE;
case WM_CLOSE:
KillTimer(hwndDlg,1);
EndDialog(hwndDlg,0);
return TRUE;
case WM_TIMER:
KeyCheck();
return TRUE;
case WM_COMMAND:
switch (wParam){
case IDC_LOGO:
ShellExecute(0,"open","http://www.extalia.com",NULL,NULL,SW_SHOWNORMAL);
return TRUE;
case IDC_ABOUT:
MessageBoxA(tDlg, About, "About", MB_ICONINFORMATION);
return true;
case IDC_EXIT:
KillTimer(hwndDlg,1);
EndDialog(hwndDlg,0);
return true;
}
return TRUE;
}
return FALSE;
}
LRESULT CALLBACK IdProc(HWND hWnd, UINT uMsg,WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass,DWORD_PTR dwRefData)
{
switch(uMsg){
case WM_SETCURSOR:
SetCursor(hIdCursor);
return TRUE;
default:
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
return FALSE;
}
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
Icon = (HICON)LoadImage(hInstance,(LPCSTR)IDI_ICON,IMAGE_ICON,0,0,LR_DEFAULTCOLOR);
mInst = hInstance;
DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_DIALOG),0,DLGPROC(DialogProc),0);
return 0;
}[/code]
BR,
Sun