Allocating and freeing memory
PyMemoryEditor can reserve new memory inside the target process and release it later. This is useful for storing custom data the target program will read, or for staging code injection scenarios.
Allocating
allocate_memory(size) reserves a new region in the target’s address space
and returns its base address. The OS may round the size up to the page
size:
with OpenProcess(process_name="game.exe") as process:
address = process.allocate_memory(64)
process.write_int(address, 1337)
Freeing
free_memory(address) releases the region. The library remembers each
allocation’s size, so you don’t have to:
process.free_memory(address)
Pass an explicit size= only when freeing a region that this object did not
allocate (e.g. one inherited from another script):
process.free_memory(address, size=4096)
Method signatures
- allocate_memory(size, *, permission=None)
Reserve and commit
sizebytes inside the target process’s address space and return the base address of the new region.- Parameters:
size (int) – number of bytes to allocate (rounded up to the OS page size by the kernel).
permission – optional, platform-specific protection for the new region — see the platform table below.
- Returns:
the base address of the new region.
- Raises:
NotImplementedError – on Linux (see below).
- free_memory(address, size=0)
Release a region previously returned by
allocate_memory().- Parameters:
address (int) – base address returned by
allocate_memory().size (int) – size of the region in bytes. May be left
0to reuse the size recorded when the region was allocated (required on macOS, ignored on Windows whereMEM_RELEASEfrees the whole allocation). Pass an explicit size only to free a region this object did not allocate.
- Returns:
Trueon success.- Raises:
NotImplementedError – on Linux.
Platform behavior
| Platform | Status | Default permission |
Underlying API |
|---|---|---|---|
| 🪟 Windows | ✅ Supported | PAGE_EXECUTE_READWRITE (executable + writable) |
VirtualAllocEx / VirtualFreeEx |
| 🍎 macOS | ✅ Supported | Mach default (read+write) | mach_vm_allocate / mach_vm_deallocate |
| 🐧 Linux | ❌ Not supported | — | Raises NotImplementedError |
Why no Linux?
Linux has no syscall to allocate memory in another process’s address space —
mmap only affects the calling process. Cross-process allocation would
require a ptrace-based engine to make the target call mmap itself.
PyMemoryEditor doesn’t ship one. Calling allocate_memory or free_memory
on Linux raises NotImplementedError.
Choosing a permission
The permission= argument mirrors OpenProcess(permission=...).
On Windows
Pass a MemoryProtectionsEnum (or the underlying integer):
from PyMemoryEditor import OpenProcess
from PyMemoryEditor.win32.enums.memory_protections import MemoryProtectionsEnum
with OpenProcess(process_name="game.exe") as process:
# Allocate a read-only buffer.
address = process.allocate_memory(64, permission=MemoryProtectionsEnum.PAGE_READONLY)
Common values:
| Value | Meaning |
|---|---|
PAGE_NOACCESS | No access at all. |
PAGE_READONLY | Read-only. |
PAGE_READWRITE | Read + write. |
PAGE_EXECUTE_READ | Read + execute. |
PAGE_EXECUTE_READWRITE (default) | Read + write + execute. |
On macOS
Pass a VM_PROT_* bitmask (or leave None for the default of read+write):
# read+write+execute (may fail under the hardened runtime).
process.allocate_memory(4096, permission=VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
Hardened runtime on Apple Silicon
Requesting executable allocations may fail on macOS, especially on Apple Silicon under the hardened runtime. Stick to read+write if you don’t need to execute injected code.
A complete example
from PyMemoryEditor import OpenProcess
with OpenProcess(process_name="game.exe") as process:
address = process.allocate_memory(128)
try:
# Write something to it
process.write_process_memory(address, str, 128, "Hello from PyMemoryEditor!")
# Read it back
msg = process.read_process_memory(address, str, 128)
print(msg.split("\x00", 1)[0])
finally:
process.free_memory(address)
See also