-
-
Notifications
You must be signed in to change notification settings - Fork 384
API_Python_Process
The MemProcFS process and module API for Python consists of two primary objects:
-
VmmProcess
- process object. -
VmmModule
- module object - represents dll/sys/exe files.
Process objects are most commonly retrieved from the base Vmm
object.
Module objects are most commonly retrieved from VmmProcess
objects.
Represents a process.
-
vmm.process_list()
- as list of all processes. -
vmm.process()
- as single process retrieved by name or PID. -
vmm.kernel.process
- the SYSTEM process (PID 4). -
module.process
- module parent process.
process.pid # int: process id. ex: process.pid -> 4280
process.ppid # int: parent process id. ex: process.ppid -> 4248
process.eprocess # int: _EPROCESS address. ex: process.eprocess -> 18446644053912244352
process.dtb # int: directory table base, dtb, cr3. ex: process.dtb -> 5930565632
process.dtb_user # int: user-mode directory table base, dtb, cr3. ex: process.dtb_user -> 5930561536
process.state # int: process state. ex: process.state -> 0
process.peb # int: process environment block, peb. ex: process.peb -> 14229504
process.peb32 # int: 64-bit OS, 32-bit process environment block, peb. ex: process.peb32 -> 0
process.is_wow64 # bool: 64-bit OS, 32-bit process. ex: process.is_wow64 -> False
process.is_usermode # bool: is process user-mode. ex: process.is_usermode -> True
process.name # str: process short name (max 15 chars). ex: process.name -> 'explorer.exe'
process.fullname # str: process full name. ex: process.fullname -> 'explorer.exe'
process.pathuser # str: process path as seen by user-mode. ex: process.pathuser -> 'C:\\Windows\\Explorer.EXE'
process.pathkernel # str: process path as seen by kernel-mode. ex: process.pathkernel -> '\\Device\\HarddiskVolume4\\Windows\\explorer.exe'
process.tp_memorymodel # int: memory model type. ex: process.tp_memorymodel -> 3
process.tp_system # int: system type. ex: process.tp_system -> 2
process.luid # int: process token LUID. ex: process.luid -> 225102
process.session # int: process token session id. ex: process.session -> 1
process.sid # str: process token SID. ex: process.sid -> 'S-1-5-21-3317879871-105768242-2947499445-1001'
process.cmdline # str: process command line. ex: process.cmdline -> 'cmd.exe /c calc.exe'
process.integrity # int: process integrity level as specified by VMMDLL_PROCESS_INTEGRITY_LEVEL. ex: process.integrity -> 3
process.maps # VmmProcessMaps: see methods below. ex: process.maps -> ProcessMaps:4280
process.memory # VmmVirtualMemory: see methods below. ex: process.memory -> VirtualMemory:4280
# Read memory from process virtual address space.
# -- address_virtual
# -- bytes_to_read
# -- flags = optional read flags memprocfs.FLAG_*.
# -- return
process.memory.read(int: address_virtual, int: bytes_to_read, opt int: flags) # -> bytes
# example:
# print(vmm.hex( process.memory.read(0x7FF750930000, 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 ........@.......
# Read memory from process virtual address space (multiple ranges).
# -- list of virtual ranges
# -- flags = optional read flags memprocfs.FLAG_*.
# -- return
process.memory.read(list: virtual_ranges, opt int: flags) # -> bytes
# example:
# process.memory.read( [[0x7FF750930000, 0x20], [0x7FF750934000, 0x10]] ) -> [b'..', b'..']
# Read a single native data type from memory.
# Valid types: i8, u8, i16, u16, f32, i32, u32, f64, i64, u64.
# -- address_virtual
# -- bytes_to_read
# -- flags = optional read flags memprocfs.FLAG_*.
# -- return
process.memory.read_type(int: address_virtual, str: type_to_read, opt int: flags) # -> type
# example:
# process.memory.read_type(0x7FF750930000, 'u16') -> 23117
# Read multiple native data type from memory.
# Valid types: i8, u8, i16, u16, f32, i32, u32, f64, i64, u64.
# -- list_of_types
# -- flags = optional read flags memprocfs.FLAG_*.
# -- return
process.memory.read_type(list: list_of_types, str: type_to_read, opt int: flags) # -> [type1, .., typeN]
# example:
# process.memory.read_type([[0x7FF750930000, 'u64'], [0x7FF750930000, 'f32']]) -> [12894362189, 1.325670526335053e-38]
# Read multiple 0x1000 bytes-sized chunks scattered among listed
# 0x1000 byte aligned addresses.
# -- address_list = list of 0x1000-aligned virtual addresses.
# -- return
process.memory.read_scatter([int: address_virtual1, ...], opt_int flags) # -> list:dict
# example:
# process.memory.read_scatter([0x7FF750930000, 0x7FF750931000]) ->
# [{'addr': 140700185460736, 'va': 140700185460736, 'data': b'MZ\x90\x00\x03...', 'size': 4096},
# {'addr': 140700185464832, 'va': 140700185464832, 'data': b'H\x83\xec(\xe8...', 'size': 4096}]
Please see VmmScatterMemory
for information about how to use the VmmScatterObject
returned by function vmm.memory.scatter_initialize(opt int: flags)
which is documented below.
# Initialize a Scatter Virtual Memory Read object which is used to simplify efficient memory reads.
# This is accomplished by using the simplified native MemProcFS VMMDLL_Scatter_* functionality.
# -- flags = flags as specified by memprocfs.FLAG_*.
# -- return
vmm.memory.scatter_initialize(opt int: flags) # -> VmmScatterMemory
# example:
# vmm.memory.scatter_initialize(memprocfs.FLAG_NOCACHE) -> VmmScatterMemory
# Write data (if supported) to already mapped process virtual memory.
# -- address_virtual
# -- data
process.memory.write(int: address_virtual, bytes: data) # -> None
# example:
# process.memory.write(0x7FF750930000, b'0000')
# Translate virtual process memory to physical memory
# -- address_virtual
# -- return
process.memory.virt2phys(int: address_virtual) # -> int
# example:
# process.memory.virt2phys(0x7FFAC7890000) -> 4704169984
# Retrieve a single module by its name.
# -- module_name
# -- return
process.module(str: module_name) # -> VmmModule
# example:
# process.module('kernel32.dll') -> Module:4280:KERNEL32.DLL
# List all modules loaded by the process.
# -- return
process.module_list() # -> list:VmmModule
# example:
# process.module_list() ->
# [Module:4280:Explorer.EXE, Module:4280:ntdll.dll, Module:4280:KERNEL32.DLL, ...]
# Search virtual memory
# See API documentation for search/yara.
# -- addr_min = opt int: min virtual address to search.
# -- addr_max = opt int: max virtual address to search.
# -- flags = opt int: optional read flags memprocfs.FLAG_*.
# -- return = VmmSearch object.
process.search(opt int: addr_min, opt int: addr_max, opt int: flags) # -> VmmSearch
# example:
# process.search(0, 0x200000000, memprocfs.FLAG_NOCACHE) -> VmmSearch:Virtual:420
# Yara search virtual memory
# See API documentation for search/yara.
# -- rules = list str: yara rule(s) to use to search. str or list of str.
# -- addr_min = opt int: min virtual address to search.
# -- addr_max = opt int: max virtual address to search.
# -- results = opt int: max search results (max = 0x10000).
# -- flags = opt int: optional read flags memprocfs.FLAG_*.
# -- return = VmmYara object.
process.search_yara(list str: rules, opt int: min, opt int: max, opt int: results, opt int: flags) # -> VmmYara
# example:
# process.search_yara('c:/temp/rules.yar', 0, 0x200000000, 1000, memprocfs.FLAG_NOCACHE) -> VmmYara:Virtual:420
# Retrieve process handle information.
# -- return
process.maps.handle() # -> list:dict
# example:
# process.maps.handle() ->
# [{'va-object': 18446644053917635680, 'handle': 4, 'access': 2031619, 'typeindex': 16, 'pid': 4280,
# 'pooltag': 1852143173, 'chandle': 1, 'cpointer': 32768, 'va-object-creatinfo': 18446644053883285568,
# 'va-securitydescriptor': 0, 'tag': '', 'type': 'Event'},
# ...]
# Retrieve process heap information.
# -- return
process.maps.heap() # -> dict
# example:
# process.maps.heap() ->
# {'heap': {0: {'va': 4980736, 'tp': 1, 'heapid': 0}, ...},
# 'segment': [{'va': 196608, 'tp': 1, 'heapid': 1, 'size': 65536}, ...]}
# Retrieve process heap allocation information.
# -- heap_address_or_number = virtual address or heap number.
# -- return
process.maps.heapalloc(int: heap_address_or_number) # -> list
# example:
# process.maps.heapalloc(1) ->
# [{'va': 8455984, 'tp': 1, 'size': 144}, ...]
# Retrieve process page table entry (PTE) information.
# -- is_identify_modules = optional value to to force module identification; default: False.
# -- return
process.maps.pte(opt int: is_identify_modules) # -> list:dict
# example:
# process.maps.pte() ->
# [{'va': 12320768, 'size': 4096, 'pages': 1, 'pages-sw': 0, 'wow64': False, 'tag': '', 'flags-pte': 9223372036854775814, 'flags': '-rw-'},
# {'va': 12386304, 'size': 28672, 'pages': 7, 'pages-sw': 0, 'wow64': False, 'tag': '', 'flags-pte': 9223372036854775814, 'flags': '-rw-'},
# ...]
# Retrieve process thread information.
# -- return
process.maps.thread() # -> list:dict
# example:
# process.maps.thread() ->
# [{'tid': 8, 'pid': 4280, 'exitstatus': 0, 'state': 5, 'running': 0, 'priority': 8, 'basepriority': 8,
# 'va-ethread': 18446644053931507840, 'va-teb': 12820480, 'va-start': 140715077586608, 'va-win32start': 140715077586608,
# 'va-stackbase': 249823232, 'va-stacklimit': 249765888, 'va-stackbase-kernel': 18446613807492460544,
# 'va-stacklimit-kernel': 18446613807492435968, 'va-trapframe': 18446613807492459264, 'reg-rip': 140715044149892,
# 'reg-rsp': 249820904, 'time-create': 132162320870207758,
# 'time-exit': 0, 'time-create-str': '2019-10-22 15:34:47 UTC', 'time-exit-str': ' ***'},
# ...]
# Retrieve process thread callstack information.
# -- tid = thread id.
# -- flags = 0, FLAG_NOCACHE or FLAG_FORCECACHE_READ.
# -- return
process.maps.thread_callstack(int: tid, opt int flags) # -> list:dict
# example:
# process.maps.thread_callstack(9816) ->
# [{'pid': 372, 'tid': 9816, 'i': 0, 'va-retaddr': 140724608669956, 'va-rsp': 0, 'va-base-sp': 0, 'displacement': 0, 'type': ''},
# {'pid': 372, 'tid': 9816, 'i': 1, 'va-retaddr': 140724662236621, 'va-rsp': 394261768, 'va-base-sp': 394261776, 'displacement': 20, 'type': 'ZwUserMsgWaitForMultipleObjectsEx'},
#{'pid': 372, 'tid': 9816, 'i': 2, 'va-retaddr': 140724006932600, 'va-rsp': 394261776, 'va-base-sp': 394261840, 'displacement': 29, 'type': 'RealMsgWaitForMultipleObjectsEx'},
#{'pid': 372, 'tid': 9816, 'i': 3, 'va-retaddr': 0, 'va-rsp': 394261840, 'va-base-sp': 394262000, 'displacement': 376, 'type': 'CoreSC::xwProcessNL'}]
# Retrieve unloaded modules.
# -- return
process.maps.unloaded_module() # -> list:dict
# example:
# process.maps.unloaded_module() ->
# [{'va': 140714921820160, 'size': 548864, 'wow64': False, 'name': 'ncsi.dll', 'dwCheckSum': 576105, 'dwTimeDateStamp': 3777288024, 'ft': 0},
# ...]
# Retrieve virtual address descriptor (VAD) info.
# -- is_identify_modules = optional value to to force module identification; default: False.
# -- return
process.maps.vad(opt int: is_identify_modules) # -> list:dict
# example:
# process.maps.vad() ->
# [{'start': 12320768, 'end': 12386303, 'cvadex-pages': 1, 'cvadex-pages-base': 0, 'subsection': 18446644053917124928,
# 'prototype': 18446663847587408016, 'prototype-len': 128, 'mem_commit': False, 'commit_charge': 0,
# 'protection': '--rw--', 'type': 'Pf ', 'tag': ''},
# ...]
# Retrieve extended VAD map.
# -- page_start = start page number.
# -- page_count = number of pages.
# -- return
process.maps.vad_ex(int: page_start, page_count) # -> list:dict
# example:
# process.maps.vad_ex(3400, 2) ->
# [{'tp': 'P', 'pml': 2, 'va': 61095936, 'pa': 0, 'pte': 0, 'pteflags': 3, 'vad-va': 56426496, 'proto-tp': '-', 'proto-pa': 0, 'proto-pte': 0},
# {'tp': 'P', 'pml': 2, 'va': 61100032, 'pa': 0, 'pte': 0, 'pteflags': 3, 'vad-va': 56426496, 'proto-tp': '-', 'proto-pa': 0, 'proto-pte': 0}
# ...]
Represents a loaded module, such as a .dll, .sys or .exe file.
-
process.module()
- as single module. -
process.module_list()
- as list of all modules within the parent process.
module.name # int: module name. ex: module.name -> 'KERNEL32.DLL'
module.fullname # str: full name / path. ex: module.fullname -> 'C:\\Windows\\System32\\KERNEL32.DLL'
module.process # VmmProcess: module parent process. ex: module.process -> Process:4280
module.is_wow64 # bool: module is 32-bit on 64-bit Windows. ex: module.is_wow64 -> False
module.base # int: module base address. ex: module.base -> 140715066195968
module.file_size # int: size of module on-disk. ex: module.file_size -> 707072
module.image_size # int: size of module in-memory. ex: module.image_size -> 729088
module.count_section # int: number of PE sections. ex: module.count_section -> 6
module.count_eat # int: number of exported functions. ex: module.count_eat -> 1629
module.count_iat # int: number of imported functions. ex: module.count_iat -> 1252
module.pdb # VmmPdb: object containing pdb debug symbols from the microsoft symbol server. ex: module.pdb -> Pdb:kernel32
module.maps # VmmModuleMaps: see methods below.
# Retrieve the address of an exported function - similar to the
# WIN32 API function GetProcAddress.
# -- function_name
# -- return
module.procaddress(str: function_name) # -> int
# example:
# module.procaddress('GetTickCount64') -> 140715066288800
# List information about the module PE data directories.
# -- return
module.maps.directories() # -> list:dict
# example:
# module.maps.directories() ->
# [{'i': 0, 'size': 56640, 'offset': 584832, 'name': 'EXPORT'},
# ...
# {'i': 15, 'size': 0, 'offset': 0, 'name': 'RESERVED'}]
# List information about the PE sections.
# -- return
module.maps.sections() # -> list:dict
# example:
# module.maps.sections() ->
# [{'i': 0, 'Characteristics': 1610612768, 'misc-PhysicalAddress': 477008, 'misc-VirtualSize': 477008,
# 'Name': '.text', 'NumberOfLinenumbers': 0, 'NumberOfRelocations': 0, 'PointerToLinenumbers': 0,
# 'PointerToRawData': 1024, 'PointerToRelocations': 0, 'SizeOfRawData': 477184, 'VirtualAddress': 4096},
# ...]
# List information about the module export address table.
# The EAT contains the exported functions.
# -- return
module.maps.eat() # -> dict
# example:
# module.maps.eat() ->
# {'va-module': 140715066195968, 'va-afn': 140715066780840, 'va-anm': 140715066787356, 'ord-base': 1, 'c-afn': 1629, 'c-anm': 1629, 'c-fwdfn': 132,
# 'e': [{'i': 0, 'ord': 1, 'oafn': 0, 'oanm': 0, 'ofn': 601199, 'va': 0, 'fn': 'AcquireSRWLockExclusive', 'fwdfn': 'NTDLL.RtlAcquireSRWLockExclusive'},
# {'i': 1, 'ord': 2, 'oafn': 1, 'oanm': 1, 'ofn': 601253, 'va': 0, 'fn': 'AcquireSRWLockShared', 'fwdfn': 'NTDLL.RtlAcquireSRWLockExclusive'},
# {'i': 1, 'ord': 3, 'oafn': 2, 'oanm': 3, 'ofn': 132736, 'va': 140705442694784, 'fn': 'ActivateActCtx', 'fwdfn': None},
# ...
# ]
# }
# List information about the module import address table.
# The IAT contains the exported functions.
# -- return
module.maps.iat() # -> list:dict
# example:
# module.maps.iat() ->
# [{'i': 0, 'va-fn': 140715077552848, 'va-mod': 140715066195968, 'fn': 'RtlInstallFunctionTableCallback',
# 'dll': 'api-ms-win-core-rtlsupport-l1-1-0.dll', '32': False, 'hint': 8, 'rvaFirstThunk': 493928,
# 'rvaOriginalFirstThunk': 649488, 'rvaNameModule': 654378, 'rvaNameFunction': 654244},
# ...
# ]
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 💖