 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
NuclearPowered Master Cheater
Reputation: 0
Joined: 30 Dec 2007 Posts: 345
|
Posted: Fri Feb 15, 2008 4:24 pm Post subject: C++ ASM script? |
|
|
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 |
|
 |
FerrisBuellerYourMyHero Master Cheater
Reputation: 0
Joined: 14 Feb 2007 Posts: 401 Location: Inside your <kernel>
|
Posted: Fri Feb 15, 2008 5:34 pm Post subject: |
|
|
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
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...
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
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
regular stack without using the [ReturnMe] method
{TOP}
{ EDI }
{ ESI }
{ RETURN ADDY }
fixed stack using the return me method
{TOP}
{ RETURN ADDY }
{ EDI }
{ ESI }
_________________
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 |
|
 |
NuclearPowered Master Cheater
Reputation: 0
Joined: 30 Dec 2007 Posts: 345
|
Posted: Sat Feb 16, 2008 6:23 am Post subject: |
|
|
| I finally get it, thanks for your help, your explanation was incredible!
|
|
| Back to top |
|
 |
|
|
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
|
|