Post subject: Poking around VBA memory
Joined: 8/31/2006
Posts: 48
Ok, first of all, I mostly fail at low-level C, so please bear with me for now. (All this is using VBA 1.7.2 rerec V19) I'm writing a small utility to ease TASing/Manipulating CGB Pokemon Trading Card Game by allowing you to view your and your current opponents deck(in a more readable manner than the Memory Viewer / Memory Watcher) and to do that, I of course need access to the memory where this is stored. Thanks to the memory map found at datacrystal.org, I know where in GB memory this is stored (0xC400 for P1,0xC480 for P2) but now I also need to find it in VBA memory. Using ArtMoney; I found it moves around every time you start VBA but a pointer to the ROM Block (Where everything I need can be found) can be found at two addresses that I don't recall offhand. So what I currently do is I read one of those two addresses for the address of the ROM Block and this simple C# code:
byte MemRead;
int BytesRead;
for(int i = 0;i<60;i++)
{
    //pReader is an object from a library designed to read the mem of other        
    //processes.This method returns an array, hence the [0].
    //Parameters are IntPtr Address,int BytesToRead, out int BytesRead.
    MemRead = pReader.ReadProcessMemory((IntPtr)(ROMBlockAddress+P1DeckOffset+i),1,out BytesRead)[0];

    //Process the byte read.
   ...
}
(The casting to IntPtr looked odd to me, but that's how it's done in the libs example programs, which work) Now if this is run while the game is open and in a battle, P1's entire deck should be read(Verified using Memory Viewer) but instead, either all zero bytes are read("Nothing" cards in "Library") or complete junk. Looking at VBA's source, it feels even more like it should work, as the memory is declared as "extern u8 *gbROM;" and used as a simple array later in code...If anyone could give me a kick in the right direction at least, it would be greatly appreciated. (Man that was a longwinded post.... Sorry) EDIT: It didn't occur to me until now that the src of the utility might be helpful.. >_< Will edit with it ASAP... EDIT 2: <Link> EDIT 3: It does seem that I am prone to posting in fits of stupidity, doesn't it?Everything was right as rain, only I was supposed to search the gbRAM array and the only reason I thought otherwise was that I thought the region-combobox in the memoryviewer changed to reflect whatever address you jumped to.It doesn't.Also removed the src link because I'm embarassed of how long my projects actually look that bad. In short, sorry for wasting forum space...
There is a whole new world beyond these walls. Break them down.
Joined: 3/7/2006
Posts: 720
Location: UK
Hey, cool. I put the RAM map up on datacrystal, so I'm glad somebody found a use for it. :) I was trying to disassemble the entire game (see sig) but wading that deep in assembly tends to give me headaches.
Voted NO for NO reason
Joined: 8/31/2006
Posts: 48
Unfortunately it appears the decks can't be read directly from memory.. The P1 "Card Index List" (0xC400-0xC43B) is only generated when you use Prof. Oak, Pokemon Breeder or such cards (Or partially for example Pokedex). This also means that you *can't* read P2's deck.Basically, the game generates the card order as it goes (based on PRNG Seed in 0xCACA-CACB (According to FractalFusion)). So predicting the deck would require reverse engineering the actual code that picks a card, as well as knowing how many times shuffling would occur (Which changes the seed). Took me two month's to write but.. >_>
There is a whole new world beyond these walls. Break them down.