Skip to main content
GameDev.net gamedev.net
🔒 Locked

Reading another program's memory

Started by Senses777 May 6, 2003 at 9:19 PM 20 replies 1.3k views
Original Post
Senses777
Senses777
When reading a process's memory via ReadProcessMemory(HANDLE,LPCVOID lpBaseAddress,LPVOID,DWORD,PDWORD), how am I able to know what the begining of the process's memory is? (for lpBaseAddress param when reading the process's memory) I know they are generally 0x400000, but that is not always the case and it is causing me problems. And problem 2: how do I know how much memory the process is using? Right now I am just attempting to read a very large amount of memory and using the last param to see how much was actually read, but this is crappy because I need to alocate a huge amount of memory, just in case that much will be read, then trim it based on how much was actually read. So, the short version of the question is: How do I get what address a program's memory starts at and How do I know how much memory the program is using Thanks! .sen [edited by - Senses777 on May 6, 2003 12:04:37 AM]
"I want to make a simple MMORPG first" - Fenryl
Senses777
Senses777
no one here knows how to get another programs base address or space used? .sen
"I want to make a simple MMORPG first" - Fenryl
Sneftel
Sneftel
You realize, right, that knowing what a program considers its base address will not allow your program to access its memory, right? That''s how virtual memory works.


How appropriate. You fight like a cow.
Senses777
Senses777
You don''t understand, I already got access to its memory, I only need to know where it starts and ends. Most programs start at 0x400000, but not all of them. I have successfully read the entire contents of one Process of Mozilla (I have not enumerated Mozilla''s individual processes and got access to all of them, but I could, my point is just that I DO have access to the memory of any process other than [system process] and system.

So, could anyone help me out? .sen
"I want to make a simple MMORPG first" - Fenryl
Senses777
Senses777
Whats your point? Its not illegal to change and read the memory in my own computer yet is it? I thought this would be fun and interesting. If I was really trying to hack or something, I'd use SoftIce, or another program.

I am also trying to learn how different compilers handle the stack, and other things like that. Now, can anyone help me out? .sen

[edited by - Senses777 on May 7, 2003 5:16:42 AM]
"I want to make a simple MMORPG first" - Fenryl
Senses777
Senses777
lol, dont accuse me of cheating on anything ^^. I am very legit, this is for fun, not so I can be a "1337 h4x0r". Cheating at online games sucks badly.

I am still looking for a way to get the size of a process, and its starting address. I found some sort of functions on msdn but they don''t seem to exist anywhere in their actuall libraries. .sen
"I want to make a simple MMORPG first" - Fenryl
Senses777
Senses777
Whats with all the APs?

Anyways, no, I''m not using this to cheat.

Please, I am desperate for an answer here, i cant find it anywhere. .sen
"I want to make a simple MMORPG first" - Fenryl
Senses777
Senses777
you''re answering my serious programming questions with yoda quotes, this is not good.

I am studying memory management, stack pointers, and how the compiler ends up managing the stack. I am also interested in getting access to another program''s drawing calls, so I can make sort of "hacked" plugins for full screen games that integrate with winamp, or other things. (This would also require getting the messages from the program for input into the plugin).

Now that you know what I''m doing, how do you get the size of a process and the base address of the process given that you know the process ID or you have a handle to the process? Thanks, and please no more APs. If you''re going to accuse me, just do it, don''t hide. .sen
"I want to make a simple MMORPG first" - Fenryl
DirectXXX
DirectXXX
"Whats your point? Its not illegal to change and read the memory in my own computer yet is it? I thought this would be fun and interesting. If I was really trying to hack or something, I'd use SoftIce, or another program."

There are some mem hacking apps avaiable with source code too.

use a game hacking software. where you can change number of bullets left etc etc. Ask some trainer/hacker forum rather than gamedev.

I use such apps to hack games which i cant play......

[edited by - DirectXXX on May 7, 2003 7:04:42 AM]
Gizz
Gizz
search for: "Peering Inside the PE: A Tour of the Win32 Portable Executable File Format" on msdn

cavemanbob
cavemanbob
Here's a chunk of code that I use to dump the valid blocks of memory from apps. It's not particularily efficient, but it gets the job done, it can be adapted to just retrieve the start and end addresses fairly easily without having to dump the blocks. Just change appname to the name of the program you want to access.

Also if you can get a copy of the microsoft DDK there's some useful stuff for finding this kind of info. They have a bunch of hidden API stuff that is accessable with the headers from there.



      
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <tlhelp32.h>
#include <aclapi.h>

HANDLE appprocess;

bool AdjustDacl(HANDLE h, DWORD DesiredAccess)
{
// the WORLD Sid is trivial to form programmatically (S-1-1-0)

SID world = { SID_REVISION, 1, SECURITY_WORLD_SID_AUTHORITY, 0 };

EXPLICIT_ACCESS ea = {
DesiredAccess,
SET_ACCESS,
NO_INHERITANCE,
{
0, NO_MULTIPLE_TRUSTEE,
TRUSTEE_IS_SID,
TRUSTEE_IS_USER,
reinterpret_cast<LPTSTR>(&world)
}
};
ACL* pdacl = 0;
DWORD err = SetEntriesInAcl(1, &ea, 0, &pdacl);
if (err == ERROR_SUCCESS)
{
err = SetSecurityInfo(h, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, pdacl, 0);
LocalFree(pdacl);
return(err == ERROR_SUCCESS);
}
else
return(FALSE);
}

bool scanproclist ()
{
HANDLE hProcessSnap = NULL;
PROCESSENTRY32 pe32 = {0};

// Take a snapshot of all processes in the system.

hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (hProcessSnap == INVALID_HANDLE_VALUE)
return false;

// Fill in the size of the structure before using it.

pe32.dwSize = sizeof(PROCESSENTRY32);

if (Process32First(hProcessSnap, &pe32))
{
HANDLE hProcess;

do
{
LPSTR pCurChar;
char pName[512];

// strip path and leave exe filename

for (pCurChar = (pe32.szExeFile + strlen (pe32.szExeFile));
*pCurChar != '\\' && pCurChar != pe32.szExeFile - 1;
--pCurChar)

strcpy(pName, pCurChar);
strlwr(pName);

if ( (strncmp (pName, "appname", 6) == 0) )
{

printf ("found - pid = %u\n\n", pe32.th32ProcessID);
hProcess = OpenProcess (PROCESS_VM_READ, FALSE, pe32.th32ProcessID);
if (hProcess == NULL)
{
HANDLE hpWriteDAC = OpenProcess(WRITE_DAC, FALSE, pe32.th32ProcessID);
if (hpWriteDAC == NULL)
{
DWORD dw;
dw = GetLastError();
printf ("OpenProcess failed DACL, error: %u\n", dw);
return false;
} else {
AdjustDacl(hpWriteDAC, PROCESS_VM_READ);
DuplicateHandle(
GetCurrentProcess(),
hpWriteDAC,
GetCurrentProcess(),
&hProcess,
PROCESS_VM_READ,
FALSE,
0
);
}
}

appprocess = hProcess;
return true;
}
}
while (Process32Next(hProcessSnap, &pe32));
}

CloseHandle (hProcessSnap);
return false;
}

void dosearch() {
if (!scanproclist()) {
printf("Error locating app!\n");
return;
}


char buf[16];
size_t num;
int curstart = 0x00100000;
char filename[80];

for (unsigned long addr = 0x00100000; addr < 0x40FFFFFF; addr+=16) {
if (ReadProcessMemory(appprocess, (void*)addr, buf, 16, NULL) == 0) {
if (curstart != addr) {
printf("\n%08X - %08X\n", curstart, addr-16);

printf("Dump to file? ");
if (getch() == 'y') {
sprintf(filename, "%08X-%08X.bin", curstart, addr-16);
FILE *file = fopen(filename, "wb");

char *buf = new char[(addr-16)-curstart];

if (ReadProcessMemory(appprocess, (void*)curstart, buf, (addr-16)-curstart, NULL) != 0) {
fwrite(buf, 1, (addr-16)-curstart, file);
}
else {
printf("Error reading range\n");
return;
}

delete buf;

fclose(file);
}
}
curstart = addr+16;
}
//else

// printf("%08X\n", addr);

}
if (curstart != addr) {
printf("%08X - %08X\n", curstart, addr-16);

sprintf(filename, "%08X-%08X.bin", curstart, addr-16);
FILE *file = fopen(filename, "wb");

char *buf = new char[(addr-16)-curstart];

if (ReadProcessMemory(appprocess, (void*)curstart, buf, (addr-16)-curstart, NULL) != 0) {
fwrite(buf, 1, (addr-16)-curstart, file);
}
else {
printf("Error reading range\n");
return;
}

delete buf;

fclose(file);
}

}

int main(int argc, char **argv) {
printf("Mem dumper:\n");

dosearch();


return 0;
}



[edited by - cavemanbob on May 7, 2003 1:59:41 PM]

[edited by - cavemanbob on May 7, 2003 2:00:33 PM]

[edited by - cavemanbob on May 7, 2003 2:04:32 PM]
Senses777
Senses777
Thanks for the tip Gizz, I found some really cool stuff! This is exactly what I was looking for.

cavemanbob: thanks a ton, I''ll try and extract those if I can, I''ll post when I''m done.

AP: Stop being AP, and whats a range finder? .sen
"I want to make a simple MMORPG first" - Fenryl
cavemanbob
cavemanbob
MMORPG mappers are fun to write though

Maybe one of these days they''ll get the idea that the client cannot be trusted with any data and stop sending so much useless stuff over the wire... Probably an unrealistic hope LOL.

Senses777
Senses777
lol yep, thats one of my furture projects ^^

Its really amazing how much info they send to you, for the client to handle. .sen
"I want to make a simple MMORPG first" - Fenryl
cavemanbob
cavemanbob
Have a look at some of the existing projects for this kind of thing, no point in reinventing the wheel and if there''s one or more for the game you''re looking at it''ll be a huge help.

As a quick warning, ReadMemoryProcess is a windows debug function and will almost surely be messed with or detected in future MMORPG patches. If you can either grab the MS detours library and inject code to extract data into the game exe (Easier way) or even better grab the MS DDK for the appropriate windows version and run some ring 0 code to rip the data out in a completely undetectable way (Harder, but way better).

I''m still using ReadProccessMemory myself, but I''m expecting that to be messed up any patch now...

Keep up the work though, it''s SO cool to see all the stuff around you pop up in your own program

Senses777
Senses777
quote:
Original post by cavemanbob
If you can either grab the MS detours library and inject code to extract data into the game exe (Easier way) or even better grab the MS DDK for the appropriate windows version and run some ring 0 code to rip the data out in a completely undetectable way (Harder, but way better).

I''m still using ReadProccessMemory myself, but I''m expecting that to be messed up any patch now...

Keep up the work though, it''s SO cool to see all the stuff around you pop up in your own program


How would I inject code and have it execute in the program to extract the data from the game exe to another program without the use of files (speed is an issue)?

I think I''m still pretty far from getting my app over the program even, or getting input, but I have figured out a way to get info on the memory, its using VirtualQueryEx.

I havn''t yet implemented it but I''m working on it right now, VirtualQueryEx gives info on like pages of memory. Interesting stuff. .sen
"I want to make a simple MMORPG first" - Fenryl

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.