Jump to content
  • Advertisement
Sign in to follow this  
Plerion

[ASM/Theoretic] Problem interpreting address from IDA

This topic is 3085 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Heya! In order to improve my knowledge in debuggin applications after compilation i decided to make a first step in finding the place where the score in Win7's Solitaire is stored. I found that it is a member of the class SolitaireGame which gets allocated dynamically so the address of it is not static. But ive found a static address like this:
.data:01097074 ; class SolitaireGame * g_pSolitaireGame
.data:01097074 ?g_pSolitaireGame@@3PAVSolitaireGame@@A dd ?
.data:01097074                                         ; DATA XREF: ChangeAppearenceDialog::Show(void)+47r
.data:01097074                                         ; ChangeAppearenceDialog::Show(void)+136r ...
So i see 0x1097074 as the absolute address of g_pSolitaireGame. As i need the RVA for ReadProcessMemory ive looked for the imagebase and thats 0x1000000. That leads me to a RVA of 0x97074. Reading the value at that location gives me 0x30000. This address cannot be a pointer to SolitaireGame. From the name:
.text:01006CC4 ; const SolitaireGame::`vftable'{for `CardSolver::ISolverGame'}
I think SolitaireGame must have virtual functions. But [0x30000] gives me an address which is not within the accessible space of the process. So 0x30000 cannot be the pointer to SolitaireGame. /Edit: Ok, i know now that it contains virtual functions, its no longer just a guess :P
.text:0102EB08 ; public: virtual bool __thiscall SolitaireGame::SolverGameOnMoveComplete(class CardSolver::CTable *, struct CardSolver::SMove const &)
What did i wrong? Greetings Plerion [Edited by - Plerion on April 14, 2010 1:58:14 AM]

Share this post


Link to post
Share on other sites
Advertisement
Actually for ReadProcessMemory, you need to use the absolute address. As far as I know, during runtime, you never have to do the RVA conversion.

As for g_pSolitaireGame, it will probably go something like this:


Code refers to some constant address (uninitialized static data section)
Static memory either has uninitialized value or pointer to actual struct.
Struct has pointer to vtable(s) along with other data.
Vtable has array of function pointers, or zeros for pure virtuals.

Share this post


Link to post
Share on other sites
Yes, i was thinking of that to. I thought that 0x1097074 should be the absolute address of that, but reading at 0x1097074 returns an error with GetLastError set to:
ERROR_PARTIAL_COPY
299 (0x12B)
Only part of a ReadProcessMemory or WriteProcessMemory request was completed.

And dwBytesRead set to 0.

Share this post


Link to post
Share on other sites
Hm, I've never seen ERROR_PARTIAL_COPY before, and I've snooped a LOT of process memory...

Try using VirtualQueryEx to see what the memory protection flags are on that block of memory (Virtual Memory comes in 4096-byte chunks which are 0x1000 aligned, so virtual query will return information about an entire range)

You're only trying to read 4 bytes when reading that global, right?


Unfortunately my memory reader app only works on 32-bit processes and I have the 64-bit version of Solitaire, so I can't try to find out what's up... :(

Share this post


Link to post
Share on other sites
You are actually using a debugger and not just static analysis, I hope. If you find the IDA one is a bit limiting (and it sometimes is) use ollydbg. Examine the memory layout of the program.

Edit: If you're on a 64-bit machine then ollydbg won't work, use windbg instead.

Share this post


Link to post
Share on other sites
Yes, thats strange...

MEMORY_BASIC_INFORMATION info;
VirtualQueryEx(hProcess, (LPCVOID)OFS_CSOLITAIRE_GAME, &info, sizeof(info));
std::cout << "Protection flags: " << std::hex << info.AllocationProtect << std::endl;

DWORD g_SolitaireGame = 0;
DWORD dwBytesRead = 0;
if(FALSE == ReadProcessMemory(hProcess, (LPCVOID)OFS_CSOLITAIRE_GAME, &g_SolitaireGame, 4, &dwBytesRead))
{
std::cout << "Error reading memory at 0x" << std::hex << OFS_CSOLITAIRE_GAME << "! (" << GetLastError() << ")" << std::endl;
std::cout << "Could read " << std::dec << dwBytesRead << " bytes!" << std::endl;
std::cin.sync();
std::cin.get();
return 0;
}


I get PAGE_READONLY so that means that that page should be accessible for read, but ReadProcessMemory returns 0 with GetLastError() returnin 0x12B. And dwBytesRead is 0.

Share this post


Link to post
Share on other sites
oh, i forgot to start the debugger once in IDA to relocate the module base. Now its 0xC97074 and thats a working address! Learned something new :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!