-
-
Notifications
You must be signed in to change notification settings - Fork 384
API_Python_ScatterMemory
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:
- 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).
-
- Populate memory ranges with multiple calls to
prepare(int: address, int: size_to_read)
function. - Retrieve the memory by calling
execute()
function. - Fetch memory retrieved in (3) by calling
read(int: address, int: size_to_read)
multiple times. - Clear the handle for subsequent uses by calling
clear(opt int: flags)
or close the handle by callingclose()
. Note that it's often recommended to callclear()
/close()
immediately after use to free up sometimes substantial internal resources rather than wait for Python to clear the allocations.
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.
-
process.memory.scatter_initialize(opt int: flags)
- new virtual memory read scatter object. -
vmm.memory.scatter_initialize(opt int: flags)
- new physical memory read scatter object.
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
# 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()
Sponsor PCILeech and MemProcFS:
PCILeech and MemProcFS is free and open source!
I put a lot of time and energy into PCILeech and MemProcFS and related research to make this happen. Some aspects of the projects relate to hardware and I put quite some money into my projects and related research. If you think PCILeech and/or MemProcFS are awesome tools and/or if you had a use for them it's now possible to contribute by becoming a sponsor!
If you like what I've created with PCIleech and MemProcFS with regards to DMA, Memory Analysis and Memory Forensics and would like to give something back to support future development please consider becoming a sponsor at: https://github.com/sponsors/ufrisk
Thank You 💖