RemotePointerο
A re-resolving, read/write handle to a typed value in a target process.
from PyMemoryEditor import RemotePointer
Most users build a RemotePointer through process.get_pointer(...). The
constructor is documented here for completeness.
Constructionο
- class RemotePointer(process, base_address, offsets=None, *, pytype=int, bufflength=None, ptr_size=None)ο
- Parameters:
process (AbstractProcess) β the open process the value lives in.
base_address (int) β starting address. For a direct handle this is the address of the value itself; for a pointer chain it is typically
module_base + static_offset.offsets β
how to reach the value from
base_address:None(default) β direct handle:addressisbase_address, with no dereferencing. Use this to wrap an address you already have (e.g. fromsearch_by_value()).a sequence (including the empty list
[]) β the value sits at the end of a pointer chain.addressis recomputed on every access viaresolve_pointer_chain().[]dereferencesbase_addressonce; a non-empty list walks each offset, dereferencing all but the last.
pytype (Type) β how to interpret the bytes β
bool,int,float,strorbytes. Defaults toint.bufflength (int) β value size in bytes. Optional for numeric types (intβ4, floatβ8, boolβ1). For
str/bytesit is required only to read (nothing to infer the width from); writing acceptsNoneand stores the whole value, while a setbufflengthcaps the width (truncating).ptr_size (int) β pointer width used when walking
offsetsβ 8 for 64-bit targets, 4 for 32-bit. LeaveNone(the default) to use the targetβspointer_size, detected automatically. Ignored for direct handles.
Propertiesο
- process: AbstractProcessο
The process this pointer reads from / writes to.
Methodsο
- read(pytype=None, bufflength=None)ο
Read the value at
address, optionally overriding the bound type for one-off reads.- Parameters:
pytype (Type) β interpret the bytes as this type for this call only.
bufflength (int) β override the bound buffer size.
- Returns:
the decoded value.
- write(value, pytype=None, bufflength=None)ο
Write
valuetoaddress, optionally overriding the bound type. Returns whateverwrite_process_memory()returns.
Operatorsο
RemotePointer supports C-style pointer arithmetic:
- __add__(delta)ο
- __radd__(delta)ο
ptr + n(orn + ptr) β a new pointernbytes ahead. Does not touch memory.
- __sub__(other)ο
ptr - nβ a new pointernbytes behind.ptr - other(whereotheris aRemotePointer) β the byte distance between the two resolved addresses.
- __int__()ο
The resolved
address. Useful for arithmetic and logging:print(f"HP is at 0x{int(hp_ptr):X}")
- __repr__()ο
Diagnostic representation, e.g.
<RemotePointer base=0x14010F4F4 -> [0, 344] pytype=int>.
Lazy chain foldingο
When you do hp_ptr + 4, the shift is folded into the last offset of the
chain (rather than the resolved address), so the returned pointer still
re-walks the chain on every access. In other words, (hp_ptr + 4) keeps
following the target as it moves around the heap β it doesnβt snapshot the
address at shift time.
Examplesο
Direct handle from a scanο
addresses = list(process.search_by_value(int, 4, 100))
ptr = process.get_pointer(addresses[0], pytype=int, bufflength=4)
ptr.value = 9999
Chained handle from a cheat-table entryο
# "game.exe" + 0x10F4F4 -> [+0x0] -> [+0x158]
module = next(m for m in process.get_modules() if m.name == "game.exe")
hp = process.get_pointer(
module.base_address + 0x10F4F4,
[0x0, 0x158],
pytype=int,
bufflength=4,
)
hp.value -= 10
Walking sibling fields with arithmeticο
# HP and MP are stored side-by-side as 4-byte ints.
mp = hp + 4
mp.value = 100
Reading the same address as a different typeο
# Peek the same address as raw bytes without building a second handle.
print(hp.read(pytype=bytes, bufflength=4))
See also