External application to monitor gamestates

Strictly for discussing ZSNES development and for submitting code. You can also join us on IRC at irc.libera.chat in #zsnes.
Please, no requests here.

Moderator: ZSNES Mods

Post Reply
Code Monkey
New Member
Posts: 5
Joined: Sun Nov 07, 2004 6:50 am

External application to monitor gamestates

Post by Code Monkey »

I saw what the Z-Net author did -- he made a dll that used a bunch of api calls to open the zsnes process and I guess watch some arbitrary memory location. This lets him get game stats in Mario Kart and provide a sort of live commentary on IRC.

Is there some magic trick to this? How would you go about finding the memory offsets for the various chunks of snes memory, like the registers, stack, and whatnot. It would be pretty neat if i could find a reasonable method to determine wins/losses in a few games. Then one of the online zsnes netplay matchmaking services could keep track of wins/losses for stuff like ladder matches. Obviously not foolproof against hacking, but seems like an interesting prospect nonetheless.
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

Using ZSNES' memory searcher/cheat creator you would find which locations for the game under question contained the info you were looking for. Then you'd see how the SNES memory is located in ZSNES so you can pinpoint it.
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
byuu

Post by byuu »

Not sure if you are referring to getting the actual SNES WRAM offset for a particular game, or the zsnes executable offset to the SNES WRAM. But since Nach already answered the former, I'll explain the latter process a bit.

Attach a debugger to zsnes. Something like visual studio would do. You can get the pointer from there with some trickery (scroll through the memory of zsnes and look for the SNES ram data, then search for a pointer to the top of the ram data. You may need to go up another pointer after that, repeat until you have a pointer >= 0x400000, as the rest are just pointers into allocated memory). Or if you prefer, you could compile zsnes yourself, and the obj files generated should give you the virtual address to where zsnes maps its snes wram to. I don't have any info on obj file formats, so I can't help you there. Since win32 apps are mapped to virtual memory, the offset will always be the same (again, only the top pointer. All the malloc'ed data will be random places in memory), but your offset will very likely be limited to one version of ZSNES. Once you have the offset, you can get the memory using ReadProcessMemory.
You will need to attach your own 'debugger' to zsnes, however. You don't actually have to add any real debugging stuff though. Or you could try using
DebugActiveProcess to get access to the processes memory, but I've never tried that before.
There's probably a way to read the memory from processes without
attaching a debugger, which is probably the best way to go about it, but I don't know it offhand.

It would honestly be easier to just compile zsnes yourself, and add a dll directly in to zsnes, that exports the SNES wram pointer for you. Set up a timer, and then you can just grab the memory at various intervals.
Code Monkey
New Member
Posts: 5
Joined: Sun Nov 07, 2004 6:50 am

Post by Code Monkey »

Good info guys, Thanks!

I'm wondering how effective watching the object files would be. I have to imagine the offsets would change on a compiler to compiler basis. What was the official 1.36 build built with anyway? My best bet is probably going to be a custom zsnes build or rev-eng the mem addr with a debugger...
adventure_of_link
Locksmith of Hyrule
Posts: 3634
Joined: Sun Aug 08, 2004 7:49 am
Location: 255.255.255.255
Contact:

Post by adventure_of_link »

If you're talking about the programming language used to make ZSnes, they used x86 assembly code for a majority (or maybe all?) of it.
<Nach> so why don't the two of you get your own room and leave us alone with this stupidity of yours?
NSRT here.
Code Monkey
New Member
Posts: 5
Joined: Sun Nov 07, 2004 6:50 am

Post by Code Monkey »

Parts of it are in C, other parts in ASM. On unix they I assume they use the usual stuff to compile it, nasm and gcc. But If the memory mapping of variables in the obj files are going to depend on the version of compiler used, I'd have to know what they used to build it on windows, as in what versions of nasm/gcc.

Then again, maybe i'm wrong and it doesn't matter from version to version...
byuu

Post by byuu »

The obj data most definately would change. nasm may not, since it's all hardcoded assembly, I doubt the obj files would differ much. But gcc, yeah. Forget it.
I don't even know how well that would work. The only time I've ever hooked the memory from another app was when I attached a debugger and manually disabled IsDebuggerPresent and patched some font stuff.
If you're going to make your own build, you really should just build in a small routine into the emulator so that you can access the memory directly. If you really don't want to bundle whatever application you're making inside ZSNES, then add an option to export memory from the MessageLoop, and just have your app use SendMessage on zsnes to get updated memory info.
Code Monkey
New Member
Posts: 5
Joined: Sun Nov 07, 2004 6:50 am

Post by Code Monkey »

For this trick, i'd recompile zsnes to recieve a new custom message.

From what I understand (which isn't much, so correct me if i'm wrong), is that if I SendMessage between applications, the only return value the sending application can recieve from the recieving application is the return value (LRESULT) of the wndproc. I assume that memory addresses are going to be relative to the context of a specific proccess, so i can't just return a malloc()'d pointer full of wram data from zsnes to the other application.

So, I figure I can get a custom message to return either the memory address of wram, or the memory address of the pointer to wram (i assume that wramdata and wramdataa are the relevant symbols here, i have yet to narrow down exactly which is what). Using this relative memory address, I can open the process with the relevant api call, and read the wram memory from the addresses I recieved from the sendmessage call. Does this make sense? Do you think I'm going about it all wrong?
funkyass
"God"
Posts: 1128
Joined: Tue Jul 27, 2004 11:24 pm

Post by funkyass »

I dunno, you could just say, have zsnes dump the requested data to a file, or a piece of shared page.

or, use IP and work it that way.

Local Procedure call might be worth looking at.
illegal eagle
Savestate Pimp
Posts: 129
Joined: Thu Jul 29, 2004 2:15 pm
Contact:

Post by illegal eagle »

funkyass wrote:a piece of shared page
http://msdn.microsoft.com/library/defau ... memory.asp

I've been thinking about using this for communicating between programs... but it's designed for exchanging data, not for exchanging messages... so a sub-standard would have to be developed.
"Other people can give you more suggestions as I just lost all my motivation to respond further to this post."
[i] - Nightcrawler[/i]

[url=http://www.geocities.com/illegal_eagle_2003/]vSNES v2.00[/url]: My SNES savestate viewer.
Code Monkey
New Member
Posts: 5
Joined: Sun Nov 07, 2004 6:50 am

Post by Code Monkey »

Good information. I'm wondering if it's going to be too big of a performance hit to copy all of wram into the shared page, but i'll try some stuff and see how it goes..
Nightcrawler
Romhacking God
Posts: 922
Joined: Wed Jul 28, 2004 11:27 pm
Contact:

Post by Nightcrawler »

Anytime I want to communicate between programs, I use windows messages. I wouldn't think it would be very hard to add a few new messages that ZSNES handles. Of course, this would only work on the win32 port. I think this is the simplest way though.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
Post Reply