Recifense I post too much Reputation: 166
Joined: 17 Mar 2008 Posts: 3688 Location: Pernambuco - Brazil
|
Posted: Wed Jan 04, 2012 4:52 pm Post subject: [DiY] Adapting a script to a new version of a game |
|
|
Hi guys,
This tutorial is a guidelines about adapting my scripts to other versions of a game.
I have recently published a table and a script for "Two Worlds II Castle Defense". This game has
already a patch available. So, instead of adapting my script, I decided to guide you on how to do that.
I hope you enjoy it.
Cheers and a very good year to everyone!
Recifense.
============================= Adapting Recifense's Scripts ===========================
Script: http://forum.cheatengine.org/viewtopic.php?t=546157
Table: http://forum.cheatengine.org/viewtopic.php?t=546156
The scripts that can be adapted without much risk, I usually publish them adding "My Notes" (Now it comes inside the script file) and
a section "Here are some info for those who wants to adapt the script ..." followed by code fragments.
Let's see how to use those information.
1) First of all:
___ 1.1 Note that the script has 3 hacking points;
Code: |
//=========================================
// Hacking Points
TW2CD.exe+02c3cf:
jmp _MonCorrupted
nop
nop
_BackMC:
TW2CD.exe+0b60cd:
jmp _GodMode
_BackGM:
TW2CD.exe+035209:
jmp _MonRes
nop
_BackMR:
|
___ 1.2 Note that there are 3 code fragments (one for each hacking point);
Code: |
_MonCorrupted:
sl = AOBScan("55 8b ec 83 ec 08 83 7d 08 00 ?? ?? c7 05 ?? ?? ?? ?? 01 00 00 00");
TW2CD.exe+2C39F - CC - int 3
TW2CD.exe+2C3A0 - 55 - push ebp <--- SL
TW2CD.exe+2C3A1 - 8B EC - mov ebp,esp
TW2CD.exe+2C3A3 - 83 EC 08 - sub esp,08
TW2CD.exe+2C3A6 - 83 7D 08 00 - cmp dword ptr [ebp+08],00
....
TW2CD.exe+2C3AC - C7 05 24A76F00 01000000 - mov [006FA724],00000001 <-- here
....
|
Code: |
_GodMode:
sl = AOBScan("8b 00 89 42 40 ?? ?? ?? ?? ?? 8b 4d f8 8b 41 40");
TW2CD.exe+B609F - CC - int 3
TW2CD.exe+B60A0 - 55 - push ebp
TW2CD.exe+B60A1 - 8B EC - mov ebp,esp
TW2CD.exe+B60A3 - 83 EC 08 - sub esp,08
TW2CD.exe+B60A6 - 89 4D F8 - mov [ebp-08],ecx
....
TW2CD.exe+B60CD - 8B 00 - mov eax,[eax] <--- here
....
|
Code: |
_MonRes:
sl = AOBScan("03 81 84 00 00 00 89 45 f4 db 45 f4");
TW2CD.exe+351AF - CC - int 3
TW2CD.exe+351B0 - 55 - push ebp
TW2CD.exe+351B1 - 8B EC - mov ebp,esp
TW2CD.exe+351B3 - 83 EC 0C - sub esp,0C
TW2CD.exe+351B6 - 89 4D F8 - mov [ebp-08],ecx
....
TW2CD.exe+35209 - 03 81 84000000 - add eax,[ecx+00000084] <----- here
....
|
___ 1.3 And note the structures at "My Notes" part of the script.
Code: |
// ****************************************
// NOTES
// ****************************************
{
V1.0.0.1
struct UNIT:
0000 = 00688628
0004 = iIndex
0024 = aName ("Gandohar", "Swordman", etc)
0034 = iNameSize
0038 = i15
003c = iID (2 = player, 1 = AI)
0040 = icHP
00b8 = aType ("Mage_2", "Warrior", etc)
struct RESOURCE:
0000 = 00f60530
0080 = iScore
0084 = iBaseGold
}
|
___ 1.4 So far so good. We are getting better at "noticing" things. Now let's analyze them:
2) Structure Analisys:
Code: |
struct UNIT:
0000 = 00688628
0004 = iIndex
0024 = aName ("Gandohar", "Swordman", etc)
0034 = iNameSize
0038 = i15
003c = iID (2 = player, 1 = AI) <----- Important [1]
0040 = icHP <----- Important [2]
00b8 = aType ("Mage_2", "Warrior", etc)
|
Code: |
struct RESOURCE:
0000 = 00f60530
0080 = iScore
0084 = iBaseGold <----- Important [3]
|
___ TutNote 01: From the "UNIT" we get 2 important info's: The player ID is at offset 003c (and should be 2 for the player's units)
___ and the unit's HP is at offset 0040. From the "RESOURCE" we get an important info: The Gold is at offset 0084. Dring the script
___ adaptation we have to pay attention to those 3 offsets. Be aware, they could have been changed.
3) Looking for the Hacking Points of the new version of the game:
___ TutNote 02: This game has already a patch. Apply it.
______ A) Note at each code fragment, a line with "sl = AOBScan("...")". It will help you to find each hacking points. It is part of
______ a script in LUA that I use to search codes in the game memory region:
Code: |
-- Search via AOB
sl = AOBScan("55 8b ec 83 ec 0c 89 4d f8 8b 4d f8 81 c1");
if(sl == nil) then
print("No code found!");
else
j = stringlist_getCount(sl);
print("Found:",j);
for i = 1, j do
print(stringlist_getString(sl,i-1));
end
object_destroy(sl);
end
-- end of the script
|
______ B) For saving this script, go to "Memory Viewer" and press "CTRL+L" to open the LUA engine. Copy the script into the editor of the LUA Engine
______ (the area with a "Execute" button at its right side). Now save it as "SEARCHER.LUA" (File->Save current script).
______ C) "sl" stand for "string list object". This object has a counter and an array of addresses. When you execute the function "AOBScan", it returns
______ Null (nil) if nothing was found or a String List object with number of addresses found and a list of addresses. If nothing was found, the script will print at
______ the "OUTPUT" section of the LUA Engine "No code found!". If something is found, it will print "Found:" + number of addresses found. It will also print the
______ list of addresses (that contains the (A)rray (O)f (B)ytes).
___ TutNote 03: Now let's search for the code fragments. Make sure that the game is running and that its process was loaded by CE.
______ A) Let's try to find the HP (Hacking Point) for "_MonCorrupted". Replace in the "SEARCHER" script the sl line by:
Code: |
sl = AOBScan("55 8b ec 83 ec 08 83 7d 08 00 ?? ?? c7 05 ?? ?? ?? ?? 01 00 00 00");
|
_____ B) Execute the script by pressing the button "Execute". In my case the following was printed:
______ C) Let's have a look at this address in the "Memory Viewer" disassembler area. Copy the address and right-click on the disassembler.
______ Choose "Go to address". Replace the address by the one we have found 0042C240. Compare the code that is displayed to the code fragment
______ we are looking for:
Code: |
0042C240 - 55 - push ebp <-- =
0042C241 - 8B EC - mov ebp,esp <-- =
0042C243 - 83 EC 08 - sub esp,08 <-- =
0042C246 - 83 7D 08 00 - cmp dword ptr [ebp+08],00 <-- =
0042C24A - 74 0A - je 0042C256 <-- <>, but similar (opcode = 74 0A)
0042C24C - C7 05 845B7000 01000000 - mov [00705B84],00000001 <-- <>, but similar (only the static address changes)
0042C256 - E8 25000000 - call 0042C280 <-- <>, but similar (a call instruction)
0042C25B - 89 45 FC - mov [ebp-04],eax <-- =
0042C25E - 83 7D FC 00 - cmp dword ptr [ebp-04],00 <-- =
0042C262 - 75 12 - jne 0042C276 <-- <>, but similar (opcode = 75 12)
0042C264 - E8 27E2FEFF - call 0041A490 <-- <>, but similar (a call instruction)
0042C269 - 89 45 F8 - mov [ebp-08],eax <-- =
0042C26C - 8B 45 F8 - mov eax,[ebp-08] <-- =
0042C26F - C7 40 2C 01000000 - mov [eax+2C],00000001 <-- <>, Important! (The offset changed from 0028 to 002c). <== HP
0042C276 - 8B 45 FC - mov eax,[ebp-04] <-- =
0042C279 - 8B E5 - mov esp,ebp <-- =
0042C27B - 5D - pop ebp <-- =
0042C27C - C3 - ret <-- =
<> => different
|
______ D) Great. We have found the first HP. The address is 0042C26F => TW2CD.exe+02c26f. The offset changed (Look at the script).
______ E) Let's try to find the HP (Hacking Point) for "_GodMode". On the LUA engine, clear the output by selecting "File->Clear output".
______ Replace in the "SEARCHER" script the sl line by:
Code: |
sl = AOBScan("8b 00 89 42 40 ?? ?? ?? ?? ?? 8b 4d f8 8b 41 40");
|
_____ F) Execute the script by pressing the button "Execute". In my case the following was printed:
______ G) Let's have a look at this address in the "Memory Viewer" disassembler area. Copy the address and right-click on the disassembler.
______ Choose "Go to address". Replace the address by the one we have found 004BD48D. Compare the code that is displayed to the code fragment
______ we are looking for:
Code: |
004BD460 - 55 - push ebp <-- =
004BD461 - 8B EC - mov ebp,esp <-- =
004BD463 - 83 EC 08 - sub esp,08 <-- =
004BD466 - 89 4D F8 - mov [ebp-08],ecx <-- =
004BD469 - 6A 01 - push 01 <-- =
004BD46B - E8 D0EDF6FF - call 0042C240 <-- <>, but similar (a call instruction)
004BD470 - 83 C4 04 - add esp,04 <-- =
004BD473 - C7 45 FC 00000000 - mov [ebp-04],00000000 <-- =
004BD47A - 8D 45 08 - lea eax,[ebp+08] <-- =
004BD47D - 50 - push eax <-- =
004BD47E - 8D 4D FC - lea ecx,[ebp-04] <-- =
004BD481 - 51 - push ecx <-- =
004BD482 - E8 A93DF4FF - call 00401230 <-- <>, but similar (a call instruction)
004BD487 - 83 C4 08 - add esp,08 <-- =
004BD48A - 8B 55 F8 - mov edx,[ebp-08] <-- =
004BD48D - 8B 00 - mov eax,[eax] <-- = Hacking Point (no change -> great)
004BD48F - 89 42 40 - mov [edx+40],eax <-- = Very important (no change in the in "health" offset = 0040)
004BD492 - E8 89EDF6FF - call 0042C220 <-- <>, but similar (a call instruction)
004BD497 - 8B 4D F8 - mov ecx,[ebp-08] <-- =
004BD49A - 8B 41 40 - mov eax,[ecx+40] <-- =
004BD49D - 8B E5 - mov esp,ebp <-- =
004BD49F - 5D - pop ebp <-- =
004BD4A0 - C2 0400 - ret 0004 <-- =
<> => different
|
______ H) Great. We have found the second HP. The address is 004BD48D => TW2CD.exe+0bd48d. The health point offset has not changed (Check the UNIT sctructure [2]).
______ I) Let's try to find the HP (Hacking Point) for "_MonRes". On the LUA engine, clear the output by selecting "File->Clear output".
______ Replace in the "SEARCHER" script the sl line by:
Code: |
sl = AOBScan("03 81 84 00 00 00 89 45 f4 db 45 f4");
|
______ J) Execute the script by pressing the button "Execute". In my case the following was printed:
______ K) That's not good. But we have the code fragment, so we can try to use other sequence of bytes of that code. So let's try the sequence of
______ of the beginning of the code fragment:
Code: |
sl = AOBScan("55 8b ec 83 ec 0c 89 4d f8 8b 4d f8 81 c1");
|
______ L) Execute the script by pressing the button "Execute". In my case the following was printed:
______ M) Let's have a look at this address in the "Memory Viewer" disassembler area. Copy the address and right-click on the disassembler.
______ Choose "Go to address". Replace the address by the one we have found 00435340. Compare the code that is displayed to the code fragment
______ we are looking for:
Code: |
00435340 - 55 - push ebp <-- =
00435341 - 8B EC - mov ebp,esp <-- =
00435343 - 83 EC 0C - sub esp,0C <-- =
00435346 - 89 4D F8 - mov [ebp-08],ecx <-- =
00435349 - 8B 4D F8 - mov ecx,[ebp-08] <-- =
0043534C - 81 C1 E8000000 - add ecx,000000E8 <-- =
00435352 - E8 39F10800 - call 004C4490 <-- <>, but similar (a call instruction)
00435357 - 0FB6 C0 - movzx eax,al <-- =
0043535A - 85 C0 - test eax,eax <-- =
0043535C - 74 02 - je 00435360 <-- <>, but similar (opcode = 74 02)
0043535E - EB 61 - jmp 004353C1 <-- <>, but similar (opcode = eb 61)
00435360 - 8B 4D F8 - mov ecx,[ebp-08] <-- =
00435363 - 81 C1 E8000000 - add ecx,000000E8 <-- =
00435369 - E8 B24F0700 - call 004AA320 <-- <>, but similar (a call instruction)
0043536E - 8B C8 - mov ecx,eax <-- =
00435370 - E8 2B3A0900 - call 004C8DA0 <-- <>, but similar (a call instruction)
00435375 - 89 45 FC - mov [ebp-04],eax <-- =
00435378 - 83 7D FC 00 - cmp dword ptr [ebp-04],00 <-- =
0043537C - 75 02 - jne 00435380 <-- <>, but similar (opcode = 75 02)
0043537E - EB 41 - jmp 004353C1 <-- <>, but similar (opcode = eb 41)
00435380 - 6A 01 - push 01 <-- =
00435382 - E8 B96EFFFF - call 0042C240 <-- <>, but similar (a call instruction)
00435387 - 83 C4 04 - add esp,04 <-- =
0043538A - 6A 00 - push 00 <-- =
0043538C - 6A 01 - push 01 <-- =
0043538E - 8B 4D FC - mov ecx,[ebp-04] <-- =
00435391 - E8 2A2D0900 - call 004C80C0 <-- <>, but similar (a call instruction)
00435396 - 8B 4D F8 - mov ecx,[ebp-08] <-- =
00435399 - 03 81 88000000 - add eax,[ecx+00000088] <-- <>, Important! (gold offset changed from 0084 to 0088)
0043539F - 89 45 F4 - mov [ebp-0C],eax <-- =
004353A2 - DB 45 F4 - fild dword ptr [ebp-0C] <-- =
004353A5 - 8B 55 F8 - mov edx,[ebp-08] <-- =
004353A8 - D8 8A F0010000 - fmul dword ptr [edx+000001F0] <-- <>, but similar (the offset changed from 01EC to 01F0).
004353AE - E8 AD551D00 - call 0060A960 <-- <>, but similar (a call instruction)
004353B3 - 8B 4D F8 - mov ecx,[ebp-08] <-- =
004353B6 - 89 81 84000000 - mov [ecx+00000084],eax <-- <>, but similar (the offset changed from 0080 to 0084)
004353BC - E8 5F6EFFFF - call 0042C220 <-- <>, but similar (a call instruction)
004353C1 - 8B E5 - mov esp,ebp <-- =
004353C3 - 5D - pop ebp <-- =
004353C4 - C2 0400 - ret 0004 <-- =
<> => different
|
______ N) Great. We have found the third HP. The address is 00435399 => TW2CD.exe+035399. The GOLD offset has changed (Check the RESOURCE sctructure [3]).
4) Adapting the Script to the new version of the game:
___ TutNote 04: Now let's adapt each part of the script: Hacking/Disable Points, ASSERTs and CHEATs.
______ A) Let's start by "_MonCorrupted":
Code: |
TW2CD.exe+02c3cf: ==> TW2CD.exe+02c26f:
jmp _MonCorrupted
nop
nop
_BackMC:
|
Code: |
TW2CD.exe+02c3cf: ==> TW2CD.exe+02c26f:
// mov [eax+28],00000001 ==> // mov [eax+2C],00000001
db c7 40 28 01 00 00 00 ==> db c7 40 2c 01 00 00 00
|
Code: |
assert(TW2CD.exe+02c3cf,c7 40 28 01 00 00 00) ==> assert(TW2CD.exe+02c26f,c7 40 2c 01 00 00 00)
|
Code: |
//=========================================
_MonCorrupted:
mov [eax+28],00000001 // Original code ==> [eax+2c],00000001
_ExitMC:
mov [eax+28],00000000 // No corruption detected ==> [eax+2c],00000000
jmp _BackMC // Back to main code
//=========================================
|
______ B) Let's adapt the "_GodMode":
Code: |
TW2CD.exe+0b60cd: ==> TW2CD.exe+0bd48d:
jmp _GodMode
_BackGM:
|
Code: |
TW2CD.exe+0bd48d: ==> TW2CD.exe+0bd48d:
// mov eax,[eax]
// mov [edx+40],eax
db 8b 00 89 42 40
|
Code: |
assert(TW2CD.exe+0b60cd,8b 00 89 42 40) ==> assert(TW2CD.exe+0bd48d,8b 00 89 42 40)
|
Code: |
//========================================= (No change needed)
_GodMode:
push ebx
mov [pUnit],edx // Save ptr for debugging
mov ebx,[edx+3c]
cmp ebx,[iPlayer]
jne _ExitGM
cmp dword ptr [iEnableGM],0
je _ExitGM // Jump if feature is disabled
mov ebx,[edx+40] // Get current HP
cmp ebx,[eax]
jle _ExitGM
mov [eax],ebx // Make next HP = current HP
_ExitGM:
pop ebx
mov eax,[eax] // Original code
mov [edx+40],eax // Original code
jmp _BackGM // Back to main code
//=========================================
|
______ C) Let's adapt the "_MonRes":
Code: |
TW2CD.exe+035209: ==> TW2CD.exe+035399:
jmp _MonRes
nop
_BackMR:
|
Code: |
TW2CD.exe+035209: ==> TW2CD.exe+035399:
// add eax,[ecx+00000084] ==> // add eax,[ecx+00000088]
db 03 81 84 00 00 00 ==> db 03 81 88 00 00 00
|
Code: |
assert(TW2CD.exe+035209,03 81 84 00 00 00) ==> assert(TW2CD.exe+035399,03 81 88 00 00 00)
|
Code: |
//=========================================
_MonRes:
push ebx
mov [pRes],ecx
cmp dword ptr [iEnableMR],0
je _ExitMR // Jump if feature is disabled
mov ebx,#15000
cmp ebx,[ecx+00000084] ==> cmp ebx,[ecx+00000084]
jle _ExitMR
mov [ecx+00000084],ebx ==> mov [ecx+00000088],ebx
_ExitMR:
pop ebx
add eax,[ecx+00000084] // Original code ==> add eax,[ecx+00000088]
jmp _BackMR // Back to main code
//=========================================
|
5) The script for the new version of the game:
Code: |
{
=========================================== 001-12
Game Title : Two Worlds II - Castle Defense
Game Version : 1.0.0.1 + patch
Process Name : TW2CD.exe
Script Version: 1.0
CE Version : 6.1
Release date : 03-Jan-2012
Author : Recifense
Features:
- God Mode
- Minimum Resources
=========================================== 002
}
[ENABLE]
//=========================================
// Check if script is compatible to this game version
// If false the script will not be loaded
assert(TW2CD.exe+02c26f,c7 40 2c 01 00 00 00) // <==
assert(TW2CD.exe+0bd48d,8b 00 89 42 40) // <==
assert(TW2CD.exe+035399,03 81 88 00 00 00) // <==
//=========================================
alloc(MyCode,1024)
//=========================================
// Declaration section
label(_MonCorrupted)
label(_BackMC)
label(_ExitMC)
label(_GodMode)
label(_BackGM)
label(_ExitGM)
label(_MonRes)
label(_BackMR)
label(_ExitMR)
label(pUnit)
label(pPlayer)
label(pRes)
label(iPlayer)
label(iEnableGM)
label(iEnableMR)
//=========================================
// Registering Symbols
registersymbol(MyCode)
registersymbol(pUnit)
registersymbol(pPlayer)
registersymbol(pRes)
registersymbol(iPlayer)
registersymbol(iEnableGM)
registersymbol(iEnableMR)
//=========================================
MyCode:
//=========================================
_MonCorrupted:
mov [eax+2c],00000001 // Original code <==
_ExitMC:
mov [eax+2c],00000000 // No corruption detected <==
jmp _BackMC // Back to main code
//========================================= (No change needed)
_GodMode:
push ebx
mov [pUnit],edx // Save ptr for debugging
mov ebx,[edx+3c]
cmp ebx,[iPlayer]
jne _ExitGM
cmp dword ptr [iEnableGM],0
je _ExitGM // Jump if feature is disabled
mov ebx,[edx+40] // Get current HP
cmp ebx,[eax]
jle _ExitGM
mov [eax],ebx // Make next HP = current HP
_ExitGM:
pop ebx
mov eax,[eax] // Original code
mov [edx+40],eax // Original code
jmp _BackGM // Back to main code
//=========================================
_MonRes:
push ebx
mov [pRes],ecx
cmp dword ptr [iEnableMR],0
je _ExitMR // Jump if feature is disabled
mov ebx,#15000
cmp ebx,[ecx+00000088] // <==
jle _ExitMR
mov [ecx+00000088],ebx // <==
_ExitMR:
pop ebx
add eax,[ecx+00000088] // Original code <==
jmp _BackMR // Back to main code
//=========================================
db '==========================>'
db 'CE6.1 Script by Recifense 010312'
//=========================================
// Variables
iEnableGM:
dd 1
iEnableMR:
dd 1
pUnit:
dd 0
pPlayer:
dd 0
pRes:
dd 0
iPlayer:
dd #2
//=========================================
// Hacking Points
//TW2CD.exe+02c3cf:
TW2CD.exe+02c26f: // <==
jmp _MonCorrupted
nop
nop
_BackMC:
//TW2CD.exe+0b60cd:
TW2CD.exe+0bd48d: // <==
jmp _GodMode
_BackGM:
//TW2CD.exe+035209:
TW2CD.exe+035399: // <==
jmp _MonRes
nop
_BackMR:
//=========================================
// Script for Restoring Original Codes
[DISABLE]
//TW2CD.exe+02c3cf:
// mov [eax+28],00000001
// db c7 40 28 01 00 00 00
TW2CD.exe+02c26f: // <==
// mov [eax+28],00000001 // <==
db c7 40 2c 01 00 00 00 // <==
//TW2CD.exe+0b60cd:
TW2CD.exe+0bd48d: // <==
// mov eax,[eax]
// mov [edx+40],eax
db 8b 00 89 42 40
//TW2CD.exe+035209:
// add eax,[ecx+00000084]
// db 03 81 84 00 00 00
TW2CD.exe+035399: // <==
// add eax,[ecx+00000088] // <==
db 03 81 88 00 00 00 // <==
//=========================================
// Unregistering Symbols
unregistersymbol(MyCode)
unregistersymbol(pUnit)
unregistersymbol(iEnableGM)
unregistersymbol(iEnableMR)
unregistersymbol(iPlayer)
unregistersymbol(pPlayer)
unregistersymbol(pRes)
//=========================================
dealloc(MyCode)
//============= Scripts End ===============
// ****************************************
// NOTES
// ****************************************
{
V1.0.0.1
struct UNIT:
0000 = 00688628
0004 = iIndex
0024 = aName ("Gandohar", "Swordman", etc)
0034 = iNameSize
0038 = i15
003c = iID (2 = player, 1 = AI)
0040 = icHP
00b8 = aType ("Mage_2", "Warrior", etc)
struct Resource:
0000 = 00f60530
0080 = iScore
0084 = iBaseGold
}
|
___ TutNote 05: Now edit the table and change the script by this one.
That's it.
Cheers!
Description: |
|
Download |
Filename: |
TwoWorlds2_CastleDefense_v1001_Script.CEA |
Filesize: |
4.1 KB |
Downloaded: |
1772 Time(s) |
|
|