Jump to content
Moopler
Sign in to follow this  
kaaskop123

Help building a new trainer

Recommended Posts

hello guys

I started again with learning some coding by remaking my old trainer.

Now i really struggly with asm language and finding pointers and stuff lol, i keep ending up at static pointers.

but i tried to put the hp/mp stathook into my trainer. can you guys have a look at it? did i missed something? cuz when i activate my stathook my game freezes.
 

Spoiler

// Stats Hook
DWORD StatHookAddy = 0x00F1F22A0;// 55 8B EC 6A FF 68 ? ? ? ? 64 A1 ? ? ? ? 50 81 EC ? ? ? ? A1 ? ? ? ? 33 C5 89 45 F0 56 57 50 8D 45 F4 64 A3 ? ? ? ? 8B F9 89 7D 84
DWORD StatHookAddy2 = 0x02AFF5C0;// CWvsContext  mov ecx, above 8D ?? ?? 53 56 57 50 E8 ?? ?? ?? ??
								 //2B 87 ? ? 00 00 3D B8 0B 00 00 76 [FUNCTION START]


int iHP, iMP;


void __declspec(naked) StatHookEnableAsm()
{
	__asm
	{
		mov eax, [StatHookAddy2] // CWvsContext
		mov eax, [eax + 0x223C]
		push esi

		// Check HP
		mov esi, [eax + 0x5A] // _ZtlSecureTear_nHP[1]
		rol esi, 05
		xor esi, [eax + 0x56] // _ZtlSecureTear_nHP[0]
		mov[iHP], esi // HP Value
		 
		// Check MP
		mov esi, [eax + 0x72] // _ZtlSecureTear_nMP[1]
		rol esi, 05
		xor esi, [eax + 0x6E] // _ZtlSecureTear_nMP[0]
		mov[iMP], esi // MP Value

		pop esi
		push ebp // Original Opcode
		mov ebp, esp // Original Opcode
		push - 01 // Original Opcode
		

	}
}
void __declspec(naked) StatHookDisableAsm()
{
	__asm
	{
		push ebp
		mov ebp, esp
		push - 01

	}
}
void StatHook(bool state)
{
	if (state)
	{
		Jump(StatHookAddy2, StatHookEnableAsm, 0);
	}
	else
	{
		Jump(StatHookAddy, StatHookDisableAsm, 0);
	}
}
void Form1::cbStatHook_CheckedChanged(System::Object^  sender, System::EventArgs^  e)
{
	if (this->cbStatHook->Checked)
	{
		StatHook(true);
	}
	else //if not checked
	{
		StatHook(false);
	}
}


void Form1::Timer1On(System::Object^  sender, System::EventArgs^  e)
{
	label1->Text = iMP.ToString();
	label2->Text = iHP.ToString();
}

 

 

Edited by kaaskop123
cleaning abit

Share this post


Link to post

Based on taking a quick glance, 

1. you are missing your return address after your original opcodes.

2. you want to change it from:

mov eax, [StatHookAddy2] // CWvsContext
mov eax, [eax + 0x223C]
push esi

to:

mov eax, [StatHookAddy2] // CWvsContext
mov eax, [eax]
mov eax, [eax + 0x223C]
push esi

 

Share this post


Link to post
mov eax,[02B24FE0]  //8B 0D ? ? ? ? 85 C9 74 ? 8B 01 6A 00 FF ? ? FF 
mov edi,[eax+15A8] //E8 ? ? ? ? 8B 8E ? ? 00 00 85 C9 74 ? 8B 01 FF ? ? 8B 8E ? ? 00 00 5E
mov edi,[edi+1B4]
mov [HP],edi
mov edx,[eax+15B0] //+4
mov edx,[edx+1B4]
mov [MP],edx

If you want an easier way to access them

Share this post


Link to post

to go to my return adress do i do it like this using the jmp DWORD?

Spoiler
On 4-6-2017 at 09:14, OuterHaven said:


mov eax,[02B24FE0]  //8B 0D ? ? ? ? 85 C9 74 ? 8B 01 6A 00 FF ? ? FF 
mov edi,[eax+15A8] //E8 ? ? ? ? 8B 8E ? ? 00 00 85 C9 74 ? 8B 01 FF ? ? 8B 8E ? ? 00 00 5E
mov edi,[edi+1B4]
mov [HP],edi
mov edx,[eax+15B0] //+4
mov edx,[edx+1B4]
mov [MP],edx

If you want an easier way to access them

 

 

 

thanks, im trying to understand how to convert all kind of scripts into c++
rather one by one at a time xD

this part is this just another hook method, because these are other adresses right, do you have to disable them the same way?

Edited by kaaskop123
added spoiler

Share this post


Link to post
Guest

Just a heads up I'm pretty sure you do not need to "hook" stats. As you can see it is just rotating left 5 then xoring by the second value.
In this case I honestly just see reading the data to be the best method you should take.

// I use generic types for this since we do not know what these values could actually be (floats / ints / misc)

// data holds the two ZtlSecure values
T data[2];

// get the result with data[1] -> rotl5 -> xor result with data[0]
T result = data[0] ^ _rotl(data[1], 5);

 

Share this post


Link to post
Spoiler

 

On 4-6-2017 at 09:14, OuterHaven said:


mov eax,[02B24FE0]  //8B 0D ? ? ? ? 85 C9 74 ? 8B 01 6A 00 FF ? ? FF 
mov edi,[eax+15A8] //E8 ? ? ? ? 8B 8E ? ? 00 00 85 C9 74 ? 8B 01 FF ? ? 8B 8E ? ? 00 00 5E
mov edi,[edi+1B4]
mov [HP],edi
mov edx,[eax+15B0] //+4
mov edx,[edx+1B4]
mov [MP],edx

If you want an easier way to access them

i been almost whole day busy trying to get hp and mp pointers hehe and finally found them and now i just noticed they are the same adresses and offsets as yours :)

Spoiler

 

Quote

#define StatBasePtr 0x02B24FE0
#define MPOffset1 0x15b0
#define MPOffset2 0x1b4
#define HPOffset1 0x15A8
#define HPOffset2 0x1B4

well its a start i think :)

tho i can't find the max hp and mp, neither the exp (no adresses popping up).

 

How i solved my thingy now to display them:

Spoiler

 

Quote

int getHP()
{
    // Get HP Structure
    unsigned long OriginalHP = GetPointedAddress(StatBasePtr, HPOffset1);
    int xMouse = ReadPointer(LPDWORD(OriginalHP), HPOffset1 );
    return (int)ReadPointer(LPDWORD(OriginalHP), HPOffset2 );
    
    
}

int getMP()
{
    // Get MP Structure
    unsigned long OriginalMP = GetPointedAddress(StatBasePtr, MPOffset1);
    int xMouse = ReadPointer(LPDWORD(OriginalMP), MPOffset1);
    return (int)ReadPointer(LPDWORD(OriginalMP), MPOffset2);


}


void Form1::Timer1On(System::Object^  sender, System::EventArgs^  e)
{
    lblHP->Text = "HP : " + System::Convert::ToString(getHP());
    lblMP->Text = "MP : " + System::Convert::ToString(getMP());
}

 

Edited by kaaskop123
added spoilers

Share this post


Link to post

small update:

got the easiest hacks are working. (just editing the bytes)

Then the ones with asm code im having isues with.

I finally managed to get the perfect stance asm working (half) but when i turn off the checkboxe, my game crashes.

i think it's due its using the space from maplestory.exe +1a22188 (if im right due the jump taking 5bytes in use?)
see the picture.

 

this is my code:

Spoiler

 


//Perfect stance
DWORD PerfectStancePtr1 = 0x01E22184; //85 F6 75 05 39 ? 10 74
DWORD PerfectStancePtr2 = 0x01E2218B; //Address of JE below
BYTE PerfectStanceEnable2[] = { 0xEB };
BYTE PerfectStanceDisable1[] = { 0x85, 0xF6, 0x75, 0x09 };
BYTE PerfectStanceDisable2[] = { 0x74 };

DWORD PerfectStancePtr1Ret = PerfectStancePtr1 + 0x05;
void __declspec(naked) PerfectStanceAsm()
{
	__asm
	{
		xor esi, esi
		nop 
		nop
		jmp PerfectStancePtr1Ret
	}
}

void PerfectStance(bool state)
{
	if (state)
	{
		Jump(PerfectStancePtr1, PerfectStanceAsm, 0);
		memcpy((void*)PerfectStancePtr2, PerfectStanceEnable2, sizeof(PerfectStanceEnable2));
	}
	else
	{
		memcpy((void*)PerfectStancePtr1, PerfectStanceDisable1, sizeof(PerfectStanceDisable1));
		memcpy((void*)PerfectStancePtr2, PerfectStanceDisable2, sizeof(PerfectStanceDisable2));
	}
}

i tried alot of things, playing with the return offset, changing the JUMP to asm INT, using push en pop esi, replacing the xor with mov esi,0; etc...

 

Would like if someone could help me abit or give me some tips

PerfectStance.png

Share this post


Link to post
9 hours ago, kaaskop123 said:

small update:

got the easiest hacks are working. (just editing the bytes)

Then the ones with asm code im having isues with.

I finally managed to get the perfect stance asm working (half) but when i turn off the checkboxe, my game crashes.

i think it's due its using the space from maplestory.exe +1a22188 (if im right due the jump taking 5bytes in use?)
see the picture.

 

this is my code:

  Reveal hidden contents

 



//Perfect stance
DWORD PerfectStancePtr1 = 0x01E22184; //85 F6 75 05 39 ? 10 74
DWORD PerfectStancePtr2 = 0x01E2218B; //Address of JE below
BYTE PerfectStanceEnable2[] = { 0xEB };
BYTE PerfectStanceDisable1[] = { 0x85, 0xF6, 0x75, 0x09 };
BYTE PerfectStanceDisable2[] = { 0x74 };

DWORD PerfectStancePtr1Ret = PerfectStancePtr1 + 0x05;
void __declspec(naked) PerfectStanceAsm()
{
	__asm
	{
		xor esi, esi
		nop 
		nop
		jmp PerfectStancePtr1Ret
	}
}

void PerfectStance(bool state)
{
	if (state)
	{
		Jump(PerfectStancePtr1, PerfectStanceAsm, 0);
		memcpy((void*)PerfectStancePtr2, PerfectStanceEnable2, sizeof(PerfectStanceEnable2));
	}
	else
	{
		memcpy((void*)PerfectStancePtr1, PerfectStanceDisable1, sizeof(PerfectStanceDisable1));
		memcpy((void*)PerfectStancePtr2, PerfectStanceDisable2, sizeof(PerfectStanceDisable2));
	}
}

i tried alot of things, playing with the return offset, changing the JUMP to asm INT, using push en pop esi, replacing the xor with mov esi,0; etc...

 

Would like if someone could help me abit or give me some tips

PerfectStance.png

It should be quite obvious what you have to do.

You're setting 5 byte (E9 XX XX XX XX) for the far jump. Then you're only restoring 4/5 bytes for the disable (85 F6 75 09), not 1A. when you reset those bytes, you've effectively changed 1A to whatever the jump-distance in E9 contained in the high byte. Add 1A to the disable-array, and it should work.

  • Like 1

Share this post


Link to post
		xor esi, esi
		nop 
		nop

That's 4 bytes, why are you using a hook (jump to your own memory) to write that? Just memcpy like you do in your second perfect stance address where you change je -> jmp, except the enable bytes would be { 0x31, 0xF6, 0x90, 0x90 }

And in the future, if you really need to jump to some allocated hook to perform your own actions, keep in mind that the initial jump is 5 bytes long, so you might need to set nops accordingly to make sure that you don't break any opcodes. This will obviously also effect the return address of your hook and whatever original opcodes/disable bytes.

Edited by DAVHEED
  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×