 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
oddgamer Advanced Cheater
Reputation: 0
Joined: 19 Jan 2013 Posts: 60
|
Posted: Sat Aug 15, 2015 2:20 pm Post subject: Lock to minimal value? |
|
|
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 |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25794 Location: The netherlands
|
Posted: Sat Aug 15, 2015 2:24 pm Post subject: |
|
|
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 |
|
 |
oddgamer Advanced Cheater
Reputation: 0
Joined: 19 Jan 2013 Posts: 60
|
Posted: Sat Aug 15, 2015 3:31 pm Post subject: |
|
|
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 |
|
 |
Eurochron89 Newbie cheater
Reputation: 1
Joined: 12 Aug 2015 Posts: 17
|
Posted: Sat Aug 15, 2015 4:22 pm Post subject: |
|
|
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 |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Sat Aug 15, 2015 4:37 pm Post subject: |
|
|
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 |
|
 |
oddgamer Advanced Cheater
Reputation: 0
Joined: 19 Jan 2013 Posts: 60
|
Posted: Sat Aug 15, 2015 5:41 pm Post subject: |
|
|
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 |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Sat Aug 15, 2015 5:54 pm Post subject: |
|
|
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 |
|
 |
Eurochron89 Newbie cheater
Reputation: 1
Joined: 12 Aug 2015 Posts: 17
|
Posted: Sat Aug 15, 2015 6:06 pm Post subject: |
|
|
@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"
|
|
Back to top |
|
 |
oddgamer Advanced Cheater
Reputation: 0
Joined: 19 Jan 2013 Posts: 60
|
Posted: Sat Aug 15, 2015 6:55 pm Post subject: |
|
|
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 |
|
 |
Eurochron89 Newbie cheater
Reputation: 1
Joined: 12 Aug 2015 Posts: 17
|
Posted: Sat Aug 15, 2015 7:19 pm Post subject: |
|
|
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 |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Sat Aug 15, 2015 8:18 pm Post subject: |
|
|
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 |
|
 |
oddgamer Advanced Cheater
Reputation: 0
Joined: 19 Jan 2013 Posts: 60
|
Posted: Sun Aug 16, 2015 2:08 pm Post subject: |
|
|
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. 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 |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Sun Aug 16, 2015 3:49 pm Post subject: |
|
|
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 |
|
 |
oddgamer Advanced Cheater
Reputation: 0
Joined: 19 Jan 2013 Posts: 60
|
Posted: Sun Aug 16, 2015 4:25 pm Post subject: |
|
|
Thanks!
|
|
Back to top |
|
 |
Eurochron89 Newbie cheater
Reputation: 1
Joined: 12 Aug 2015 Posts: 17
|
Posted: Sun Aug 16, 2015 9:58 pm Post subject: |
|
|
@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.
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.
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.
|
|
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
|
|