 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
Ulic Qel-Droma Newbie cheater
Reputation: 0
Joined: 13 Jul 2010 Posts: 15
|
Posted: Mon Nov 26, 2012 1:00 pm Post subject: Towns - Unit Owner Help |
|
|
I am attempting to use what I think is a unit owner id to write a script that applies only to my units and I have a few questions.
I'm playing around with Towns, for the uninitiated you have citizens who build your town but get tired and hungry over time and also have health. I'd like to set/freeze these values for all my citizens. I have the unit's structure mapped out and know the offsets for Current Health, Turns to Sleep, and Turns to Eat and with a little tweak of jgoemat's table (forum.cheatengine[dot]org/viewtopic.php?t=567707&sid=2a711eea06faa9213f5cb337afdf1f3c) to find the selected unit I can create a table that lets me edit the selected unit's values. The downside is that I have to do this again and again for each unit because as soon as I click a new unit the values for the previous unit obviously unfreeze.
I have found that what writes to the Health address when I take damage or the Turns to Sleep and Turns to Eat address when they decrease is always the same. I know there is a script I could write which would prevent the game from changing the values for my units but unfortunately I can't figure out what these opcodes are doing because I don't know Assembly. Can someone recommend a resource or help me decipher it?
| Code: |
036101C8 - 8B D0 - mov edx,eax
036101CA - C1 EA 19 - shr edx,19
036101CD - 83 E2 01 - and edx,01
036101D0 - C1 E8 1C - shr eax,1C
036101D3 - 83 E0 0F - and eax,0F
036101D6 - 0F85 0C000000 - jne 036101E8
036101DC - 58 - pop eax
036101DD - 59 - pop ecx
036101DE - 3B 01 - cmp eax,[ecx]
036101E0 - 88 04 19 - mov [ecx+ebx],al
036101E3 - E9 C8000000 - jmp 036102B0
036101E8 - 83 F8 03 - cmp eax,03 <-- Could this be checking for unit owner/type? If so I am 3?
036101EB - 0F85 0C000000 - jne 036101FD
036101F1 - 58 - pop eax
036101F2 - 59 - pop ecx
036101F3 - 3B 01 - cmp eax,[ecx]
036101F5 - 89 04 19 - mov [ecx+ebx],eax <--Found writing to my health address. Could this be lowering my Health/decreasing Turns to Sleep/Eat
036101F8 - E9 B3000000 - jmp 036102B0
036101FD - 83 F8 07 - cmp eax,07
03610200 - 0F85 17000000 - jne 0361021D
03610206 - 58 - pop eax
03610207 - 59 - pop ecx
03610208 - 3B 01 - cmp eax,[ecx]
0361020A - 89 04 19 - mov [ecx+ebx],eax
0361020D - C1 E9 09 - shr ecx,09
03610210 - C6 04 0D 00503D4B 00 - mov byte ptr [ecx+4B3D5000],00
03610218 - E9 93000000 - jmp 036102B0
0361021D - 83 F8 01 - cmp eax,01
03610220 - 0F85 0D000000 - jne 03610233
03610226 - 58 - pop eax
03610227 - 59 - pop ecx
03610228 - 3B 01 - cmp eax,[ecx]
0361022A - 66 89 04 19 - mov [ecx+ebx],ax
|
If I'm right and "mov [ecx+ebx],eax" is responsible for me taking damage, turns to sleep decreasing, etc. in the script I write should I just "nop" "mov [ecx+ebx],eax" when active or is there a better way to handle this?
So…
Am I on the right track?
Does it seem like I’m reading Assembly right there?
Any advice on the script I ultimately write?
Thanks in advance to anyone who responds.
|
|
| Back to top |
|
 |
Gniarf Grandmaster Cheater Supreme
Reputation: 43
Joined: 12 Mar 2012 Posts: 1285
|
Posted: Tue Nov 27, 2012 12:21 pm Post subject: Re: Towns - Unit Owner Help |
|
|
| Ulic Qel-Droma wrote: | | I'm playing around with Towns | If you're speaking about this town: http://www.townsgame.com/ then I recommend getting a java/.jar decompiler, and maybe a java source code editor if notepad is not enough. Unless the source code is obfuscated modding the game is way easier the hacking it with cheat engine.
| Ulic Qel-Droma wrote: | | I can't figure out what these opcodes are doing because I don't know Assembly. Can someone recommend a resource or help me decipher it? | It's not really noob-friendly, but whenever I have a doubt about what an instruction does, I check Intel® 64 and A-32 Architectures Software Developer’s Manual. It's the official definition of each x86 opcode.
| Ulic Qel-Droma wrote: | | If I'm right and "mov [ecx+ebx],eax" is responsible for me taking damage, turns to sleep decreasing, etc. in the script I write should I just "nop" "mov [ecx+ebx],eax" when active or is there a better way to handle this? | At the left of mov [ecx+ebx],eax you can see 3 pairs of numbers, that means your instruction takes 3 bytes, so you should write 3 nops. Your script would then be:
| Code: | [enable]
036101F5:
nop
nop
nop
[disable]
036101F5:
mov [ecx+ebx],eax | That's for how to use the nop instruction.
But your game is in java, which means [blah blah blah] that your code code will most likely NOT be at 036101F5 the next time you restart your game simple way to check: in the memory editor, go to view->show module addresses. If each address becomes like Something.exeOR.dll+12345 then aobscans are not mandatory. Anyway, I bet the address display will not change so you should use an aobscan (scan for code signature). Your script would then look like this:
| Code: | [enable]
label(CodeToPatch)
aobscan(CodeToPatch_aob,89 04 19 E9 B3 00 00 00 83 F8 07)
registersymbol(CodeToPatch)
CodeToPatch_aob:
CodeToPatch:
nop
nop
nop
[disable]
CodeToPatch:
mov [ecx+ebx],eax
unregistersymbol(CodeToPatch) | As for the bunch of numbers on the aobscan line, it's just the bytes at the left of the instruction you want to modify + those of the few next instructions. Just pick enough so that the signature is unique/there is only one match. That's for the aobscan...
...but actually if you disable this mov I guess your game will not work as expected. Perhaps it'll crash, or at least lots of things won't work because this single instruction looks like it handle lots of stuff: you said health, food and sleep, but it probably does much more. To quickly test that, right click on "mov [ecx+ebx],eax"->replace by code that does nothing. Use the code list (main window->advanced options) when you want to restore the mov.
| Ulic Qel-Droma wrote: | | Am I on the right track? | If it were a typical game, I'd say yes, but since it's in java, go for the source code decompiler.
| Ulic Qel-Droma wrote: | | Does it seem like I’m reading Assembly right there? | Yes.
|
|
| Back to top |
|
 |
Ulic Qel-Droma Newbie cheater
Reputation: 0
Joined: 13 Jul 2010 Posts: 15
|
Posted: Wed Nov 28, 2012 6:48 pm Post subject: |
|
|
Hey Gniarf thanks.
| Quote: | | If you're speaking about this town: www[DOT]townsgame[DOT]com/ then I recommend getting a java/.jar decompiler |
I was talking about this game. I'll look into a decompiler.
| Quote: | | Intel® 64 and A-32 Architectures Software Developer’s Manual. |
Thanks I'll keep it in mind as a reference.
| Quote: | | ...but actually if you disable this mov I guess your game will not work as expected |
Nopping the region does kill the game so I guess I'll stick to manually messing with it until I can look into a decompiler
However I have one more question...
I have a script using the aobscan command to return the selected unit which I then use to create pointers to get that unit's health etc. which works most of the time, (see below) however occasionally it doesn't because when I search for the array it sometimes returns two distinct addresses relatively close together instead of one. I've tried comparing the two regions around the addresses and they are identical for many many many lines preceding and proceeding the target address so I don't really know how to handle this.
I thought maybe I could somehow limit the region it started and/or stopped searching in as it always seems to be the second address in these cases but sometimes the second address will appear in the same region as the first address did in a previous scan so....
When this come up I've been manually cheating it by searching for the array and manually inserting that address into the script.
| Code: | [ENABLE]
alloc(newmem,1024)
aobscan(aobHover,8B 94 24 ?? 01 00 00 8B B2 BC 00 00 00)
//=========================================
// Declarations
label(injectHover)
label(_Hover)
label(_returnHover)
label(pHoverBase)
label(pHoverStats)
registersymbol(injectHover)
registersymbol(pHoverBase)
registersymbol(pHoverStats)
//=========================================
// Code
newmem:
_Hover:
mov esi,[edx+000000BC] // original code
mov [pHoverBase],edx
mov [pHoverStats],esi
jmp _returnHover
//=========================================
// Variables
pHoverBase:
dd 0
pHoverStats:
dd 0
//=========================================
// Hacking Point
aobHover+7:
//????????+7:
injectHover:
jmp _Hover
nop
_returnHover:
[DISABLE]
injectHover:
// ALT: mov esi,[edx+000000BC]
db 8B B2 BC 00 00 00
unregistersymbol(injectHover)
unregistersymbol(pHoverBase)
unregistersymbol(pHoverStats)
dealloc(newmem) |
Any general advice here or is this an odd case because it's a Java game?
Thanks again.
|
|
| Back to top |
|
 |
Gniarf Grandmaster Cheater Supreme
Reputation: 43
Joined: 12 Mar 2012 Posts: 1285
|
Posted: Wed Nov 28, 2012 8:15 pm Post subject: |
|
|
There are actually 2 versions of the aobscan:
-the auto assembler command that you know.
-the lua version, that can returns multiple results (sample script).
I suggest:
1-writing a lua function (ex: MyAobScan) that will do the aobscan and put a registered label at the 2nd match if any, otherwise the first.
2-Then using an AA script like:
(changes marked with //*******)
| Code: | [enable]
alloc(newmem,1024)
//aobscan(aobHover,8B 94 24 ?? 01 00 00 8B B2 BC 00 00 00)
luacall(MyAobScan) //*******
//=========================================
// Declarations
label(injectHover)
label(_Hover)
label(_returnHover)
label(pHoverBase)
label(pHoverStats)
registersymbol(injectHover)
registersymbol(pHoverBase)
registersymbol(pHoverStats)
//=========================================
// Code
newmem:
_Hover:
mov esi,[edx+000000BC] // original code
mov [pHoverBase],edx
mov [pHoverStats],esi
jmp _returnHover
//=========================================
// Variables
pHoverBase:
dd 0
pHoverStats:
dd 0
//=========================================
// Hacking Point
//aobHover+7:
RegisteredAOBScanResult+7: //*******
//????????+7:
injectHover:
jmp _Hover
nop
_returnHover:
[DISABLE]
injectHover:
// ALT: mov esi,[edx+000000BC]
db 8B B2 BC 00 00 00
unregistersymbol(injectHover)
unregistersymbol(pHoverBase)
unregistersymbol(pHoverStats)
unregistersymbol(RegisteredAOBScanResult) //*******
dealloc(newmem) |
3-You may need to put the luacall line in a separate AA script if it is not executed before the rest of the script.
|
|
| Back to top |
|
 |
Ulic Qel-Droma Newbie cheater
Reputation: 0
Joined: 13 Jul 2010 Posts: 15
|
Posted: Wed Nov 28, 2012 11:01 pm Post subject: |
|
|
That's super helpful thanks. I've been trying to mess around with this but sadly Dark Byte's table for the tutorial never got reposted after the forum crash and I'm having some trouble...
First I run the lua script with the "LUA Engine" option in the memory viewer...
Here's the script almost verbatim Dark Byte's sample
| Code: | function _memrec_myCheat_activating(mr)
results=AOBScan("8B 94 24 ?? 01 00 00 8B B2 BC 00 00 00") --Saves my AOBScan to "results"
if (results~=nil) then --If "results" does not equal nil then...
count=stringlist_getCount(results) --Count the results
if (count>1) then --If the count is greater than 1 then...
address=stringlist_getString(results,1) -- Take the second address in "results." ,0 is the first
script=[[
label(aobresult_myCheat) --Label the second address "aobresult_myCheat"
registersymbol(aobresult_myCheat) -- Register the symbol "aobresult_myCheat"
]]..address..[[: --?????
aobresult_myCheat:
]]
autoAssemble(script);
end
object_destroy(results) --Destroys saved AOBScan
results=nil --Sets "results" equal" to nil
end
end |
I'm on board until here:
| Code: | ]]..address..[[: --?????
aobresult_myCheat:
]]
autoAssemble(script); |
What's happening there?
Second do I run this manually each time I start up cheat engine?
Lastly, I'm having trouble with the script you suggested. Line 5 is failing.
| Code: | | luacall(aobresult_myCheat) |
It says "Error in line 5 (luacall(aobresult_myCheat)) :[string "aobresult_myCheat"]1: '=' expected near '<eof>'"
What's that about?
Thanks again.
|
|
| Back to top |
|
 |
Gniarf Grandmaster Cheater Supreme
Reputation: 43
Joined: 12 Mar 2012 Posts: 1285
|
Posted: Thu Nov 29, 2012 3:38 am Post subject: |
|
|
| Ulic Qel-Droma wrote: | I'm on board until here:
| Code: | ]]..address..[[: --?????
aobresult_myCheat:
]]
autoAssemble(script); |
What's happening there? | It's some string concatenation. Lets say that address contains 12345678, this line and the few around are making the variable script contain:
| Code: | label(aobresult_myCheat) --Label the second address "aobresult_myCheat"
registersymbol(aobresult_myCheat) -- Register the symbol "aobresult_myCheat"
12345678:
aobresult_myCheat: | Does look like a simple auto assembler script, heh? Well, the next line is used to run that small script.
| Ulic Qel-Droma wrote: | | Second do I run this manually each time I start up cheat engine? | No, you only need to run it each time you use this hack for Towns, or after each modification.
Note: the big "execute" button at the bottom of the lua window will compile your function, NOT execute it.
| Ulic Qel-Droma wrote: | Lastly, I'm having trouble with the script you suggested. Line 5 is failing.
| Code: | | luacall(aobresult_myCheat) |
It says "Error in line 5 (luacall(aobresult_myCheat)) :[string "aobresult_myCheat"]1: '=' expected near '<eof>'"
What's that about? | Luacall is use to run a lua FUNCTION, so you should past the name of the function you created, _memrec_myCheat_activating, in your case. You'll probably need to remove the "mr" parameter from the function declaration if you want to use this function through luacall.
|
|
| Back to top |
|
 |
Ulic Qel-Droma Newbie cheater
Reputation: 0
Joined: 13 Jul 2010 Posts: 15
|
Posted: Thu Nov 29, 2012 8:21 pm Post subject: |
|
|
Super cool thanks.
For the record I'll post my final lua script and table here. Really the only things of value in the table are Current Health, Happiness, Turns to Eat, Turns to Sleep, and Experience. If anyone ends up using it I'd just delete the others but I left them there for completeness anyway. The table is currently set up with aobscan rather than lua so if you want lua just run the lua script and delete out/add the comments in assembler script
lua script:
| Code: | function _memrec_myCheat_activating()
results=AOBScan("8B 94 24 ?? 01 00 00 8B B2 BC 00 00 00")
if (results~=nil) then
count=stringlist_getCount(results)
if (count>1) then
address=stringlist_getString(results,1)
script=[[
label(aobresult_myCheat)
registersymbol(aobresult_myCheat)
]]..address..[[:
aobresult_myCheat:
]]
autoAssemble(script);
end
object_destroy(results)
results=nil
end
end |
| Description: |
|
 Download |
| Filename: |
Towns - v8a Full.CT |
| Filesize: |
6.73 KB |
| Downloaded: |
1519 Time(s) |
| Description: |
|
 Download |
| Filename: |
Towns - v8a.lua |
| Filesize: |
492 Bytes |
| Downloaded: |
910 Time(s) |
|
|
| Back to top |
|
 |
Ulic Qel-Droma Newbie cheater
Reputation: 0
Joined: 13 Jul 2010 Posts: 15
|
Posted: Sat Dec 01, 2012 10:24 am Post subject: |
|
|
After some more playing I've found that sometimes there's only one address, sometimes there are two, and sometimes there are three. I modified the script to grab the third address if it's there:
| Code: | function _memrec_myCheat_activating()
results=AOBScan("8B 94 24 ?? 01 00 00 8B B2 BC 00 00 00")
if (results~=nil) then
count=stringlist_getCount(results)
if (count>1) then
if (count==3) then
address=stringlist_getString(results,2) else
if (count==2) then
address=stringlist_getString(results,1)
end
end
script=[[
label(aobresult_myCheat)
registersymbol(aobresult_myCheat)
]]..address..[[:
aobresult_myCheat:
]]
autoAssemble(script);
end
object_destroy(results)
results=nil
end
end |
However I'm worried that this will keep going on forever. As it always seems to be the last address what I really want is the lua script to just grab the final address in "results." Anyone have advice on how to do that?
|
|
| Back to top |
|
 |
Gniarf Grandmaster Cheater Supreme
Reputation: 43
Joined: 12 Mar 2012 Posts: 1285
|
Posted: Mon Dec 03, 2012 12:29 pm Post subject: |
|
|
| Ulic Qel-Droma wrote: | | what I really want is the lua script to just grab the final address in "results." Anyone have advice on how to do that? | Try something like that:
| Code: | function _memrec_myCheat_activating()
results=AOBScan("8B 94 24 ?? 01 00 00 8B B2 BC 00 00 00")
if (results~=nil) then
count=stringlist_getCount(results)
address=stringlist_getString(results,count-1) -- <-most important modification here
script=[[
label(aobresult_myCheat)
registersymbol(aobresult_myCheat)
]]..address..[[:
aobresult_myCheat:
]]
autoAssemble(script);
object_destroy(results)
end
results=nil
end |
|
|
| Back to top |
|
 |
frenchiveruti Cheater
Reputation: 0
Joined: 07 Jun 2009 Posts: 35
|
|
| 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
|
|