Skip to content

API_Python_ScatterMemory

Ulf Frisk edited this page Oct 9, 2023 · 5 revisions

Overview:

The MemProcFS simplified Scatter Memory Read API consists of the VmmScatterMemory object.

The Scatter Memory Read API is used for efficient parallel memory access. This greatly increases efficiency since multiple regular memory read calls may be read in one efficient call due to lower combined device latency times. The Scatter Memory Read API may be used to retrieve both physical memory as well as process virtual memory. Memory sizes ranging between 1 byte and 1GB may be read.

Flow is as follows:

  1. Fetch new VmmScatterMemory object from either:
    • process.memory.scatter_initialize(opt int: flags) (virtual process memory).
    • vmm.memory.scatter_initialize(opt int: flags) (physical memory).
  2. Populate memory ranges with multiple calls to prepare(int: address, int: size_to_read) function.
  3. Retrieve the memory by calling execute() function.
  4. Fetch memory retrieved in (3) by calling read(int: address, int: size_to_read) multiple times.
  5. Clear the handle for subsequent uses by calling clear(opt int: flags) or close the handle by calling close(). Note that it's often recommended to call clear()/close() immediately after use to free up sometimes substantial internal resources rather than wait for Python to clear the allocations.

VmmScatterMemory:

Represents a scatter memory read. Scatter memory reads are backed by native C/C++ objects as given by the MemProcFS VMMDLL_Scatter_* C/C++ API.

Sources:

Attributes:

scatter_memory.pid   # int: process id (in case of virtual memory scatter object). ex: scatter_memory.pid -> 4280
scatter_memory.flags # int: combination of one or multiple memprocfs.FLAGS_*. ex: scatter_memory.flags -> 1

Methods:

# Prepare memory to read in later in execute() function call.
# All ranges must be populated before the execute() function is called.
# -- address
# -- bytes_to_read
scatter_memory.prepare(int: address, int: bytes_to_read) # -> None
# example:
#   scatter_memory.prepare(0x7ff7f3a90000, 0x20)


# Retrieve the memory ranges previously populated with multiple prepare() calls.
# If one wish to refresh already read and populated ranges later in time this
# function may be called again multiple times.
scatter_memory.execute() # -> None
# example:
#   scatter_memory.execute()


# Fetch data prepared with prepare() and already retrieved by execute().
# All memory fetched must be within the ranges prepared but may optionally
# be less than the actual memory read if one so wish.
# -- address
# -- size_to_read
# -- return
scatter_memory.read(int: address, int: size_to_read) # -> bytes
# example:
#   print(vmm.hex( scatter_memory.read(0x7ff7f3a90000, 0x20) )) ->
#   0000    4d 5a 90 00 03 00 00 00  04 00 00 00 ff ff 00 00   MZ..............
#   0010    b8 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00   ........@.......


# Fetch multiple data ranges prepared with prepare() and already
# retrieved by execute(). All memory fetched must be within the
# ranges prepared but may optionally be less than what was prepared.
# -- list of ranges
# -- return
scatter_memory.read(list: list_of_ranges) # -> list: bytes
# example:
#   scatter_memory.read([[0x7ff7f3a90000, 0x20], [0x7ff7f3a98000, 0x10]) -> [b'..', b'..']


# Fetch a single data type prepared with prepare().
# Valid types: i8, u8, i16, u16, f32, i32, u32, f64, i64, u64.
# -- address_virtual
# -- bytes_to_read
# -- flags = optional read flags memprocfs.FLAG_*.
# -- return
scatter_memory.read_type(int: address_virtual, str: type_to_read, opt int: flags) # -> type
# example:
#   scatter_memory.read_type(0x7FF750930000, 'u16') -> 23117


# Fetch multiple data types prepared with prepare().
# Valid types: i8, u8, i16, u16, f32, i32, u32, f64, i64, u64.
# -- list_of_types
# -- flags = optional read flags memprocfs.FLAG_*.
# -- return
scatter_memory.read_type(list: list_of_types, str: type_to_read, opt int: flags) # -> [type1, .., typeN]
# example:
#   scatter_memory.read_type([[0x7FF750930000, 'u64'], [0x7FF750930000, 'f32']]) -> [12894362189, 1.325670526335053e-38]


# Clear / Reset the scatter object for new use.
# -- flags
scatter_memory.clear(opt int: flags) # -> None
# examples:
#   scatter_memory.clear()
#   scatter_memory.clear(memprocfs.FLAG_NOCACHE)


# Close a scatter object and free up its internal resources. It is recommended
# to call close rather than wait for Python to free up scatter_memory objects
# since internal resource consumption may be substantial.
scatter_memory.close() # -> None
# example:
#   scatter_memory.close()
Clone this wiki locally