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