Tulip 2021 Game Assistive Technology Intermediate Class (5)

046-C,C++ optimize macro call

Make macro calls support UTF-8 character encoding.

Insert image description here

In the previous code, the string was not transcoded (transcoded to UTF-8), so we grabbed the string in UTF-8 format from the memory and used it. In this lesson, we will support Chinese Add to it.

Insert image description here

Insert image description here

We change the directory name of the self-written functional interface to 001-self-written API interface, then copy the AnsiToUtf8 function to the end of AsciiUnicodeUtf8.cpp, and add the function prototype to AsciiUnicodeUtf8.h.

Insert image description here

Modify the macro test function:

Insert image description here

Insert image description here

Let’s write the call here like this temporarily and test it first.

Insert image description here

We copy a copy of the macro execution function, put it in the game function interface.cpp, and add it to the TGAME class.

Insert image description here

Insert image description here

Insert image description here

Insert image description here

Entering the game test, there is no problem, but in the end our goal is to enter the macro command in the edit box and execute it successfully. So far, we have only succeeded in transcoding.

Insert image description here

Since the AnsiToUtf8 function we just wrote only supports converting multi-byte character sets to UTF-8, not Unicode to UTF-8, we temporarily changed the character set of the project to use multi-byte character sets. Problems occurred after compilation. , let’s fix it:

Insert image description here

We add an associated value variable to the edit box:

Insert image description here

Insert image description here

Give this edit box value variable an initial value:

Insert image description here

Insert image description here

Insert image description here

Insert image description here

Insert image description here

Insert image description here


047-C, C++ Analysis of Release of Souls and Resurrection of Angels

Insert image description here

Insert image description here

After we use xdbg to attach the wow game, when the character is dead (there are two ways to resurrect, one is angel resurrection, and the other is to find the body), we go to the wow module in xdbg and search for the current module and constant 6B0B50. Searching for places where this plaintext package is called, you will find more than 600 places. If you want to do offline assistance, you must analyze it all. Since we do not do offline assistance, we only need to analyze the parts we need:

Insert image description here

Insert image description here

Insert image description here

Then, wherever we break without pressing the release soul button on the game interface, there are some heartbeat packages and other functions (steering, etc.). We cancel the breakpoints in those places, and then click to release the soul. The place where the button is broken is most likely the package that releases the soul.

Insert image description here

Of course, it is also possible that we call a CALL higher than this CALL (we double-click to go to the return address 0085898A in the stack in the lower right corner of the picture above), or it may be disconnected, but we still need to verify whether it is, or it may be several layers above. (Analyze to see if you can find the skill string name).

Insert image description here

Let’s go to ecx and take a look:

Insert image description here

The selected part in the picture above is the content of our package. The value 5 may be the size of the package, and 23FCD350 is the buffer of the package. We have analyzed it before when analyzing skills:

Insert image description here

After canceling the breakpoint, it was also broken in another place. Of course, it may not have much to do with releasing the soul:

Insert image description here

Insert image description here

The further to the back the breakpoint is, the less likely it is to be related to the release of the soul. The further to the front, the greater the possibility. We can also go in and take a look at the content of the following packages:

Insert image description here

Take a look at what’s inside the package:

Insert image description here

Insert image description here

There are many broken places later, we will copy and record them all:

Insert image description here

That is to say, after we click the release soul button, about 8 packages are sent. After we return to the game, we will see the Angel NPC in a dead state:

Insert image description here

We use the right mouse button to click on the angel and break several places. We record and cancel these breakpoints one by one:

Insert image description here

Insert image description here

After we click the accept button in the picture above, we can see where the CALL of this plaintext package will be called:

Insert image description here

After recording it, cancel the breakpoint, let the game run, and then break to other places:

Insert image description here

Although it is said that the later the package is grouped, the less likely it is, but if it is the later package, it is still possible;
As shown in the picture above, There are about three packages related to the resurrection of angels, after clicking the accept button.

Insert image description here

There are 4 packs when you right-click on the NPC, and there are about 7 packs for releasing the soul. But which one is the real release of the soul, which one is the real right-clicking on the NPC, and which one is the real command for the resurrection of the angel? We will write code to test in the next class (write a structure to assemble the package and call the corresponding CALL for testing). Of course, we will focus on analyzing the first package group now, because the possibility of subsequent package groups is very small. Generally, The probability of being the first is as high as 90%.

Let’s first look at the package analysis process of right-clicking an NPC:

Insert image description here

The value at position +10 may be the size of the packet, position +4 is the packet buffer, and position +0 is the vftable of the package object. Let’s take a look at the contents of the package at position +4:

Insert image description here

Insert image description here

The combination of these two is a complete package object and the contents of the package. That is to say, when we right-click the NPC normally, we need to group the package.

Insert image description here

This means which NPC (monster) you want to visit, you pass its GUID, and 13D should be the command to open the NPC. This is a fixed integer, used as a calling convention, I passed it It is a value of 13D, which means that you need to access, open, and right-click this NPC. This is probably what it means. This is a guess on our part.

Let’s take a look at the package and package contents when the angel was resurrected:

Insert image description here

Insert image description here

What is pushed on the stack is ecx. We see that the content of the packet has basically not changed. Only the address of the packet buffer at position +4 has changed. Let’s take a look at the content of the packet buffer:

Insert image description here

You can see that the release soul command 15A in the packet buffer has not changed and is fixed.

Let's take a look at the package formed by clicking the accept button of the angel's resurrection:

Insert image description here

What is pushed onto the stack is edx, and the contents of the package are:

Insert image description here

Insert image description here

Let's test to see if ID1 and ID2 are the player's own ID. Let's go to the CALL to get the player object and set a breakpoint:

Insert image description here

Insert image description here

Insert image description here

The eax obtained after the CALL interrupts and returns is the character pointer. We found that the content of the +30 address is not the ID 5B015407, indicating that 5B015407 may belong to the angel NPC. Specifically, we can print the monster list in the next lesson. Just compare.


048-C, C++ Write code to test the soul release and resurrection code

In this lesson we will write code for testing.

Insert image description here

Insert image description here

In order to be more versatile, we modify the plaintext packet function:

Insert image description here

Insert image description here

Insert image description here

Insert image description here

Let's test it. If it fails, we need to analyze the following CALL packages. In special cases, it may require several packages to be used together, but generally only one package is used. Specifically, we Need to do testing.

Insert image description here

Insert image description here

The soul has been released successfully and has arrived at the angel's side. Now there are two steps to be done:
Visit the NPC package and click the accept button to resurrect the package.

Insert image description here

Insert image description here

Insert image description here

We need to see if the ID filled in buf belongs to an angel. We can verify it by traversing the monster list.

The test failed and the NPC cannot be opened;
Let’s first package the angel’s resurrection and test to see if it can be resurrected without opening the NPC. If so, we will jump By opening the NPC function:

Insert image description here

The test was successful when very close to the angel, and the second package was successful.

Let’s continue to analyze the function of right-clicking an NPC with the mouse:

Insert image description here

We found that the test to open the NPC failed because the NPC's ID was incorrect, indicating that the angel's ID changes dynamically (it will change every time the game is reopened). In this case, we need to dynamically traverse to the angel's ID, and Take it out.

Insert image description here

After our testing (clicking the open NPC button multiple times, the NPC dialog box interface never appears, and successful resurrection after clicking Resurrection, it means that the NPC dialog box interface is not displayed; the packet only has an effect, and there will be no interface). Currently, this The situation indicates that a higher-level CALL needs to be called.

Insert image description here

If you call it with one click, it means that these three functions are called together:

Insert image description here

After testing, we found that one-click resurrection is not possible, and the character needs to be moved near the angel NPC to be resurrected. Therefore, we need to traverse the monster list, obtain the coordinates of the angel, and then move to the angel for resurrection.


049-C, C++ second repair and improvement of traversal code+

There is a problem with our traversal monster code and the traversal is incomplete. Let’s improve it this time.

Insert image description here

Insert image description here

From the picture above, we can see that after the monster object's first node is judged to be an even number, after the object is obtained in line 179, the object is not judged to be an even number. The even number in the while condition is still The judgment result of the first node of the monster object.

Insert image description here

Because we did not add such a judgment that the object is an even number before, it will cause the object address in the while loop to be an odd number, which will causeR4(对象+0x20) to obtain the object and generate an exception, and the program will be terminated in advance. If it terminates, the traversal will be incomplete.

Let's streamline the code and make it more complete:

Insert image description here

Insert image description here

The traversal is incomplete. There is another problem with the previous code. We can see that when the 6th traversal is reached (i=5), the program exits.

We set the TopMost property of the form to true, and set Minimize to true to add a minimize button. Maximizing is generally not needed.

Insert image description here

We added a few print output statements to assist debugging, and finally found that we did not reach the end of the traversal linked list printed by printf on line 235 (selecting that line in the figure below only starts traversing, and there is no i=37 to end the traversal linked list) , indicating that there is still a problem. Only when we reach line 237 does it mean that our traversal is successful. If we do not reach this line, it means that there must be a problem in the code.
There is probably a problem with the function of traversing the linked list.

Insert image description here

We can see from the picture above that after i=36 is completed, an error occurred when i=37 started traversing the linked list. It can be determined that the error occurred in the function of traversing the linked list. At first glance, it may be in the function of printing monster object information. Problem:

Insert image description here

But this time the test was successful, but the code is still unstable. We will improve it later.


050-ce, xdbg analysis equipment durability analysis (current value, upper limit value)

The current suspicion is that there is a problem in the function that prints monster object information on line 185:

Insert image description here

We can start from the head of the function or start from the suspicious place to add exception handling. It is speculated that there is a problem in getting the name of the backpack object:

Insert image description here

Insert image description here

Pop up a window when it makes an error and make it stop:

Insert image description here

We also add a large exception handling to it on the upper layer and include the entire function, because if the exception is not caused by the backpack name, it will be passed to this layer:

Insert image description here

Insert image description here

We can comment out the MessageBox in the exception handling in the above figure, so that it can still traverse subsequent nodes, but we will keep this information packet here for now:

Insert image description here

For example, we can also move the starting block of __try back to the assignment of the utf8 object name (which means there is no problem with the previous part of the code at this time), so that we can narrow the scope step by step and finally determine the error. The location of the code.

Durability analysis

Insert image description here

For this numerical type, we use CE to search the memory:

Insert image description here

Insert image description here

We can use the starting address of this object to specify a range for it, roughly what the range is (start and stop as shown in the figure below). Generally speaking, the durability is very close to the address of this object (equipment object). Of course This is not absolute either:

Insert image description here

We found it immediately, but whether this value is our durability or not, we will know after we change it (use CE to modify the address value 24 to 11).

Insert image description here

We can see that the durability has become 11, which means that this address must be durable.

Insert image description here

At this time we use CE's debugger to find out what accessed this address:

Insert image description here

After we point the mouse up (as shown in the picture above), several assembly instructions are displayed. From here, its first offset is +D8.
Display the disassembler to see the flow of the code and see what the previous offset (the offset related to eax) is:

Insert image description here

Insert image description here

Insert image description here

We record the register environment in the picture above, and edi is equal to 2DD905C8, which happens to be the address of the apprentice robe.

Insert image description here

Insert image description here

Let’s use xdbg again to see the upper limit of equipment:

Insert image description here

As shown in the memory window below, the equipment limit of 35 is next to the durability:

Insert image description here

Insert image description here

We modified the durability to 333 in CE, and you can see that the upper limit of the apprentice's robe's durability is 333.

Insert image description here


051-ce, xdbg debugging analysis, repairing single equipment function and repairing all equipment

Repairing a single piece of equipment and repairing all equipment must be outsourced to the server group. Please refer to the knowledge points in Lesson 29:

Insert image description here

Insert image description here

Insert image description here

You can see that there are more than 400 group package functions, and we only need a few group packages now.

Now let’s look at the function of repairing all equipment (on your body and in your backpack)

Insert image description here

Go to the game and cancel all breakpoints that are not related to repairing:

Insert image description here

We open the NPC at the blacksmith, cancel all broken items, and then click on the picture below to repair all items:

Insert image description here

Insert image description here

Copy and select part of the code in the picture above for record, because if you send a package to the server, if you repair all the equipment, the package format may only have one instruction. If you modify a single equipment, there may be a GUID of the equipment. What exactly is it? We still have to take a look to find out.

As shown in the figure above, go to the address represented by eax in the memory window:

Insert image description here

Insert image description here

That is, 3A9FB50 is a package object. We copy the contents of the package and record it:

Insert image description here

Let’s take a look at the contents of the packet buffer at position +4 of the packet object:

Insert image description here

You need to copy and record at least 21 bytes of the content in the above picture.

Insert image description here

In fact, the part selected at +14 in the picture above is useless.

In theory, all the objects we repair here do not need the two item IDs F1300000 and 4E013851, so these two may be the IDs of players or NPCs:

Insert image description here

At this point we can determine that the ID is the ID of the NPC selling equipment.

Insert image description here

Repair a single piece of equipment

Cancel the breakpoint, continue running the game, and cancel all the breakpoints that have been broken;
Then click to repair a single equipment, and then click on the equipment with insufficient durability (apprentice robe ):

Insert image description here

Insert image description here

Insert image description here

We found that the contents of the package buffer for repairing a single equipment, compared with repairing all equipment, have two more values ​​0x8277 and 0x40000000:

Insert image description here

These two values ​​are the item IDs of the apprentice robes.

Insert image description here

Write code to package test and repair individual equipment

As long as you don’t change characters, servers, exit the game, or the game version is not updated, these IDs will generally not change; in addition, if you buy another apprentice robe, the ID of the new apprentice robe will definitely be different. Each copy has an independent GUID.

Insert image description here

Insert image description here

Insert image description here

Insert image description here

The first member of the plaintext packet object in the picture above is not what we analyze. Since we don’t know what it is used for, it doesn’t matter if it is wrong. Let’s test it first and see if it doesn’t work. If it doesn’t work, change it to the correct value noted later.

Insert image description here

Insert image description here

We first manually open the NPC (this step is indispensable). If we find that the durability of the equipment is full, we will go to fight monsters and get beaten up to let the durability drop some for testing.

Insert image description here

Insert image description here

Then run to the NPC and open his and your character information to test:

Insert image description here

After the test, it was found that it was not successful. I closed the role panel and reopened it to refresh it. I found that it was still unsuccessful. This means that the content of the first member of the group package is effective and needs to be modified to the correct value and try again. In addition, we also changed the length of the package. If the modification is not correct, the test may fail due to packet length issues.

Insert image description here

Insert image description here

The discovery is still unsuccessful. We first traverse some monster equipment items to see if the GUID of the apprentice robe has changed. After traversing and searching, we found that the GUID has not changed, and the GUID of the NPC has not changed either, so it is possible Or there is something wrong with the analysis of our package.
Let’s add a piece of debugging information to the plaintext packet sending EX function to see if it is executed to this place:

Insert image description here

Insert image description here

Judging from the debugging information output, the plaintext packet EX function must have been called.

Maybe the package we analyzed was wrong, let’s re-analyze it:

Insert image description here

Insert image description here

Insert image description here

Insert image description here

Cancel irrelevant breakpoints until the game can run.

Insert image description here

We found that there are many CALLs that use package object parameters before calling 6B0B50. It may be necessary to call these previous CALLs to initialize this object, and we see that the package object content in the memory window in the lower left corner also 0x100 and other data, let’s expand the scope of the packet object (to +24) and try again;
The content of the packet buffer should be 0x15 bytes, and the previous analysis of this piece should be correct. :

Insert image description here

Let’s regroup this package and give it a try:

Insert image description here

Insert image description here

There is also a situation where the equipment has been repaired but has not been refreshed. If we exit the game for a while and then enter again, the data may be updated (the function of repairing all equipment is simpler, it does not have redundant parameters such as item IDs; Repairing individual ones is more complicated).

Let’s test it by killing monsters and then resurrecting the character (you can also directly use the command .die to die. After resurrection, the durability of the equipment will be reduced). Open the character panel and backpack, and you can see the equipment. The durability has all dropped, and now it is more convenient to test;
At this time, we can use our code to inject it and try it:

Insert image description here

The repair was completed and the test was successful. It may indeed be related to the data (0x100) behind the package content that we did not add before:

Insert image description here

But it may not matter. You can go down and test it yourself. For example, in the picture above, lines 39 and 40 are set to 0, and line 41 is still 0x100. Give it a try; you can also try it when the NPC is not opened; repair all equipment Go down and assemble the package yourself and give it a try.


052-C, C++ writing code to traverse equipment durability

Traverse the durability of equipment in the monster list. It is said to be a monster list. In fact, all equipment, backpacks, things on the ground, monsters, and NPCs are in this monster list, and the durability of all these objects is traversed.

Insert image description here

Insert image description here

We write code to traverse the equipment in all monster arrays and print its current durability and upper limit of durability.

We add an "equipment-related" directory, a "backpack-related" directory, and a "monster-related" directory to the project's game function test directory:

Insert image description here

Add the "Equipment Array.cpp" source file and the "Equipment Array.h" header file, and then copy the codes of several functions related to traversing monsters:

Insert image description here

Change the name of the function to get the latest object to traverse equipment, and delete the code that has nothing to do with traversing equipment. We only need a simple traversal:

Insert image description here

Let’s modify the parameters for traversing the linked list:

Insert image description here

Insert image description here

The function of saving recent objects in the two figures above is no longer needed and should be deleted.

Insert image description here

The selected part in the picture above is no longer needed and should be deleted.

Then continue to modify the traversal linked list function (the function written before is problematic):

Insert image description here

Let’s see how to determine whether it is an equipment object:

Insert image description here

As you can see from the picture above, all categories 3 are basically equipment. This is one place to judge;
Another place is the virtual function table vftable: a>

Insert image description here

Both of these places can be used to judge equipment. We can currently consider judging from the classification, which is more accurate, because if it is really a game, as long as the game is updated a little bit, the address of this virtual function table will occur. If it changes, we have to re-analyze the virtual function table, but the classification will not change.

So here we have to read out the object classification first:

Insert image description here

In our previous code, we wrote functions for obtaining object types. Copy their function prototypes to the "Equipment Array.h" header file to use:

Insert image description here

Insert image description here

Rename the previous function of printing monster information to printing equipment information, and modify the function:

Insert image description here

If it is equipment, it definitely does not have the monster name (the offset is wrong). If it is the equipment name, take a look at how the previous code gets the name:

Insert image description here

Insert image description here

The name of the equipment object is also obtained through the "Get Backpack Object Name" interface (the name must be transcoded after being obtained).

Insert image description here

Printing object information does not require coordinates and distance information, so delete it.

Insert image description here

Insert image description here

To obtain the durability, we specially write two functions:

Insert image description here

Insert image description here

Insert image description here

Insert image description here

Insert image description here

Finally, we use the main line to call the traversal equipment function:

Insert image description here

Insert image description here

Let the printed equipment information be formatted and aligned:

Insert image description here

Insert image description here

The test found that the printed count was 0, the durability was incorrect, and the name was empty. It seemed that other objects were passed in and were not filtered. Let’s take a look at a randomly selected object in the picture above:

Insert image description here

Check the code and find that it is because the classification is not judged. Just modify it as shown in the picture above (if(分类1==3) 打印装备信息(对象);), so that if it is an NPC or monster, it will not be printed.

Insert image description here

You can see that in addition to the equipment on the body, the equipment in the backpack is also traversed (if we repair it at the NPC, we may only need to repair the equipment on the body);
If If you only need to iterate over the equipment you are wearing, you will need to analyze this equipment array in the next lesson.

Insert image description here

In addition, apprentice's boots, apprentice's shirt, and light throwing knives do not have durability. They are novice equipment and have no durability. Only equipment purchased or purchased by yourself has durability.

Insert image description here

Insert image description here

Insert image description here

So how do we distinguish the two (body equipment and backpack)?
When we analyzed the backpack before, we knew that the backpack is actually an 8-byte array. Each grid of the backpack array stores the 8-byte GUID of the item; and we learned from the above You can also see in the picture that the equipment on the character information is also a grid. It should most likely be an array, similar to our backpack array. We will analyze this equipment array together in the next lesson.


053-ce,xdbg analyzes equipment array

The principle of equipment analysis is actually the same as that of our backpack analysis. During backpack analysis, we search for related addresses in CE by moving the first grid of the backpack. In fact, if you move an object in any grid, it will Can be used as a breakthrough point;

Insert image description here

Similarly, you can also use the equipment in the character object panel that we open as a backpack. For example, we take the apprentice robe on the equipment as an example and move it into the backpack:

Insert image description here

Insert image description here

At this time, this position is vacant. This position is generally a fixed value, either negative 1 or 0. Generally, the probability of 0 is higher;
Then we move the apprentice robe up. To play the game, we need to write the object address to the chest space, or write the serial number or ID of the object here. After moving it up, it means that there must be something in the corresponding memory location. Write to this corresponding memory, as long as your game does not restart, then if you move something up, it will write the corresponding data to the location of the equipment;
If it is the same as the backpack array here If so, then what is written should be the ID of our equipment:

Insert image description here

Insert image description here

We first remove the apprentice robe, then this grid will be empty. Then, we search for 4 bytes of 0 in CE, and then we put this item on it, then it will be a non-0 value, which can also be said is greater than 0, because the numerical types set here in CE are calculated as unsigned numbers:

Insert image description here

And we didn’t change it at this time, so we can search for the unchanged value (keep clicking to scan again to search many times, and you can move other equipment, but it will have no effect on the chest grid):

Insert image description here

Then remove the apprentice robe again and search for the exact value 0 again. This way, the results will be much less. We can also remove other equipment. The chest position is still 0, but scanning again in this way can filter out a lot of things. , then equip the other removed equipment back, and then scan again, repeating several times.

Then we put the apprentice robe on it and search for values ​​greater than 0. This can be searched repeatedly, and it has not changed. We can search for unchanged values, and when there are relatively few results, we can manually delete the repeated values ​​in the results. Change the red content:

Insert image description here

Then we click on the apprentice robe on the equipment, but we do not actually remove it (we have not moved the apprentice robe into the backpack yet):

Insert image description here

Insert image description here

So we still searched for unchanged values ​​and filtered down to only 36 results. Then we put the apprentice robe back, but there was still no change. We moved it again and moved it to the backpack, and then deleted the unchanged content. Or you can directly search for the exact value 0 to filter out a lot of content, then put on other equipment, search for the exact value 0, or search for the unchanged value; then put the apprentice robe back on, search for values ​​greater than 0, and take off the other items. Equip or move other equipment, and then search for unchanged values, or search for values ​​greater than 0.

Insert image description here

Insert image description here

Insert image description here

We can see that 0x8277 is the ID1 of the apprentice robe, and the address value 29BB7118+4=29BB711C is the address of ID2 of the apprentice robe. From this point of view, these two addresses are the addresses related to this item. They may be in the equipment array. The sex ratio is greater, and other possibilities are unlikely.

We give the address value ID1 the next access breakpoint:

Insert image description here

Insert image description here

We can see that the disassembly code in the above picture is indeed an array access method. Whether it is an array or not, we uninstall the CE debugger and use xdbg to attach the game to take a look. It is more convenient to use xdbg to view the memory. .

Insert image description here

We go to the 7543D3 position in xdbg. We see here that we analyzed the backpack before. It has almost the same structure as the backpack object, except that they are located at different offsets. So what is the specific offset? We go to the memory window. Let’s take a look at the next hardware access breakpoint at 29BB7118:

Insert image description here

Insert image description here

Then move the mouse to the apprentice robe on the chest of the character panel in the game, xdbg breaks:

Insert image description here

We see that the value of eax is 4 and ecx is 29BB70F8, then29BB70F8+4*8+4The 8 in this formula should be the 8 bytes occupied by the item ID1 and ID2, then let’s do it again Take a look at the backpack lesson analyzed earlier:

Insert image description here

We guess that the offset is not 172. It seems that 4 is added here. Let’s see if it is specific in xdbg:

Insert image description here

We see that 29BB70F8 is definitely not a character object, but we don’t know whether [角色对象+8] is equal to 29BB70F8.

Insert image description here

And29BB70F8+4*8+4 the value of this formula is ID2, so the two addresses 7543D3 and 7543D6 are IDs, so we have to look forward to find the source of ecx.

Insert image description here

Insert image description here

We can see that this ecx comes from the upper layer CALL0062E214:

Insert image description here

The two lines selected in the above picture are also key points, we copy and record them.

Insert image description here

At present, its subscript value is 4. Let's replace it and take a look in the memory window. We find that it is indeed ID2, so now we have to take a look at what edi is.

Insert image description here

You can see that the value of edi is the address of an object, but we don’t know whether this object is a player. We copy it and record it. We will find out later when we traverse the character object. If so, then the base address offset of our equipment is Yes.

During testing, if the program or game gets stuck (abnormal), we can just re-enter the game and re-test and verify.

Insert image description here

Let’s take a look at the virtual function table address of the role object in CE:

Insert image description here

Insert image description here

Now we can be sure that this edi is our player's character object. Specifically, let's put this value into the formula in CE to see:

Insert image description here

Insert image description here

Insert image description here

Insert image description here

And we can see from the equipment information that the apprentice robe happens to be in the grid with the subscript 4, and the apprentice shirt is in the grid with the subscript 5.

We go to the formula in the memory window of xdbg2C4D9010+18F0+4. The calculated 2C4DAE78 is the base address of the equipment array. We view it in 8 bytes:

Insert image description here

Insert image description here

We can see that the GUIDs here are not in the order of the grid of equipment information. There may be some in the backpack. Let's first traverse our equipment, directional files, traverse monsters, and then click the console to close the file handle. , check the debugging information, and then compare it with the GUID in the memory above:

Insert image description here

Insert image description here

Comparison shows that the subscripts in the equipment array in the memory are in a different order than the subscripts of the equipment grids we see in the game:

Insert image description here

The order is a bit messy, but the equipment is all in the equipment array in the memory. Let's organize and analyze the rules.

Insert image description here

Insert image description here

Insert image description here

Insert image description here

Insert image description here

It means that it has been our backpack since 8281. We move the hearthstone in the second grid in the backpack to the first grid:

Insert image description here

You can see that 8281 has moved to the first 8-byte memory address, which means that the large section in front of the selected one in the picture above is equipped, and starting from the address where 8281 is located is the backpack.
We put the second-to-last equipment in the backpack, the light throwing knife, into the 2nd slot of the backpack:

Insert image description here

Let's count the 23 spaces in front of 8287 in the first space of the backpack in the memory above. These 23 spaces are for equipment, and after 23 spaces is the backpack.

Insert image description here

From the picture above, we can see that the base addresses of the equipment array and the backpack array are different, but from the memory window above, we can see that the two are next to each other, and in the game we open the character panel and count the equipment. I found that there are only 20 grids in total, and I don’t know what the extra 3 grids are used for.

Since the monster array also contains the backpack array, in the next lesson we only need to use the formula above[角色对象+18F0+4]+下标*8 to traverse the ID1 and ID2 of all equipment (subscript limited 0 to 22), so there will be no backpack items such as hearthstones.


054-Write code to traverse the equipment array

When we analyzed the monster array before, we knew that after taking out the ID, we can obtain the backpack object and the equipment object by calling the 4D4BB0 function. In fact, all objects can be obtained through ID1 and ID2:

Insert image description here

Because each member of the equipment array stores ID1 and ID2, the equipment object is obtained by calling the 4D4BB0 function, and then the information of the equipment is printed out. However, this is not efficient, and when looping This CALL must be called every time, and this CALL must be traversed in a loop, which is not very efficient;
Here we will talk about a more efficient method, which is in the previous section On the basis of the lesson, we operate in reverse:

Insert image description here

Because in the last lesson we traversed all objects, then took out the ID1 and ID2 of all objects, and then used this ID1 and ID2 to traverse and compare with the ID1 and ID2 in the equipment array. If we traverse all the objects and take out the ID, if It is in the first 20 cells, so it means that this is our equipment object. In this way, we can get all the equipment in the equipment information of the character panel without getting the equipment in the backpack. This is how we distinguish the two. is on, so we use the second, better method to solve it. We don’t need to call the CALL 4D4BB0. That means there are two ideas. We use the latter idea to implement it, because we already have the traversal The code of all objects is already there, we only need to change it to achieve it.

Let’s continue the code from the previous lesson and write:

Insert image description here

Because what we traversed before was the entire backpack and equipment, which have been printed out, now we need to block out the part of the equipment in the backpack, and we need to add a judgment to it:

Insert image description here

We only need to determine whether ID1 and ID2 exist in this equipment array. If they belong to our equipment array, then we will print it. If not, it means that it belongs to the backpack array. We distinguish the two, and we write A function will do.

Insert image description here

First we need to get the pointer of the character object, and then calculate the base address of the equipment array through the formula:

Insert image description here

In fact, this equipment array function does not need to pass in object parameters, just pass in ID1 and ID2 directly and compare it with the id1 and id2 we read through the formula here (because ID1 and ID2 are in the previous layer's printing equipment information function. read), if the object is passed in, you have to read and retrieve the ID1 and ID2 of the object.

Insert image description here

Insert image description here

If the printed information is 0, it must be in the backpack, and if it is 1, it is the equipment.

We compile and run and click the traverse equipment button:

Insert image description here

We found that the printout included the contents of the backpack and gear.

Insert image description here

After analysis, we found that it was because we added a 4 less to the base address of the equipment array. As shown in the above picture, it prints correctly after modification:

Insert image description here

Guess you like

Origin blog.csdn.net/zhaopeng01zp/article/details/133101587