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!
 
 | 
			 
		  |