Utilities

A small set of helpers exposed under PyMemoryEditor.util for advanced callers that want to operate on bytes directly β€” convert between Python and ctypes types, compile AOB patterns without a live process, or chunk an arbitrary region for scanning.

from PyMemoryEditor.util import (
    resolve_bufflength,
    convert_from_byte_array,
    value_to_bytes,
    values_to_bytes,
    get_c_type_of,
    compile_pattern,
    iter_region_chunks,
    scan_memory,
    scan_memory_for_exact_value,
    PatternLike,
    DEFAULT_MAX_REGION_CHUNK,
)

Type conversion

resolve_bufflength(pytype, bufflength)

Return a concrete buffer length: the caller-provided value, or the default for numeric pytype when bufflength is None.

Raises:

ValueError – bufflength is required for pytype=str / pytype=bytes.

convert_from_byte_array(byte_array, pytype, length)

Convert a ctypes byte array to a Python value of type pytype. String decoding uses errors="replace".

value_to_bytes(pytype, bufflength, value)

Encode a single value as fixed-width bytes using the same ctypes representation the backend compares against.

values_to_bytes(pytype, bufflength, value)

Convert either a single value or a tuple of values (for VALUE_BETWEEN / NOT_VALUE_BETWEEN) to the corresponding byte form.

get_c_type_of(pytype, length)

Return the underlying ctypes object for the given Python type and width.

Pattern compilation

compile_pattern(pattern, *, byte_length=0)

Compile pattern into a (re.Pattern[bytes], byte_length) pair.

Parameters:
  • pattern – an IDA-style hex string, a raw bytes regex, or a compiled re.Pattern[bytes].

  • byte_length (int) – required for regex / compiled patterns β€” the number of bytes one match consumes.

Raises:

ValueError – malformed IDA-style token, or byte_length omitted for a regex / pre-compiled pattern.

Example

from PyMemoryEditor.util import compile_pattern

regex, byte_length = compile_pattern("48 8B ? 00 00")
print(regex.pattern)   # b'\\x48\\x8B.\\x00\\x00'
print(byte_length)     # 5
PatternLike

Type alias: Union[str, bytes, re.Pattern[bytes]]. The set of input forms compile_pattern accepts.

Region chunking

DEFAULT_MAX_REGION_CHUNK

Maximum chunk size used by iter_region_chunks() (currently 256 MiB). Tunes the trade-off between syscall overhead (small chunks) and peak memory use (huge chunks).

iter_region_chunks(region_size, target_value_size, max_chunk=DEFAULT_MAX_REGION_CHUNK)

Yield (offset, chunk_size) pairs that walk a single memory region in bounded-size chunks. Regions up to max_chunk yield a single chunk; larger ones are split into contiguous, non-overlapping chunks whose size is a multiple of target_value_size so a typed numeric scan never splits a value across a boundary. Boundary handling for patterns is done one level up by the scanner (it overlaps consecutive chunks by pattern_length - 1 bytes); arbitrary str matches in a region larger than max_chunk may still be missed at a chunk boundary β€” a documented limitation.

scan_memory(...)
scan_memory_for_exact_value(...)

Low-level scan kernels used by the backends. Public for advanced use only β€” the high-level search_by_value() / search_by_pattern() methods are the recommended API.

Region predicates

The helpers in PyMemoryEditor.process.region operate on a raw platform struct β€” the same struct field carried by a MemoryRegion. Useful when you’ve obtained a platform descriptor outside the normal flow and want to compute the portable booleans yourself.

from PyMemoryEditor.process.region import (
    is_region_readable,
    is_region_writable,
    is_region_executable,
    is_region_shared,
    region_path,
    make_region,
)
is_region_readable(struct)
is_region_writable(struct)
is_region_executable(struct)
is_region_shared(struct)

True/False from a platform descriptor (MEMORY_BASIC_INFORMATION on Windows/Linux; the VM struct on macOS). For a fully-populated region, prefer the boolean attributes on MemoryRegion (region.is_readable, etc.).

region_path(struct)

Best-effort path of the file backing the region, or "" when unknown (Linux only β€” Windows/macOS would need extra syscalls).

make_region(address, size, struct)

Build a fully-populated MemoryRegion from a platform struct. The four boolean fields and path are computed once via the predicates above. Backends call this once per region; user code rarely needs it.