Archived

This topic is now archived and is closed to further replies.

Valderman

Locked memory?

Recommended Posts

Can anyone here with good knowledge of how Windows handles memory give me a clue on how I get which areas of another process''s RAM is available to alter with ReadProcessMemory and WriteProcessMemory under Windows XP? I''m writing a simple app which searches another program''s RAM, and lets you change interesting memory locations (like the cheat function of ZSNES). I''ve only managed to read the first 500 or so kilobytes after 0x00400000, then there''s some locked memory, and then theres another readable chunk, and then... [repeat until insanity sets in]


Three shall be the number thou shall count, and the number of the counting shall be three...

Share this post


Link to post
Share on other sites
Im no expert on windows, but it would seem to me you would need a process running on a lower rung than the application you want to read. Its been a while since I have dealt with rungs and memory protection crap though. Can you run code in rung 0 on windows?

Share this post


Link to post
Share on other sites
Semi-random guess:
If you can get the path to the executable, you can get the size of it. If you can get the size of the executable, you can determine how much data is allocated after 0x00400000. Maybe. You can get the address of the exe (if you don't already have it) from the ToolHelp functions ISTR [CreateToolhelp32Snapshot(), Process32First(), ...])

Edit: Actually, i'm talking crap :s That won't tell you anything abount memory allocated with new(), malloc(), etc...



[edited by - Evil Bill on December 23, 2002 8:17:25 PM]

Share this post


Link to post
Share on other sites
I don''t see what difference it makes, really -- if you have an NT OS you can allocate memory in the other process, copy a function to that memory, and CreateRemoteThread() to begin execution within the other process.

But if that''s no good, perhaps you can use VirtualQueryEx() to obtain this information.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You can absolutely access other processes'' memory with ReadProcessMemory/WriteProcessMemory (that''s how a debugger does it), but the problem is to find what addresses to read from. What memory are you trying to read? It''s as you understand almost impossible to read the value of a stack variable for a thread that calls a function unless you write a debugger and single-step the program. In order to read memory, your chance is if that memory is long-lived and allocated from the heap.

The IsBad*Ptr() family of functions works for the current process, so that will work only if you create a remote thread in the process you want to search in.

In order to search, you might want to suspend all threads in the process while searching.

Share this post


Link to post
Share on other sites
quote:
Original post by Witchcraven
Im no expert on windows, but it would seem to me you would need a process running on a lower rung than the application you want to read. Its been a while since I have dealt with rungs and memory protection crap though. Can you run code in rung 0 on windows?


It''s RING.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Witchcraven
Im no expert on windows, but it would seem to me you would need a process running on a lower rung than the application you want to read. Its been a while since I have dealt with rungs and memory protection crap though. Can you run code in rung 0 on windows?
You can run code in ring 0 ("kernel mode" in Windows terms) if you write a device driver, but you don''t need this to read another process'' memory. Either you can attach as a debugger, create a remote thread, or register a dll that gets loaded for each program started and in that way access the memory of a certain process.

In order to debug or attach remote threads, you need to run as administrator (or in some other way adjust security so you get sufficient rights). Normal low-priviliged users would not be able to do this as it would clearly be a security issue.

Share this post


Link to post
Share on other sites
VirtualQueryEx worked fine to obtain information on which pages I could read - which created a new problem! I'm testing the search with a simple test app, which just displays the address and value of a two byte variable, and when I search for the value of that variable, I get about 35 results. It's just that the address of the var is 0x12ff7c, and the addresses found in the search are either below 0x500000 or 0x77e677ae and up.
Here's my search function:

  DWORD CALLBACK FindValue(LPVOID lpParam)
{
MEMORY_BASIC_INFORMATION m;
int nMatches = 0;
LPSEARCHINFO s = (LPSEARCHINFO)lpParam;
DWORD br, dwRegionSize, tmp;
char lpTxt[100];
unsigned char *lpSearchBuffer;

VirtualQueryEx(s->hProcess, (void *)0x00400000, &m, sizeof m);
dwRegionSize = m.RegionSize;
for(int i=(int)m.BaseAddress;i<0x80000000;i+=m.RegionSize)
{
VirtualQueryEx(s->hProcess, (void *)i, &m, sizeof m);
if(m.Protect != PAGE_NOACCESS)
{
lpSearchBuffer = new unsigned char[m.RegionSize];
ReadProcessMemory(s->hProcess, m.BaseAddress, lpSearchBuffer, m.RegionSize, &br);
if(br)
{
tmp = br - s->nSize;
for(DWORD j=0;j<=tmp;j++)
{
if(!memcmp(lpSearchBuffer+j, &s->dwValue, s->nSize))
{
nMatches++;
sprintf(lpTxt, "%x", i+j);
SendDlgItemMessage(s->hWnd, IDC_MATCHES, LB_ADDSTRING, 0, (LPARAM)lpTxt);
}
}
}
delete [] lpSearchBuffer;
}
SendDlgItemMessage(s->hWnd, IDC_PROGRESS1, PBM_STEPIT, 0, 0);
}

sprintf(lpTxt, "Found %d matches.", nMatches);
MessageBox(s->hWnd, lpTxt, "Search finished!", MB_ICONINFORMATION);
return 0;
}


Does anyone have a clue on what I'm doing wrong? It's probably something simple and obvious, but I've stared at this code for about an hour without finding it.

EDIT: Changed code tag to source tag




You have just read a controversial statement by Valderman. Thank you for your tolerance.

[edited by - Valderman on December 24, 2002 2:59:29 PM]

Share this post


Link to post
Share on other sites