 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
bld01 How do I cheat?
Reputation: 0
Joined: 14 Nov 2010 Posts: 8
|
Posted: Sun Nov 14, 2010 5:59 pm Post subject: [supcom] need help ^^ [resolved] |
|
|
Hello all,
I use cheat engine for a while, some games are really too hard to finish ^^ But I like to code and I tried to make a trainer for supreme commander. This game is prety cool, not too hard but I took it for exercice
The point is to have illimited ressource (mass and energy).
First I tried to find the adresses of the mass -> found ! there is a float value.
So I tried to make a trainer that change the value on this adresses, It runs but if you change the map, it fails so I guess the adress is changing everytime a map is started.
I though it's better to find the instruction that write the value at the adress of mass : found ! it's a ...
After a look at the register, I saw xmm1 is the maximum amout of mass you can have in the game. Eureka! Its simple ^^
I made a code injection very simple :
that runs just before the movss [edi], xmm0, like that, everytime the movss put the value in the adress of the amount of mass, it puts the maximum amount -> the mass is everytime to the maximum The trainer runs ok ^^
BUT.........
AFter a quick look, i saw that the energy is ALSO to the maximum.... MMMMM.... there is a bug somewhere......
After some reflection, I think the problem is the instruction movss is a part of a routine used for EVERY player and EVERY ressource... so the trainer gives maximum of mass (and energy...) to every player, AI player too....
I tried to find a way to understand how to know where the routine is runs for my player but I block.... How to find that?????
I put you a part of the code all around the movss instruction, maybe U can bring me light in this shadow ^^
| Code: | 00767571 - 8b 31 - mov esi,[ecx]
00767573 - 8b 51 04 - mov edx,[ecx+04]
00767576 - f3 0f 10 44 84 34 - movss xmm0,[esp+eax*4+34]
0076757C - 89 74 24 5c - mov [esp+5c],esi
00767580 - 8b f2 - mov esi,edx
00767582 - 81 e2 ff ff ff 7f - and edx,7fffffff
00767588 - 81 e6 00 00 00 80 - and esi,80000000
0076758E - 89 54 24 60 - mov [esp+60],edx
00767592 - df 6c 24 5c - fild qword ptr [esp+5c]
00767596 - 89 74 24 50 - mov [esp+50],esi
0076759A - 89 5c 24 4c - mov [esp+4c],ebx
0076759E - df 6c 24 4c - fild qword ptr [esp+4c]
007675A2 - d9 e0 - fchs
007675A4 - de c1 - faddp
007675A6 - d9 5c 24 24 - fstp dword ptr [esp+24]
007675AA - f3 0f 10 4c 24 24 - movss xmm1,[esp+24]
007675B0 - 0f 2f c8 - comiss xmm1,xmm0
007675B3 - 77 03 - ja moho::sim::flattenmaprect+23ab8
007675B5 - 0f 28 c1 - movaps xmm0,xmm1
007675B8 - 0f 2f d0 - comiss xmm2,xmm0
007675BB - 76 03 - jna moho::sim::flattenmaprect+23ac0
007675BD - 0f 28 c2 - movaps xmm0,xmm2
007675C0 - f3 0f 11 07 - movss [edi],xmm0
007675C4 - 83 c0 01 - add eax,01
007675C7 - 83 c1 08 - add ecx,08
007675CA - 83 c7 04 - add edi,04
007675CD - 83 f8 02 - cmp eax,02
007675D0 - 7c 9f - jnge moho::sim::flattenmaprect+23a71
007675D2 - 8b bc 24 a4 00 00 00 - mov edi,[esp+000000a4]
007675D9 - 8b 0f - mov ecx,[edi]
007675DB - 8b 91 20 09 00 00 - mov edx,[ecx+00000920]
007675E1 - 3b d3 - cmp edx,ebx
007675E3 - 8b 77 04 - mov esi,[edi+04]
007675E6 - 74 16 - je moho::sim::flattenmaprect+23afe
007675E8 - 8b 81 24 09 00 00 - mov eax,[ecx+00000924] |
I see after the movss instruction some "add" and an cmp eax,02. I guess that the comp instruction is to swap between the energy and mass, after verification it's seems to be that. I think the other add are in charge for choose the player but after some try, I found nothing to work with....
The point now is to make the same code injection but with some instruction before to make it runs only for the player. Any ideas?
Thanks a lot,
bld01
Last edited by bld01 on Wed Nov 17, 2010 8:08 am; edited 1 time in total |
|
| Back to top |
|
 |
Geri Moderator
Reputation: 112
Joined: 05 Feb 2010 Posts: 5627
|
Posted: Mon Nov 15, 2010 3:29 am Post subject: |
|
|
Yep, usually codes that are writing to an address are shared. Look for addresses that are reading Your value. Use the "Find out what acesses this address". To find all codes that are reading or writing to from/to the address.
Is writing the register's value in the memory.
If You would swap the order and the value is written to a register, than the program is reading it. There could be many reasons why a program would read Your resources and not read the enemy's. Like displaying the amount on the screen, check if You have enough money for this or that unit and mark them as "inactive" in Your production list and things like that.
So check out the other codes that are accessing to the value and You can make the same code injection there too.
And also check that the code that You have choosen is used for You only, or for the enemies too.
_________________
|
|
| Back to top |
|
 |
bld01 How do I cheat?
Reputation: 0
Joined: 14 Nov 2010 Posts: 8
|
Posted: Mon Nov 15, 2010 11:34 pm Post subject: |
|
|
Hi Geri,
thanks for help ^^
ok i have some news :
First I put a breakpoint on the movss instruction, with that, i found the adress of the amount of mass for the AI player. When I make a memory scanning with this amout, it found 2 adresses wich contains this amount. If I search the amount of mass for me (the player), I found 4 adresses.
So i guess that the 2 more adress for the player are specefic to him.
I have to investigate more, but I think I'm on the good way
EDIT :
Yep all,
I got it I think but I block to code it.
I found that the adress of the amount of the mass of the player have everytime this form : XXXX035C (and XXXX0358 for the energy)
So it's simple to add to the routine which write the amount of ressource in the adress a code able to detect the last 4 numbers of the adress.
But my code fail, the cmp never match....
| Code: | mov ebp,edi // save the adress in ebp
cmp [ebp+4],035c // compare the 4 last bytes with 035c, i'm wrong here i think
jne notplayer // if not match, go to "notplayer"
movss xmm0,xmm1 // put the max amount in xmm0
mov ebp,00000000 // clear ebp
notplayer:
mov ebp,00000000 |
someone can help?
thanks a lot
bld01
|
|
| Back to top |
|
 |
Geri Moderator
Reputation: 112
Joined: 05 Feb 2010 Posts: 5627
|
Posted: Tue Nov 16, 2010 4:00 am Post subject: |
|
|
Now this code has more than one error.
1. When You use a register for Your own purposes, You can't just change it to 0 after You are done with it (unless it was 0 before You have changed it). You need to use the push and pop instructions. push is saving the register in the stack, and pop is loading it. so at the start, You should use "push ebp" and at the end "pop ebp" to restore it's original value.
I usually use pushad and popad which are saving/loading all register values. In some cases, You may also need to use pushfd and popfd to save the flags too, which is in this case may be changed by the cmp instruction.
2. XXXX035C is stored on 4 bytes. You can store 00-FF on one byte. Addresses are stored on 4 bytes with 8 hexadecimal digits. So 035C is actually 2 bytes only.
3. By using [ebp+4], You have compared the value on the address, not the address itself. EBP+4 would be the next address after XXXX035C anyway.
4. Don't use EBP, ESP, and EIP for Your own purposes. First 2 is needed for stack operations and EIP is pointing to the next instruction in the code, thus changing it will create a jump to the address that it is containing. Changing any of them just to store some values will most likely result in interesting tough undesired outcomes, like crashes.
5. If You want to check only some bytes of a register and not all 4 of it, check this table to see how they are built up.
http://www.sandpile.org/ia32/reg.htm
And finally, I am not sure how it is working in Supreme Commander, but there were codes in SupCom2 which was reading the player's resources only and I think there is a 90% chance that SupCom has some codes too.
Checking the last 2 digit of the address will probably not work anyway, because the enemy has the same player structure so probably it will work for the enemy too.
Proof of my theory if the value that You have found has some copies that the enemy don't have. Search for all the codes which are accessing to Your resources and You will probably find at least one which is accessing to Your resources only.
If You wouldn't find any codes that are accessing to Your resource only, You could still check the code to see how is it copied to another addresses (but this may be a long process) and You can also search for unique data in the data structure with the data dissector in CE. Using the last 2 digits of the address will probably not the best approach, but as I said, I didn't look into that specific game, I have made cheats for SupCom2 only.
EDIT:
Yeah, I may be remember wrongly, I see I have used cmp [ebx+04],0 to check if the resource is the player's or the computers in SupCom2. And the resources were stored this way.
[ebx+38] energy
[ebx+3c] mass
[ebx+40] research
Maybe the player ID is the same or similar in SupCom too. Just check the data structure. Or backtrace where are those copies for Your resource values coming from, if they are copied only for You.
_________________
|
|
| Back to top |
|
 |
bld01 How do I cheat?
Reputation: 0
Joined: 14 Nov 2010 Posts: 8
|
Posted: Tue Nov 16, 2010 5:42 am Post subject: |
|
|
Thanks for this accurate answer.
ouch, I have to study a little more the x86 asm ^^ I know only (basically) the c64 asm ^^
| Geri wrote: | Now this code has more than one error.
1. When You use a register for Your own purposes, You can't just change it to 0 after You are done with it (unless it was 0 before You have changed it). You need to use the push and pop instructions. push is saving the register in the stack, and pop is loading it. so at the start, You should use "push ebp" and at the end "pop ebp" to restore it's original value.
I usually use pushad and popad which are saving/loading all register values. In some cases, You may also need to use pushfd and popfd to save the flags too, which is in this case may be changed by the cmp instruction. |
yep understood, i used ebp because it stays at 0 during the routine runtinme but in the future I will use the stack.
| Quote: | 2. XXXX035C is stored on 4 bytes. You can store 00-FF on one byte. Addresses are stored on 4 bytes with 8 hexadecimal digits. So 035C is actually 2 bytes only.
3. By using [ebp+4], You have compared the value on the address, not the address itself. EBP+4 would be the next address after XXXX035C anyway. |
undestood (and shame on me for this mistake....) so the good one may be EBP+2?
| Quote: | | 4. Don't use EBP, ESP, and EIP for Your own purposes. First 2 is needed for stack operations and EIP is pointing to the next instruction in the code, thus changing it will create a jump to the address that it is containing. Changing any of them just to store some values will most likely result in interesting tough undesired outcomes, like crashes. |
Can I use a kind of variable instead a register ?
cmp myvariable+2,035c will make the correct test?
| Quote: |
And finally, I am ...... |
yep I will explain why I choose this (quick and easy) way. :
First I made a mistake : Ai players have 4 memory adresses that contains the mass amount as the human player.
I start the game and choose a skirmish battle. 8 slots are avalable. I see that the player is everytime on the first place. I put 7 other Ai players.
When I breakpoint to the movss instruction, It breaks on every players and the value of edi (wich contains the adress of the mass amount) is different for each player. Everytime U start a game, the 4 left digits of the adress changes but the 4 right digits are the same.
Now about the method you gave me : I checked all the 4 adresses of the human player with "what acces to this adress", i made that too for a ai player. the results are :
| Code: |
human player :
1
00767989 - f0 0f b1 0e - lock cmpxchg [esi],ecx
00767994 - f0 0f b1 33 - lock cmpxchg [ebx],esi
2
00767cea - f3 0f 10 4f 1c - movss xmm1,[edi+1c]
007039a6 - b9 0e 00 00 00 - mov ecx,0000000e
00766e9b - 8b 53 1c - mov edx,[ebx+1c]
007675c0 - f3 0f 11 07 - movss [edi],xmm0
0076798d - 8b 77 1c - mov esi,[edi+1c]
3
007039df - 8b fb - mov edi,ebx
007039a6 - b9 0e 00 00 00 - mov ecx,0000000e
4
00821aa6 - 8d bc 24 38 01 00 00 - lea edi,[esp+00000138]
007039df - 8b fb - mov edi,ebx
AI player :
1
00767989 - f0 0f b1 0e - lock cmpxchg [esi],ecx
00767994 - f0 0f b1 33 - lock cmpxchg [ebx],esi
2
00766e9b - 8b 53 1c - mov edx,[ebx+1c]
007675c0 - f3 0f 11 07 - movss [edi],xmm0
0076798d - 8b 77 1c - mov esi,[edi+1c]
00767cea - f3 0f 10 4f 1c - movss xmm1,[edi+1c]
007039a6 - b9 0e 00 00 00 - mov ecx,0000000e
3
007039a6 - b9 0e 00 00 00 - mov ecx,0000000e
007039df - 8b fb - mov edi,ebx
4
007039df - 8b fb - mov edi,ebx
|
3 adresses are used by the same codes (both ai and human) but one adress is used by only one code for the AI player and by 2 code for the human. the code only for the human is :
| Code: | | lea edi,[esp+00000138] |
I tried to understood what's going on around this code but it's hard for me ^^ this is why I choose to test the 035c. But I realize that is not the best way so I will try to find with the other method. Hard time for my brain
Thanks a lot for your help Geri :topcool:
bld01
|
|
| Back to top |
|
 |
Geri Moderator
Reputation: 112
Joined: 05 Feb 2010 Posts: 5627
|
Posted: Tue Nov 16, 2010 7:50 am Post subject: |
|
|
If EBP = XXXX035C, then EBP+2 = XXXX035E, not the last 2 digits of the EBP register. The last 2 digits of this register are stored on BP.
Open this table:
http://www.sandpile.org/ia32/reg.htm
Now see the first register, EAX. It is a 32-bit register, so it is stored on 4 bytes. The last 2 bytes can be referred as AX, the 3rd byte as AH and the 4th byte as AL.
In Your case, the last 2 bytes of EBP are BP. Which means BP=035C.
Of course You can use an allocated variable for the compare, but still, You need to be aware that storing EDI+2 on the variable will not be the last 2 digits of EDI, but XXXX035C+2, which is XXXX035E. The last 2 digits can be referenced as DI. Try to save BP or DI on another register or value and see what happens in the debugger. You will see how is it operating with the values.
Anyway this method may work in this game, but I have never tried it.
It was easy to find a player ID in SupCom2 though. The code to change the mass has looked like this:
SupremeCommander2.exe+4BA2CB Change Mass :mov edx,[ebx+3c]
For the energy:
SupremeCommander2.exe+4BA2C8 Change Energy :mov ecx,[ebx+38]
And for the research:
SupremeCommander2.exe+4BA2C5 Change Research :mov eax,[ebx+40]
As You can see, they are stored right after each other in the data structure. I have compared the data of my structure and the enemy structure from EBX, and came to this conclusion:
If the value on [ebx+04] is 0, then the structure belongs to the human player. If not 0, it is an AI controlled player's data. So my script was simply like that:
cmp [ebx+04],0 //check player ID
jne +7 //jump if not player
mov [ebx+3c],47C34F80 //change mass to 999999999
mov edx,[ebx+3c] //continues the original code
Now this is a much more reliable method and it was easy to find it too, so maybe You should check if You can see some similar player ID in SupCom. If You use the data dissector in CE, You can easily compare data structures and see what is common or different between Your data structure and between the enemy's. Then You can make a compare for that data to see if it is Your resource or not and make the neccessary steps according to that.
_________________
|
|
| Back to top |
|
 |
bld01 How do I cheat?
Reputation: 0
Joined: 14 Nov 2010 Posts: 8
|
Posted: Wed Nov 17, 2010 3:01 am Post subject: |
|
|
Hi there,
So the 035c method fails, it finally changes.
SO I try your method Geri, but I found nothing valable. I analyze the data structures of the players but nothing seems to be different bewteen them, here's an example (human player):
| Code: | 0000 - Float 2425
0004 - Float 392,5
0008 - Float 1
000C - Float 0,100000001490116
0010 - Dword 0
0014 - Dword 0
0018 - Dword 1086324736
001C - Dword 1058642330
0020 - Dword 1086324736
0024 - Dword 1058642330
0028 - Dword 2500
002C - Dword 0
0030 - Dword 400
0034 - Dword 0
0038 - Byte 192
0039 - Byte 19
003A - Word 10082
003C - Dword 779382785
0040 - pointer to ->2BCB8B18
0044 - pointer to ->2BCB8B18
0048 - pointer to ->27642980
004C - Dword 0
0050 - pointer to ->0000000E
0054 - pointer to ->21C44C80 |
the first line is energy, the second is mass, when compare with ai players structure, it seems to be identical. I try to follow the construction of the adresse store in edi but i finally lost my way....
I pause a litlle now, 6 hours to scan memory have reduce my brain in ashes
|
|
| Back to top |
|
 |
Geri Moderator
Reputation: 112
Joined: 05 Feb 2010 Posts: 5627
|
Posted: Wed Nov 17, 2010 4:47 am Post subject: |
|
|
I see You have found out how to use the dissector, but You are missing one thing. You have to compare them from the base address of the data structure. The base address is usually the register between the brackets.
In Your case, it is seems to be edi, but it is obviously not. That is just a code which are changing more types of data. However looking at Your code, I see that some codes are using [edi+1c] usually. So I would say that
| Code: | | base address + 1C = address of mass |
Which of course also means that
| Code: | | address of mass - 1C = base address |
And if mass is stored on 1C, then energy is stored on
Calculate the base address or just check the register's value when the code with [edi+1c] is executed and start comparing the data from there.
Btw. You don't even need to calculate anything. You can put addresses in the data dissector in this form too:
XXXXXXXX-1C (where the address with X is the address of the mass of course, so just type in the address of mass-1C).
Then CE will calculate it for You (pretty cool, save lots of times for You).
Find the mass for let's say 4 players (3 enemies and You) and compare the structure from the base address. Probably You will see some obvious number for each player like 0,1,2,3 or similar (at least there was in SupCom2). Then You can just write a code to check the value on "base address+the offset You have found" and check if it is Your structure or not.
EDIT:
Btw. You have posted the data of the player only but I hope You see that You can "Add extra address" to put more structures next to each other for easier comparing.
_________________
|
|
| Back to top |
|
 |
bld01 How do I cheat?
Reputation: 0
Joined: 14 Nov 2010 Posts: 8
|
Posted: Wed Nov 17, 2010 7:36 am Post subject: |
|
|
Yep Geri,
I think it's okay ^^
I compare 4 players, but when I check EDI-1C, I saw nothing....
So I think maybe have something before that. I check the 4 players with EDI-2C, I redefined the structure and this is what I found :
| Code: | 0000 - String 001_lod0.scm ? ? ?
000D - Byte 1 0 0 0
000E - Word 10763 0 0 0
0010 - Dword 705364391 30 0 0
0014 - pointer to ->2412E308 ->2412E308 ->2412E308 ->2412E308
0018 - Dword 0 1 2 3
001C - Dword 0 0 0 1084227584
0020 - Dword 0 0 0 1050253722
0024 - Dword 0 0 0 1084227584
0028 - Dword 0 0 0 1050253722
002C - Float 1000,03381347656 2408,80224609375 2397,20434570313 2358,40551757813
0030 - Float 379,997528076172 275,000427246094 283,499633789063 285,299224853516
0038 - Float 0,5 0,300000011920929 0,300000011920929 0,300000011920929
003C - Dword 0 0 0 0
0040 - Double 14745,6015625 1,34110464955484E-8 1,34110464955484E-8 11468,796875
0048 - Float 0,600000023841858 0 0 0,600000023841858
004C - Float 6,40000009536743 0,200000002980232 0,200000002980232 6,19999980926514
0050 - Float 0,600000023841858 0 0 0,600000023841858
0054 - Dword 2500 2500 2500 2500
0058 - Dword 0 0 0 0
005C - Dword 400 400 400 400
0060 - Dword 0 0 0 0
0064 - pointer to ->23CBCEA0 ->23CBE7A0 ->23CBE880 ->23CBE870
0068 - Byte 1 1 1 1
0069 - Byte 112 0 97 97
006A - Word 11892 0 29952 29952
006C - pointer to ->2C976280 ->1AD2EB78 ->1AD2B908 ->1AD29190
0070 - pointer to ->25997690 ->29E113A8 ->2A6DE740 ->29E11C90
0074 - Byte 176 8 8 8
0075 - Byte 48 227 227 227
0076 - Word 10331 9234 9234 9234
0078 - Dword 0 0 0 0
007C - Dword 14 681450408 681451464 681451656
0080 - Byte 128 136 72 8
0081 - Byte 104 32 33 34
0082 - Word 10315 10398 10398 10398
0084 - Dword 0 742392544 681451680 675399360
0088 - Dword 14 742392556 681451692 675399396 |
on the line 18 I see a wonderful serie ^^ 0,1,2 and 3 wich is corresponding to the player ID ^^ I'm not see it before because there was an mismatch with the type of the value (double instead of 4bytes), the structure was not correct. So i will try a code injection and see what happened. I have to check if the hack works in campaign mode too but i think this time it will be ok
Again thanks a lot for your help Geri ^^
bld01
|
|
| Back to top |
|
 |
Geri Moderator
Reputation: 112
Joined: 05 Feb 2010 Posts: 5627
|
Posted: Wed Nov 17, 2010 7:51 am Post subject: |
|
|
Yeah, it seems base address+08 is the player ID.
Sometimes the value types are not correctly recognized but the data dissector is still very cool and mostly accurate. A double-check never hurt as You have found out Yourself. Now it easy from here, You need to write the script only and build armies to kick ass.
_________________
|
|
| Back to top |
|
 |
bld01 How do I cheat?
Reputation: 0
Joined: 14 Nov 2010 Posts: 8
|
Posted: Wed Nov 17, 2010 8:03 am Post subject: |
|
|
YEAH!
It runs ^^
I made a code injection with this code :
| Code: | [ENABLE]
alloc(newmem,2048) //2kb should be enough
label(returnhere)
label(originalcode)
label(exit)
label(mass)
moho::sim::flattenmaprect+23ac0:
jmp newmem
nop
nop
returnhere:
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
cmp eax,0 // 0 = energy, 1 = mass
jne mass // if eax=1 goto mass:
cmp [edi-14],0 // check the player ID
jne originalcode // if <> 0 (not human) goto originalcode
movss xmm0,xmm1 // put the maximum energy
jmp originalcode // goto originalcode
mass:
cmp [edi-18],0 // check the player ID
jne originalcode // if <> 0 (not human) goto originalcode
movss xmm0,xmm1 // put the maximum mass
originalcode:
movss [edi],xmm0
add eax,01
exit:
jmp returnhere
[DISABLE]
moho::sim::flattenmaprect+23ac0:
movss [edi],xmm0
add eax,01
|
and it works perfectly ^^
A very big thank you for your help Geri, in these last days you make me understand many tricks with CE. A big up to you
peace,
bld01
EDIT : After check It runs ok for both campaign and skirmish here's the link to download the trainer if somebody need it :
| Code: | | http://www*fileden*com/files/2007/10/2/1477527/supcom-3217-trainer*rar |
replace the "*" by "."
|
|
| 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
|
|