Execute a Process from Memory Within Another Process

Execute a process from memory within another process?

Short answer: no.

Long answer: It's possible but rather tricky to do this without writing it out to disk. You can theoretically write your own elf loader that reads the binary, maps some memory, handles the dynamic linking as required, and then transfers control but that's an awful lot of work, that's hardly ever going to be worth the effort.

The next best solution is to write it to disk and call unlink ASAP. The disk doesn't even have to be "real" disk, it can be tmpfs or similar.

The alternative I've been using recently is to not pass complete compiled binaries around, but to pass LLVM bytecode instead, which can then be JIT'd/interpreted/saved as fit. This also has the advantage of making your application work in heterogeneous environments.

It may be tempting to try a combination of fmemopen, fileno and fexecve, but this won't work for two reasons:

  1. From fexecve() manpage:

    "The file descriptor fd must be opened read-only, and the caller must have permission to execute the file that it refers to"

    I.e. it needs to be a fd that refers to a file.

  2. From fmemopen() manpage:

    "There is no file descriptor associated with the file stream returned by these functions (i.e., fileno(3) will return an error if called on the returned stream)"

Can a process free the memory of another process?

Some operating systems allow privileged processes to schedule software interrupts for another process. You allocate a block of memory in the system space, write your code to modify the other process into the block of memory (ensuring the block gets freed), then schedule the software interrupt for the other process to execute this block of code.

Is it possible to free leaked memory from another process?

Assuming we are talking about Unix-like operating systems (this also applies to Windows and the majority of other modern operating systems)...

What is happening here? Why is it not possible to free the leaked memory?

First of all: every running process have it's own virtual address space (or VAS). This VAS is a way the operating system have to lay out and organize the physical memory between different processes. It ranges from 0x0 to 0xFFFFFFFF on 32 bits processors and contains all the memory of the process - its code, static data, stack, heap, etc, it is all in the process VAS. A virtual address (or VA) is a specific address inside the virtual address space.

When you allocate memory with malloc the system will search for a valid unallocated memory on the process heap and if it finds, return a pointer of it (i.e. malloc essentially returns a virtual address).

After the process ends its VAS will be automatically "freed" by the operating system, so that memory is no longer valid, or allocated in that matter. Asides that, each process have its own virtual address space. You can not directly access a process VAS (virtual address space) using a VA (virtual address) of another process - by doing that what you actually end up doing is trying to access that VA in the running process which in your example is very likely to result in an unhandled ACCESS_VIOLATION exception and crashes the process.

how to access memory allocated to different process?

First and foremost, let me say that in modern operating systems, the address values that your program sees (like that 0x00402000) are not physical addresses. They are virtual addresses, they're private to the owning process (i. e. make no sense or mean something else in other processes), and are mapped to physical addresses via a CPU-based mechanism ("the paging unit") that only OS has control over.

If you want to share a variable between different processes, there's a mechanism called shared memory. Read up on it. The relevant APIs are CreateFileMapping with the the first parameter being INVALID_HANDLE_VALUE, MapViewOfFile, OpenFileMapping. There are other ways of interprocess communication, too.

If you want to read process' memory without that process' explicit cooperation, you need to read up on debugging API. This is a much trickier job than using shared memory.

What you've coded, by the way, is a classic undefined behavior.

Fill allocated memory with data from another process

So basic function readVirtualMemory doin this(i guess i presented too short explanation above, but nvm now):

template <typename type>
type ReadVirtualMemory(ULONG64 ProcessId, ULONG64 ReadAddress, SIZE_T Size)
{
type Buffer;

KERNEL_READ_REQUEST ReadRequest;

ReadRequest.ProcessId = ProcessId;
ReadRequest.Address = ReadAddress;
ReadRequest.pBuff = &Buffer;
ReadRequest.Size = Size;

if (DeviceIoControl(hDriver, IO_READ_REQUEST, &ReadRequest, sizeof(ReadRequest), &ReadRequest, sizeof(ReadRequest), 0, 0))
{
return Buffer;
}

return Buffer;
}

And KERNEL_READ_REQUEST is:

   typedef struct _KERNEL_READ_REQUEST
{
ULONG64 ProcessId;
ULONG64 Address;
PVOID64 pBuff;
ULONG64 Size;

} KERNEL_READ_REQUEST, * PKERNEL_READ_REQUEST;

So the problem was with necessary type definition in original function and structure of function. Problem was solved with next solution: adding a new kernel_read function, without type declaration, with pointer to buffer which needs to be filled by read data. (thanks to @SamiKuhmonen for idea):

    bool ReadBuffer(ULONG64 ProcessId, void* buffer, ULONG64 ReadAddress, SIZE_T Size, bool secondary = false)
{
KERNEL_READ_REQUEST ReadRequest;

ReadRequest.ProcessId = ProcessId;
ReadRequest.Address = ReadAddress;
ReadRequest.pBuff = buffer;
ReadRequest.Size = Size;

if (DeviceIoControl(hDriver, IO_READ_REQUEST, &ReadRequest, sizeof(ReadRequest), &ReadRequest, sizeof(ReadRequest), 0, 0))
{
return true;
}

return false;
}

After that my buffer

char* matricies_buf_buf = new char[size_matricies_buffer];
driver.ReadBuffer(pid, matricies_buf_buf, transform_data[0], size_matricies_buffer);

was filled with needed data.

sry for some ppl, who was annoyed with that question, it's my first time when i trying to ask a question and stackoverflow.

Grabbing memory from another process

You should be able to use the ReadProcessMemory function.

See also How to write a Perl, Python, or Ruby program to change the memory of another process on Windows?



Related Topics



Leave a reply



Submit