Recifense I post too much Reputation: 166
Joined: 17 Mar 2008 Posts: 3688 Location: Pernambuco - Brazil
|
Posted: Sun Jan 09, 2011 9:52 pm Post subject: [Tutorial] Cheating Galactic Civilization 2 (V1.0) - Part 2 |
|
|
This is the second part of the tutorial
The first part can be found at: http://forum.cheatengine.org/viewtopic.php?t=529802
4 - Cheating Ship's Movement Points:
___ TutNote 13: Enable the script "Tutorial_MET_MRT" and load the game (that we saved in 1.4). Press DONE for the Report, Research and Colony screens.
___ Note that the game starts with two ships: A flagship and a Colony ship. Let's have a look at each ship, paying close attention to numbers:
Code: |
The Hit Points : Flagship = 17/17 and Colony = 1/1;
The Moves Left points: Flagship = 3/0 and Colony = 2/0;
Sensor Range : Flagship = 9 pc and Colony = 3 pc;
Range : Flagship = 1.6 gct and Colony = 1.5 gct;
Level : Flagship = 0
Colonists : Colony = 100
|
___ TutNote 14: So we know each ship "Moves Left" points. If you click on icon "i" just after the ship's name, you can get additional information.
___ Note that the ship can auto-survey, auto-explore, auto-retreat and auto-attack. This is a tip of how we should implement the MLP cheat.
___ We cannot enable free movement for all our ships because they may not stop moving. So, the best approach here is to enable just the
___ one that is under our selection. Let's see what we can do with movement points.
______ A) Go to CE, write 3 on value field, change the Scan type to 'Exact Value' and Value type to '4 bytes'. Enable Fast scan by clicking in its check-box;
______ Now click on FIRST SCAN. A lot of addresses was found;
______ B) Go back to the game and move you flagship to a nearby place in order to decrease MLP by 1;
______ C) Go back to CE and write 2 on value field. Now click on NEXT SCAN. A few addresses remained;
______ D) Go back to the game and move you flagship to a nearby place in order to decrease MLP by 1;
______ E) Go back to CE and write 1 on value field. Now click again on NEXT SCAN. Now only 2-3 addresses remained;
______ F) Go back to the game and move you flagship to a nearby place in order to decrease MLP by 1;
______ G) Go back to CE and write 0 on value field. Now click oncemore on NEXT SCAN. Now only 1 address remained;
______ H) If this didn't happen to you. End your game turn and repeat the steps from A to G;
______ I) Transfer the address to CE's table and change its value to 4;
______ J) Go back to game and verify the flagship "Moves Left" points. If everything was fine, it will be 4.
______ K) Now let's see what codes access this address.
______ k.01 - Right-click on this entry on the table and select "Find out what accesses this address";
______ k.02 - Go back to the game. Note the 1 code line is already on the codelist;
______ k.03 - Move the flagship. Note that 3 more code lines were added to the codelist;
______ k.04 - Let's have a look at those code lines
Code: |
C18 0055B790 - 83 b9 f0 01 00 00 00 - cmp dword ptr [ecx+000001f0],00
C19 004DB21D - 8b 80 f0 01 00 00 - mov eax,[eax+000001f0]
C20 0056716A - 39 ae f0 01 00 00 - cmp [esi+000001f0],ebp
C21 00567198 - 29 86 f0 01 00 00 - sub [esi+000001f0],eax
|
___ TutNote 15: C18 verifies if the ship can move. Select it on list and click on SHOW DISASSEMBLER. Go to CE's "Memory Viewer" and scroll up the code. There are
___ INT 3 codes near it, change at least the 5 nearest ones to NOP to avoid crashes. Go gack to the list and add this line code to the codelist. Add "- MP" to the description.
___ Now select MORE INFORMATION. We can conclude that the MLP is at offset 01f0 of a structure and that ECX is the base of this structure. So create a new structure, naming
___ it "Ship" and with size 0x400 (From the PlayerInfo structure, just click on File->New Window). Change the address to the value of ECX.
___ Select Structures->Define new structure. Change the name to Ship. Click OK. Click YES. Change the value to 0x400. Click OK.) Rename offset 01f0 to "Moves Left".
___ Note that at the offset 000c we have the ship's name. Rename it to "Ship Name", type = String, bytesize = 32.
___ C19 and C20 just read the MLP value. C21 decreases the MLP. Transfer this code line to the codelist. Add "- MP" to the description. This will be the hacking point.
___ But we cannot implement it yet. We need to know how we can distinguish our ships from those of the AIs (foes).
___ TutNote 16: Close the found list (press STOP/CLOSE).Select C18 from the Advanced Options->Code List, right-click on it and choose "Find out what addresses this code writes to"
___ (If you forgot to change the INT 3's into NOPs, the game will crash).
______ A) Go back to the game. Note that an address was added to Changed Addresses list. It is related to the flagship.
______ B) Select the Colony Ship. Note that a second address was added to the list.
______ C) Go to CE and right-click on the second address and choose "Show register states";
______ D) Add an extra address on the Ship structure and change its address to the value of ECX (of the register states list);
______ E) Seeing the 2 ships structure side-by-side we can conlude:
______ e.01 - Offset 000C is really the ship's name;
______ e.02 - Offset 01ac is the range, so rename it to "Range";
______ e.03 - Offset 01dc is the Hit Points, so rename it to "Hit Points"
______ e.04 - Offset 01f0 is the "Moves Left";
______ F) Let's see what we can do with ships' addresses. Select the flagship. Copy its address from the
______ structure. Go to CE and click on the Hex box near the value to found field. Click on NEW SCAN.
______ Select the value field and paste the flagship address on it. Turn FAST SCAN on. Click on FIRST SCAN.
______ A few addresses appeared.
______ G) Go to the game and select the Colony Ship.
______ H) Go back to CE and copy the Colony ship address from the structure to the search field. Select "Changed value" for "Scan Type" and press NEXT SCAN;
______ I) Now only 3-4 addresses remained. Now go to the game and select a planet.
______ J) Back to CE, note that two addresses point to 00000000. Add them to the table. Rename them to "Pointer to Selected";
______ K) Let's see what codes access the first pointer by right-clicking on it and select "Find out what accesses this address";
______ L) Go back to the game. Note that two code lines were added to the list. Select the flagship. Note that other code lines were
______ added to the list. Note that only one updates the content of the pointer. Select it on the list and Add it to the codelist.
______ Add "- pSel Ship" to the description. Close the code finder (STOP/CLOSE).
Code: |
C22 005CE76B - 89 b7 5c d1 01 00 - mov [edi+0001d15c],esi
|
______ M) Add the flagship MLP address to the table and freeze it. Now Let's try to find other ships. Two AI factions with 2 ships each are enough.
______ N) When you find an AI ship, click on it and observe the first pointer content address. Add an extra adress for each new ship on the Ship structure
______ and change each address to the content of the pointer.
______ O) Now with that we have at least 6 ships, let's have another look on the ship structure:
______ o.01 - Offset 00c8 is OwnerID. The same value found at offset 0004 and 04f4 of Playerinfo structure. Rename it to "OwnerID";
______ o.02 - Offset 01d4 is a pointer to ship type. Just look in the area they point to by right-clicking on each pointer, choosing "memory browse pointer" and observing
______ the Copy memory on the Memory Viewer. Reneme it to "pTypeInfo";
______ o.03 - Offset 01d8 is the Type ID. Rename it to "TypeID"
______ o.04 - Offset 01e0 can be the maximum Hit Points value. But we are not sure yet.
___ TutNote 17: Now we have enough information to implement a cheat for the Moves Left points. Since the script is getting bigger,
___ let's also implement a mechanism to enable/disable each cheat individually. Here is what have to do:
______ A) Implement a mechanism to enable/disable each cheat individually;
______ B) Modify the _MonET script to add get the player ID;
______ C) Implement a script to get the selected ship address (C22);
______ D) Implement a script to give free movement to player's selected ship (C21).
______ AATut 6: If we use an instruction like "cmp [iEnableME],0", the compiler will not know if the content of
______ the memory address "iEnableME" is a byte, or a word, or a double-word, etc. So we need to make it clear what
______ it is. For this purpose we use the directive "type PTR", where type can be BYTE, WORD, DWORD or QWORD).
______ Since "iEnableME" is a double-word, the corrent instruction is: cmp DWORD PTR [iEnableME],0.
______ Instructions that involves registers like cmp al,[esi+04] or cmp ax,[esi+18] or ,mov eax,[iEnableME] don't need
______ the directive, since the compiler knows that register AL is a BYTE, AX is a WORD and EAX is a DWORD.
______ He is our script till now:
Code: |
{
Script for Galactic Civilization 2 V1.0
Example on a Tutorial
Implementing a script to monitor the player's Treasure Value
Implementing a script to monitor the player's Research Technology
Implementing a script to monitor the player's Ship Moves Left (new)
}
[ENABLE]
alloc(MyCode,1024) // Allocating memory. 1024 (1Kb) is enough.
label(_MonET) // Declaring a label
label(_BackME) // Declaring a label
label(_ExitME) // Declaring a label
label(_MonRT) // Declaring a label
label(_BackMR) // Declaring a label
label(_ExitMR) // Declaring a label
label(_MonSelShip) // Declaring a label (new)
label(_BackMSS) // Declaring a label (new)
label(_ExitMSS) // Declaring a label (new)
label(_MonMovesLeft) // Declaring a label (new)
label(_BackMML) // Declaring a label (new)
label(_ExitMML) // Declaring a label (new)
label(pPlayer) // Declaring a label
label(pSelShip) // Declaring a label (new)
label(iPlayerID) // Declaring a label (new)
label(iEnableME) // Declaring a label (new)
label(iEnableMR) // Declaring a label (new)
label(iEnableMM) // Declaring a label (new)
registersymbol(MyCode) // Registering "MyCode", so it can be easily find it in the memory viewer.
registersymbol(pPlayer) // Registering "pPlayer", so it can be easily used in a table or structure.
registersymbol(pSelShip) // Registering "pSelShip", so it can be easily used in a table or structure. (new)
registersymbol(iPlayerID) // Registering "iPlayerID", so it can be easily used in a table or structure. (new)
registersymbol(iEnableME) // Registering "iEnableME", so it can be easily used in a table or structure. (new)
registersymbol(iEnableMR) // Registering "iEnableMR", so it can be easily used in a table or structure. (new)
registersymbol(iEnableMM) // Registering "iEnableMM", so it can be easily used in a table or structure. (new)
//======================= Just to separate script parts
MyCode: // This is the address of the memory that was allocated
//======================= Just to separate script parts
// This script will monitor the player's Treasure to guarantee a minimum value (10000)
// [Note] The register EBP is modified by the original code, so we are free to use it.
_MonET: // This is the address of this script part (Same as MyCode)
mov [pPlayer],edi // Let's save the content of register EDI for debugging
mov ebp,[edi+04] // Get the player ID at offset 0004 (new)
mov [iPlayerID],ebp // Saving it for further use (new)
cmp dword ptr [iEnableME],0 // The content of variable iEnableME is 0? (new)
je _ExitME // Jump if yes (e = equal to) We assumed that 0 is disabled.(new)
mov ebp,#10000 // The assemble instruction MOV is used to load value into an address or register
// In this case, EBP will be loaded with 10000 (the # indicates that it is a decimal value)
cmp ebp,[edi+000004f0] // The assemble instruction CMP is use to compare two values
// In this case, the content of the register EBP is compared to the
// content of the memory pointed by the content of register EDI plus offset 000004f0
jle _ExitME // The assemble instruction Jcc is used to perform conditional jumps.
// In this case, the condition is LE which means (less or equal).
mov [edi+000004f0],ebp // If the content of EBP is greater than that at the memory
// then the value at the memory will be changed to 10000
_ExitME: // This is the label needed because of the conditional jump
mov ebp,[edi+000004f0] // Original code should be executed
jmp _BackME // Go back to the original code
//======================= Just to separate script parts
// This script will monitor the player's Research Progress to guarantee that it is concluded in one turn
// [Note] The register EDX is modified by the original code, so we are free to use it.
_MonRT: // This is the address of this script part
cmp dword ptr [iEnableMR],0 // The content of variable iEnableMR is 0? (new)
je _ExitMR // Jump if yes (e = equal to) We assumed that 0 is disabled.(new)
cmp esi,[pPlayer] // The register ESI points to a PlayerInfo structure. Is it ours?
jne _ExitMR // The code will jump if it is not equal (NE = not equal)
mov edx,[esi+00000504] // Get the pointer to the array of research progress values
// Remember that at this point: EDX = Base, EDI = Index and EAX = value needed to complete research
mov [edx+edi*4],eax // So let's update the current research progress with the value needed to complete this research
_ExitMR: // This is the label needed because of the conditional jump
mov edx,[esi+00000504] // Original code should be executed
jmp _BackMR // Go back to the original code
//======================= Just to separate script parts (new)
// This script will monitor when a ship is selected in order to save its address
_MonSelShip: // This is the address of this script part
pushfd // Note that the first instruction after the hacking point is a conditional
// jump (jE). So we have to preserve the EFLAGS by pushing them into the stack.
or esi,esi // ESI or ESI return Zero if the content of register ESI is 0
jz _ExitMSS // Jump if content od ESI is 0 (i.e. a NULL pointer)
mov [pSelShip],esi // Save in the variable pSelShip, the address of just selected ship
// It will be used on the Moves Left script
_ExitMSS:
popfd // We need to restore the EFLAGS status.
// So we take back its value from the stack.
mov [edi+0001d15c],esi // Original code should be executed
jmp _BackMSS // Go back to the original code
//======================= Just to separate script parts (new)
// This script will monitor a ship movement points and will not let it decrease
// if it is the player's last select ship
_MonMovesLeft: // This is the address of this script part
push ebx // A register will be needed in this script. Since the original code
// is not modifying one, we decided to use the register EBX.
// But we have to preserve its content. So push it into the stack.
cmp dword ptr [iEnableMM],0 // The content of variable iEnableMR is 0?
je _ExitMML // Jump if yes (e = equal to) We assumed that 0 is disabled.
cmp esi,[pSelShip] // The register ESI points to a Ship structure. Is it the selected?
jne _ExitMML // The code will jump if it is not equal (NE = not equal)
mov ebx,[esi+000000c8] // Get the value stored at offset 00C8 (The OwnerID)
cmp ebx,[iPlayerID] // Compare the ship's OwnerID with the PlayerID
jne _ExitMML // Jump if they are not equal (NE)
mov eax,00000000 // Make the content of register EAX = 0
// The instruction XOR EAX,EAX could have been used (it is shorter)
_ExitMML: // This is the label needed because of the conditional jump
pop ebx // We need to restore the register EBX content.
// So we take back its value from the stack.
sub [esi+000001f0],eax // Original code should be executed
// It subtracts from Ship's Moves Left the value stored in register EAX
jmp _BackMML // Go back to the original code
//======================= Variables ==============================
// We can put the variables here, right after the last script.
pPlayer: // The variable name followed by : (in fact, it is a lable)
dd 0 // Reserving 4 bytes and initializing its value with 0
pSelShip: // The variable name followed by : (in fact, it is a lable) (new)
dd 0 // Reserving 4 bytes and initializing its value with 0
iPlayerID: // The variable name followed by : (in fact, it is a lable)
dd #999 // Reserving 4 bytes and initializing its value with 999
iEnableME: // The variable name followed by : (in fact, it is a lable) (new)
dd 1 // Reserving 4 bytes and initializing its value with 1
iEnableMR: // The variable name followed by : (in fact, it is a lable) (new)
dd 1 // Reserving 4 bytes and initializing its value with 1
iEnableMM: // The variable name followed by : (in fact, it is a lable) (new)
dd 1 // Reserving 4 bytes and initializing its value with 1
//=================== The Haking Points ==========================
// It can also be placed before the scripts. But let's put it after them, just to remind us
// that the script was created and loaded into the computer memory and now can be accessed.
galciv2.exe+07ebad: // The address to be intercepted
jmp _MonET // Jumping to the script (this instruction is 5 bytes long)
nop // Adding a NOP (90h) instruction to complete 6 bytes (remember this!)
_BackME: // This label is the address to go back. It is galciv2.exe+07ebad plus 6 bytes.
galciv2.exe+18f0f2: // The address to be intercepted (new)
jmp _MonRT // Jumping to the script (this instruction is 5 bytes long)
nop // Adding a NOP (90h) instruction to complete 6 bytes (remember this!)
_BackMR: // This label is the address to go back. It is galciv2.exe+18f0f2 plus 6 bytes.
galciv2.exe+1ce76b: // The address to be intercepted (new)
jmp _MonSelShip // Jumping to the script (this instruction is 5 bytes long)
nop // Adding a NOP (90h) instruction to complete 6 bytes (remember this!)
_BackMSS: // This label is the address to go back. It is galciv2.exe+1ce76b plus 6 bytes.
galciv2.exe+167198: // The address to restore the code (new)
jmp _MonMovesLeft // Jumping to the script (this instruction is 5 bytes long)
nop // Adding a NOP (90h) instruction to complete 6 bytes (remember this!)
_BackMML: // This label is the address to go back. It is galciv2.exe+167198 plus 6 bytes.
//======================= Just to separate script parts
// This part is performed when we disable the script by uncking its frozen box.
// Here we should:
// - Restore the original codes
// - Unregister the symbols
// - Deallocate (free) the memory
[DISABLE]
galciv2.exe+07ebad: // The address to restore the code
mov ebp,[edi+000004f0] // The code to be restored (this instruction is 6 bytes long)
// = 8b af f0 04 00 00
galciv2.exe+18f0f2: // The address to restore the code (new)
mov edx,[esi+00000504] // The code to be restored (this instruction is 6 bytes long)
// = 8b 96 04 05 00 00
galciv2.exe+1ce76b: // The address to restore the code (new)
mov [edi+0001d15c],esi // The code to be restored (this instruction is 6 bytes long)
// = 89 b7 5c d1 01 00
galciv2.exe+167198: // The address to restore the code (new)
sub [esi+000001f0],eax // The code to be restored (this instruction is 6 bytes long)
// = 29 86 f0 01 00 00
unregistersymbol(MyCode) // UNregistering "MyCode", so it cannot be accessed anymore.
unregistersymbol(pPlayer) // UNregistering "pPlayer", so it cannot be accessed anymore.
unregistersymbol(pSelShip) // UNregistering "pSelShip", so it cannot be accessed anymore. (new)
unregistersymbol(iPlayerID)// UNregistering "iPlayerID", so it cannot be accessed anymore. (new)
unregistersymbol(iEnableME)// UNregistering "iEnableME", so it cannot be accessed anymore. (new)
unregistersymbol(iEnableMR)// UNregistering "iEnableMR", so it cannot be accessed anymore. (new)
unregistersymbol(iEnableMM)// UNregistering "iEnableMM", so it cannot be accessed anymore. (new)
dealloc(MyCode) // DE-allocating memory so the system can use it for other purposes.
|
______ A) Time to save the script. On the Auto Assemble, left-click on File and then select Save.
______ B) Let's add the script to CE table. Left-click on File and then select "Assigned to current cheat table".
______ CE will check the script and, if everything is ok, it will be added to the table with the discription "Auto assemble cheat".
______ Change it to "Tutorial_MET_MRT_MSS_MML".
______ C) Save the table;
______ D) Disable the previous script by unchecking its frozen box.
______ E) Now enable the new script;
______ F) Add the new variables to the table: pSelShip, iPlayerID, iEnableME, iEnableMR and iEnableMM.
______ G) Let's test the enable section of the script:
______ g.01 - Select your flagship and check the content of pSelShip. Now move it around;
______ g.02 - Check if the Moves Left value does not change;
______ g.03 - Select your colony ship and check the content of pSelShip. Now move it around;
______ g.04 - Check if the Moves Left value does not change;
______ g.05 - Change the value of iEnableMM to 0 and move the colony ship;
______ g.06 - Chack if the Moves Left value decreases;
______ g.07 - Change the value of iEnableMM back to 1 and move the colony ship;
______ g.08 - Check if the Moves Left value does not change;
______ g.09 - So the new cheat is working.
___ TutNote 18: That concludes the 3rd part of the tutorial.
It continues...
The Third and last part can be found at:
http://forum.cheatengine.org/viewtopic.php?t=529804
Cheers!
|
|