Reading/Editing Memory of Other Programs

Is there a way to read and/or modify the memory that is allocated to other programs?
Generally, no. Maybe if you attach a debugger or something, yes.
> Generally, no

???
What do you think WPM() is about ?
Last edited on
DLL injection + ReadProcessMemory() + WriteProcessMemory()
But I never tried this myself.
What do you think WPM() is about ?


Can I have a link? I searched on MSDN for that and I didn't get anything.
Depends on the OS. If its UNIX-based then google 'man 2 ptrace'. Otherwise try ReadProcessMemory for Windows. You'll also need fork() or CreateProcess respectively.
closed account (S6k9GNh0)
There should be no reason to want to change a executables belongings. What'chya hackin'?
Last edited on
I have a question about doing this, mainly I was wondering how you could exchange variables between a server/client processes on the same machine. I was thinking that you could just use sockets to do it, but I was wondering if there was a faster way that would involve just directly modifying the variables in the programs.
closed account (ivMjLyTq)
I am actually writing a cross-platform programs that does it. The solution depends on the OS:
- Windows: use OpenProcess() to get a handle to the process, then read its memory with ReadProcessMemory() and write to it with WriteProcessMemory().
- Linux: use ptrace() with request PTRACE_ATTACH to gain access to the process, then monitor SIGCHLD signals to make sure the process is stopped during each read/write operation. Read the memory easily in /proc/<pid>/mem where <pid> is the process identifier and write to it with ptrace() with request PTRACE_POKETEXT.
- Mac OS: I haven't tested it yet, but I am planning to use task_for_pid() to get the process' task, then read its memory with vm_read_overwrite() and write to it with vm_write().

I do not know how to do it on other operating systems.
In the child on Linux you need to do a ptrace PTRACE_TRACEME; I think.

Something along the lines of
1
2
3
4
5
6
7
8
9
10
11
12
pid_t pid = fork()

switch (pid) {
    case -1:
        /* Error */
    case 0:
        /* This is the child process */
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
    case 1:
        /* This is the parent process */
        /* Do something with ptrace here */
}


Edit:
Never mind.

PTRACE_ATTACH
Attaches to the process specified in pid, making it a traced "child" of the current process; the behavior of the child is as if it had done a PTRACE_TRACEME. The current process actually becomes the parent of the child process for most purposes (e.g., it will receive notification of child events and appears in ps(1) output as the child's parent), but a getppid(2) by the child will still return the PID of the original parent. The child is sent a SIGSTOP, but will not necessarily have stopped by the completion of this call; use wait() to wait for the child to stop. (addr and data are ignored.)
Last edited on
closed account (ivMjLyTq)
@chrisname

The child does not need to do anything. The man page for ptrace states that when the tracing process does a PTRACE_ATTACH, it has the same effect as if the traced process had done a PTRACE_TRACEME. However, in the specific case that you considered, where the tracing process starts the traced process with fork() and presumably exec(), any of the two options (the one with PTRACE_ATTACH vs the one with PTRACE_TRACEME) will do. In my program I need to trace a process which is already running, therefore my only option is the one with PTRACE_ATTACH.

Edit: sorry, I hadn't refreshed to see your edit.
Last edited on
:P that's fine.
Just a quick question: how do I get process's base address for ReadProcessMemory() function?
closed account (ivMjLyTq)
@Null

Here again, it depends on the operating system. There is no single "base address", but several ranges in the process' address space that are actually mapped to physical storage (see http://en.wikipedia.org/wiki/Virtual_address_space for a basic introduction). Here is how to get a list of those ranges:
- Windows: once you have a handle to the process, call the VirtualQueryEx() function in a loop, starting at address 0. Each invocation will fill a MEMORY_BASIC_INFORMATION structure with information about a range of consecutive addresses. You will be interested in those associated with storage (State == MEM_COMMIT). Also look at the Protect member if you need read and/or write access.
- Linux: parse the /proc/<pid>/maps file. See man proc for details.
- Mac OS X: I haven't tested it yet, but the vm_region() Mach system call seems to play a similar role as VirtualQueryEx() under Win32, with vm_region_basic_info instead of MEMORY_BASIC_INFORMATION. Use task_for_pid() to get a task from the process' id.
Topic archived. No new replies allowed.