Post subject: RAM/Memory watch
Joined: 9/29/2011
Posts: 10
Is there any method to watch the RAM of a game other than the supplied Cheat Search in Dolphin? (r7718) I'd prefer something that updated dynamically with the game and can track multiple addresses at the same time (unless I'm missing something, and Dolphin can already do this). Right now I have to rely on searching for the address with the cheat search, then change the comparison to unknown and hit "next scan" to get the addresses to update. the only thing I can do to them after they are found is to create an AR code, which doesn't show what the address currently is, instead it shows what you chose to let the code set the address to if you activate it.
Active player (434)
Joined: 4/21/2004
Posts: 3517
Location: Stockholm, Sweden
Unfortunately, I don't think so man. What you are requesting is something pretty important to have and I suggest you create an issue for it at dolphin (at their webpage) so they are fully aware of this.
Nitrogenesis wrote:
Guys I come from the DidyKnogRacist communite, and you are all wrong, tihs is the run of the mileniun and everyone who says otherwise dosnt know any bater! I found this run vary ease to masturbate too!!!! Don't fuck with me, I know this game so that mean I'm always right!StupedfackincommunityTASVideoz!!!!!!
Arc wrote:
I enjoyed this movie in which hands firmly gripping a shaft lead to balls deep in multiple holes.
natt wrote:
I don't want to get involved in this discussion, but as a point of fact C# is literally the first goddamn thing on that fucking page you linked did you even fucking read it
Cooljay wrote:
Mayor Haggar and Cody are such nice people for the community. Metro City's hospitals reached an all time new record of incoming patients due to their great efforts :P
Skilled player (1720)
Joined: 9/17/2009
Posts: 4956
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
Try Cheat Engine. It worked for hourglass, so I think it may work on Dolphin.
Former player
Joined: 5/4/2005
Posts: 502
Location: Onett, Eagleland
Cheat engine works, only problem is values inside of Dolphin are big endian. So looking at a 2/4/8/float/double value can be troublesome unless you write a custom scan script for Cheat Engine. 2 Byte Big Endian Custom Scan:

//2-Byte big endian scan

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
mov ax,word [rcx] //eax now contains the bytes 'input' pointed to
xchg ah,al

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 ax so it's handled as a normal 2 byte value
xchg ah,al

shl eax,16
shr eax,16

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:
push rcx
//bswap ecx
xchg ch,cl
mov [rdx],ecx //place the integer the 4 bytes pointed to by rdx
pop rcx

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

//bswap eax
mov dword [ebx],0

xchg ah,al
mov [ebx],ax //write the value into the address

pop ebx
pop eax

pop ebp
ret 8
[/32-bit]

4 Byte Big Endian Custom Scan:
//4 Byte Big Endian Scan
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
mov eax,[rcx] //eax now contains the bytes 'input' pointed to
bswap eax

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:
push rcx
bswap ecx
mov [rdx],ecx //place the integer the 4 bytes pointed to by rdx
pop rcx

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

bswap eax
mov [ebx],eax //write the value into the address

pop ebx
pop eax

pop ebp
ret 8
[/32-bit]
I think.....therefore I am not Barry Burton
darkszero
He/Him
Joined: 7/12/2009
Posts: 181
Location: São Paulo, Brazil
Wait, the search script is written in assembly? What kind of program uses assembly as a scripting language o.O
Former player
Joined: 5/4/2005
Posts: 502
Location: Onett, Eagleland
A very powerful one.
I think.....therefore I am not Barry Burton
Joined: 10/20/2006
Posts: 1248
More on how to find stuff in Dolphin with Cheat Engine. Sorry for not having used 0x00 notation to properly indicate hex values. It took me quite a while to find out how to add custom value types to it, the secret is that you have to right click the type selection combo box. The first thing you should be searching for is the game ID of the game you are playing, which you can find by right clicking a game -> properties -> info (then do a text search). You should find about two addresses that end in 0000. The first one is usually the start address of the region of the game's RAM that you are interested in. Then you look for the pointer to this address, either by right clicking the found address, once you've drag- and dropped it down to your watch list, and selecting pointer scan, or by searching for it as a 4byte hexadecimal value. You are looking for an address that will remain constant within a certain build, no matter how often you are restarting it. If you've done a pointer search you should have found something like Dolphin.exe+435C4EC (this the result I got for the 3.0 516 x86 TAS version build), if you've done the hexadecimal value search, you should have gotten an address that if you add it to the RAM watchlist below and doubleclick it will give you the same result. Great. Now whenever you are looking for some real addresses you want them to be in the range > of the address that Dolphin.exe+435C4EC points to (let's say it's 0b130000, then you are looking for 0b-something results). Let's say you find an interesting value at 0b4f45f6, then you now need to subtract 0b130000 from it to get an offset of 3c45f6. You now want to add a new address manually, check pointer, fill in Dolphin.exe+435C4EC as the pointer and 3c45f6 as the offset. Now you won't have to look for that value again everytime you resteart anymore. Success! Another complication is that you won't be able to scan for Big Endian Float or Double in the newest official release, but you can join the beta testing group of the 6.2 version of Cheat Engine [URL=http://forum.cheatengine.org/groupcp.php]here[/URL] or just get it from [URL=http://cheatengine.org/temp/CheatEngine62Beta6.rar]here[/URL] (the link might be dead by the time you are reading this). This is the code that you should paste in to enable Big Endian Float and Double support, as provided to me by mgr.inz.Player: Big Endian Float - full AA script
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]
Big Endian Double - full AA script "(it's not perfect conversion)"
alloc(TypeName,256)
alloc(ByteSize,4)
alloc(ConvertRoutine,1024)
alloc(ConvertBackRoutine,1024)
alloc(UsesFloat,4)
alloc(PreferedAlignment,4)
alloc(TEMPVAL,8)

TypeName:
db 'Double Big Endian',0
ByteSize:
dd 08
UsesFloat:
dd 01
PreferedAlignment:
dd 04
TEMPVAL:
dq 00

ConvertRoutine:
[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]
bswap eax
mov [TEMPVAL+4],eax

mov eax,[ebp+8] //place the address that contains the bytes into eax
mov eax,[eax+4]
bswap eax
mov [TEMPVAL],eax

finit
fld qword ptr [TEMPVAL]
fstp dword ptr [TEMPVAL]
mov eax,[TEMPVAL]

pop ebp
ret 4
[/32-bit]

[64-bit]
//rcx=address of input
mov rcx,[rcx] //eax now contains the bytes 'input' pointed to
bswap rcx
mov [TEMPVAL],rcx

finit
fld qword ptr [TEMPVAL]
fstp dword ptr [TEMPVAL]
mov eax,[TEMPVAL]

ret
[/64-bit]

ConvertBackRoutine:
[32-bit]
push ebp
mov ebp,esp
//[ebp+8]=input
//[ebp+c]=address of output
//example:
push eax
push ebx
mov ebx,[ebp+c] //load the address into ebx

finit
fld dword ptr [ebp+8]
fstp qword ptr [TEMPVAL]

mov eax,[TEMPVAL+4]
bswap eax
mov [ebx],eax //write the value into the address

mov eax,[TEMPVAL]
bswap eax
mov [ebx+4],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
mov [TEMPVAL],ecx

finit
fld dword ptr [TEMPVAL]
fstp qword ptr [TEMPVAL]

mov rax,[TEMPVAL]
bswap rax

mov [rdx],rax //place the integer the 4 bytes pointed to by rdx
ret
[/64-bit] 
Another neat trick is that you can look at AR codes inside Dolphin, which will usually contain very useful addresses as their leftside expressions. F.e. 023c4c09 00000150 continuously writes 0x150 to the offset 3c4c09. Try searching for one AR code yourself and Dolphin will load a list of readymade codes for the game for you. Thanks for your attention.
Active player (334)
Joined: 1/19/2010
Posts: 383
Location: Texas
I am trying to use MHS to look at the memory in Dolphin. I can easily find certain addresses, but each time Dolphin is started the address for a specific thing changes. I looked at an ammo value to be at 0BA3B6D7. I restarted Dolphin and it became 0B7DB6D7. Does this have to do with what you were talking about Kuwaga where I need to subtract the offset of where the gameID is? I found it to be at 0B670000 for Biohazard4.
RachelB
She/Her
Player (128)
Joined: 12/3/2011
Posts: 1579
You need to find a static pointer. To do that, search for the game ID, and take the first result that ends with 0000 (so in your case 0B670000 was probably what you wanted). Then take that address and search for it as a 4 byte value. That will give you your pointer. Then when adding addresses use that pointer, and then an offset relative to the where the game id is. So using your addresses, with ammo at 0B7DB6D7, and game id at 0B670000, your offset would be 16B6D7 (0B7DB6D7-0B670000).
Active player (425)
Joined: 9/21/2009
Posts: 1047
Location: California
SoulCal wrote:
I am trying to use MHS to look at the memory in Dolphin. I can easily find certain addresses, but each time Dolphin is started the address for a specific thing changes.
How are you even doing that? Whenever I try to search for anything in Dolphin with MHS it just crashes...
Active player (334)
Joined: 1/19/2010
Posts: 383
Location: Texas
sonicpacker wrote:
SoulCal wrote:
I am trying to use MHS to look at the memory in Dolphin. I can easily find certain addresses, but each time Dolphin is started the address for a specific thing changes.
How are you even doing that? Whenever I try to search for anything in Dolphin with MHS it just crashes...
I notice that it will crash if you boot MHS before starting Dolphin. Start Dolphin and load the game, then start MHS.
Player (33)
Joined: 3/8/2012
Posts: 398
Location: Windfall Island
Using MHS isn't really worth it. I doubt you can use it for a full TAS. The main thing is the lack of Float Big Endian. I've been using Cheat Engine and after adding Float Big Endian, 2 Byte Big Endian, and using pointers and all that crap, it automatically syncs when I connect it to Dolphin. Big thanks to Kuwaga for the help. I'd just suggest that anyone uses Cheat Engine 6.2. Good luck to anyone. Also, one other thing I noticed is that the offset for use with pointers is equal to the AR code. That's helpful for converting between the two.
IronSlayer wrote:
Your counterargument would be like me saying that the Earth is round and then you telling me that I need to show it's flat so I can "prove us all wrong".
Seems legit.
ALAKTORN
He/Him
Player (105)
Joined: 10/19/2009
Posts: 2527
Location: Italy
Kuwaga wrote:
The first thing you should be searching for is the game ID of the game you are playing, which you can find by right clicking a game -> properties -> info (then do a text search).
What does this even mean? Where do I right click? Dolphin’s window is not showing the game for me, even when I browse for the folder with the game in it. My game file is called ck-psoe12.gcm which I have no idea what .gcm even is. I’m on Dolphin 4.0 x32. Help? Edit: I think I’ve found it on GameFAQs. “GPOE”. Edit: Someone should sticky this topic. It looks useful.
JosJuice
She/They
Editor, Emulator Coder
Joined: 7/3/2010
Posts: 193
Location: Sweden
ALAKTORN wrote:
What does this even mean? Where do I right click? Dolphin’s window is not showing the game for me, even when I browse for the folder with the game in it.
Go to Config > Paths and add the folder that contains the game. The game should then show up in Dolphin's main window, ready to be right-clicked. If it doesn't show up, make sure that everything is checked in Show Platforms and Show Regions in the View menu.
ALAKTORN wrote:
My game file is called ck-psoe12.gcm which I have no idea what .gcm even is.
It's the same thing as ISO, just with a different extension.
ALAKTORN
He/Him
Player (105)
Joined: 10/19/2009
Posts: 2527
Location: Italy
Thanks, but it still doesn’t show up. Doesn’t matter though, I grabbed the ID off of GameFAQs.
ALAKTORN
He/Him
Player (105)
Joined: 10/19/2009
Posts: 2527
Location: Italy
Pasky13 wrote:
Cheat engine works, only problem is values inside of Dolphin are big endian. So looking at a 2/4/8/float/double value can be troublesome unless you write a custom scan script for Cheat Engine. 2 Byte Big Endian Custom Scan:
—cropped—
Been using this and it’s been great. Today though, for the first time Cheat Engine is reading a value incorrectly… it is 2 bytes big endian (0x0514 = 1300) but it shows as 276. This is a boss’s HP. After I drop it below “0”, it goes to ≈ 1023 then keeps dropping to 0, death. What’s going on here? http://i.imgur.com/EUmF9TY.jpg Edit: It seems like it’s reading the value with a modulo 1024… so 1024 = 0 and 1025 = 1 for whatever reason… Edit2: I used the custom type from a different topic and that one works.