Log in

View Full Version : Getting a Process's Address map?


Lutrosis
September 15th, 2001, 20:29
I'm writing a little app that will scan the area in memory where the text displayed in the console of a particular game is stored, looking for text that it can interpret as commands; in other words, I'll run this app, and then the game, and the app will moniter the section of memory where the console is stored looking for commands that I've typed into the console.

It's a simple enough idea, I've already written code to find the start of the console, along with code to read commands. But I'm not happy with it - rather than starting the search at the beginning of the program's address space, I have to start it at a hard-coded address. It works - since the memory is allocated just after the program starts up, it's usually in just about the same spot, but I don't like hard-coding memory addresses.

How would I get the Address map of the process so that I'd know which areas of memory are readable, allowing me to scan *all* of the process's readable memory?

I know it can be done without too much trouble, I have a program that does it, among other things. I've checked the program's dependencies and can't find an API call that looks like it would do the job.

I have a feeling this post belongs in the newbie forum, as I'm hoping it's a simple answer. Anybody able to throw some hints at me as to where to start looking?

Kayaker
September 16th, 2001, 02:07
Hi Lutrosis

Interesting question, what are you using the app for, as a game trainer? Will you be patching a memory location, or are you just monitoring the text commands for some other reason?

I'm not sure exactly what it is you're trying to do. If you're trying to scan memory paged out by a program on initialization I'd think you'd have to code a vxd to have access to the addresses. If your own app loads the program in question you could inject a dll to have access to the processes address space as if it was its own.

If you are typing commands in on a console, could you not create a patch, either in the file or in memory, to monitor the variable that holds the keyboard input say, rather than doing an overall memory scan for a particular sequence of bytes?

If the variable holding your text command is passed to a call, maybe to a routine which scans the ascii bytes or somthing, you can probably reference it to the stack frame pointer EBP. To get the values of the local variables or of the passed parameters of a call, you can reference EBP, i.e.:

mov eax, [ebp-4] ;copy local variable 1 into eax
mov ebx, [ebp+8] ;copy passed parameter 1 into ebx

If you find such a location in the program code you could patch it to intercept the address and make any changes to it you want. Even if the address isn't used implicitly in a call you still might find it sitting somewhere on the stack unchanged and can reference it there. There may be other ways to intercept the console text as well such as hooking keyboard input.

What is the program you mention that does what it is you are trying emulate? That might help answer the question.

Cheers,
Kayaker

Lutrosis
September 16th, 2001, 12:00
Thanks for the reply =) Actually yes, it is a game trainer of sorts that I'm working on. I've been playing around with a program called Game Trainer, and it has me intrigued. A good way to get some more replay value out of older titles, if you ask me.

But having to alt-tab in and out of a game to search for various values in memory is a pain, especially on some less-than-stable games that like to crash occasionally when you do that. So I figured, why not write a similar program that takes its commands from the game's console? Unfortunately, I don't have all that good an idea of what I'm doing yet. I've dabbled in cracking for the past week or two (for the intellectual challenge - I remove the software when I've cracked it), and while I can crack simple protection schemes and get the general idea of what's going on from the asm (enough to write a keygen for the last app I worked with), I'm still a beginner.

Basically, I want to know how GameTrainer does what it does - generate a map of a process's address space so that it knows which memory locations are readable and which aren't. Finding the console is easy, because it's always found in the same section of memory somewhere, and that section of memory always starts at the same address. But in order to emulate the program's functionality, I need to be able to search *all* of a process's readable memory for a specific value.

I've decided to change my approach somewhat. Rather than re-invent the wheel here and mirror the functionality, I'm just going to have my program act as an interface for GameTrainer. It will moniter the console for commands, and then have GameTrainer execute those commands, writing the results back into the console when necessary.

All the same, I'd like to know how one would go about generating the address map of a process's memory. I'm considering e-mailing GameTrainer's author to ask for a hint that would get me started.

Kayaker
September 16th, 2001, 17:39
Hi Lutrosis

I had a quick look at Game Trainer. It generates a map of a process's address space by using information returned from VirtualQueryEx.

VirtualQueryEx function provides information about a range of pages within the virtual address space of a specified process.

DWORD VirtualQueryEx(

HANDLE hProcess, // handle of process
LPCVOID lpAddress, // address of region
PMEMORY_BASIC_INFORMATION lpBuffer, // address of information buffer
DWORD dwLength // size of buffer


OpenProcess is used to get the handle of the process for the call, and the address pointed to by the 3rd parameter is a MEMORY_BASIC_INFORMATION structure which is filled when the call returns.


The MEMORY_BASIC_INFORMATION structure contains information about a range of pages in the virtual address space of a process. The VirtualQuery and VirtualQueryEx functions use this structure.

typedef struct _MEMORY_BASIC_INFORMATION { // mbi
PVOID BaseAddress; // base address of region
PVOID AllocationBase; // allocation base address
DWORD AllocationProtect; // initial access protection
DWORD RegionSize; // size, in bytes, of region
DWORD State; // committed, reserved, free
DWORD Protect; // current access protection
DWORD Type; // type of pages


The program also uses the Toolhelp32Snapshot series of API's (there's 12 of these, undocumented in the Win32API reference, get updated info from MS) to scan for active processes.


If you set a breakpoint on VirtualQueryEx here and display EDX (the MEMORY_BASIC_INFORMATION structure) in the data window you'll see the address, state and protection of each memory region being processed by the call. The data is then printed out by the program with wsprintfA.

0167:00401C58 6A1C PUSH 1C
0167:00401C5A 52 PUSH EDX
0167:00401C5B 89442424 MOV [ESP+24],EAX
0167:00401C5F 50 PUSH EAX
0167:00401C60 A188204100 MOV EAX,[00412088]
0167:00401C65 50 PUSH EAX
0167:00401C66 FF1514624600 CALL [KERNEL32!VirtualQueryEx]


After each call the BaseAddress is added to the RegionSize (retrieved from the MEMORY_BASIC_INFORMATION structure) and this new address is used as the lpAddress of the next VirtualQueryEx call, so it sort of steps through each memory region this way and writes out the information from the MBI structure.

This is actually a nice example of a memory mapper routine using VirtualQueryEx. Hope this helps some.

Kayaker

Lutrosis
September 16th, 2001, 23:13
Many thanks I actually did check out the Toolhelp32Snapshot functions when I saw them listed in the disassembly, and I tucked the knowledge away for future use, though for my particular program I'm using FindWindow/GetWindowThreadProcessId, as I'm only going to support a few games (if that many - depends on how long this project keeps my interest ). I'm fairly disappointed in myself for not finding that function immediately, but that's what the forums are for I suppose. Thanks again!