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 


Lock to minimal value?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
oddgamer
Advanced Cheater
Reputation: 0

Joined: 19 Jan 2013
Posts: 60

PostPosted: Sat Aug 15, 2015 2:20 pm    Post subject: Lock to minimal value? Reply with quote

I have a pointer to an address in Cheat Engine. I want to lock the value in such a way that upon having an address to point to (which isn't constant), the value is no less than X, but can be more than X. Is this possible in CE?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 470

Joined: 09 May 2003
Posts: 25794
Location: The netherlands

PostPosted: Sat Aug 15, 2015 2:24 pm    Post subject: Reply with quote

Once it has a specific value press the numeric plus key to let the value increase, but never decrease

minus for the opposite

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
oddgamer
Advanced Cheater
Reputation: 0

Joined: 19 Jan 2013
Posts: 60

PostPosted: Sat Aug 15, 2015 3:31 pm    Post subject: Reply with quote

This... doesn't quite work.

The pointer directs to a value that differs for differing entities. That is, when looking at a bunch of different units they all have a value that I want to be X or higher. The problem is that if I set the thing to be 9 and then press +, then when I move to a unit that already has 10, that becomes the new minimum. I don't want that to be the new minimum, I want it to always be 9 minimum so that any unit I switch to which has 8 or less becomes 9, but ones with more than 9 are not affected, nor is the minimal value 9 altered at any point.

The reason this matters is that going from 9 to 10 triggers things for the unit which I can't find, but I only want to set it to 9 so it'll trigger after, not set it above 9 to begin with when dealing with a new unit. Right now I have to tab out of the game each time I get to a new unit and set it manually to 9 so it'll trigger the event by going to 10 and then go on to 11, 12, 13, etc. I was hoping to automate it so I wouldn't have to keep doing that as generating new units is a fairly frequent event.
Back to top
View user's profile Send private message
Eurochron89
Newbie cheater
Reputation: 1

Joined: 12 Aug 2015
Posts: 17

PostPosted: Sat Aug 15, 2015 4:22 pm    Post subject: Reply with quote

Do you need to use the Pointer or would it be possible for you to use an AoB Injection instead?
-> This would require you to use the debugger and "find out what writes to that address"

If you edit the instruction that changes this value, you could use the AoB Injection to handle the minimum value.
You could save the AoB Injection into CE's Cheat Table as a script with [Enable] and [Disable].
And then you only have to activate the script once after starting the game.
Back to top
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Sat Aug 15, 2015 4:37 pm    Post subject: Reply with quote

Right-click the address and create a hotkey
Use the hotkey to set the value to 9 on key press
Now go through each unit and press the hotkey
Back to top
View user's profile Send private message
oddgamer
Advanced Cheater
Reputation: 0

Joined: 19 Jan 2013
Posts: 60

PostPosted: Sat Aug 15, 2015 5:41 pm    Post subject: Reply with quote

I'm not sure if I need the pointer or not. I'm fairly new to using this beyond just "search for value, change value". Right now the units come up on a particular screen where I can see their stats. Each unit has the values in a specific place, of course, and when that screen isn't up the pointer shows the values as "?????????". I put in a value, and whenever I am on the screen for checking out the unit the pointer has a value which I can lock in and thus each time I switch to a new unit it updates the value for that unit, allowing me to quickly go through and reset things on all units.

With the debugger, should I be looking for what writes to the pointer itself, or what writes to the address the pointer is pointing to? Will that then work when it's a different address that the pointer is referencing later on?
Back to top
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Sat Aug 15, 2015 5:54 pm    Post subject: Reply with quote

Find what accesses (not writes) to the address the pointer is pointing to.
Click show disassembler on the instruction.
Right-click it and find out what addresses it accesses.
Verify that it's only touching the values you're expecting.
If so, Tools > Auto Assemble. Template > AOB Injection.
Paste the generated code here.
Back to top
View user's profile Send private message
Eurochron89
Newbie cheater
Reputation: 1

Joined: 12 Aug 2015
Posts: 17

PostPosted: Sat Aug 15, 2015 6:06 pm    Post subject: Reply with quote

@oddgamer: Do what Zanzer said, but just one more thing you should know:

In order to see any instructions accessing the address, you have to make sure
the game changes the value at least once while CE is "finding out what accesses this address" Wink
Back to top
View user's profile Send private message
oddgamer
Advanced Cheater
Reputation: 0

Joined: 19 Jan 2013
Posts: 60

PostPosted: Sat Aug 15, 2015 6:55 pm    Post subject: Reply with quote

Not sure I did this right. Most specifically I'm not sure I got the "verify" part of your instructions correct since I don't know how I'd verify that it's getting the values I expect. It already changes the values correctly as a pointer, so... I'm not sure what else I should do. The code generated was this:

Edit: I should add that, specifically, the lowest number I'm interested in is 99,999, not just 9! I was using that as an example.

{ Game : Civ3Conquests.exe
Version:
Date : 2015-08-15
Author : Oddgamer

This script does blah blah blah
}

[ENABLE]

aobscanmodule(INJECT CULTURE,Civ3Conquests.exe,8B 94 88 40 01 00 00 A1) // should be unique
alloc(newmem,$1000)

label(code)
label(return)

newmem:

code:
mov edx,[eax+ecx*4+00000140]
jmp return

INJECT CULTURE:
jmp code
nop
nop
return:
registersymbol(INJECT CULTURE)

[DISABLE]

INJECT CULTURE:
db 8B 94 88 40 01 00 00

unregistersymbol(INJECT CULTURE)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "Civ3Conquests.exe"+19912

"Civ3Conquests.exe"+198F8: 51 - push ecx
"Civ3Conquests.exe"+198F9: 50 - push eax
"Civ3Conquests.exe"+198FA: 52 - push edx
"Civ3Conquests.exe"+198FB: 8B CB - mov ecx,ebx
"Civ3Conquests.exe"+198FD: E8 4E 55 1E 00 - call Civ3Conquests.exe+1FEE50
"Civ3Conquests.exe"+19902: 8B CD - mov ecx,ebp
"Civ3Conquests.exe"+19904: E8 27 84 00 00 - call Civ3Conquests.exe+21D30
"Civ3Conquests.exe"+19909: 8B 44 24 10 - mov eax,[esp+10]
"Civ3Conquests.exe"+1990D: 33 C9 - xor ecx,ecx
"Civ3Conquests.exe"+1990F: 8A 48 28 - mov cl,[eax+28]
// ---------- INJECTING HERE ----------
"Civ3Conquests.exe"+19912: 8B 94 88 40 01 00 00 - mov edx,[eax+ecx*4+00000140]
// ---------- DONE INJECTING ----------
"Civ3Conquests.exe"+19919: A1 C0 72 9C 00 - mov eax,[Civ3Conquests.exe+5C72C0]
"Civ3Conquests.exe"+1991E: 83 F8 01 - cmp eax,01
"Civ3Conquests.exe"+19921: 89 54 24 18 - mov [esp+18],edx
"Civ3Conquests.exe"+19925: 89 44 24 14 - mov [esp+14],eax
"Civ3Conquests.exe"+19929: 7E 1A - jle Civ3Conquests.exe+19945
"Civ3Conquests.exe"+1992B: 8B C8 - mov ecx,eax
"Civ3Conquests.exe"+1992D: 3B CA - cmp ecx,edx
"Civ3Conquests.exe"+1992F: 7F 14 - jg Civ3Conquests.exe+19945
"Civ3Conquests.exe"+19931: 8B F8 - mov edi,eax
"Civ3Conquests.exe"+19933: 0F AF 7C 24 14 - imul edi,[esp+14]
}
Back to top
View user's profile Send private message
Eurochron89
Newbie cheater
Reputation: 1

Joined: 12 Aug 2015
Posts: 17

PostPosted: Sat Aug 15, 2015 7:19 pm    Post subject: Reply with quote

oddgamer wrote:
Most specifically I'm not sure I got the "verify" part of your instructions correct

Some games or programs will use a function for many different tasks.

If you change the instruction which accesses and changes your value, you have to make sure
that the same function does not change any other addresses you don't want to change.

In order to verify this:
1) Find what accesses (not writes) to the address the pointer is pointing to.
-> now go back to the game, make sure the game changes your value
2) Click 'show disassembler' on the instruction.
3) In the Memory Viewer Window: Right-click your instruction (should be selected already) and 'Find out what addresses this instruction accesses'.
-> now go back to the game, make sure the game changes your value
4) then in the window called 'changed addresses' make sure that only ONE address is accessed
-> this ONE address should be the same as the one pointed to by your pointer


If you notice that the instruction accesses more than one address, you could get unexpected behavior out of the game.
-> which means you should look at other instructions and better not use this one
-> or if you really need this instruction, you would have to add some conditions for the change
Back to top
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Sat Aug 15, 2015 8:18 pm    Post subject: Reply with quote

Well I can pretty much tell by the instruction that it is going to access multiple addresses you probably don't want.
When you find out what accesses your address, choose this instruction again.
Select more information and tell me the value of ECX.
Feel free to give this a try:
Code:
[ENABLE]
aobscanmodule(culture,Civ3Conquests.exe,8B 94 88 40 01 00 00 A1)
alloc(newmem,$1000)

label(code)
label(return)

newmem:

code:
mov edx,[eax+ecx*4+00000140]
cmp edx,9
jge return
mov edx,9
mov [eax+ecx*4+00000140],edx
jmp return

culture:
jmp code
nop
nop
return:
registersymbol(culture)

[DISABLE]
culture:
db 8B 94 88 40 01 00 00
unregistersymbol(culture)
dealloc(newmem)
Back to top
View user's profile Send private message
oddgamer
Advanced Cheater
Reputation: 0

Joined: 19 Jan 2013
Posts: 60

PostPosted: Sun Aug 16, 2015 2:08 pm    Post subject: Reply with quote

Okay... tried to follow the directions by starting a new game. Created my first city, changed its culture to 99,999 and let it change the culture level by ending my turn.

What I got was a mess. I couldn't tell which of the 7 "instructions" I should do the assembler on. In case it matters, I got this:

Count | Instruction
2 | 00419912 - 8B 94 88 40010000 - mov edx,[eax+ecx*4+00000140]
1 | 004B2927 - 8B 84 96 40010000 - mov eax,[esi+edx*4+00000140]
1 | 004B2947 - 89 11 - mov [ecx],edx
1 | 004B0D10 - 8B 8C 8E 40010000 - mov ecx,[esi+ecx*4+00000140]
6 | 005D37AF - 8B 94 B5 40010000 - mov edx,[ebp+esi*4+00000140]
7 | 0054235D - 3B 8C 82 40010000 - cmp ecx,[edx+eax*4+00000140]
1 | 004FCC3C - C2 E9 02 - shr ecx,02


Highlighting each one:
{00419912 - 8B 94 88 40010000 - mov edx,[eax+ecx*4+00000140]} shows:
0041990D - 33 C9 - xor ecx,ecx
0041990F - 8A 48 28 - mov cl,[eax+28]
00419912 - 8B 94 88 40010000 - mov edx,[eax+ecx*4+00000140] <<
00419919 - A1 C0729C00 - mov eax,[Civ3Conquests.exe+5C72C0]
0041991E - 83 F8 01 - cmp eax,01

EAX=0BE190F0
EBX=00740C34
ECX=00000001
EDX=0001869F
ESI=00000000
EDI=07B0CFF5
ESP=0018CE54
EBP=007409C0
EIP=00419919

================================
{004B2927 - 8B 84 96 40010000 - mov eax,[esi+edx*4+00000140]} shows:
004B2923 - 6A 00 - push 00
004B2925 - 6A 00 - push 00
004B2927 - 8B 84 96 40010000 - mov eax,[esi+edx*4+00000140] <<
004B292E - 8D 8C 96 40010000 - lea ecx,[esi+edx*4+00000140]
004B2935 - 8B 96 3C010000 - mov edx,[esi+0000013C]

EAX=0001869F
EBX=00000000
ECX=00000003
EDX=00000001
ESI=0BE190F0
EDI=00000053
ESP=0018AD80
EBP=000003E4
EIP=004B292E

================================
{004B2947 - 89 11 - mov [ecx],edx} shows:
004B2944 - 4A - dec edx
004B2945 - 23 D0 - and edx,eax
004B2947 - 89 11 - mov [ecx],edx <<
004B2949 - 8B CE - mov ecx,esi
004B294B - E8 A0E3FFFF - call Civ3Conquests.exe+B0CF0

EAX=000186A4
EBX=00000000
ECX=0BE19234
EDX=000186A4
ESI=0BE190F0
EDI=00000053
ESP=0018AD80
EBP=000003E4
EIP=004B2949

================================
{004B0D10 - 8B 8C 8E 40010000 - mov ecx,[esi+ecx*4+00000140]} shows:

004B0D09 - BB 01000000 - mov ebx,00000001
004B0D0E - 8B C7 - mov eax,edi
004B0D10 - 8B 8C 8E 40010000 - mov ecx,[esi+ecx*4+00000140] <<
004B0D17 - 3B C8 - cmp ecx,eax
004B0D19 - 7C 0B - jnge Civ3Conquests.exe+B0D26

EAX=0000000A
EBX=00000001
ECX=000186A4
EDX=000186A4
ESI=0BE190F0
EDI=0000000A
ESP=0018AD68
EBP=009B7510
EIP=004B0D17
================================

{005D37AF - 8B 94 B5 40010000 - mov edx,[ebp+esi*4+00000140]} shows:

005D37AA - 57 - push edi
005D37AB - 89 74 24 14 - mov [esp+14],esi
005D37AF - 8B 94 B5 40010000 - mov edx,[ebp+esi*4+00000140] <<
005D37B6 - 3B CA - cmp ecx,edx
005D37B8 - 0F8F 1B020000 - jg Civ3Conquests.exe+1D39D9

EAX=0BE3AFE8
EBX=00000006
ECX=00000000
EDX=000186A4
ESI=00000001
EDI=0BE3AFE8
ESP=0018ACF8
EBP=0BE190F0
EIP=005D37B6
================================
{0054235D - 3B 8C 82 40010000 - cmp ecx,[edx+eax*4+00000140]} shows:

00542353 - 8A 42 28 - mov al,[edx+28]
00542356 - 8B 8C 8D 40010000 - mov ecx,[ebp+ecx*4+00000140]
0054235D - 3B 8C 82 40010000 - cmp ecx,[edx+eax*4+00000140] <<
00542364 - 7F 0B - jg Civ3Conquests.exe+142371
00542366 - 46 - inc esi

EAX=00000001
EBX=00000001
ECX=00000001
EDX=0BE190F0
ESI=00000000
EDI=00B38C4C
ESP=0018D4A0
EBP=0BE37E40
EIP=00542364
================================
{004FCC3C - C2 E9 02 - shr ecx,02} shows:

004FCC37 - 8D 7A 08 - lea edi,[edx+08]
004FCC3A - 8B D1 - mov edx,ecx
004FCC3C - C1 E9 02 - shr ecx,02 <<
004FCC3F - F3 A5 - repe movsd
004FCC41 - 8B CA - mov ecx,edx

EAX=0BE190F0
EBX=0DBF4FFC
ECX=00000026
EDX=000000A4
ESI=0BE19238
EDI=0DBF50E4
ESP=0018CE74
EBP=00184FDE
EIP=004FCC3F
================================

I then went to the next round and created a second city. I left its culture alone but put something in it to raise the culture from 0 where it starts, then ended my turn. This second round there were 8 instructions (so, again, I didn't know what to run the assembler on), the counts changed, and the details listed when I selected them. Here is after the second round.

Count | Instruction
3 | 00419912 - 8B 94 88 40010000 - mov edx,[eax+ecx*4+00000140]
2 | 004B2927 - 8B 84 96 40010000 - mov eax,[esi+edx*4+00000140]
2 | 004B2947 - 89 11 - mov [ecx],edx
2 | 004B0D10 - 8B 8C 8E 40010000 - mov ecx,[esi+ecx*4+00000140]
15 | 005D37AF - 8B 94 B5 40010000 - mov edx,[ebp+esi*4+00000140]
15 | 0054235D - 3B 8C 82 40010000 - cmp ecx,[edx+eax*4+00000140]
2 | 004FCC3C - C2 E9 02 - shr ecx,02
1 | 004F51B6 - 3B B4 AF 40010000 - cmp esi,[edi+ebp*4+00000140]

{00419912 - 8B 94 88 40010000 - mov edx,[eax+ecx*4+00000140]} shows:

0041990D - 33 C9 - xor ecx,ecx
0041990F - 8A 48 28 - mov cl,[eax+28]
00419912 - 8B 94 88 40010000 - mov edx,[eax+ecx*4+00000140] <<
00419919 - A1 C0729C00 - mov eax,[Civ3Conquests.exe+5C72C0]
0041991E - 83 F8 01 - cmp eax,01

EAX=0BE190F0
EBX=00740C34
ECX=00000001
EDX=0001869F
ESI=00000000
EDI=07B0CFF5
ESP=0018CE54
EBP=007409C0
EIP=00419919
================================
{004B2927 - 8B 84 96 40010000 - mov eax,[esi+edx*4+00000140]} shows:

004B2923 - 6A 00 - push 00
004B2925 - 6A 00 - push 00
004B2927 - 8B 84 96 40010000 - mov eax,[esi+edx*4+00000140] <<
004B292E - 8D 8C 96 40010000 - lea ecx,[esi+edx*4+00000140]
004B2935 - 8B 96 3C010000 - mov edx,[esi+0000013C]

EAX=0001869F
EBX=00000000
ECX=00000003
EDX=00000001
ESI=0BE190F0
EDI=00000053
ESP=0018AD80
EBP=000003E4
EIP=004B292E
================================
{004B2947 - 89 11 - mov [ecx],edx} shows:

004B2944 - 4A - dec edx
004B2945 - 23 D0 - and edx,eax
004B2947 - 89 11 - mov [ecx],edx <<
004B2949 - 8B CE - mov ecx,esi
004B294B - E8 A0E3FFFF - call Civ3Conquests.exe+B0CF0

EAX=000186A4
EBX=00000000
ECX=0BE19234
EDX=000186A4
ESI=0BE190F0
EDI=00000053
ESP=0018AD80
EBP=000003E4
EIP=004B2949
================================
{004B0D10 - 8B 8C 8E 40010000 - mov ecx,[esi+ecx*4+00000140]} shows:

004B0D09 - BB 01000000 - mov ebx,00000001
004B0D0E - 8B C7 - mov eax,edi
004B0D10 - 8B 8C 8E 40010000 - mov ecx,[esi+ecx*4+00000140] <<
004B0D17 - 3B C8 - cmp ecx,eax
004B0D19 - 7C 0B - jnge Civ3Conquests.exe+B0D26

EAX=0000000A
EBX=00000001
ECX=000186A4
EDX=000186A4
ESI=0BE190F0
EDI=0000000A
ESP=0018AD68
EBP=009B7510
EIP=004B0D17
================================
{005D37AF - 8B 94 B5 40010000 - mov edx,[ebp+esi*4+00000140]} shows:

005D37AA - 57 - push edi
005D37AB - 89 74 24 14 - mov [esp+14],esi
005D37AF - 8B 94 B5 40010000 - mov edx,[ebp+esi*4+00000140] <<
005D37B6 - 3B CA - cmp ecx,edx
005D37B8 - 0F8F 1B020000 - jg Civ3Conquests.exe+1D39D9

EAX=0BE3AFE8
EBX=00000006
ECX=00000000
EDX=000186A4
ESI=00000001
EDI=0BE3AFE8
ESP=0018ACF8
EBP=0BE190F0
EIP=005D37B6
================================
{0054235D - 3B 8C 82 40010000 - cmp ecx,[edx+eax*4+00000140]} shows:

00542353 - 8A 42 28 - mov al,[edx+28]
00542356 - 8B 8C 8D 40010000 - mov ecx,[ebp+ecx*4+00000140]
0054235D - 3B 8C 82 40010000 - cmp ecx,[edx+eax*4+00000140] <<
00542364 - 7F 0B - jg Civ3Conquests.exe+142371
00542366 - 46 - inc esi

EAX=00000001
EBX=00000001
ECX=00000001
EDX=0BE190F0
ESI=00000000
EDI=00B38C4C
ESP=0018D4A0
EBP=0BE37E40
EIP=00542364
================================
{004FCC3C - C2 E9 02 - shr ecx,02} shows:

004FCC37 - 8D 7A 08 - lea edi,[edx+08]
004FCC3A - 8B D1 - mov edx,ecx
004FCC3C - C1 E9 02 - shr ecx,02 <<
004FCC3F - F3 A5 - repe movsd
004FCC41 - 8B CA - mov ecx,edx

EAX=0BE190F0
EBX=0DBF4FFC
ECX=00000026
EDX=000000A4
ESI=0BE19238
EDI=0DBF50E4
ESP=0018CE74
EBP=00184FDE
EIP=004FCC3F
================================
{004F51B6 - 3B B4 AF 40010000 - cmp esi,[edi+ebp*4+00000140]} shows:

004F51A9 - 81 E5 FF000000 - and ebp,000000FF
004F51AF - 8B B4 B0 40010000 - mov esi,[eax+esi*4+00000140]
004F51B6 - 3B B4 AF 40010000 - cmp esi,[edi+ebp*4+00000140] <<
004F51BD - 7E 0A - jle Civ3Conquests.exe+F51C9
004F51BF - 3A D1 - cmp dl,cl

EAX=0BE16B40
EBX=00000000
ECX=07978301
EDX=07978401
ESI=00000003
EDI=0BE190F0
ESP=0018D4A4
EBP=00000001
EIP=004F51BD
================================

Sorry if I'm being incredibly dense here. Embarassed I've been only a basic user of Cheat Engine for a long time, never really delved into the depths of it... though I probably should.
Back to top
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Sun Aug 16, 2015 3:49 pm    Post subject: Reply with quote

Code:
[ENABLE]
aobscanmodule(culture,Civ3Conquests.exe,8B 94 88 40 01 00 00 A1)
alloc(newmem,$1000)

label(code)
label(return)

newmem:

code:
mov edx,[eax+ecx*4+00000140]
cmp ecx,1
jne return
cmp edx,9
jge return
mov edx,9
mov [eax+ecx*4+00000140],edx
jmp return

culture:
jmp code
nop
nop
return:
registersymbol(culture)

[DISABLE]
culture:
db 8B 94 88 40 01 00 00
unregistersymbol(culture)
dealloc(newmem)
Back to top
View user's profile Send private message
oddgamer
Advanced Cheater
Reputation: 0

Joined: 19 Jan 2013
Posts: 60

PostPosted: Sun Aug 16, 2015 4:25 pm    Post subject: Reply with quote

Thanks! Smile
Back to top
View user's profile Send private message
Eurochron89
Newbie cheater
Reputation: 1

Joined: 12 Aug 2015
Posts: 17

PostPosted: Sun Aug 16, 2015 9:58 pm    Post subject: Reply with quote

@oddgamer: It is one thing to copy&paste things and to be glad that it works, but you should also try to understand what it does.

That is why I am gonna explain what happens here. This should help you understand how it works.
Let me know if you have any further questions. Wink


AoB = Array of Bytes -> in your case, these bytes are the instruction which changes the value:
Code:
aobscanmodule(culture,Civ3Conquests.exe,8B 94 88 40 01 00 00 A1)

These Bytes do have a meaning of course, and the more you understand them, the easier it gets to do things like this yourself.
This is where the AoB Code Injection happens in your Game:
Code:
"Civ3Conquests.exe"+19912: 8B 94 88 40 01 00 00 - mov edx,[eax+ecx*4+00000140]

- "Civ3Conquests.exe" is the name of the module (for CE this also is the address of the entry point this module has in the memory)
- "+19912" is the Offset at which the instruction gets executed in memory
- "8B 94 88 40 01 00 00" is the Array of Byte view of the instruction which changes your value
- "mov edx,[eax+ecx*4+00000140]" is the assembler view of the instruction which changes your value

-> If you look into the Memory Viewer and look at other instructions, the Byte '8B' is translated to 'mov'
-> 'mov' is the 'copy memory' instruction with this synthax: 'mov destination,source' (if you want to know more, just google 'asm mov')



Code:
alloc(newmem,$1000)

This will allocate the memory for your Code Injection
-> basically this looks for free memory and stores the address of the free memory in 'newmem'
-> This free Memory can also be called a 'Code Cave'


Code:
label(code)
label(return)

Labels are used to jump to specific memory addresses - you can see these labels like a pointer to that address
-> example: 'culture' ist the label created within the AoBScan-Method and holds the address where the instructions is executed in memory
-> 'culture' is also the address where the code injection is made


The following instructions are the code injection, all of these get executed within the 'code cave':
(I have added comments like this: "// <explanation>" to each line)
Code:

// 'newmem' holds the address of the allocated free memory within the games memory
// this is like a pointer to the address of the 'code cave'
newmem:

// 'code' now points to the same address as 'newmen' (and is used later to jump into the code cave)
code:

// this is the 'original opcode' - the instruction that changes your value
// in this case '[eax+ecx*4+00000140] ' represents the value pointed to by your pointer
// and 'EDX' is a register - the instruction 'mov' = 'copy memory' stores/copies the value into 'EDX'
mov edx,[eax+ecx*4+00000140]

// 'cmp' = compare - we are comparing the register 'ECX' to '1'
// (see the next line to understand why and also look back at the Value of ECX in the Memory Dumps you posted)
cmp ecx,1

// 'jne' = jump if not equal - 'return' is the destination of the jump
// this refers to the 'cmp ecx,1' - whenever ECX is NOT 1, we jump to the 'return'-label and skip all other code
// this is the condition to make sure we only execute this when the right parameters are met
// (if you look back at your Memory Dumps, you can see 'ECX=00000001' when '8B 94 88 40010000 - mov edx,[eax+ecx*4+00000140]' was selected)
jne return

// another compare - this time we compare the register 'EDX' to '9'
// this is the condition you wanted to have in your first post (minimum value of 9)
// hint: do you remember the original instruction? >> mov edx,[eax+ecx*4+00000140]
cmp edx,9

// 'jge' is another jump condition: 'jump if greater or equal' - 'return' is the destination of the jump (again)
// so whenever EDX (your value) is 9 (or greater) we jump to 'return' and skip all other code
jge return

// note: this code is only reached, when the value is less than 9!
// 'mov' = 'copy memory' - we store the value '9' into the register 'EDX'
mov edx,9

// do you remember the original instruction? >> mov edx,[eax+ecx*4+00000140]
// note how it is changed this time - we basically overwrite the value with '9'
//  '[eax+ecx*4+00000140] ' represents the value pointed to by your pointer
// and 'EDX' is the minimum value we want to have: '9'
mov [eax+ecx*4+00000140],edx

// The code injection is done, we use the 'return' label to jump back to the instruction following our original instruction
// 'jmp' = 'jump' - this will jump to another address in memory represented by the 'return' label
// this is done in order to go back to the normal execution of the games code
jmp return


// The following instructions are used to 'overwrite' the original instruction and instead jump into the 'code cave'
// this is the part where we 'inject' our own code and therefore change the execution of the game how we want it
Code:

// 'culture' is a label, which is like a pointer to the address where the original instructiion is executed in memory
// the address was received via the AoBScan: 'aobscanmodule(culture,Civ3Conquests.exe,8B 94 88 40 01 00 00 A1)'
culture:

// 'jmp' = 'jump' - this will jump to another address in memory represented by the 'code' label
// if you look back up, I have mentioned that 'code' points to the same address as 'newmem'
// so it points to the codecave - 'jmp code' brings the game to our 'code cave' now
jmp code

// 'nop' = 'no operation' (byte view = 90) ... this does nothing - but it is still usefull and needed here
// 8B 94 88 40 01 00 00 << is the original instruction - translated as: mov edx,[eax+ecx*4+00000140]
// E9 XX XX XX XX 90 90 << this is the replacment of the original code (90 = nop) translated to: jmp <address of code cave> nop nop
// nop does just fill the 'missing bytes', because the original instruction has 7 bytes, and 'jmp <address> has only 5 bytes
nop
nop

// finally the 'return' label points to the address just after the original instruction
// this is important so the code execution can jump back out of the code cave and continue where it should.
// so whenever we used a jump (jmp, jge, jne, ...) like this: 'jmp return' - we redirect the code execution back to the address just after the original instruction
return:

// this is used to save the'symbol name 'culture', which is pointing to the address where the original instruction is executed in memory
registersymbol(culture)



And now we look at the disable part - which gets executed only if you disable the auto assemble script
Code:
[DISABLE]

// 'culture' is pointing to the address where the original instruction is executed in memory
culture:

// 'db' = 'define byte' - this will restore the original instruction (mov edx,[eax+ecx*4+00000140])
// (look into the Memory View to see the changes when you enable/disable the script)
db 8B 94 88 40 01 00 00

// deleting the pointer to the memory address of the original instruction
unregistersymbol(culture)

// freeing the memory allocated for the codecave
dealloc(newmem)




I know... very much to read and to understand. Razz

In short, this script does:
1) Scan for the Array of Bytes of the instruction and save the address
2) Allocate new (free) memory (= Code Cave)
3) Replace the Original Instruction with a jump to the Code Cave
4) (within the Code Cave): Compare your value to the minimum Value (9) and if it is less than 9 it overwrites the current value with 9
5) Return to the instruction right after the original instruction and continue code execution as normal


I hope this was a good addition to Zanzer's code.
I just tried to explain what is happening, and hopefully you will understand it a bit better this way.


@Zanzer: if you happen to read this: let me know if i explained it correctly and good enough, please. Embarassed Very Happy
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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