Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


[Tutorial] Cheating Galactic Civilization 2 (V1.0) - Part 1

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials -> Auto Assembler tutorials
View previous topic :: View next topic  
Author Message
Recifense
I post too much
Reputation: 166

Joined: 17 Mar 2008
Posts: 3688
Location: Pernambuco - Brazil

PostPosted: Sun Jan 09, 2011 9:49 pm    Post subject: [Tutorial] Cheating Galactic Civilization 2 (V1.0) - Part 1 Reply with quote


    Hi guys,

    My first contribution for this year (2011) is a tutorial. I want to share part of my knowledge with you. I want you to know also
    that it is not so complex to implement a script. I chose a turn base strategic game (a good one), because we could explore
    many things. This game can be played in window mode, so it would help us, because we could have CE and the game screen visible
    at the same time. The game is Galactic Civilization 2 (V1.0).

    Please look in the internet for IA32_SDM_Vol2A.pdf and IA32_SDM_Vol2B.pdf to use as OPCODE reference.
    Use CE help for its reference.
    If you could first follow the CE tutorial, would be helpful, but not essential.

    Thanks to Dark Byte for the fantastic tool.

    I hope you, guys, like it.

    Cheers!

    Recifense.

    ============================= THE TUTORIAL ===========================

    1) First of all:

    ___ 1.1 Start Cheat Engine 5.6.1;
    ___ 1.2 Start GalCiv2 in Window Mode;
    ___ 1.3 Creat a new game using default parameters;
    ___ 1.4 Save it at the start.
    ___ 1.5 Click on CE and open GalCiv2.exe process;
    ___ 1.6 Go back to the game;

    2) Cheating the Empire Treasure:

    ___ TutNote 01: Take a look, at the left down corner, at the "Empire Treasure" value (5000).
    ___ Go to CE, enter 5000 on value to be searched field (Scan type = Exact Value, Value type = 4 Bytes,
    ___ Memory Scan Options = Usermode and Fast scan checked) and click on FIRST SCAN.
    ___ Now we need to make the "Treasure value" change and find out what code access it;

    ______ A) Back to the game, click on planet EARTH. At the bottom of the screen, the planet information is displayed.
    ______ Click on VIEW. The "Colony management screen" is displayed. Choose a free slot on the planet
    ______ and select a project to be built there (it could be "Basic Factory"). There are two option: BUY or BUILD.
    ______ Selelect BUY and accept it. Note that the "Empire Treasure" has changed.
    ______ B) Go back to CE and put the new "Empire Treasure" value on the value to be searched field and click on NEXT SCAN.
    ______ Since you are a lucky guy, only one address had its value changed. Double-click on it in order to add it to CE table;
    ______ C) Now let's find out what code accesses it by right-clicking on this table entry and choosing "Find out what access this address";
    ______ A confirmation window will appear. Click on YES to attach the debugger.
    ______ D) Back to the game, click on DONE on the "Colony Management Screen". Then click on TURN, and then, and it again;
    ______ E) Go back to CE. Note that about 10 code lines are displayed. Add them to the code list on advanced option
    ______ by selecting all and clicking on ADD TO THE CODELIST;

    ___ TutNote 02: Now we need to know when each code is used and, if needed, what they do. Before that
    ___ we have to be sure that each code line is safe to be used on next step. We have to check each one
    ___ looking at the code lines near it. We have to help CE not to crash the game because of an INT 3 instruction;
    ___ If you find an INT 3 near the code we are about to analyse (inside 5 bytes distance from the code), change it to NOP
    ___ (just double click on it and write NOP). It is important to know that when in an instruction there is something between [],
    ___ it means access to a memory address. The only exception is the instruction LEA.

    Code:

       C01 0047EBAD - 8b af f0 04 00 00             - mov ebp,[edi+000004f0]         
       C02 00677087 - 81 bf f0 04 00 00 20 4e 00 00 - cmp [edi+000004f0],00004e20
       C03 00583E63 - 8b b9 f0 04 00 00             - mov edi,[ecx+000004f0]
       C04 00583EC6 - 83 b8 f0 04 00 00 00          - cmp dword ptr [eax+000004f0],00
       C05 00583EDB - 03 98 f0 04 00 00             - add ebx,[eax+000004f0]
       C06 00594827 - 81 bf f0 04 00 00 0c fe ff ff - cmp [edi+000004f0],fffffe0c
       C07 0058F820 - 01 8e f0 04 00 00             - add [esi+000004f0],ecx
       C08 0058F826 - 8b 86 f0 04 00 00             - mov eax,[esi+000004f0]
       C09 0058F864 - 81 be f0 04 00 00 0c fe ff ff - cmp [esi+000004f0],fffffe0c
       C10 005C157D - 83 be f0 04 00 00 00          - cmp dword ptr [esi+000004f0],00
       


    ___ TutNote 03: Looking at code lines we can see that all of them, except for C07, just read the value.
    ___ C07 updates the value by adding the content of the register ECX. C02 compares the value with 00004e20 (20000)
    ___ which must be the "superior limit" of the value. C06 and C09 compare the value with FFFFFE0C (-500) which must
    ___ be the "inferior limit" of the value. C4 and C10 just verify if it is zero. C01, C03 and C08 read the value into
    ___ a register. C05 adds the value to register EBX. An important information is that the value is stored
    ___ at offset 000004f0 of a structure. Let's check that. Smile

    ______ A) Make a copy on the entry on the table by copying and pasting it. Choose one of the entries and double-click
    ______ on the address value. The edit box will show up. Add to the current address value the text "-04f0" and click OK.
    ______ Now the address is pointing to top of the structure. Right-click on the just edited entry and choose
    ______ "Browse this memory region".
    ______ B) Go to the "Memory Viewer" window and look at "Copy memory" section. You can see some strings as for instance:
    ______ "Terran Alliance", "Terran", "Alan Bradley", "Earth", "Sol", etc. Now from "Memory Viewer" select Tools->Dissect data/structures
    ______ (or use the shortcut Ctrl+D). The "Memory dissect" window will appear with the address field already filled.
    ______ Select Structures->Define new structure. Give it a name (for instance, PlayerInfo) and press OK and then YES.
    ______ Now for the size enter the value in hexdecimal 0x600 since the "Empire Treasure" has offset 0x04f0. CE will do its best to
    ______ figure out the offsets.
    ______ C) We already know what the offset 04f0 is, so let's change its name to "Empire Treasure".
    ______ Just double-click on the description "Dword" and then change it. Let's save what we have done till now.
    ______ Click on the diskette on CE to save the table. Let's continue, we will probably find the meaning of some of those remaining offsets.
    ______ D) Let's verify what addresses those codes access by right-clicking on each of them on the codelist and choosing the option
    ______ "Find out what addresses the code reads/writes from/to";

    ___ TutNote 04: C01 and C09 read only the player's "Empire Treasure". C02, C04 and C05 read 7 different addresses. C03, C06, C07, C08 and C10
    ___ read 8 different addresses. Conclusion: There are 8 players. C01 and C09 are important codes because they only access the human player's value.
    ___ Now let's add the AI player's to the PlayInfo structure. On the last Changed addresses result (related to cmp dword ptr [esi+000004f0],00),
    ___ right-click on each AI value and choose "Show register states". Get the value of the register ESI and add it to the "Memory dissect - PlayerInfo".
    ___ (Memory dissect window->File->Add extra address). Let's re-analyse the PlayerInfo structure.

    ______ A) Observing the players side-by-side, we can conclude the following:
    ______ a.01 - Offset 0000 is a pointer and the value depends on the player;
    ______ a.02 - Offset 0004 is an index or the player ID (to be confirmed). You can change its name to "PlayerID";
    ______ a.03 - Offset 0008 is the player faction name. You can change its name to "FactionName" and the size to 32.
    ______ a.04 - Offset 0028 is the player Race name. You can change its name to "RaceName" and the size to 32.
    ______ a.05 - Offset 0048 is the player Governor name. You can change its name to "Governor" and the size to 32.
    ______ a.06 - Offset 0068 is the player Main Planet name. You can change its name to "MainPlatet" and the size to 32.
    ______ a.07 - Offset 0088, although CE considered a pointer, is, in fact, the player System Sun name. You can change its name to "MainPlatet" and the size to 32.
    ______ a.08 - Offset 04f4 is an index or the player ID (to be confirmed). You can change its name to "PlayerID";
    ______ B) Time to Save the table; Smile

    ___ TutNote 05: Now we have enough information to implement a script to monitor the Empire Treasure value. So lets do it.

    ______ A) Resource, differently from HP, is not a critical value, so the codes that read only the human player value are the candidates
    ______ and they both could be used since they are greater the 4 bytes. But let's take the shorter one. So C01 is the chosen one
    ______ (0047EBAD - 8b af f0 04 00 00 - mov ebp,[edi+000004f0]).
    ______ B) Right-click on it on the codelist and select "Open the disassembler at this location";
    ______ C) Go to Memory Viewer window and, on View, turn off "Show symbols" and turn on "Show module addresses";
    ______ D) Still on Memory Viwer window press Ctrl+A to open the Auto assemble editor;

    ______ AATut 1: The script is divided in two modules: one that is performed when you enable the script and other that is performed when
    ______ you disable the script. The keywords for this are [ENABLE] and [DISABLE]. Have in mind that our script will be transformed (compiled)
    ______ in machine code and will need a place in the computer memory to be executed. So we need to allocate memory for it. This is made via
    ______ the script instruction alloc(Name, Size). To add comment to the script we use // for a line or { } for a block;

    ______ He is our script till now:

    Code:

    {
     Script for Galactic Civilization 2 V1.0
     Example on a Tutorial
    }

    [ENABLE]                   // Keyword to indicate that this part of script is executed when
                               // the script is enabled via its check box on a CE table
    alloc(MyCode,1024)         // 1024 (1Kb) is enough

    [DISABLE]                  // Keyword to indicate that this part of script is executed when
                               // the script is disabled via its check box on a CE table


    ______ AATut 2: Now let's add the hacking point, the original code on the "disable module" and the associated part of the script.
    ______ The hacking point is at galciv2.exe+07ebad. We are gonna use it in the the two modules: one to intercept the code and
    ______ the other to restore the original code. All the labels that we use should be declared on AA "enable module" via label(name).
    ______ A label represents a memory address at some point of the script. At that point, it should be followed by ":".
    ______ But when a label is referenced to, the ":" is not needed.

    ______ AATut 3: You can add variables to your script and register their name so we can easily find them when the script is enabled.
    ______ For that, we should declare it as a label (label(varname)) and register it using registersymbol(varname).
    ______ We donīt need to allocate memory for the variables, we simply put them after the script. But we must reserve area for each variable that we add.
    ______ The reserve size depend on each variable type. A pointer, the content of a 32 bits register and a float number take 4 bytes.
    ______ There are define directives for some predefined sizes: DB = Define Byte (1 byte), DW = Define Word (2 bytes) DD = Define Double-word (4 bytes).
    ______ The default type for constants is hexdecimal, so 100 is, in fact, 256 in decimal. You can use symbols to change a constant type:
    ______ #100 is decimal, (float)100 is a 32 bits float and (double)100 is 64 bits float. We can also use string constant like 'CE56'.

    ______ 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
    }

    [ENABLE]
    alloc(MyCode,1024)         // 1024 (1Kb) is enough

    label(_MonET)              // Declaring a label
    label(_BackME)             // Declaring a label
    label(_ExitME)             // Declaring a label
    label(pPlayer)             // Declaring a label

    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.

    //======================= 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 that 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,#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

    //======================= 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

    //=================== 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.

    //======================= 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

    unregistersymbol(MyCode)   // UNregistering "MyCode", so it cannot be accessed anymore.
    unregistersymbol(pPlayer)  // UNregistering "pPlayer", so it cannot be accessed anymore.

    dealloc(MyCode)            // DE-allocating memory so the system can use it for other purposes.


    ______ E) Time to save the script. On the Auto Assemble, click on File and then select Save.
    ______ Now give a name to the script (for instance, "GalCiv2_tutorial") and click on Save.
    ______ F) Let's add the script to CE table. 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".
    ______ G) Now enable it, by clicking on its frozen box. Now let's add the variable pPlayer to the table, so we can
    ______ easily find our player structure everytime we start a game and/or use it as a structure address:

    ______ g.01 - Click on ADD ADDRESS MANUALLY;
    ______ g.02 - Replace the address by "pPlayer" and copy it to the description field;
    ______ g.03 - Make sure the type is 4 bytes and click on OK;
    ______ g.04 - Now right-click on this new entry on the table and choose "Show as hexadecimal value"

    ______ H) Let's test the enable section of the script. Go back the game and click on TURN.

    ______ h.01 - Verify if the "Empire Treasure" value is 10000 or greater;
    ______ h.02 - Verify on the table, if the content of "pPlayer" is the same as in the dissect structure;
    ______ h.03 - Right-click on assembly section of the Memory Viewer, choose "Go to address" and replace the number by "MyCode"
    ______ Note that the script is displayed and that the "pPlayer" can be easily identified.
    ______ h.04 - Compare the code with the script. Note that 10000 appears as 00002710 which is its hexdecimal representation.
    ______ h.05 - Now right-click on Copy memory section of the Memory Viewer, choose "Go to address" and replace the number by "pPlayer"
    ______ Note that its content is displayed backwords. That's the way it is stored in the computer memory.

    ______ I) Now let's test the disable section of the script by unckecking the script fronzen box. Go back the game load the game (that we saved in 1.4).
    ______ Check if the "Empire Treasure" value is 5000.

    ___ TutNote 06: That concludes the 1st part of the tutorial. Wink


    3 - Cheating the Technology Research:


    ___ TutNote 07: Enable the script "Tutorial_MET" and load the game (that we saved in 1.4). It will start at the "Research Screen". One of the research technology
    ___ will be selected by default. Let's check what happens when we change the selection. Our goal is to find a pointer or an index. Since we don't know what
    ___ we will find, lets do the following:

    ______ A) Go to CE , change the Scan type to 'Unknown initial value' and Value type to '4 bytes'. Enable Fast scan by clicking in its check-box;
    ______ Now click on the FIRST SCAN. This time a lot of addresses were found;
    ______ B) Go back to the game and change select the next technology;
    ______ C) Go back to CE and change Scan type to 'Changed value' and click on NEXT SCAN. Now some addresses are displayed but they are still a lot;
    ______ D) Repeat step b and c;
    ______ E) Pay attention to the current selected technology. Select another and then select it back;
    ______ F) Go back to CE and change Scan type to 'Unchanged value' and click on NEXT SCAN. Now the address list was really decreased;

    ___ TutNote 08: Let's check if there is any address that can be associated to the player structure. For example, the player structure in my system is 0x06230020.
    ___ Take note of yours. Browse the address list, looking for addresses that start with the first 4 digits/letters of your player structure. In my example, 0623.
    ___ I have just found 1 address at 06230528. I guess you too. Double-click on it to add it to the table. The value doesn't look like a pointer (too small).

    ______ G) Let's check what codes access this value:

    ______ g.01 - Right-click on this table entry and choose "Find out what access this address". Organize the windows in order to be able to see the game and the
    ______ code finder window. Do this always;
    ______ g.02 - Go back to the game and select the first technology; You can see that 3 code lines appeared on the list.
    ______ g.03 - Now let's see what happens when we end the TURN. Do it. Close the Research screen by clicking on DONE. A new code line was added to the list.
    ______ Click on DONE in the next screen. Now we have 4 code lines on the list. End the TURN. If nothing was added to the list, end the turn again.
    ______ Now 3 lines were added to the list and we have the following:

    Code:

       C11 00584002 - 89 be 08 05 00 00             - mov [esi+00000508],edi
       C12 004CC2BD - 8b 8d 08 05 00 00             - mov ecx,[ebp+00000508]
       C13 004CC4D3 - 8b 95 08 05 00 00             - mov edx,[ebp+00000508]
       C14 0047EDFF - 8b 87 08 05 00 00             - mov eax,[edi+00000508]
       C15 0058F093 - 8b 86 08 05 00 00             - mov eax,[esi+00000508]
       C16 0058F0CF - 8b 96 08 05 00 00             - mov edx,[esi+00000508]
       C17 0058F0E5 - 8b be 08 05 00 00             - mov edi,[esi+00000508]
       


    ___ TutNote 09: C11, C12 and C3 are activated when we select the technology to be researched. C11 is the only code that writes at the address. Let's add it to CE code list.
    ___ Just select it and click on ADD TO THE CODELIST. Add to the code name "- RT on sel" so we can easily identify it on the list.
    ___ C14 is activated when we leave the "Research screen". Nothing special about it. C15, C16 and C17 are activated between turns. Let's analyse them.
    ___ Select C15 and click on MORE INFORMATION. Note that ESI points to our player structure and the offset 0508 is ralated to research. So go to the PlayerInfo structure
    ___ and change the description of offset 0508 to "RT" (It is just a reminder, since we do not know what it is yet).
    ___ Select C15 again and click on SHOW DISASSEMBLER. The following code is displayed. Let's dissect it. Smile

    Code:

       AL01 - 0058F093 - 8b 86 08 05 00 00          - mov eax,[esi+00000508]
       AL02 - 0058F099 - 83 f8 ff                   - cmp eax,ff
       AL03 - 0058F09C - 0f 84 82 00 00 00          - je 0058f124
       AL04 - 0058F0A2 - 3b 86 fc 04 00 00          - cmp eax,[esi+000004fc]
       AL05 - 0058F0A8 - 77 70                      - ja 0058f11a
       AL06 - 0058F0AA - 8b 8e 04 05 00 00          - mov ecx,[esi+00000504]
       AL07 - 0058F0B0 - 83 3c 81 ff                - cmp dword ptr [ecx+eax*4],ff
       AL08 - 0058F0B4 - 74 64                      - je 0058f11a
       


    ______ AssemblerTut 1:
    ______ AL01: The value that changes when we select different technologies is loaded into register EAX;
    ______ AL02: This values is compared with -1 (checking if the value is valid);
    ______ AL03: The code jumps to other place if it is -1 (The conditional jump instruction Jcc is used and cc, in this case is "e" (= equal to));
    ______ AL04: The value is compared to the value stored at offset 04fc. In my PlayerInfo Structure, the value at this offset is 248;
    ______ AL05: The code jumps to other place if the value is above (ja = jg = greater than) the value stored at offset 04fc.
    ______ AL06: The value stored at offset 0504 is loaded into register ECX.
    ______ AL07: This instruction uses ECX as base address and EAX as an index and verifies if the value stored at BASE+Index*4 is -1.
    ______ The *4 indicates that each stored value is 4 bytes long.

    ___ TutNote 10: So we can conclude that the value at offset 0508 is the technology index and the value at offset 0504 is a pointer to an array of 4 bytes values.
    ___ We can also conclude that the value at offset 04fc is the maximum index value. So let's update the description of these offsets on the PlayerInfo Structure:
    ___ offset 04fc = MaxResearchIndex, offset 0504 = ptrResearchArray and 0508 = CurrentResearchIndex.
    ___ Now Select C16 and click on SHOW DISASSEMBLER and scroll one line up. The following code is displayed. Let's dissect it as well:

    Code:

       AL09 - 0058F0C9 - 8b 8e 04 05 00 00          - mov ecx,[esi+00000504]
       AL10 - 0058F0CF - 8b 96 08 05 00 00          - mov edx,[esi+00000508]
       AL11 - 0058F0D5 - 8d 14 91                   - lea edx,[ecx+edx*4]
       AL12 - 0058F0D8 - 8b 4c 24 0c                - mov ecx,[esp+0c]
       AL13 - 0058F0DC - 01 0a                      - add [edx],ecx
       AL14 - 0058F0DE - 83 86 0c 05 00 00 01       - add dword ptr [esi+0000050c],01
       AL15 - 0058F0E5 - 8b be 08 05 00 00          - mov edi,[esi+00000508]
       AL16 - 0058F0EB - 8b c8                      - mov ecx,eax
       AL17 - 0058F0ED - e8 8e 13 ff ff             - call 00580480
       AL18 - 0058F0F2 - 8b 96 04 05 00 00          - mov edx,[esi+00000504]
       AL19 - 0058F0F8 - 39 04 ba                   - cmp [edx+edi*4],eax
       AL20 - 0058F0FB - 72 16                      - jb 0058f113
       


    ______ AssemblerTut 2:
    ______ AL09: The ptrResearchArray value is loaded into register ECX;
    ______ AL10: The CurrentResarchIndex value is loaded into register EDX;
    ______ AL11: The instruction LEA (Load Effective Address) does not read a value in memory. It loads a register with the result of the math operation defined between [].
    ______ So EDX is loaded with the result of BASE+Index*4 operation. For example, if ECX = 06000000 and EDX = 00000002, then the result is 06000008.
    ______ AL12: Register ECX is loaded with a value from the stack (the register ESP points to a stack);
    ______ AL13: The value that was read from the stack is added to current research progress in the array.
    ______ AL14: The offset 050c of the PlayerInfo structure is increased by 1. It can be the week counter.
    ______ AL15: The CurrentResarchIndex value is loaded into register EDI (This is also the last codeline on the list);
    ______ AL16: The register ECX is loaded with the register EAX content (unkown to us);
    ______ AL17: A subroutine is called. When an instruction RET is executed in that subroutine, the flux will continue on AL18;
    ______ AL18: The ptrResearchArray value is loaded into register EDX;
    ______ AL19: The current research progress [BASE+Index*4] is compared to register EAX (the result of the subroutine);
    ______ AL20: The code jumps to other place if current research progress value is below (jb = jl = less than) the value needed to finish research.

    ___ TutNote 11: So we can conclude that the assebler line AL18 is the best place for implementing a script to research a technology in one turn
    ___ because, at this point, we know the value expected to finish the research (EAX) and we can identify when the resarch is ours with help of pPlayer.
    ___ So add it to the codelist by right-clicking on it in the desassebler section on the memory Viewer and choosing "Add to the code list". Add "- RT" to the codeline name.
    ___ Close "The follwing opcodes accessed the selected address" window by clicking on STOP and then on CLOSE;

    ______ AATut 5: Now let's add the hacking point, the original code on the disable module and the associated part of the script on the enable module.
    ______ The hacking point is at galciv2.exe+18f0f2[b]. We are gonna use it in the the two modules: one to intercept the code and the other to restore the original code.

    ______ 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 (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 (new)
    label(_BackMR)             // Declaring a label (new)
    label(_ExitMR)             // Declaring a label (new)
    label(pPlayer)             // Declaring a label

    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.
          
    //======================= 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,#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    (new)
    // 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 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

    //======================= 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
          
    //=================== 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.

    //======================= 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

    unregistersymbol(MyCode)   // UNregistering "MyCode",  so it cannot be accessed anymore.
    unregistersymbol(pPlayer)  // UNregistering "pPlayer", so it cannot be accessed anymore.

    dealloc(MyCode)              // DE-allocating memory so the system can use it for other purposes.


    ______ [b]A)
    Time to save the script. On the Auto Assemble, click on FILE and then select SAVE.
    ______ B) Let's add the script to CE table. 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 description "Auto assemble cheat".
    ______ Change it to "Tutorial_MET_MRT".
    ______ C) Save the table;
    ______ D) Disable the previous script by unchecking its frozen box.
    ______ E) Now enable the new script;
    ______ F) Let's test the enable section of the script. Go back the game and click on TURN.

    ______ f.01 - Verify that the "Research Complete" screen pops out. Now click on DONE;
    ______ f.02 - Choose another technology to be researched and click on DONE;
    ______ f.03 - Finish TURN again and repeat steps f.01 and f.02;
    ______ f.04 - Disable the script by unchecking its frozen box and finish TURN once more;
    ______ f.05 - Verify that NO "Research Complete" screen pops out;

    ___ TutNote 12: That concludes the 2nd part of the tutorial. Wink

    It continues...

    The second part can be found at: http://forum.cheatengine.org/viewtopic.php?t=529803
    The Third and last part can be found at: http://forum.cheatengine.org/viewtopic.php?t=529804

    Cheer!

Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials -> Auto Assembler tutorials All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites