Code replacing and injecting. Example of "Europa Universalis IV"


Find address of money in game "Europa Universalis IV" (Search for exact value, integer 4 bytes, multiply by 1000). Addresses change every time after the restart of the game. The game has not valid pointer. Click rigth mouse button on this address and select in menu "Find an instruction that's accessing the address". Set "Read/Write" access and press "Start" button. Play the game and return to ArtMoney:



We have found instructions that's reading your money from memory. Most frequent instruction is mov ecx,[r15+00000820] (3310 times). Important thing is r15 register contains an address to player structure. Each player has structure. Player ID stored in the same structure [r15+00000024]. You don't need check Player ID for singleplayer game. You have to know you Player ID for multiplayer game!

Start the multiplayer game. We have found our Player ID - 01000027h from [r15+00000024], if you know your money from [r15+00000820]. Search for exact value 01000027h, integer 4 bytes, and on each address do "Find an instruction that's accessing the address". We have found one instruction (13FBCA820 cmp byte ptr [rcx+00001E46],06) for one address. You player ID you can read from [rcx+00001E44].

We can read our Player ID [rcx+00001E44] from first address 13FBCA820. And we can read the address to player structure (r15 register) from second address 1400CB525. The structure contains all parameters for our player!

At First, declare variables PlayerID and PlayerStr on "Code injecting" page. PlayerStr is the address to player structure (8 bytes for 64-bit processes). Set "Inject the code" and "Only after successed code replacing".



Add first address 13FBCA820 to the table, set "Assembly instruction" type and "Replace the code" option. Input replaced code to get our PlayerID. Insert pop/push for used registers. Add original instruction to the end of the code.



Add second address 1400CB525 to the table, set "Assembly instruction" type and "Replace the code" option. Input replaced code to get our PlayerStr. Don't forget to add original instruction to the end of the code!



Add new address to the table, set "Address of variable" address type. Input PlayerID as variable name, address 0 (it added to variable address if need).



Add new address to the table, set "Address of variable" address type. Input PlayerStr as variable name, address 0. Set "Pointer" address type and input offset 820h (because it is pointer to player structure). Add another player parameters: Stability (offset 848), Prestige (offset 968), Manpower (offset A08), Legitimacy (offset CC8) and etc.



Our code is ready. You can activate it by "Replace all codes and inject" button or automatically. You have to switch to game after code injecting activation and all addresses will become valid. Our addresses can change after game update. Use signatures to prevent it. Create 2 signatures SigResource and SigPlayerID.



Try to use signature length 20-30 bytes. Replace JMP instruction with ??, because JMP instruction depends on addresses. For example, replace je and jne with ?? for SigPlayerID.



Open 13FBCA820, 1400CB525 addresses and set "Address of signature" address type. Now your artmoney table will work after game update! You can inject your assembler code in a process and start own thread from any line ( use directive {thread} ).
Back    Contents    Forward

Copyright (C) 1996-2020, System SoftLab
Last update of this page: July 19, 2020.