Skip to content

API_Python_Process

Ulf Frisk edited this page Nov 21, 2024 · 14 revisions

Overview:

The MemProcFS process and module API for Python consists of two primary objects:

Process objects are most commonly retrieved from the base Vmm object.

Module objects are most commonly retrieved from VmmProcess objects.

VmmProcess:

Represents a process.

Example:

Sources:

  • 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.

Attributes:

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

Methods:

# 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}
#    ...]

VmmModule:

Represents a loaded module, such as a .dll, .sys or .exe file.

Example:

Sources:

  • process.module() - as single module.
  • process.module_list() - as list of all modules within the parent process.

Attributes:

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.

Methods:

# 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},
#    ...
#   ]
Clone this wiki locally