Memory API

Memory API

Architectural Stack (ql.arch)

1value = ql.arch.stack_pop()          # pop value, adjust SP
2ql.arch.stack_push(value)            # push value, adjust SP
3value = ql.arch.stack_read(offset)   # peek at offset from top (no SP change)
4ql.arch.stack_write(offset, value)   # replace at offset from top (no SP change)

Offset may be positive, negative, or zero (zero = top of stack).

Memory Management (ql.mem)

MethodDescription
map(addr, size, perms, info)Map a region; must be page-aligned
unmap(addr, size)Reclaim a mapped region (supports partial ranges)
unmap_all()Reclaim all mapped regions
map_anywhere(size)Map at an unspecified location
protect(addr, size, perms)Modify rwx protection bits
find_free_space(size)Find available region of given size
is_available(addr, size)True if region is entirely unmapped
is_mapped(addr, size)True if region is entirely mapped

Note: is_available and is_mapped are not inverses — a partially mapped region returns False for both.

map

1ql.mem.map(addr: int, size: int, perms: int = UC_PROT_ALL, info: Optional[str] = None) -> None

Raises QlMemoryMappedError if range is not entirely available.

unmap

1ql.mem.unmap(addr: int, size: int) -> None

Raises QlMemoryMappedError if range is not entirely mapped.

Reading Memory

Memory protections do not apply to Qiling itself — all mapped memory is readable by the emulator regardless of page permissions.

Read bytes

1ql.mem.read(addr: int, size: int) -> bytearray

Raises UcError if range is not entirely mapped.

Read integer

1ql.mem.read_ptr(addr: int, size: int = 0, *, signed: bool = False) -> int

Writing Memory

All mapped memory is writable by the emulator regardless of page permissions.

Write bytes

1ql.mem.write(addr: int, data: bytes) -> None

Write integer

1ql.mem.write_ptr(addr: int, value: int, size: int = 0, *, signed: bool = False) -> None

Searching Memory

1ql.mem.search(
2    needle: Union[bytes, Pattern[bytes]],
3    begin: Optional[int] = None,
4    end: Optional[int] = None
5) -> List[int]

Alignment Utilities

Align down (to page boundary)

1ql.mem.align(value: int, alignment: Optional[int] = None) -> int

Returns value rounded down to alignment (default: native page size). Used to find enclosing page base.

Align up

1ql.mem.align_up(value: int, alignment: Optional[int] = None) -> int

Returns value rounded up to alignment (default: native page size). Used to find enclosing page end.

Both methods require alignment to be a power of 2.