 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
xcynic Cheater
Reputation: 0
Joined: 28 Aug 2010 Posts: 31
|
Posted: Tue Mar 26, 2013 3:47 pm Post subject: Need help fixing my AA script! |
|
|
Hello, I've yet again found trouble when trying to vacuum mobs out of the map (they die if the reach a certain altitude). The script I've made works portionally, but not as I want it to. I'm sure that the code is really messy, and I could use some help to make it do what I want it to.
Here's the code:
| Code: |
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048) //2kb should be enough
label(hack)
label(returnhere)
label(originalcode)
label(exit)
newmem:
cmp [267AE27C],0 // [267AE27C] = Number of mobs on the map (Havn't gotten down to finding the pointer yet)
je originalcode
pushfd
push eax
push ebx
mov ebx,(int)50000000000 //Move 5.000.000 into ebx
mov eax,"DunDefGame.exe"+00DE2288 //Pointer into eax (The value of the pointer??)
mov eax,[eax]
add eax,48
mov eax,[eax]
add eax,110
mov eax,[eax]
add eax,410
mov eax,[eax]
add eax,5c
add eax,[ebx] // Add 5.000.000 into eax
{fsave [eax-49] //Original code
ret //Original code
add [eax],al //Original code}
pop eax
pop ebx
popfd
hack:
cmp [267AE27C],0 // [267AE27C] = Number of mobs on the map
jne newmem
originalcode:
fsave [eax-49]
ret
add [eax],al
exit:
jmp returnhere
[[[["DunDefGame.exe"+00DE2288]+48]+110]+410]+5c: //Current Z value of the last spawned enemy. (Changes everytime a mob dies or spawns)
jmp newmem
nop
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
[[[["DunDefGame.exe"+00DE2288]+48]+110]+410]+5c:
fsave [eax-49]
ret
add [eax],al
//Alt: db DD 70 B7 C3 00 00 |
So basically, what I want is my script to check if there are more than 0 enemies on the map (cmp [267AE27C],0 where [267AE27C] is the value of mobs currently on the map.
Then, if the value is greater than 0 (whenever there are mobs on the map) I want the code togo down to my code, and add a value of 5.000.000 to the pointer that changes the Z position of the enemy. I then want it to check again if there are still any mobs left, and if so do the process again (The pointer shows the Z-value of the last mob that spawned. If that mob dies, it shows the Z-value of the mob that spawned before it.)
Then, when there are no mobs left on the map. I want it to simply exit. (Because I'm also using the same Z-value, so if there is no monsters and it still runrs the code, I'm the one who will end up dying.)
This code works to the extent that it runs, kills one monster, then it stops. So by spam clicking this I basically get what I want, but I don't want to have to spam click Toggle on/off.
Thanks in advance. And sorry for the wall of text.
EDIT: I just noticed that the hack label is quite redundant. Also, I noticed that my character actually dies if I run the code after the mobs have died, so I'm guessing that I'm doing something very wrong here!
|
|
| Back to top |
|
 |
SteveAndrew Master Cheater
Reputation: 30
Joined: 02 Sep 2012 Posts: 323
|
Posted: Tue Mar 26, 2013 5:50 pm Post subject: |
|
|
Okay I see several problems with your script here... What mainly sticks out is that your code isn't even running! lol...
You haven't hooked a proper address to hook. You can't hook data, you can only hook code...
[[[["DunDefGame.exe"+00DE2288]+48]+110]+410]+5c
Like you said that is a pointer to the current monsters Z coordinate... You can't hook that, but you can change it's value. Which is the only reason why your script seems to 'work' upon enabling/disabling it the re-enabling it, etc...
Your just changing the value of the address that pointer points to, to some value 'e9 ? ? ?' which had your desired effect just by changing it some some random value
I confirmed this by single line assembling 'fsave [eax-49]' then 'ret' into some memory I allocated then adding that address to my ct... it equals: (float)-366.8817444 which seems like that was probably the monsters coordinate when you made that script. If you haven't noticed looking at that address after going back into the game and coming back out, you'll see that 'code' change, that's because it isn't code it's data [though CE still tried to assemble it as if it was code, that's where you'll have to learn to be able to tell what is data and what is code [it's usually code that doesn't look like it makes any sense, which is what that looks like to me]
Have that pointer added to your CT and do a 'find what accesses the address pointed to by this pointer' to find a proper hook address to use... Although since you have the pointer you don't actually have to hook any address, you could just create your own thread instead, which should work pretty effectively...
Next issue:
mov ebx,(int)50000000000 //Move 5.000.000 into ebx
Since your value is a float, moving an '(int)' is not what you want, although in your case it will probably still work because since your just trying to get them off map, any ridiculous value will probably do just that... (any value not in the bounds of the map)
Also that isn't 5,000,000 (did you see how many zeros you put there?) that is a for sure overflow as in a 32-bit (4 byte) value theres only a max of 4294967295 (if treated as an unsigned value [0 - 4294967295])
mov ebx,(float)5000000.0 is probably more what you wanted...
Moving on:
| Code: |
mov eax,"DunDefGame.exe"+00DE2288 //Pointer into eax (The value of the pointer??)
mov eax,[eax]
add eax,48
mov eax,[eax]
add eax,110
mov eax,[eax]
add eax,410
mov eax,[eax]
add eax,5c
|
All that can be fine, except the last line 'add eax,[ebx] // Add 5.000.000 into eax
you had it backwards... doing any thing with [ebx] (in brackets) would crash for sure, as 5,000,000 float value is probably almost for sure not going to be a valid address, [so that's an access violation]
it should have been 'add [eax],ebx'
Since ebx contains your 5,000,000 float value and eax contains (at this point) your dynamic address of the current monsters z coordinate (or last monster that moved)
There is a simpler way to write it though...
You could have done it like this:
| Code: |
mov eax,["DunDefGame.exe"+00DE2288] //(1st pointer into eax)
mov eax,[eax+48] //second pointer into eax
mov eax,[eax+110] //third pointer into eax
mov eax,[eax+410] //fourth pointer into eax
//add 5,000,000 float value to current Z address which knocks this particular monster
//off the map
add [eax+5c],ebx
|
the last offset if you just moved into eax like 'mov eax,[eax+5c]', eax would instead contain the value of the current monsters z coordinate rather then the address of it... If you really wanted to use [eax] instead of [eax+5c] when adding ebx to it you could use lea like:
mov eax,["DunDefGame.exe"+00DE2288] //(1st pointer into eax)
mov eax,[eax+48] //second pointer into eax
mov eax,[eax+110] //third pointer into eax
mov eax,[eax+410] //fourth pointer into eax
lea eax,[eax+5c] //fifth pointer into eax
add [eax],ebx
As lea is kind of like what you were going for, which this would be equivalent:
mov eax,["DunDefGame.exe"+00DE2288] //(1st pointer into eax)
mov eax,[eax+48] //second pointer into eax
mov eax,[eax+110] //third pointer into eax
mov eax,[eax+410] //fourth pointer into eax
add eax,5c //fifth pointer into eax
add [eax],ebx
So either find a proper hook address (which you shouldn't have to use that pointer even then) or create your own thread like this, which utilizes that pointer:
| Code: |
[enable]
alloc(SuckMonstersOffMapThread,1024)
label(ExitTheThread)
label(ExitMonsterVacThread)
createthread(SuckMonstersOffMapThread)
registersymbol(ExitMonsterVacThread)
SuckMonstersOffMapThread:
push 0a
call Sleep //Always have a sleep with at least 10ms delay in any thread you make
cmp [ExitMonsterVacThread],1
je ExitTheThread
cmp [267AE27C],0 // [267AE27C] = Number of mobs on the map
je SuckMonstersOffMapThread //All monsters are vacced, so just sleep until more
mov ebx,(float)5000000.0
mov eax,["DunDefGame.exe"+00DE2288] //(1st pointer into eax)
mov eax,[eax+48] //second pointer into eax
mov eax,[eax+110] //third pointer into eax
mov eax,[eax+410] //fourth pointer into eax
//move 5,000,000 float value to current Z which knocks this particular monster
//off the map
mov [eax+5c],ebx
//I suggest mov instead of add, incase this happens so fast
//that the same monster passes through multiple times before he dies
//so that it doesn't keep adding 5,000,000 to it's z coord
jmp SuckMonstersOffMapThread
ExitTheThread:
ret
ExitMonsterVacThread:
dd 0
[disable]
ExitMonsterVacThread:
dd 1
unregistersymbol(ExitMonsterVacThread)
|
And sorry for my 'wall-o-text' as well lol! but you had some major issues with your script that I had to clear up!
_________________
|
|
| Back to top |
|
 |
foxfire9 Advanced Cheater
Reputation: 0
Joined: 23 Mar 2012 Posts: 57
|
Posted: Wed Mar 27, 2013 3:13 am Post subject: |
|
|
Use AOB Scans is much more prettier but complex, try practicing it.
For what I can see. You need to have proper arrangement of the Codes.
|
|
| Back to top |
|
 |
xcynic Cheater
Reputation: 0
Joined: 28 Aug 2010 Posts: 31
|
Posted: Wed Mar 27, 2013 3:51 am Post subject: |
|
|
| SteveAndrew wrote: |
TEXT  |
Thanks a lot for taking time to write this insightful comment! It really helped me out a lot and this will surely help me out in the future aswell!
I just have a couple of questions, if that's alright
Firstly, what exactly does the "push 0a" do? Is this for the "ret" command to know where it's supposed to return to?
Secondly, if I find a pointer for the number of mobs on the map ([267AE27C]) in this case, can I just do the same thing for it?
Example:
| Code: |
//Let's say that the pointer for the mobs on map is:
//"ddgame.exe+12345"+5+30+50+1
mov esi,["ddgame.exe+12345"] //Use a random register that isn't being used.
mov esi,[esi+5]
mov esi,[esi+30]
mov esi,[esi+50]
cmp [esi+1],0
je SuckMonstersOffMapThread
|
And for my 3rd, and final question. Does the call sleep command by default use a 10ms delay? Or did you somehow set it to 10ms?
Thanks again for your help!
|
|
| Back to top |
|
 |
foxfire9 Advanced Cheater
Reputation: 0
Joined: 23 Mar 2012 Posts: 57
|
Posted: Wed Mar 27, 2013 4:25 am Post subject: |
|
|
0A (hex) = 10 (dec)
For what I understand "call" and "ret" are similar.
Ex:
call Sleep
is equal
ExitTheThread:
ret
Therefore, you're creating sleep command for where it is. And your pushing 10 or 0A to "Sleep". So when it jumps to "Sleep" you push the value 0A to delay the process.
|
|
| Back to top |
|
 |
xcynic Cheater
Reputation: 0
Joined: 28 Aug 2010 Posts: 31
|
Posted: Wed Mar 27, 2013 4:48 am Post subject: |
|
|
| foxfire9 wrote: | 0A (hex) = 10 (dec)
For what I understand "call" and "ret" are similar.
Ex:
call Sleep
is equal
ExitTheThread:
ret
Therefore, you're creating sleep command for where it is. And your pushing 10 or 0A to "Sleep". So when it jumps to "Sleep" you push the value 0A to delay the process. |
Ah, ofcourse! I should have figured that out.
I'm still a bit confused over the "ret" part though. Does it return directly to the sleep command? If so, doesn't it skip the push part and then shouldn't the sleep part be quite redundant?
Thanks again
EDIT:
Just found this ""RETurn from subroutine", and this typically involves popping a return address from the top of the stack and jumping to that address."
So I guess it means that it pops the 0a and then runs the code from there?
|
|
| Back to top |
|
 |
SteveAndrew Master Cheater
Reputation: 30
Joined: 02 Sep 2012 Posts: 323
|
Posted: Wed Mar 27, 2013 10:39 am Post subject: |
|
|
push 0a
is the same as push #10
0x0a (hex) == 10 decimal
it's pushing the parameter for sleep (to sleep for approximately 10 milliseconds)
| Code: |
VOID WINAPI Sleep(_In_ DWORD dwMilliseconds);
|
Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx
Sleep cleans up this parameter off the stack itself noted by 'WINAPI' keyword which means '__stdcall' it's the calling convention. In stdcall the callee (the function you are calling) is responsible for cleaning up the stack. Some functions/api's that are __cdecl you will have to clean up the stack yourself after the call...
Note that the push 0a, and call to Sleep need to both be there... (there is no 'default' time for sleep, you have to specify with your pushed parameter how long to sleep for)
If you wanted it to sleep for longer say about 1 second perhaps... you could do:
| Code: |
push 3e8 //1,000 milliseconds approximately
call Sleep
|
Or:
| Code: |
push #1000
call Sleep
|
whichever way you want to write it...
The only reason the sleep is even in there, is to not hog the CPU with your thread... Sleep actually doesn't just put your thread to sleep, in lets other threads do their thing while your thread is 'sleeping'...
When you create a thread, the return address on the stack will exit the thread... If however you're forcing some other thread to quit that isn't your own (because likely it will be in the middle of other things [that proper exit thread address wont be on the top of the stack to just do 'ret'] so you would:
| Code: |
push 0
call ExitThread
|
So if you put this instead of the just the 'ret' it would work equally as well...
(Note this is why I called that label 'ExitTheThread' rather than just 'ExitThread' to not confuse with the API with that name:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682659(v=vs.85).aspx
| Code: |
ExitTheThread:
push 0
call ExitThread
|
If you haven't noticed the only way it will ever reach that label 'ExitTheThread' is when you disable the script.... (It changes 'ExitMonsterVacThread' to 1, which causes this 'cmp [ExitMonsterVacThread],1' to set the Zero Flag (ZF) then the next instruction 'je ExitTheThread' the conditional jump is taken) If you noticed upon enabling that dword value 'ExitMonsterVacThread' is set to zero with
'ExitMonsterVacThread:
dd 0'
and upon disabling set to 1:
'ExitMonsterVacThread:
dd 1'
All other code paths keep the thread in an infinite loop (main reason why the sleep is there)
'je SuckMonstersOffMapThread'
Keeps jumping back to the start of the infinite loop because there aren't any monsters in that address it just checked for with 'cmp [267AE27C],0' (so it skips the code that actually forces their z coordinate so high that they actually are off the map and die [to prevent you from dying as you said if the code runs and their aren't any you will die instead])
then after the code that gets them off map:
'jmp SuckMonstersOffMapThread'
which just keeps the loop going after it vacced one off map, next time it executes it will reach here again ONLY if it didn't get that address '267AE27C' to zero yet... So the code will essentially only enough to times to get them off map, then just wait for more, get them off map, etc...
Finally:
| Code: |
mov esi,["ddgame.exe+12345"] //Use a random register that isn't being used.
mov esi,[esi+5]
mov esi,[esi+30]
mov esi,[esi+50]
cmp [esi+1],0
je SuckMonstersOffMapThread
|
Yes it seems that your catching on as that looks like it will work assuming +1 is the last offset... AND it's truly a 4 byte (dword) variable... If it was 2 byte you would do:
cmp word [esi+1],0
or if it was 1 byte you would do:
cmp byte [esi+1],0
This is because it assumes it's a 4 byte value if you don't specify the keyword, so that's why I prefer not to write it when I don't have to... but some people are explicit and write it always...
_________________
|
|
| Back to top |
|
 |
xcynic Cheater
Reputation: 0
Joined: 28 Aug 2010 Posts: 31
|
Posted: Wed Mar 27, 2013 2:11 pm Post subject: |
|
|
You, my friend, is truly an awesome person for taking your time to write such an indepth guide for someone like myself!
I feel like my understanding of assembly has been taken to a new level with your expertise.
Do you have any website or ebook that you recommend for taking ASM to learning ASM to an even higher extent?
Thanks again for all your help, this world needs more people lijke yourself!
|
|
| 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
|
|