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 size bytes 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 0 to reuse the size recorded when the region was allocated (required on macOS, ignored on Windows where MEM_RELEASE frees the whole allocation). Pass an explicit size only to free a region this object did not allocate.

Returns:

True on 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:

ValueMeaning
PAGE_NOACCESSNo access at all.
PAGE_READONLYRead-only.
PAGE_READWRITERead + write.
PAGE_EXECUTE_READRead + 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)