4

First off, I'm new to more "Low level" things like this using Python, so please excuse me if this is a noob question.

I had an idea for something like an "Achievement" system similar to Xbox and Playstation, where you could possibly track certain things in a Gameboy emulator using Python by reading memory addresses.

I decided that I should try this with Pokemon. (Leaf Green to start out)

My first idea was to make a couple achievements like so:

Fire! - Chose Charmander as your starter
Water! - Chose Squirtle as your starter
Grass! - Chose Bulbasaur as your starter

So after Googling a little for some memory addresses I ended up HERE.

It says in the article that in Leaf Green, a Trainer's Party Data starts at 0x02024284 and each Pokemon's individual data is 100 bytes. Right.

So I go into VisualBoyAdvance (My emulator) and click

Tools -> Memory Viewer

Now I type in 02024284 in the search box and it takes me to the data.

The article says that from that line, with an offset of 8 bits over, the next 10 bytes are the pokemon's nickname.

If I read this from my emulator (in 8 bit mode) I read the next 10 sets of 8 bits, and I get:

C3 D0 D3 CD BB CF CC FF 00 00

Which should be Ivysaur (I am assuming this is in hexidecimal, so I googled a hex to string converter and typed this in, but it brought back a bunch of gibberish (below) )

ÃÐÓÍ»ÏÌÿ��

Now, my two questions.

  1. How would I go about pulling these memory addresses from VBA to Python? (I'm using Python 2.7 on Windows 7)

  2. How would I decode/decrypt the string returned into a "Human readable format"? - Thanks to @blubberdiblub for clearing this part up

I couldn't find much info to guide me on this, regarding VBA and Python working together, and was hoping that someone could help shed some light on this for me. I would like to get into memory addresses (For reasons like this) and I think this would be a cool little project to start out with.

Jebby
  • 1,845
  • 1
  • 12
  • 25
  • Subtract 0x7a (decimal 122) from the values and you should have the ASCII codes you're looking for. Example: `chr(0xc3 - 0x7a)` -> `'I'` – blubberdiblub Apr 30 '17 at 05:31
  • Awesome, that part works like a charm. Passed the string of values in to it as a list, and it spelled out "IVYSAUR". Thanks for the quick reply on that part, it will DEFINITELY save a lot of time searching. May I ask, why exactly you subtract 0x7a? – Jebby Apr 30 '17 at 05:40
  • Also, any idea on how to automatically pull that string from VisualBoyAdvance using Python? – Jebby Apr 30 '17 at 05:42
  • Well, I don't **know** the reason, I just found it by taking the values you had plus (well, minus, really) the string you expected there. But my educated guess is that they're not actually using ASCII in that game. It hails from a Japanese context, so it's not unlikely they made up their own encoding that has lots of Japanese characters (Hiragana, Katakana, and a couple of common Kanji) at the lower values and then the western characters after that. So the value of 0x7a might be just the result of how many Japanese characters are at the lower values. – blubberdiblub Apr 30 '17 at 05:46
  • So if I catch say, a Pidgey and move 100 bytes ahead, to read my second Pokemon, I would assume I still subtract 0x7a from the values? – Jebby Apr 30 '17 at 05:49
  • That I don't know, but I'd consider it likely, yes. I don't think it uses up as much as 100 bytes per team member, tho ;) They can carry only 1 item and have at most 4 attacks at all times, right? Plus a couple of hidden stats. – blubberdiblub Apr 30 '17 at 05:52
  • I caught a Rattata, and read forward 100 bytes, and tested those 10 sets of 8 bits. It returned "Rattata" !!!! :D That would be 100 bytes per team member, correct? That's what the site I linked to said. (every member being 100 bytes and the team as a whole being spanning 600 bytes) (Sorry if I'm coming off Noobish, I haven't really dabbled in memory addresses or anything "Low Level" and such) – Jebby Apr 30 '17 at 06:02
  • Sounds ok to me then :) If you want, you could verify by catching another separate type of Pokémon (or by giving it an individual name) and going forward another 100 bytes. – blubberdiblub Apr 30 '17 at 06:08
  • I caught a Pidgey and named it "TESTING". I moved forward another 100 bytes, made a list of the 10 values, and it returned "TESTING" so it looks like this should work as far as reading the data goes. I can't thank you enough for this sir! Now only for pulling the data from the application itself. I honestly have no clue on where to start on that haha. – Jebby Apr 30 '17 at 06:22
  • Well, I suspect that may be really difficult, and on multiple levels, too. First, you would have to get at the emulator's memory, which is OS dependent (and it would be a shame to make this work on only 1 OS while the emulator is available on multiple OSes) as far as I know and usually a brittle affair. And from there you would have to find a somewhat stable way to get at the start address of the image of the emulated system's memory, which might involve jumping multiple hoops (pointers and offsets). Reading VBA's source code might help, but come a new version, it might all change. – blubberdiblub Apr 30 '17 at 06:31
  • Your best bet would likely be if the emulator offers a plugin system with an API to access the emulated memory. – blubberdiblub Apr 30 '17 at 06:33
  • Well what kind of programmers are we if we don't challenge ourselves a little every now and then huh? haha. I was planning to implement ways of going about this on Linux as well (I would do Mac too, but my poor Mac mini is so outdated I'm not sure it could support (stable) emulation for testing) But as of now, to get the gist of it all, I'm only working on a version for Windows at the moment. If I do somehow succeed in all this I do plan to push this to PyPi or Github though. – Jebby Apr 30 '17 at 06:44
  • Well, I don't mind a challenge, but what I was getting at is that it might crash randomly (due to reading memory pages that went away), might stop working altogether with every new version of the emulator, with every new system reboot or even with every new emulator session. Which would not be the most rewarding outcome for all the work put into it ;) – blubberdiblub Apr 30 '17 at 06:49
  • 1
    Yeah, I completely understand haha. I read something last night about getting the base address of the module or something of the sort. What I had read was linking to the windows API and was incorporating C++ and while I DO know a little C++, my compiler is broken, and even clean installs wont fix it, so I looked into the win32process (or win32api, I cant remember) for Python and it has calls to the same C++ methods, so I'm hoping to tinker around with those and find SOMETHING out, even if I have to handle Python code like C++ – Jebby Apr 30 '17 at 06:55

0 Answers0