I have found that the 64-bit version of Dolphin is different, I'm not sure on how to use it. This tutorial only applies to 32-bit Dolphin.
Okay, a couple of people have wanted to know how to use cheat engine for Dolphin. Download Cheat Engine (
http://cheatengine.org/) and follow the tutorial a bit. It helps to be comfortable with the program.
First, open Dolphin and cheat engine. Press the computer/magnifying glass in the corner and connect it to Dolphin.
In Cheat Engine, click Edit, then Settings. Go to Scan Settings and check MEM_PRIVATE, MEM_IMAGE, and MEM_MAPPED.
The first thing you will want to do is add the Big Endian search types. Right click on the value type and click "Define new custom type(Auto Assembler)".
Paste the following:
alloc(TypeName,256)
alloc(ByteSize,4)
alloc(ConvertRoutine,1024)
alloc(ConvertBackRoutine,1024)
TypeName:
db '2 Byte Big Endian',0
ByteSize:
dd 2
//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 ax,[rcx] //eax now contains the bytes 'input' pointed to
xchg ah,al //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 ax,[eax] //place the bytes into eax so it's handled as a normal 4 byte value
and eax,ffff //cleanup
xchg ah,al //convert to big endian
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:
xchg ch,cl //convert the little endian input into a big endian input
mov [rdx],cx //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
xchg ah,al
mov [ebx],ax //write the value into the address
pop ebx
pop eax
pop ebp
ret 8
[/32-bit]
Press ok, then create another custom search type:
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]
These are used for searching for 2 Byte and 4 Byte float values.
Now here comes the annoying part. Dolphin opens up the game in a random area in the memory, so you'll need to find a pointer for the beginning that memory. The reason that you have to do this is because each version of Dolphin uses a different pointer. The memory always starts with the internal name of the game. To find it, right click on the iso you want to use and click properties.
The internal name of the game is shown at the top.
Now, start the game in Dolphin and search for the game name as a String.
There should be 2 addresses that end with 0000. Usually the first one is correct, so let's use this. Add it to the address list and right click it, and select "Pointer scan for this address".
Wait until the progress bar goes all the way across the screen and until this box opens up.
Press stop and you should get a list like this.
The first value is usually the right one. The correct one to add will have only one offset, and it will be an offset of 0. Double click it, add it to the list, and if you double click on the Address column for it, it'll look something like this.
I keep this pointer simply to make things easier. To save time and processing power, you can set Cheat Engine to start the scans at the value that it points to, so it doesn't scan a bunch of Dolphin's values.
Now, go ahead and find some value, in this example I use health. Copy and paste the pointer value that you found for the start of the memory, and set the offset to the difference between the Health value, and the start of the memory.
The Health address is 0B0C623B.
The Starting address is 0AD30000.
0B0C623B - 0AD30000 = 39623B.
Interesting note: The offset is also equal to the address for an Action Replay code.
Single byte scans can still be used normally. Instead of 2 byte and 4 byte, use the supplied scans. All the values you get MUST use pointers, or else they will be lost whenever Dolphin is reset. The main pointer will work for all games, so you only need to find it once.
Here is a picture of an example scan for speed. Note the settings, and the memory region.
Special thanks to this topic:
http://tasvideos.org/forum/viewtopic.php?t=11885