📜 ⬆️ ⬇️

Cursed Earths - We improve running and experience with teammates


Many have played this wonderful game. An interesting plot, good music, good gameplay. Only there are a couple of things that I don’t like. The run of characters is very limited, just a few seconds, and the reserve of forces is restored for a long time. The experience accrual system does not encourage taking partners, because the experience is distributed equally to everyone, and it is better to run alone to take the whole experience for yourself. Take the debugger and try to fix it.

We need ArtMoney, IDA, Hiew.

There is nothing complicated in the actions, the main result here. Offsets are given for version 1.07.

Run IDA, load the game.exe file, wait for the analysis to complete. Start the starter, remove the setting "Fullscreen mode". We start the game in the debugger, load the save where it is already possible to take a partner. We take the partner, we leave on the map.
')



Run


We look, how much is the reserve of strength of the character. Here it is 54. Launch ArtMoney. We are looking for this value. Type "With a point of 4 bytes." Run a little and weed out the new value. We repeat as necessary, I immediately have one value left.



We try to freeze, if the reserve of forces is restored when running, it means that you have found it correctly. Only need to be removed later. Turn on the run mode. Put the game on pause (space).

We put a breakpoint on this address to write to IDA. Before this, you must do the 'Pause process', otherwise crashes occur. Switch to the game, send the character to some point, remove from pause.

Breakpoint works.

.text:00548315 loc_548315: .text:00548315 fld dword ptr [edi+14h] .text:00548318 fld dword ptr [edi+18h] .text:0054831B fmul ds:dbl_73F088 .text:00548321 fsubp st(1), st .text:00548323 fst dword ptr [edi+14h] .text:00548326 > fcomp ds:flt_73B858 .text:0054832C fnstsw ax .text:0054832E test ah, 1 .text:00548331 jz short loc_548388 

The recording takes place in the fst dword ptr [edi+14h] . You can put Operand type - Floating point to this address and to the next [edi+18h] .



Judging by the values, it is stored there:

[edi+14h] - current value
[edi+18h] - maximum value

It can be seen that the maximum power of the character is multiplied by the constant dbl_73F088 , and the result is subtracted from the current value. Therefore, all the characters run the same way.

 .rdata:0073F088 dbl_73F088 dq 6.666666666666666e-3 ; 6.666666666666666e-3 = 0.006666666666666666 = 1/150 

That is, a character can run about 150 "steps", but these are not exactly steps that can be seen in the animation, because the subtraction occurs more often. A full supply of forces is spent in 9-10 seconds, so subtraction is called 15 - 16.66 times per second.

Most likely these are green dots indicating the path.




In bytes, this constant is written as:

 4E 1B E8 B4 81 4E 7B 3F 

Open game.exe in Hiew and go to the address ".73F088".



There are no other constants with such a value, the link to it is only in the considered code. You can change it to any value that you need. I made myself 3 times less.
(1/150) / 3 = 1/450 = 0.0022222222222222222

To convert float / double to hex representation, you can use an online converter, for example this .

for reference
 0.0066666666666666667 - 0x3F7B4E81B4E81B4F 0.006666666666666666 - 0x3F7B4E81B4E81B4E 0.0022222222222222222 - 0x3F623456789ABCDF 0.002222222222222222 - 0x3F623456789ABCDE 


It turns out a beautiful number 0x3F623456789ABCDF

 DF BC 9A 78 56 34 62 3F 

Replace, save, run. Now, so much better.

Experience


It's a little more complicated here. It is not stored explicitly. It is necessary to search through the associated values. We start, however, the same way.

We look at how much experience a character has. This can be done in the mode between the cards. I have this 116.




We are looking for this value. Here you need the type "Integer 4 bytes".

This is not a source variable, but a calculated value cast to an int. The experience itself is stored in the float, but there is a different meaning, more on that below.

Now you can fight with someone. You cannot leave the map to view the experience, you can not reboot either, because the memory is re-allocated, and when you re-enter the map there will be other addresses. It is necessary to add in the mind. At the same time it is necessary to consider rounding. That is, if 5 points of experience are given for the enemy, and 2 characters are in the team, then experience 2 will be displayed on the screen, but you need to add 2.5 and take the whole part.




After a couple of repetitions, I have 6 values ​​left, which change synchronously.



Let's try to put a breakpoint on the record at each address. Do not forget about the "Pause process".

The first address is appropriate. The rest are triggered by rep movsd .

 .text:00522D00 fld dword ptr [ebx+700h] .text:00522D06 fadd dword ptr [ebx+4] .text:00522D09 fsub dword ptr [ebx+8] .text:00522D0C fstp [ebp+var_10] .text:00522D0F fld [ebp+var_10] .text:00522D12 fistp [ebp+var_C] .text:00522D15 mov edx, [ebp+var_C] .text:00522D18 mov [edi+8], edx .text:00522D1B > mov eax, [ebx+10h] .text:00522D1E mov [ebp+var_10], eax 

It is triggered when running or when fighting any of the characters. Therefore, it is better to manage only one thing here and not a group so as not to be confused. In ebx is the address of the object character. In [ebx+700h] is 0.

Let's look at the values.



387 - 271 = 116

It can be assumed that this is a received and spent experience, and the current one is calculated as their difference.

My game dropped several times, so I put a breakpoint on the code and loaded it from save. Therefore, there are 116, not 120. But this only confirms the guess.

Put a new breakpoint on [ebx+4] .

We select the whole group and attack the enemy.




Breakpoint works before it is visible on the screen.

 .text:005239D7 fld ds:dbl_73E128 .text:005239DD fld dword ptr [esi+20h] .text:005239E0 fsub ds:flt_73E124 .text:005239E6 call __CIpow .text:005239EB fmul [ebp+arg_4] .text:005239EE fadd dword ptr [esi+700h] .text:005239F4 fcom ds:flt_73B858 .text:005239FA fst dword ptr [esi+700h] .text:00523A00 fnstsw ax .text:00523A02 test ah, 41h .text:00523A05 jnz short loc_523A19 .text:00523A07 fadd dword ptr [esi+4] .text:00523A0A mov dword ptr [esi+700h], 0 .text:00523A14 fstp dword ptr [esi+4] .text:00523A17 > jmp short loc_523A1B 

In [esi+4] new meaning of experience. In [ebp+arg_4] number is 2.0. For a young wild boar, 4.0 is given, so the division is before the function is called.

Exit the function with Ctrl + F7. This is a wrapper, exit again.

We look a little higher, there is such a code.

 .text:00591521 loc_591521: .text:00591521 fild [ebp+var_18] .text:00591524 xor esi, esi .text:00591526 cmp eax, edi .text:00591528 mov [ebp+var_14], esi .text:0059152B fdivr [ebp+arg_4] .text:0059152E fstp [ebp+arg_4] .text:00591531 jle short loc_5915A5 .text:00591533 jmp short loc_591537 

We set a breakpoint at 00591521 and take part in the battle again.

fdivr divides the argument by st(0) and writes the result to st(0) : st(0) = arg / st(0) . In st(0) is the value of [ebp+var_18] , in which there are 2 - the number of characters. In [ebp+arg_4] is 4.0 - experience for the enemy. When performing a mission, accrual also occurs here.

Also, the division by the number of participants is higher:

 .text:00591324 fdiv [ebp+var_18] 

But I did not find when this code is executed. There will not touch.

Now through Hiew, you can remove the code for division. Due to the fdivr replace all 3 commands with nop (9 bytes).

 ;  .00591521: DB45E8 fild d,[ebp][-018] .00591524: 33F6 xor esi,esi .00591526: 3BC7 cmp eax,edi .00591528: 8975EC mov [ebp][-014],esi .0059152B: D87D0C fdivr d,[ebp][00C] .0059152E: D95D0C fstp d,[ebp][00C] .00591531: 7E72 jle .0005915A5 .00591533: EB02 jmps .000591537 ;  .00591521: 909090 nop .00591524: 33F6 xor esi,esi .00591526: 3BC7 cmp eax,edi .00591528: 8975EC mov [ebp][-014],esi .0059152B: 909090 nop .0059152E: 909090 nop .00591531: 7E72 jle .0005915A5 .00591533: EB02 jmps .000591537 

Now the characters and run normally, and the supply of forces is not infinite, the spells are spent as usual, the mechanics of the game saved. And partners get their independent experience that can be spent on their development.

Go!

Source: https://habr.com/ru/post/335498/


All Articles