Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


C++ ASM script?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
NuclearPowered
Master Cheater
Reputation: 0

Joined: 30 Dec 2007
Posts: 345

PostPosted: Fri Feb 15, 2008 4:24 pm    Post subject: C++ ASM script? Reply with quote

Hey guys, I've been dedicating my last 2 hours to making an injectible DLL in Visual C++ using various topics on this forum, one question I still do not have answered is how I can make an address jump to a script and then back.

Anyone kind enough to spoonfeed me an example?

Let's say I want this this random addy 006D565A jumping to this script:

Code:

alloc(MyGod,64)

MyGod:
pushad
mov [ebp+c],0
mov [ebp+8],1
mov [ebp+10],0
popad
cmp [ebp+0c],ebx
jne 006D5660
jmp 006D565B


how does that work?
Help greatly appreciated.
Back to top
View user's profile Send private message
FerrisBuellerYourMyHero
Master Cheater
Reputation: 0

Joined: 14 Feb 2007
Posts: 401
Location: Inside your <kernel>

PostPosted: Fri Feb 15, 2008 5:34 pm    Post subject: Reply with quote

its very simple actually but that is not a c++ inline asm script...

it should be like this

Code:

void _declspec(naked) MyGod(void)
{
   _asm
   {
      pushad
      mov [ebp+0x0C], 0
      mov [ebp+8], 1
      mov [ebp+0x10], 0
      popad
      cmp [ebp+0x0C], ebx
      jne 0x006D5660
      push 0x006D565B
      ret
   }
}



and inline asm is a little wierd, you can't have a JMP 0x006D565B for some reason, so instead you emulate it by pushing the addy into the stack and doing a "ret" [ret just pops the address on the top of the stack and jmps to it] so its basically the same as a jump, also any hex number has to be preceded with an 0x other wise it will be read as a decimal...

ok now you've got your script in c++ ASM, and its able to compile...

next you have to decide how you want to hook it... either using c++ code, or more inline asm

I assume you want it to be hooked on the press of a hotkey right?

heres both ways of making 0x6D565A jmp to MyGod script...

but you should have put the correct address, because it doesn't make sense that it would return to 6D565B as that is one byte in front of 6D565A
it would have to be at least 5 bytes ahead of 6D565A

but even though it doesnt make sense, ill just show you anyway just for an example...

C++ method:

put this at the top of your code under your includes:
Code:

#define JMP(frm, to) (int)(((int)to - (int)frm) - 5);


now in your hotkey thread:

Code:

if(GetAsyncKeyState(VK_F12))
{
   *(BYTE*)0x006D565A = 0xE9;
   *(DWORD*)0x006D565B = JMP(0x006D565A, MyGod);
   OutputDebugStringA("DamageControl Enabled!");
}


see it changes the first byte to E9 which signifys a JMP
then completes the long jump by putting the offset to jump in the next 4 bytes... which completes the 5 bytes long jump Very Happy


inline ASM method:
Code:

if(GetAsyncKeyState(VK_F12))
{
      _asm
       {
   push eax
   push ecx
   mov eax, 0x006D565A    // source
   mov ecx, offset MyGod  // destination
   sub ecx, eax           // destination - source
   sub ecx, 5             // minus 5 = distance to jump
   mov byte ptr [eax], 0xE9   // E9 = JMP, E8 = CALL
   mov dword ptr [eax+1], ecx // complete hook
                                   // 0x006D565A now has a "JMP MyGod"
   pop ecx
   pop eax
        }

   OutputDebugStringA("DamageControl Enabled!");
}


it does exactly the same thing except its already written in ASM... the first one will convert into this anyway...

Razz

youll get the hang of it!!


also I like to do calls instead of jumps! then you don't have to know the return address, it automatically pushed into the stack for you Smile

so you would change the code like this

Code:

void _declspec(naked) MyGod(void)
{
   _asm
   {
      pushad
      mov [ebp+0x0C], 0
      mov [ebp+8], 1
      mov [ebp+0x10], 0
      popad
      cmp [ebp+0x0C], ebx
      jne 0x006D5660
      ret
   }
}


if(GetAsyncKeyState(VK_F12))
{
   *(BYTE*)0x006D565A = 0xE8; // Now it makes it a CALL instead of a JMP
   *(DWORD*)0x006D565B = JMP(0x006D565A, MyGod);
   OutputDebugStringA("DamageControl Enabled!");
}




EDIT: now that I think about it though, using a call for damage control is a bad idea, seeing as that script has a JNE in it... if it follows that jump, the return address is still on the stack since it never gets to ret, which would fuckup the stack with unpredictable results(probably a crash)

but there is a fix for it IF you really still want to use a call BUT its only particular for this script, as a value is moved into eax immediately when it follows that JNE "mov eax,[ebp-10]"

you would change the script like so:
Code:

void _declspec(naked) MyGod(void)
{
   _asm
   {
      pushad
      mov [ebp+0x0C], 0
      mov [ebp+8], 1
      mov [ebp+0x10], 0
      popad
      cmp [ebp+0x0C], ebx
      jne fixStack
      ret

      fixStack:
      pop eax
      push 0x006D5660
      ret
      
      
   }
}



Id also like to add a problem with calls, is if there are pushes in the overwritten code you have that will mess up the ret because it will pop out the last pushed value into the stack instead of the return addy so what I do to fix it is this...

lets use the CRC bypass script as an example because it has pushes in the 5 bytes of code you overwrite

Code:



DWORD ReturnMe = 0, CRCaddy = 0x00473980;

__declspec(naked) void CRC_hook()
{
   __asm
   {
      pop [ReturnMe]      //pop the return address into [ReturnMe]
      cmp ecx, 0x00400000
      jb original
      cmp ecx, 0x00780000
      ja original
      sub ecx, 0x00400000
      add ecx, [CRC]

      original:
      mov eax,[ebp+0x10]
      push esi            // these are the pushes i was talking about
      push edi            // calling a ret would pop what was in edi
                                    // instead of the real return addy
      push [ReturnMe]     // this fixes it by pushing it on top of the stack
      ret
   }
}


void EnableCRC(void)
{
   *(BYTE*)CRCaddy = 0xE8;
   *(DWORD*)((unsigned long)CRCaddy + 1) = JMP(CRCaddy, CRC_hook);
   OutputDebugStringA("CRC BYPASS ACTIVATED!!!");
}



see the push esi, push edi instructions?

attempting to do a "ret" after those are pushed into the stack would crash the game...

the value that was in edi, would be popped off the stack and it would try to jump to that "address" but its probably not an address, and even if it is, its not the proper place that it has to return... so it results in a crash...

pushing the real return address to the top of the stack fixes that problem and enables you to still use a call Smile

regular stack without using the [ReturnMe] method

{TOP}
{ EDI }
{ ESI }
{ RETURN ADDY }

fixed stack using the return me method

{TOP}
{ RETURN ADDY }
{ EDI }
{ ESI }


Cool

_________________
You know, life moves pretty fast. If you don't stop and look around once in a while, You could miss it!



Last edited by FerrisBuellerYourMyHero on Sat Feb 16, 2008 5:38 pm; edited 1 time in total
Back to top
View user's profile Send private message MSN Messenger
NuclearPowered
Master Cheater
Reputation: 0

Joined: 30 Dec 2007
Posts: 345

PostPosted: Sat Feb 16, 2008 6:23 am    Post subject: Reply with quote

I finally get it, thanks for your help, your explanation was incredible!
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites