I recommend getting the latest version of Cheat Engine from https://www.cheatengine.org
Open Cheat Engine and then open RPCS3 & launch the game you want to memory edit.
In Cheat Engine, click on Edit and then Settings.
Navigate to “Scan Settings” and toggle “MEM_MAPPED”, it will allow Cheat Engine to scan the emulator’s memory.
Select RPCS3.exe in Cheat Engine
Right click on Value Type’s dropbox and click on “Define new custom type (Auto Assembler)
Since the endianness in RPCS3 is Big-Endian and Cheat Engine can only scan for Little-Endian values we will have to add a custom 4 bytes value type that is Big-Endian. I took the liberty of searching on Google for Big-Endian type codes for Cheat Engine.
4 Bytes Big Endian:
alloc(TypeName,256)
alloc(ByteSize,4)
alloc(ConvertRoutine,1024)
alloc(ConvertBackRoutine,1024)
TypeName:
db '4 Byte Big Endian',0
ByteSize:
dd 4
//The convert routine should hold a routine that converts the data to an integer (in eax)
//function declared as: stdcall int ConvertRoutine(unsigned char *input);
//Note: Keep in mind that this routine can be called by multiple threads at the same time.
ConvertRoutine:
//jmp dllname.functionname
[64-bit]
//or manual:
//parameters: (64-bit)
//rcx=address of input
xor eax,eax
mov eax,[rcx] //eax now contains the bytes 'input' pointed to
bswap eax //convert to big endian
ret
[/64-bit]
[32-bit]
//jmp dllname.functionname
//or manual:
//parameters: (32-bit)
push ebp
mov ebp,esp
//[ebp+8]=input
//example:
mov eax,[ebp+8] //place the address that contains the bytes into eax
mov eax,[eax] //place the bytes into eax so it's handled as a normal 4 byte value
bswap eax
pop ebp
ret 4
[/32-bit]
//The convert back routine should hold a routine that converts the given integer back to a row of bytes (e.g when the user wats to write a new value)
//function declared as: stdcall void ConvertBackRoutine(int i, unsigned char *output);
ConvertBackRoutine:
//jmp dllname.functionname
//or manual:
[64-bit]
//parameters: (64-bit)
//ecx=input
//rdx=address of output
//example:
bswap ecx //convert the little endian input into a big endian input
mov [rdx],ecx //place the integer the 4 bytes pointed to by rdx
ret
[/64-bit]
[32-bit]
//parameters: (32-bit)
push ebp
mov ebp,esp
//[ebp+8]=input
//[ebp+c]=address of output
//example:
push eax
push ebx
mov eax,[ebp+8] //load the value into eax
mov ebx,[ebp+c] //load the address into ebx
//convert the value to big endian
bswap eax
mov [ebx],eax //write the value into the address
pop ebx
pop eax
pop ebp
ret 8
[/32-bit]
Float Big Endian:
alloc(TypeName,256)
alloc(ByteSize,4)
alloc(ConvertRoutine,1024)
alloc(ConvertBackRoutine,1024)
alloc(UsesFloat,4)
TypeName:
db 'Float Big Endian',0
ByteSize:
dd 4
UsesFloat:
db 01
ConvertRoutine:
[32-bit]
push ebp
mov ebp,esp
mov eax,[ebp+8] //place the address that contains the bytes into eax
mov eax,[eax] //place the bytes into eax
bswap eax
pop ebp
ret 4
[/32-bit]
[64-bit]
//rcx=address of input
mov eax,[rcx] //eax now contains the bytes 'input' pointed to
bswap eax
ret
[/64-bit]
ConvertBackRoutine:
[32-bit]
push ebp
mov ebp,esp
//[ebp+8]=input
//[ebp+c]=address of output
push eax
push ebx
mov eax,[ebp+8] //load the value into eax
mov ebx,[ebp+c] //load the address into ebx
bswap eax
mov [ebx],eax //write the value into the address
pop ebx
pop eax
pop ebp
ret 8
[/32-bit]
[64-bit]
//ecx=input
//rdx=address of output
bswap ecx
mov [rdx],ecx //place the integer the 4 bytes pointed to by rdx
ret
[/64-bit]
Paste the 4 Bytes Big Endian code into the Auto-Assemble window and click ‘OK’ and repeat the same process with Float Big Endian.
Let’s go to our game and change the money value.
Our money value is 765,000,000, we will select the Value Type to ‘4 Byte Big Endian’ and search for 765000000
I bought something so I can get the correct addresses
We are left with 2 addresses, let’s change them both to 995,000,000
And would you look at that
Now that you are equipped with this knowledge, go and have fun.