Skip to main content
Glama
Evan7198

PCILeech MCP Server

by Evan7198
vmmdll.h126 kB
// vmmdll.h : header file to include in projects that use vmm.dll / vmm.so // // Please also consult the guide at: https://github.com/ufrisk/MemProcFS/wiki // // U/W functions // ============= // Windows may access both UTF-8 *U and Wide-Char *W versions of functions // while Linux may only access UTF-8 versions. Some functionality may also // be degraded or unavailable on Linux. // // (c) Ulf Frisk, 2018-2025 // Author: Ulf Frisk, pcileech@frizk.net // // Header Version: 5.15 // #include "leechcore.h" #ifndef __VMMDLL_H__ #define __VMMDLL_H__ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifdef _WIN32 #include <Windows.h> #undef EXPORTED_FUNCTION #define EXPORTED_FUNCTION typedef unsigned __int64 QWORD, *PQWORD; #endif /* _WIN32 */ #if defined(LINUX) || defined(MACOS) #include <inttypes.h> #include <stdarg.h> #include <stdlib.h> #undef EXPORTED_FUNCTION #define EXPORTED_FUNCTION __attribute__((visibility("default"))) typedef void VOID, *PVOID, *HANDLE, **PHANDLE, *HMODULE; typedef long long unsigned int QWORD, *PQWORD, ULONG64, *PULONG64; typedef size_t SIZE_T, *PSIZE_T; typedef uint64_t FILETIME, *PFILETIME; typedef uint32_t DWORD, *PDWORD, *LPDWORD, BOOL, *PBOOL, NTSTATUS; typedef uint16_t WORD, *PWORD; typedef uint8_t BYTE, *PBYTE, *LPBYTE, UCHAR; typedef char CHAR, *PCHAR, *LPSTR; typedef const char *LPCSTR; typedef uint16_t WCHAR, *PWCHAR, *LPWSTR; typedef const uint16_t *LPCWSTR; #define MAX_PATH 260 #define _In_ #define _In_z_ #define _In_opt_ #define _In_reads_(x) #define _In_reads_bytes_(x) #define _In_reads_opt_(x) #define _Inout_ #define _Inout_bytecount_(x) #define _Inout_opt_ #define _Inout_updates_opt_(x) #define _Out_ #define _Out_opt_ #define _Out_writes_(x) #define _Out_writes_bytes_opt_(x) #define _Out_writes_opt_(x) #define _Out_writes_to_(x,y) #define _When_(x,y) #define _Frees_ptr_opt_ #define _Post_ptr_invalid_ #define _Check_return_opt_ #define _Printf_format_string_ #define _Success_(x) #endif /* LINUX || MACOS */ typedef struct tdVMM_HANDLE *VMM_HANDLE; typedef struct tdVMMVM_HANDLE *VMMVM_HANDLE; typedef BYTE OPAQUE_OB_HEADER[0x40]; //----------------------------------------------------------------------------- // INITIALIZATION FUNCTIONALITY BELOW: // Choose one way of initializing the VMM / MemProcFS. //----------------------------------------------------------------------------- /* * Initialize VMM.DLL with command line parameters. For a more detailed info * about the parameters please see github wiki for MemProcFS and LeechCore. * NB! LeechCore initialization parameters are _also_ valid to this function. * Important parameters are: * -printf = show printf style outputs. * -v -vv -vvv = extra verbosity levels. * -device = device as on format for LeechCore - please see leechcore.h or * Github documentation for additional information. Some values * are: <file>, fpga, usb3380, hvsavedstate, totalmeltdown, pmem * -remote = remote LeechCore instance - please see leechcore.h or Github * documentation for additional information. * -norefresh = disable background refreshes (even if backing memory is * volatile memory). * -memmap = specify a physical memory map given by file or specify 'auto'. * example: -memmap c:\\temp\\my_custom_memory_map.txt * example: -memmap auto * -pagefile[0-9] = page file(s) to use in addition to physical memory. * Normally pagefile.sys have index 0 and swapfile.sys index 1. * Page files are in constant flux - do not use if time diff * between memory dump and page files are more than few minutes. * Example: 'pagefile0 swapfile.sys' * -disable-python = prevent the python plugin sub-system from loading. * -disable-symbolserver = disable symbol server until user change. * This parameter will take precedence over registry settings. * -disable-symbols = disable symbol lookups from .pdb files. * -disable-infodb = disable the infodb and any symbol lookups via it. * -waitinitialize = Wait for initialization to complete before returning. * Normal use is that some initialization is done asynchronously * and may not be completed when initialization call is completed. * This includes virtual memory compression, registry and more. * Example: '-waitinitialize' * -userinteract = allow vmm.dll to, on the console, query the user for * information such as, but not limited to, leechcore device options. * Default: user interaction = disabled. * -vm = virtual machine (VM) parsing. * -vm-basic = virtual machine (VM) parsing (physical memory only). * -vm-nested = virtual machine (VM) parsing (including nested VMs). * -forensic-yara-rules = perfom a forensic yara scan with specified rules. * Full path to source or compiled yara rules should be specified. * Example: -forensic-yara-rules "C:\Temp\my_yara_rules.yar" * -forensic = start a forensic scan of the physical memory immediately after * startup if possible. Allowed parameter values range from 0-4. * Note! forensic mode is not available for live memory. * 1 = forensic mode with in-memory sqlite database. * 2 = forensic mode with temp sqlite database deleted upon exit. * 3 = forensic mode with temp sqlite database remaining upon exit. * 4 = forensic mode with static named sqlite database (vmm.sqlite3). * Example -forensic 4 * * -- argc * -- argv * -- ppLcErrorInfo = optional pointer to receive a function allocated memory of * struct LC_CONFIG_ERRORINFO with extended error information upon * failure. Any memory received should be free'd by caller by * calling LcMemFree(). * -- return = VMM_HANDLE on success for usage in subsequent API calls. NULL=fail. */ EXPORTED_FUNCTION _Success_(return != NULL) VMM_HANDLE VMMDLL_Initialize(_In_ DWORD argc, _In_ LPCSTR argv[]); EXPORTED_FUNCTION _Success_(return != NULL) VMM_HANDLE VMMDLL_InitializeEx(_In_ DWORD argc, _In_ LPCSTR argv[], _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcErrorInfo); /* * Close an instantiated version of VMM_HANDLE and free up any resources. * -- hVMM */ EXPORTED_FUNCTION VOID VMMDLL_Close(_In_opt_ _Post_ptr_invalid_ VMM_HANDLE hVMM); /* * Close all instantiated versions of VMM_HANDLE and free up all resources. */ EXPORTED_FUNCTION VOID VMMDLL_CloseAll(); /* * Query the size of memory allocated by the VMMDLL. * -- pvMem * -- return = number of bytes required to hold memory allocation. */ EXPORTED_FUNCTION _Success_(return != 0) SIZE_T VMMDLL_MemSize(_In_ PVOID pvMem); /* * Free memory allocated by the VMMDLL. * -- pvMem */ EXPORTED_FUNCTION VOID VMMDLL_MemFree(_Frees_ptr_opt_ PVOID pvMem); //----------------------------------------------------------------------------- // CONFIGURATION SETTINGS BELOW: // Configure MemProcFS or the underlying memory // acquisition devices. //----------------------------------------------------------------------------- /* * Options used together with the functions: VMMDLL_ConfigGet & VMMDLL_ConfigSet * Options are defined with either: VMMDLL_OPT_* in this header file or as * LC_OPT_* in leechcore.h * For more detailed information check the sources for individual device types. */ #define VMMDLL_OPT_CORE_PRINTF_ENABLE 0x4000000100000000 // RW #define VMMDLL_OPT_CORE_VERBOSE 0x4000000200000000 // RW #define VMMDLL_OPT_CORE_VERBOSE_EXTRA 0x4000000300000000 // RW #define VMMDLL_OPT_CORE_VERBOSE_EXTRA_TLP 0x4000000400000000 // RW #define VMMDLL_OPT_CORE_MAX_NATIVE_ADDRESS 0x4000000800000000 // R #define VMMDLL_OPT_CORE_LEECHCORE_HANDLE 0x4000001000000000 // R - underlying leechcore handle (do not close). #define VMMDLL_OPT_CORE_VMM_ID 0x4000002000000000 // R - use with startup option '-create-from-vmmid' to create a thread-safe duplicate VMM instance. #define VMMDLL_OPT_CORE_SYSTEM 0x2000000100000000 // R #define VMMDLL_OPT_CORE_MEMORYMODEL 0x2000000200000000 // R #define VMMDLL_OPT_CONFIG_IS_REFRESH_ENABLED 0x2000000300000000 // R - 1/0 #define VMMDLL_OPT_CONFIG_TICK_PERIOD 0x2000000400000000 // RW - base tick period in ms #define VMMDLL_OPT_CONFIG_READCACHE_TICKS 0x2000000500000000 // RW - memory cache validity period (in ticks) #define VMMDLL_OPT_CONFIG_TLBCACHE_TICKS 0x2000000600000000 // RW - page table (tlb) cache validity period (in ticks) #define VMMDLL_OPT_CONFIG_PROCCACHE_TICKS_PARTIAL 0x2000000700000000 // RW - process refresh (partial) period (in ticks) #define VMMDLL_OPT_CONFIG_PROCCACHE_TICKS_TOTAL 0x2000000800000000 // RW - process refresh (full) period (in ticks) #define VMMDLL_OPT_CONFIG_VMM_VERSION_MAJOR 0x2000000900000000 // R #define VMMDLL_OPT_CONFIG_VMM_VERSION_MINOR 0x2000000A00000000 // R #define VMMDLL_OPT_CONFIG_VMM_VERSION_REVISION 0x2000000B00000000 // R #define VMMDLL_OPT_CONFIG_STATISTICS_FUNCTIONCALL 0x2000000C00000000 // RW - enable function call statistics (.status/statistics_fncall file) #define VMMDLL_OPT_CONFIG_IS_PAGING_ENABLED 0x2000000D00000000 // RW - 1/0 #define VMMDLL_OPT_CONFIG_DEBUG 0x2000000E00000000 // W #define VMMDLL_OPT_CONFIG_YARA_RULES 0x2000000F00000000 // R #define VMMDLL_OPT_WIN_VERSION_MAJOR 0x2000010100000000 // R #define VMMDLL_OPT_WIN_VERSION_MINOR 0x2000010200000000 // R #define VMMDLL_OPT_WIN_VERSION_BUILD 0x2000010300000000 // R #define VMMDLL_OPT_WIN_SYSTEM_UNIQUE_ID 0x2000010400000000 // R #define VMMDLL_OPT_FORENSIC_MODE 0x2000020100000000 // RW - enable/retrieve forensic mode type [0-4]. // REFRESH OPTIONS: #define VMMDLL_OPT_REFRESH_ALL 0x2001ffff00000000 // W - refresh all caches #define VMMDLL_OPT_REFRESH_FREQ_MEM 0x2001100000000000 // W - refresh memory cache (excl. TLB) [fully] #define VMMDLL_OPT_REFRESH_FREQ_MEM_PARTIAL 0x2001000200000000 // W - refresh memory cache (excl. TLB) [partial 33%/call] #define VMMDLL_OPT_REFRESH_FREQ_TLB 0x2001080000000000 // W - refresh page table (TLB) cache [fully] #define VMMDLL_OPT_REFRESH_FREQ_TLB_PARTIAL 0x2001000400000000 // W - refresh page table (TLB) cache [partial 33%/call] #define VMMDLL_OPT_REFRESH_FREQ_FAST 0x2001040000000000 // W - refresh fast frequency - incl. partial process refresh #define VMMDLL_OPT_REFRESH_FREQ_MEDIUM 0x2001000100000000 // W - refresh medium frequency - incl. full process refresh #define VMMDLL_OPT_REFRESH_FREQ_SLOW 0x2001001000000000 // W - refresh slow frequency. // PROCESS OPTIONS: [LO-DWORD: Process PID] #define VMMDLL_OPT_PROCESS_DTB 0x2002000100000000 // W - force set process directory table base. #define VMMDLL_OPT_PROCESS_DTB_FAST_LOWINTEGRITY 0x2002000200000000 // W - force set process directory table base (fast, low integrity mode, with less checks) - use at own risk!. static LPCSTR VMMDLL_MEMORYMODEL_TOSTRING[5] = { "N/A", "X86", "X86PAE", "X64", "ARM64" }; typedef enum tdVMMDLL_MEMORYMODEL_TP { VMMDLL_MEMORYMODEL_NA = 0, VMMDLL_MEMORYMODEL_X86 = 1, VMMDLL_MEMORYMODEL_X86PAE = 2, VMMDLL_MEMORYMODEL_X64 = 3, VMMDLL_MEMORYMODEL_ARM64 = 4, } VMMDLL_MEMORYMODEL_TP; typedef enum tdVMMDLL_SYSTEM_TP { VMMDLL_SYSTEM_UNKNOWN_PHYSICAL = 0, VMMDLL_SYSTEM_UNKNOWN_64 = 1, VMMDLL_SYSTEM_WINDOWS_64 = 2, VMMDLL_SYSTEM_UNKNOWN_32 = 3, VMMDLL_SYSTEM_WINDOWS_32 = 4, VMMDLL_SYSTEM_UNKNOWN_X64 = 1, // deprecated - do not use! VMMDLL_SYSTEM_WINDOWS_X64 = 2, // deprecated - do not use! VMMDLL_SYSTEM_UNKNOWN_X86 = 3, // deprecated - do not use! VMMDLL_SYSTEM_WINDOWS_X86 = 4 // deprecated - do not use! } VMMDLL_SYSTEM_TP; /* * Get a device specific option value. Please see defines VMMDLL_OPT_* for infor- * mation about valid option values. Please note that option values may overlap * between different device types with different meanings. * -- hVMM * -- fOption * -- pqwValue = pointer to ULONG64 to receive option value. * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_ConfigGet(_In_ VMM_HANDLE hVMM, _In_ ULONG64 fOption, _Out_ PULONG64 pqwValue); /* * Set a device specific option value. Please see defines VMMDLL_OPT_* for infor- * mation about valid option values. Please note that option values may overlap * between different device types with different meanings. * -- hVMM * -- fOption * -- qwValue * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_ConfigSet(_In_ VMM_HANDLE hVMM, _In_ ULONG64 fOption, _In_ ULONG64 qwValue); //----------------------------------------------------------------------------- // FORWARD DECLARATIONS: //----------------------------------------------------------------------------- typedef struct tdVMMDLL_MAP_PFN *PVMMDLL_MAP_PFN; //----------------------------------------------------------------------------- // LINUX SPECIFIC DEFINES: //----------------------------------------------------------------------------- #if defined(LINUX) || defined(MACOS) #define IMAGE_SIZEOF_SHORT_NAME 8 typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; DWORD Size; } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; typedef struct _SERVICE_STATUS { DWORD dwServiceType; DWORD dwCurrentState; DWORD dwControlsAccepted; DWORD dwWin32ExitCode; DWORD dwServiceSpecificExitCode; DWORD dwCheckPoint; DWORD dwWaitHint; } SERVICE_STATUS, *LPSERVICE_STATUS; #endif /* LINUX || MACOS */ //----------------------------------------------------------------------------- // VFS - VIRTUAL FILE SYSTEM FUNCTIONALITY BELOW: // NB! VFS FUNCTIONALITY REQUIRES PLUGINS TO BE INITIALIZED // WITH CALL TO VMMDLL_InitializePlugins(). // This is the core of MemProcFS. All implementation and analysis towards // the virtual file system (vfs) is possible by using functionality below. //----------------------------------------------------------------------------- #define VMMDLL_STATUS_SUCCESS ((NTSTATUS)0x00000000L) #define VMMDLL_STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) #define VMMDLL_STATUS_END_OF_FILE ((NTSTATUS)0xC0000011L) #define VMMDLL_STATUS_FILE_INVALID ((NTSTATUS)0xC0000098L) #define VMMDLL_STATUS_FILE_SYSTEM_LIMITATION ((NTSTATUS)0xC0000427L) #define VMMDLL_VFS_FILELIST_EXINFO_VERSION 1 #define VMMDLL_VFS_FILELIST_VERSION 2 #define VMMDLL_VFS_FILELISTBLOB_VERSION 0xf88f0001 typedef struct tdVMMDLL_VFS_FILELIST_EXINFO { DWORD dwVersion; BOOL fCompressed; // set flag FILE_ATTRIBUTE_COMPRESSED - (no meaning but shows gui artifact in explorer.exe) union { FILETIME ftCreationTime; // 0 = default time QWORD qwCreationTime; }; union { FILETIME ftLastAccessTime; // 0 = default time QWORD qwLastAccessTime; }; union { FILETIME ftLastWriteTime; // 0 = default time QWORD qwLastWriteTime; }; } VMMDLL_VFS_FILELIST_EXINFO, *PVMMDLL_VFS_FILELIST_EXINFO; typedef struct tdVMMDLL_VFS_FILELIST2 { DWORD dwVersion; VOID(*pfnAddFile) (_Inout_ HANDLE h, _In_ LPCSTR uszName, _In_ ULONG64 cb, _In_opt_ PVMMDLL_VFS_FILELIST_EXINFO pExInfo); VOID(*pfnAddDirectory)(_Inout_ HANDLE h, _In_ LPCSTR uszName, _In_opt_ PVMMDLL_VFS_FILELIST_EXINFO pExInfo); HANDLE h; } VMMDLL_VFS_FILELIST2, *PVMMDLL_VFS_FILELIST2; typedef struct tdVMMDLL_VFS_FILELISTBLOB_ENTRY { ULONG64 ouszName; // byte offset to string from VMMDLL_VFS_FILELISTBLOB.uszMultiText ULONG64 cbFileSize; // -1 == directory VMMDLL_VFS_FILELIST_EXINFO ExInfo; // optional ExInfo } VMMDLL_VFS_FILELISTBLOB_ENTRY, *PVMMDLL_VFS_FILELISTBLOB_ENTRY; typedef struct tdVMMDLL_VFS_FILELISTBLOB { DWORD dwVersion; // VMMDLL_VFS_FILELISTBLOB_VERSION DWORD cbStruct; DWORD cFileEntry; DWORD cbMultiText; union { LPSTR uszMultiText; QWORD _Reserved; }; DWORD _FutureUse[8]; VMMDLL_VFS_FILELISTBLOB_ENTRY FileEntry[0]; } VMMDLL_VFS_FILELISTBLOB, *PVMMDLL_VFS_FILELISTBLOB; /* * Helper functions for callbacks into the VMM_VFS_FILELIST2 structure. */ EXPORTED_FUNCTION VOID VMMDLL_VfsList_AddFile(_In_ HANDLE pFileList, _In_ LPCSTR uszName, _In_ ULONG64 cb, _In_opt_ PVMMDLL_VFS_FILELIST_EXINFO pExInfo); VOID VMMDLL_VfsList_AddFileW(_In_ HANDLE pFileList, _In_ LPCWSTR wszName, _In_ ULONG64 cb, _In_opt_ PVMMDLL_VFS_FILELIST_EXINFO pExInfo); EXPORTED_FUNCTION VOID VMMDLL_VfsList_AddDirectory(_In_ HANDLE pFileList, _In_ LPCSTR uszName, _In_opt_ PVMMDLL_VFS_FILELIST_EXINFO pExInfo); VOID VMMDLL_VfsList_AddDirectoryW(_In_ HANDLE pFileList, _In_ LPCWSTR wszName, _In_opt_ PVMMDLL_VFS_FILELIST_EXINFO pExInfo); EXPORTED_FUNCTION BOOL VMMDLL_VfsList_IsHandleValid(_In_ HANDLE pFileList); /* * List a directory of files in MemProcFS. Directories and files will be listed * by callbacks into functions supplied in the pFileList parameter. * If information of an individual file is needed it's neccessary to list all * files in its directory. * -- hVMM * -- [uw]szPath * -- pFileList * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_VfsListU(_In_ VMM_HANDLE hVMM, _In_ LPCSTR uszPath, _Inout_ PVMMDLL_VFS_FILELIST2 pFileList); _Success_(return) BOOL VMMDLL_VfsListW(_In_ VMM_HANDLE hVMM, _In_ LPCWSTR wszPath, _Inout_ PVMMDLL_VFS_FILELIST2 pFileList); /* * List a directory of files in MemProcFS and return a VMMDLL_VFS_FILELISTBLOB. * CALLER FREE: VMMDLL_MemFree(return) * -- hVMM * -- uszPath * -- return */ EXPORTED_FUNCTION _Success_(return != NULL) PVMMDLL_VFS_FILELISTBLOB VMMDLL_VfsListBlobU(_In_ VMM_HANDLE hVMM, _In_ LPCSTR uszPath); /* * Read select parts of a file in MemProcFS. * -- hVMM * -- [uw]szFileName * -- pb * -- cb * -- pcbRead * -- cbOffset * -- return * */ EXPORTED_FUNCTION NTSTATUS VMMDLL_VfsReadU(_In_ VMM_HANDLE hVMM, _In_ LPCSTR uszFileName, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset); NTSTATUS VMMDLL_VfsReadW(_In_ VMM_HANDLE hVMM, _In_ LPCWSTR wszFileName, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset); /* * Write select parts to a file in MemProcFS. * -- hVMM * -- [uw]szFileName * -- pb * -- cb * -- pcbWrite * -- cbOffset * -- return */ EXPORTED_FUNCTION NTSTATUS VMMDLL_VfsWriteU(_In_ VMM_HANDLE hVMM, _In_ LPCSTR uszFileName, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbWrite, _In_ ULONG64 cbOffset); NTSTATUS VMMDLL_VfsWriteW(_In_ VMM_HANDLE hVMM, _In_ LPCWSTR wszFileName, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbWrite, _In_ ULONG64 cbOffset); /* * Utility functions for MemProcFS read/write towards different underlying data * representations. */ EXPORTED_FUNCTION NTSTATUS VMMDLL_UtilVfsReadFile_FromPBYTE(_In_ PBYTE pbFile, _In_ ULONG64 cbFile, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset); EXPORTED_FUNCTION NTSTATUS VMMDLL_UtilVfsReadFile_FromQWORD(_In_ ULONG64 qwValue, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset, _In_ BOOL fPrefix); EXPORTED_FUNCTION NTSTATUS VMMDLL_UtilVfsReadFile_FromDWORD(_In_ DWORD dwValue, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset, _In_ BOOL fPrefix); EXPORTED_FUNCTION NTSTATUS VMMDLL_UtilVfsReadFile_FromBOOL(_In_ BOOL fValue, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset); EXPORTED_FUNCTION NTSTATUS VMMDLL_UtilVfsWriteFile_BOOL(_Inout_ PBOOL pfTarget, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbWrite, _In_ ULONG64 cbOffset); EXPORTED_FUNCTION NTSTATUS VMMDLL_UtilVfsWriteFile_DWORD(_Inout_ PDWORD pdwTarget, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbWrite, _In_ ULONG64 cbOffset, _In_ DWORD dwMinAllow); //----------------------------------------------------------------------------- // PLUGIN MANAGER FUNCTIONALITY BELOW: // Function and structures to initialize and use MemProcFS plugin functionality. // The plugin manager is started by a call to function: // VMM_VfsInitializePlugins. Each built-in plugin and external plugin of which // the DLL name matches m_*.dll will receive a call to its InitializeVmmPlugin // function. The plugin/module may decide to call pfnPluginManager_Register to // register plugins in the form of different names one or more times. // Example of registration function in a plugin DLL below: // 'VOID InitializeVmmPlugin(_In_ VMM_HANDLE H, _In_ PVMM_PLUGIN_REGINFO pRegInfo)' //----------------------------------------------------------------------------- /* * Initialize all potential plugins, both built-in and external, that maps into * MemProcFS. Please note that plugins are not loaded by default - they have to * be explicitly loaded by calling this function. They will be unloaded on a * general close of the vmm dll. * -- hVMM * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_InitializePlugins(_In_ VMM_HANDLE hVMM); #define VMMDLL_PLUGIN_CONTEXT_MAGIC 0xc0ffee663df9301c #define VMMDLL_PLUGIN_CONTEXT_VERSION 5 #define VMMDLL_PLUGIN_REGINFO_MAGIC 0xc0ffee663df9301d #define VMMDLL_PLUGIN_REGINFO_VERSION 18 #define VMMDLL_FORENSIC_JSONDATA_VERSION 0xc0ee0002 #define VMMDLL_FORENSIC_INGEST_VIRTMEM_VERSION 0xc0dd0001 #define VMMDLL_FORENSIC_INGEST_OBJECT_VERSION 0xc0de0001 #define VMMDLL_PLUGIN_NOTIFY_VERBOSITYCHANGE 0x01 #define VMMDLL_PLUGIN_NOTIFY_REFRESH_FAST 0x05 // refresh fast event - at partial process refresh. #define VMMDLL_PLUGIN_NOTIFY_REFRESH_MEDIUM 0x02 // refresh medium event - at full process refresh. #define VMMDLL_PLUGIN_NOTIFY_REFRESH_SLOW 0x04 // refresh slow event - at registry refresh. #define VMMDLL_PLUGIN_NOTIFY_FORENSIC_INIT 0x01000100 #define VMMDLL_PLUGIN_NOTIFY_FORENSIC_INIT_COMPLETE 0x01000200 #define VMMDLL_PLUGIN_NOTIFY_VM_ATTACH_DETACH 0x01000400 typedef DWORD VMMDLL_MODULE_ID; typedef HANDLE *PVMMDLL_PLUGIN_INTERNAL_CONTEXT; typedef struct tdVMMDLL_CSV_HANDLE *VMMDLL_CSV_HANDLE; #define VMMDLL_MID_MAIN ((VMMDLL_MODULE_ID)0x80000001) #define VMMDLL_MID_PYTHON ((VMMDLL_MODULE_ID)0x80000002) #define VMMDLL_MID_DEBUG ((VMMDLL_MODULE_ID)0x80000003) #define VMMDLL_MID_RUST ((VMMDLL_MODULE_ID)0x80000004) typedef struct tdVMMDLL_PLUGIN_CONTEXT { ULONG64 magic; WORD wVersion; WORD wSize; DWORD dwPID; PVOID pProcess; LPSTR uszModule; LPSTR uszPath; PVOID pvReserved1; PVMMDLL_PLUGIN_INTERNAL_CONTEXT ctxM; // optional internal module context. VMMDLL_MODULE_ID MID; } VMMDLL_PLUGIN_CONTEXT, *PVMMDLL_PLUGIN_CONTEXT; typedef struct tdVMMDLL_FORENSIC_JSONDATA { DWORD dwVersion; // must equal VMMDLL_FORENSIC_JSONDATA_VERSION DWORD _FutureUse; LPSTR szjType; // log type/name (json encoded) DWORD i; DWORD dwPID; QWORD vaObj; BOOL fva[2]; // log va even if zero QWORD va[2]; BOOL fNum[2]; // log num even if zero QWORD qwNum[2]; BOOL fHex[2]; // log hex even if zero QWORD qwHex[2]; // str: will be prioritized in order: szu > wsz. LPCSTR usz[2]; // str: utf-8 encoded LPCWSTR wsz[2]; // str: wide BYTE _Reserved[0x4000+256]; } VMMDLL_FORENSIC_JSONDATA, *PVMMDLL_FORENSIC_JSONDATA; typedef enum tdVMMDLL_FORENSIC_INGEST_OBJECT_TYPE { VMMDLL_FORENSIC_INGEST_OBJECT_TYPE_FILE = 1, } VMMDLL_FORENSIC_INGEST_OBJECT_TYPE; typedef struct tdVMMDLL_FORENSIC_INGEST_OBJECT { OPAQUE_OB_HEADER _Reserved; DWORD dwVersion; // must equal VMMDLL_FORENSIC_INGEST_OBJECT_VERSION VMMDLL_FORENSIC_INGEST_OBJECT_TYPE tp; QWORD vaObject; LPSTR uszText; PBYTE pb; DWORD cb; DWORD cbReadActual; // actual bytes read (may be spread out in pb) } VMMDLL_FORENSIC_INGEST_OBJECT, *PVMMDLL_FORENSIC_INGEST_OBJECT; typedef struct tdVMMDLL_FORENSIC_INGEST_PHYSMEM { BOOL fValid; QWORD pa; DWORD cb; PBYTE pb; DWORD cMEMs; PPMEM_SCATTER ppMEMs; PVMMDLL_MAP_PFN pPfnMap; } VMMDLL_FORENSIC_INGEST_PHYSMEM, *PVMMDLL_FORENSIC_INGEST_PHYSMEM; typedef struct tdVMMDLL_FORENSIC_INGEST_VIRTMEM { OPAQUE_OB_HEADER _Reserved; DWORD dwVersion; // must equal VMMDLL_FORENSIC_INGEST_VIRTMEM_VERSION BOOL fPte; BOOL fVad; PVOID pvProcess; DWORD dwPID; QWORD va; PBYTE pb; DWORD cb; DWORD cbReadActual; // actual bytes read (may be spread out in pb) } VMMDLL_FORENSIC_INGEST_VIRTMEM, *PVMMDLL_FORENSIC_INGEST_VIRTMEM; typedef struct tdVMMDLL_PLUGIN_REGINFO { ULONG64 magic; // VMMDLL_PLUGIN_REGINFO_MAGIC WORD wVersion; // VMMDLL_PLUGIN_REGINFO_VERSION WORD wSize; // size of struct VMMDLL_MEMORYMODEL_TP tpMemoryModel; VMMDLL_SYSTEM_TP tpSystem; HMODULE hDLL; BOOL(*pfnPluginManager_Register)(_In_ VMM_HANDLE H, struct tdVMMDLL_PLUGIN_REGINFO *pPluginRegInfo); LPSTR uszPathVmmDLL; DWORD _Reserved[30]; // python plugin information - not for general use struct { BOOL fPythonStandalone; DWORD _Reserved; HMODULE hReservedDllPython3; HMODULE hReservedDllPython3X; } python; // general plugin registration info to be filled out by the plugin below: struct { PVMMDLL_PLUGIN_INTERNAL_CONTEXT ctxM; // optional internal module context [must be cleaned by pfnClose() call]. CHAR uszPathName[128]; BOOL fRootModule; BOOL fProcessModule; BOOL fRootModuleHidden; BOOL fProcessModuleHidden; CHAR sTimelineNameShort[6]; CHAR _Reserved[2]; CHAR uszTimelineFile[32]; CHAR _Reserved2[32]; } reg_info; // function plugin registration info to be filled out by the plugin below: struct { BOOL(*pfnList)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _Inout_ PHANDLE pFileList); NTSTATUS(*pfnRead)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset); NTSTATUS(*pfnWrite)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbWrite, _In_ ULONG64 cbOffset); VOID(*pfnNotify)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _In_ DWORD fEvent, _In_opt_ PVOID pvEvent, _In_opt_ DWORD cbEvent); VOID(*pfnClose)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP); BOOL(*pfnVisibleModule)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP); PVOID pvReserved[10]; } reg_fn; // Optional forensic plugin functionality for forensic (more comprehensive) // analysis of various data. Functions are optional. // Functions are called in the below order and way. // 1: pfnInitialize() - multi-threaded (between plugins). // 2: (multiple types see below) - multi-threaded (between plugins). // pfnLogCSV() // pfnLogJSON() // pfnFindEvil() // pfnIngestPhysmem() // pfnIngestVirtmem() // 3. pfnIngestFinalize() - single-threaded. (pfnLogCSV/pfnLogJSON/pfnFindEvil may still be active). // 4. pfnTimeline() - single-threaded. (pfnLogCSV/pfnLogJSON/pfnFindEvil may still be active). // 5. pfnFinalize() - single-threaded. struct { PVOID(*pfnInitialize)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP); VOID(*pfnFinalize)(_In_ VMM_HANDLE H, _In_opt_ PVOID ctxfc); VOID(*pfnTimeline)( _In_ VMM_HANDLE H, _In_opt_ PVOID ctxfc, _In_ HANDLE hTimeline, _In_ VOID(*pfnAddEntry)(_In_ VMM_HANDLE H, _In_ HANDLE hTimeline, _In_ QWORD ft, _In_ DWORD dwAction, _In_ DWORD dwPID, _In_ DWORD dwData32, _In_ QWORD qwData64, _In_ LPCSTR uszText), _In_ VOID(*pfnEntryAddBySql)(_In_ VMM_HANDLE H, _In_ HANDLE hTimeline, _In_ DWORD cEntrySql, _In_ LPCSTR *pszEntrySql)); VOID(*pfnIngestObject)(_In_ VMM_HANDLE H, _In_opt_ PVOID ctxfc, _In_ PVMMDLL_FORENSIC_INGEST_OBJECT pIngestObject); VOID(*pfnIngestPhysmem)(_In_ VMM_HANDLE H, _In_opt_ PVOID ctxfc, _In_ PVMMDLL_FORENSIC_INGEST_PHYSMEM pIngestPhysmem); VOID(*pfnIngestVirtmem)(_In_ VMM_HANDLE H, _In_opt_ PVOID ctxfc, _In_ PVMMDLL_FORENSIC_INGEST_VIRTMEM pIngestVirtmem); VOID(*pfnIngestFinalize)(_In_ VMM_HANDLE H, _In_opt_ PVOID ctxfc); VOID(*pfnFindEvil)(_In_ VMM_HANDLE H, _In_ VMMDLL_MODULE_ID MID, _In_opt_ PVOID ctxfc); PVOID pvReserved[6]; VOID(*pfnLogCSV)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _In_ VMMDLL_CSV_HANDLE hCSV); VOID(*pfnLogJSON)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _In_ VOID(*pfnLogJSON)(_In_ VMM_HANDLE H, _In_ PVMMDLL_FORENSIC_JSONDATA pData)); } reg_fnfc; // Additional system information - read/only by the plugins. struct { BOOL f32; DWORD dwVersionMajor; DWORD dwVersionMinor; DWORD dwVersionBuild; DWORD _Reserved[32]; } sysinfo; } VMMDLL_PLUGIN_REGINFO, *PVMMDLL_PLUGIN_REGINFO; //----------------------------------------------------------------------------- // FORENSIC-MODE SPECIFIC FUNCTIONALITY BELOW: //----------------------------------------------------------------------------- /* * Append text data to a memory-backed forensics file. * All text should be UTF-8 encoded. * -- H * -- uszFileName * -- uszFormat * -- .. * -- return = number of bytes appended (excluding terminating null). */ EXPORTED_FUNCTION _Success_(return != 0) SIZE_T VMMDLL_ForensicFileAppend( _In_ VMM_HANDLE H, _In_ LPCSTR uszFileName, _In_z_ _Printf_format_string_ LPCSTR uszFormat, ... ); //----------------------------------------------------------------------------- // VMM LOG FUNCTIONALITY BELOW: // It's possible for external code (primarily external plugins) to make use of // the MemProcFS logging system. // ---------------------------------------------------------------------------- typedef enum tdVMMDLL_LOGLEVEL { VMMDLL_LOGLEVEL_CRITICAL = 1, // critical stopping error VMMDLL_LOGLEVEL_WARNING = 2, // severe warning error VMMDLL_LOGLEVEL_INFO = 3, // normal/info message VMMDLL_LOGLEVEL_VERBOSE = 4, // verbose message (visible with -v) VMMDLL_LOGLEVEL_DEBUG = 5, // debug message (visible with -vv) VMMDLL_LOGLEVEL_TRACE = 6, // trace message VMMDLL_LOGLEVEL_NONE = 7, // do not use! } VMMDLL_LOGLEVEL; /* * Log a message using the internal MemProcFS vmm logging system. Log messages * will be displayed/suppressed depending on current logging configuration. * -- hVMM * -- MID = module id supplied by plugin context PVMMDLL_PLUGIN_CONTEXT or * id given by VMMDLL_MID_*. * -- dwLogLevel * -- uszFormat * -- ... */ EXPORTED_FUNCTION VOID VMMDLL_Log( _In_ VMM_HANDLE hVMM, _In_opt_ VMMDLL_MODULE_ID MID, _In_ VMMDLL_LOGLEVEL dwLogLevel, _In_z_ _Printf_format_string_ LPCSTR uszFormat, ... ); /* * Log a message using the internal MemProcFS vmm logging system. Log messages * will be displayed/suppressed depending on current logging configuration. * -- hVMM * -- MID = module id supplied by plugin context PVMMDLL_PLUGIN_CONTEXT or * id given by VMMDLL_MID_*. * -- dwLogLevel * -- uszFormat * -- arglist */ EXPORTED_FUNCTION VOID VMMDLL_LogEx( _In_ VMM_HANDLE hVMM, _In_opt_ VMMDLL_MODULE_ID MID, _In_ VMMDLL_LOGLEVEL dwLogLevel, _In_z_ _Printf_format_string_ LPCSTR uszFormat, va_list arglist ); //----------------------------------------------------------------------------- // VMM CORE FUNCTIONALITY BELOW: // Vmm core functaionlity such as read (and write) to both virtual and physical // memory. NB! writing will only work if the target is supported - i.e. not a // memory dump file... // To read physical memory specify dwPID as (DWORD)-1 //----------------------------------------------------------------------------- #define VMMDLL_PID_PROCESS_WITH_KERNELMEMORY 0x80000000 // Combine with dwPID to enable process kernel memory (NB! use with extreme care). // FLAG used to supress the default read cache in calls to VMM_MemReadEx() // which will lead to the read being fetched from the target system always. // Cached page tables (used for translating virtual2physical) are still used. #define VMMDLL_FLAG_NOCACHE 0x0001 // do not use the data cache (force reading from memory acquisition device) #define VMMDLL_FLAG_ZEROPAD_ON_FAIL 0x0002 // zero pad failed physical memory reads and report success if read within range of physical memory. #define VMMDLL_FLAG_FORCECACHE_READ 0x0008 // force use of cache - fail non-cached pages - only valid for reads, invalid with VMM_FLAG_NOCACHE/VMM_FLAG_ZEROPAD_ON_FAIL. #define VMMDLL_FLAG_NOPAGING 0x0010 // do not try to retrieve memory from paged out memory from pagefile/compressed (even if possible) #define VMMDLL_FLAG_NOPAGING_IO 0x0020 // do not try to retrieve memory from paged out memory if read would incur additional I/O (even if possible). #define VMMDLL_FLAG_NOCACHEPUT 0x0100 // do not write back to the data cache upon successful read from memory acquisition device. #define VMMDLL_FLAG_CACHE_RECENT_ONLY 0x0200 // only fetch from the most recent active cache region when reading. #define VMMDLL_FLAG_NO_PREDICTIVE_READ 0x0400 // (deprecated/unused). #define VMMDLL_FLAG_FORCECACHE_READ_DISABLE 0x0800 // disable/override any use of VMMDLL_FLAG_FORCECACHE_READ. only recommended for local files. improves forensic artifact order. #define VMMDLL_FLAG_SCATTER_PREPAREEX_NOMEMZERO 0x1000 // do not zero out the memory buffer when preparing a scatter read. #define VMMDLL_FLAG_NOMEMCALLBACK 0x2000 // do not call user-set memory callback functions when reading memory (even if active). #define VMMDLL_FLAG_SCATTER_FORCE_PAGEREAD 0x4000 // force page-sized reads when using scatter functionality. /* * Read memory in various non-contigious locations specified by the pointers to * the items in the ppMEMs array. Result for each unit of work will be given * individually. No upper limit of number of items to read, but no performance * boost will be given if above hardware limit. Max size of each unit of work is * one 4k page (4096 bytes). Reads must not cross 4k page boundaries. Reads must * start at even DWORDs (4-bytes). * -- hVMM * -- dwPID - PID of target process, (DWORD)-1 to read physical memory. * -- ppMEMs = array of scatter read headers. * -- cpMEMs = count of ppMEMs. * -- flags = optional flags as given by VMMDLL_FLAG_* * -- return = the number of successfully read items. */ EXPORTED_FUNCTION DWORD VMMDLL_MemReadScatter(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Inout_ PPMEM_SCATTER ppMEMs, _In_ DWORD cpMEMs, _In_ DWORD flags); /* * Write memory in various non-contigious locations specified by the pointers to * the items in the ppMEMs array. Result for each unit of work will be given * individually. No upper limit of number of items to write Max size of each * unit of work is one 4k page (4096 bytes). Writes must not cross 4k page boundaries. * -- hVMM * -- dwPID - PID of target process, (DWORD)-1 to write physical memory. * -- ppMEMs = array of scatter read headers. * -- cpMEMs = count of ppMEMs. * -- return = the number of hopefully successfully written items. */ EXPORTED_FUNCTION DWORD VMMDLL_MemWriteScatter(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Inout_ PPMEM_SCATTER ppMEMs, _In_ DWORD cpMEMs); /* * Read a single 4096-byte page of memory. * -- hVMM * -- dwPID - PID of target process, (DWORD)-1 to read physical memory. * -- qwA * -- pbPage * -- return = success/fail (depending if all requested bytes are read or not). */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_MemReadPage(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ ULONG64 qwA, _Inout_bytecount_(4096) PBYTE pbPage); /* * Read a contigious arbitrary amount of memory. * -- hVMM * -- dwPID - PID of target process, (DWORD)-1 to read physical memory. * -- qwA * -- pb * -- cb * -- return = success/fail (depending if all requested bytes are read or not). */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_MemRead(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ ULONG64 qwA, _Out_writes_(cb) PBYTE pb, _In_ DWORD cb); /* * Read a contigious amount of memory and report the number of bytes read in pcbRead. * -- hVMM * -- dwPID - PID of target process, (DWORD)-1 to read physical memory. * -- qwA * -- pb * -- cb * -- pcbRead * -- flags = flags as in VMMDLL_FLAG_* * -- return = success/fail. NB! reads may report as success even if 0 bytes are * read - it's recommended to verify pcbReadOpt parameter. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_MemReadEx(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ ULONG64 qwA, _Out_writes_(cb) PBYTE pb, _In_ DWORD cb, _Out_opt_ PDWORD pcbReadOpt, _In_ ULONG64 flags); /* * Prefetch a number of addresses (specified in the pA array) into the memory * cache. This function is to be used to batch larger known reads into local * cache before making multiple smaller reads - which will then happen from * the cache. Function exists for performance reasons. * -- hVMM * -- dwPID = PID of target process, (DWORD)-1 for physical memory. * -- pPrefetchAddresses = array of addresses to read into cache. * -- cPrefetchAddresses */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_MemPrefetchPages(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_reads_(cPrefetchAddresses) PULONG64 pPrefetchAddresses, _In_ DWORD cPrefetchAddresses); /* * Write a contigious arbitrary amount of memory. Please note some virtual memory * such as pages of executables (such as DLLs) may be shared between different * virtual memory over different processes. As an example a write to kernel32.dll * in one process is likely to affect kernel32 in the whole system - in all * processes. Heaps and Stacks and other memory are usually safe to write to. * Please take care when writing to memory! * -- hVMM * -- dwPID = PID of target process, (DWORD)-1 to read physical memory. * -- qwA * -- pb * -- cb * -- return = TRUE on success, FALSE on partial or zero write. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_MemWrite(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ ULONG64 qwA, _In_reads_(cb) PBYTE pb, _In_ DWORD cb); /* * Translate a virtual address to a physical address by walking the page tables * of the specified process. * -- hVMM * -- dwPID * -- qwVA * -- pqwPA * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_MemVirt2Phys(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ ULONG64 qwVA, _Out_ PULONG64 pqwPA); //----------------------------------------------------------------------------- // SIMPLIFIED EASIER TO USE READ SCATTER MEMORY FUNCTIONALITY BELOW: // The flow is as following: // 1. Call VMMDLL_Scatter_Initialize to initialize handle. // 2. Populate memory ranges with multiple calls to VMMDLL_Scatter_Prepare // and/or VMMDLL_Scatter_PrepareEx functions. The memory buffer given to // VMMDLL_Scatter_PrepareEx will be populated with contents in step (3). // 3. Retrieve the memory by calling VMMDLL_Scatter_Execute function. // 4. If VMMDLL_Scatter_Prepare was used (i.e. not VMMDLL_Scatter_PrepareEx) // then retrieve the memory read in (3). // 5. Clear the handle for reuse by calling VMMDLL_Scatter_Clear alternatively // Close the handle to free resources with VMMDLL_Scatter_CloseHandle. // NB! buffers given to VMMDLL_Scatter_PrepareEx must not be free'd before // handle is closed since it may be used internally. // NB! VMMDLL_Scatter_ExecuteRead may be called at a later point in time to // update (re-read) previously read data. // NB! larger reads (up to 1 GB max) are supported but not recommended. //----------------------------------------------------------------------------- typedef HANDLE VMMDLL_SCATTER_HANDLE; /* * Initialize a scatter handle which is used to call VMMDLL_Scatter_* functions. * CALLER CLOSE: VMMDLL_Scatter_CloseHandle(return) * -- hVMM * -- dwPID - PID of target process, (DWORD)-1 to read physical memory. * -- flags = optional flags as given by VMMDLL_FLAG_* * -- return = handle to be used in VMMDLL_Scatter_* functions. */ EXPORTED_FUNCTION _Success_(return != NULL) VMMDLL_SCATTER_HANDLE VMMDLL_Scatter_Initialize(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ DWORD flags); /* * Prepare (add) a memory range for reading. The memory may after a call to * VMMDLL_Scatter_Execute*() be retrieved with VMMDLL_Scatter_Read(). * -- hS * -- va = start address of the memory range to read. * -- cb = size of memory range to read. * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Scatter_Prepare(_In_ VMMDLL_SCATTER_HANDLE hS, _In_ QWORD va, _In_ DWORD cb); /* * Prepare (add) a memory range for reading. The buffer pb and the read length * *pcbRead will be populated when VMMDLL_Scatter_Execute*() is later called. * NB! the buffer pb must not be deallocated before VMMDLL_Scatter_CloseHandle() * has been called since it's used internally by the scatter functionality! * -- hS * -- va = start address of the memory range to read. * -- cb = size of memory range to read. * -- pb = buffer to populate with read memory when calling VMMDLL_Scatter_ExecuteRead() * -- pcbRead = optional pointer to be populated with number of bytes successfully read. * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Scatter_PrepareEx(_In_ VMMDLL_SCATTER_HANDLE hS, _In_ QWORD va, _In_ DWORD cb, _Out_writes_opt_(cb) PBYTE pb, _Out_opt_ PDWORD pcbRead); /* * Prepare (add) a memory range for writing. * The memory contents to write is processed when calling this function. * Any changes to va/pb/cb after this call will not be reflected in the write. * The memory is later written when calling VMMDLL_Scatter_Execute(). * Writing takes place before reading. * -- hS * -- va = start address of the memory range to write. * -- pb = data to write. * -- cb = size of memory range to write. * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Scatter_PrepareWrite(_In_ VMMDLL_SCATTER_HANDLE hS, _In_ QWORD va, _In_reads_(cb) PBYTE pb, _In_ DWORD cb); /* * Prepare (add) a memory range for writing. * Memory contents to write is processed when calling VMMDLL_Scatter_Execute(). * The buffer pb must be valid when VMMDLL_Scatter_Execute() is called. * The memory is later written when calling VMMDLL_Scatter_Execute(). * Writing takes place before reading. * -- hS * -- va = start address of the memory range to write. * -- pb = data to write. Buffer must be valid when VMMDLL_Scatter_Execute() is called. * -- cb = size of memory range to write. * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Scatter_PrepareWriteEx(_In_ VMMDLL_SCATTER_HANDLE hS, _In_ QWORD va, _In_reads_(cb) PBYTE pb, _In_ DWORD cb); /* * Retrieve and Write memory previously populated. * Write any memory prepared with VMMDLL_Scatter_PrepareWrite function (1st). * Retrieve the memory ranges previously populated with calls to the * VMMDLL_Scatter_Prepare* functions (2nd). * -- hS * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Scatter_Execute(_In_ VMMDLL_SCATTER_HANDLE hS); /* * Retrieve the memory ranges previously populated with calls to the * VMMDLL_Scatter_Prepare* functions. * -- hS * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Scatter_ExecuteRead(_In_ VMMDLL_SCATTER_HANDLE hS); /* * Read out memory in previously populated ranges. This function should only be * called after the memory has been retrieved using VMMDLL_Scatter_ExecuteRead(). * -- hS * -- va * -- cb * -- pb * -- pcbRead * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Scatter_Read(_In_ VMMDLL_SCATTER_HANDLE hS, _In_ QWORD va, _In_ DWORD cb, _Out_writes_opt_(cb) PBYTE pb, _Out_opt_ PDWORD pcbRead); /* * Clear/Reset the handle for use in another subsequent read scatter operation. * -- hS = the scatter handle to clear for reuse. * -- dwPID = optional PID change. * -- flags * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Scatter_Clear(_In_ VMMDLL_SCATTER_HANDLE hS, _In_opt_ DWORD dwPID, _In_ DWORD flags); /* * Close the scatter handle and free the resources it uses. * -- hS = the scatter handle to close. */ EXPORTED_FUNCTION VOID VMMDLL_Scatter_CloseHandle(_In_opt_ _Post_ptr_invalid_ VMMDLL_SCATTER_HANDLE hS); //----------------------------------------------------------------------------- // MEMORY CALLBACK FUNCTIONALITY: // Allows for advanced memory access statistics and the creation of specialized // custom memory views for physical memory or per-process virtual memory. // Callback functions may be registered to modify memory reads and/or writes. //----------------------------------------------------------------------------- typedef enum tdVMMDLL_MEM_CALLBACK_TP { VMMDLL_MEM_CALLBACK_READ_PHYSICAL_PRE = 1, VMMDLL_MEM_CALLBACK_READ_PHYSICAL_POST = 2, VMMDLL_MEM_CALLBACK_WRITE_PHYSICAL_PRE = 3, VMMDLL_MEM_CALLBACK_READ_VIRTUAL_PRE = 4, VMMDLL_MEM_CALLBACK_READ_VIRTUAL_POST = 5, VMMDLL_MEM_CALLBACK_WRITE_VIRTUAL_PRE = 6, } VMMDLL_MEM_CALLBACK_TP; /* * MEM callback function definition. * -- ctxUser = user context pointer. * -- dwPID = PID of target process, (DWORD)-1 for physical memory. * -- cpMEMs = count of pMEMs. * -- ppMEMs = array of pointers to MEM scatter read headers. */ typedef VOID(*VMMDLL_MEM_CALLBACK_PFN)(_In_opt_ PVOID ctxUser, _In_ DWORD dwPID, _In_ DWORD cpMEMs, _In_ PPMEM_SCATTER ppMEMs); /* * Register or unregister am optional memory access callback function. * It's possible to have one callback function registered for each type. * To clear an already registered callback function specify NULL as pfnCB. * -- hVMM * -- tp = type of callback to register / unregister - VMMDLL_MEM_CALLBACK_*. * -- ctxUser = user context pointer to be passed to the callback function. * -- pfnCB = callback function to register / unregister. * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_MemCallback(_In_ VMM_HANDLE hVMM, _In_ VMMDLL_MEM_CALLBACK_TP tp, _In_opt_ PVOID ctxUser, _In_opt_ VMMDLL_MEM_CALLBACK_PFN pfnCB); //----------------------------------------------------------------------------- // VMM PROCESS MAP FUNCTIONALITY BELOW: // Functionality for retrieving process related collections of items such as // page table map (PTE), virtual address descriptor map (VAD), loaded modules, // heaps and threads. //----------------------------------------------------------------------------- #define VMMDLL_MAP_PTE_VERSION 2 #define VMMDLL_MAP_VAD_VERSION 6 #define VMMDLL_MAP_VADEX_VERSION 4 #define VMMDLL_MAP_MODULE_VERSION 6 #define VMMDLL_MAP_UNLOADEDMODULE_VERSION 2 #define VMMDLL_MAP_EAT_VERSION 3 #define VMMDLL_MAP_IAT_VERSION 2 #define VMMDLL_MAP_HEAP_VERSION 4 #define VMMDLL_MAP_HEAPALLOC_VERSION 1 #define VMMDLL_MAP_THREAD_VERSION 4 #define VMMDLL_MAP_THREAD_CALLSTACK_VERSION 1 #define VMMDLL_MAP_HANDLE_VERSION 3 #define VMMDLL_MAP_POOL_VERSION 2 #define VMMDLL_MAP_KOBJECT_VERSION 1 #define VMMDLL_MAP_KDRIVER_VERSION 1 #define VMMDLL_MAP_KDEVICE_VERSION 1 #define VMMDLL_MAP_NET_VERSION 3 #define VMMDLL_MAP_PHYSMEM_VERSION 2 #define VMMDLL_MAP_USER_VERSION 2 #define VMMDLL_MAP_VM_VERSION 2 #define VMMDLL_MAP_SERVICE_VERSION 3 // flags to check for existence in the fPage field of VMMDLL_MAP_PTEENTRY #define VMMDLL_MEMMAP_FLAG_PAGE_W 0x0000000000000002 #define VMMDLL_MEMMAP_FLAG_PAGE_NS 0x0000000000000004 #define VMMDLL_MEMMAP_FLAG_PAGE_NX 0x8000000000000000 #define VMMDLL_MEMMAP_FLAG_PAGE_MASK 0x8000000000000006 #define VMMDLL_POOLMAP_FLAG_ALL 0 #define VMMDLL_POOLMAP_FLAG_BIG 1 #define VMMDLL_MODULE_FLAG_NORMAL 0 #define VMMDLL_MODULE_FLAG_DEBUGINFO 1 #define VMMDLL_MODULE_FLAG_VERSIONINFO 2 typedef enum tdVMMDLL_PTE_TP { VMMDLL_PTE_TP_NA = 0, VMMDLL_PTE_TP_HARDWARE = 1, VMMDLL_PTE_TP_TRANSITION = 2, VMMDLL_PTE_TP_PROTOTYPE = 3, VMMDLL_PTE_TP_DEMANDZERO = 4, VMMDLL_PTE_TP_COMPRESSED = 5, VMMDLL_PTE_TP_PAGEFILE = 6, VMMDLL_PTE_TP_FILE = 7, } VMMDLL_PTE_TP, *PVMMDLL_PTE_TP; typedef struct tdVMMDLL_MAP_PTEENTRY { QWORD vaBase; QWORD cPages; QWORD fPage; BOOL fWoW64; DWORD _FutureUse1; union { LPSTR uszText; LPWSTR wszText; }; // U/W dependant DWORD _Reserved1; DWORD cSoftware; // # software (non active) PTEs in region } VMMDLL_MAP_PTEENTRY, *PVMMDLL_MAP_PTEENTRY; typedef struct tdVMMDLL_MAP_VADENTRY { QWORD vaStart; QWORD vaEnd; QWORD vaVad; // DWORD 0 DWORD VadType : 3; // Pos 0 DWORD Protection : 5; // Pos 3 DWORD fImage : 1; // Pos 8 DWORD fFile : 1; // Pos 9 DWORD fPageFile : 1; // Pos 10 DWORD fPrivateMemory : 1; // Pos 11 DWORD fTeb : 1; // Pos 12 DWORD fStack : 1; // Pos 13 DWORD fSpare : 2; // Pos 14 DWORD HeapNum : 7; // Pos 16 DWORD fHeap : 1; // Pos 23 DWORD cwszDescription : 8; // Pos 24 // DWORD 1 DWORD CommitCharge : 31; // Pos 0 DWORD MemCommit : 1; // Pos 31 DWORD u2; DWORD cbPrototypePte; QWORD vaPrototypePte; QWORD vaSubsection; union { LPSTR uszText; LPWSTR wszText; }; // U/W dependant DWORD _FutureUse1; DWORD _Reserved1; QWORD vaFileObject; // only valid if fFile/fImage _and_ after wszText is initialized DWORD cVadExPages; // number of "valid" VadEx pages in this VAD. DWORD cVadExPagesBase; // number of "valid" VadEx pages in "previous" VADs QWORD _Reserved2; } VMMDLL_MAP_VADENTRY, *PVMMDLL_MAP_VADENTRY; #define VMMDLL_VADEXENTRY_FLAG_HARDWARE 0x01 #define VMMDLL_VADEXENTRY_FLAG_W 0x10 #define VMMDLL_VADEXENTRY_FLAG_K 0x40 #define VMMDLL_VADEXENTRY_FLAG_NX 0x80 typedef struct tdVMMDLL_MAP_VADEXENTRY { VMMDLL_PTE_TP tp; BYTE iPML; BYTE pteFlags; WORD _Reserved2; QWORD va; QWORD pa; QWORD pte; struct { DWORD _Reserved1; VMMDLL_PTE_TP tp; QWORD pa; QWORD pte; } proto; QWORD vaVadBase; } VMMDLL_MAP_VADEXENTRY, *PVMMDLL_MAP_VADEXENTRY; typedef enum tdVMMDLL_MODULE_TP { VMMDLL_MODULE_TP_NORMAL = 0, VMMDLL_MODULE_TP_DATA = 1, VMMDLL_MODULE_TP_NOTLINKED = 2, VMMDLL_MODULE_TP_INJECTED = 3, } VMMDLL_MODULE_TP; typedef struct tdVMMDLL_MAP_MODULEENTRY_DEBUGINFO { DWORD dwAge; DWORD _Reserved; BYTE Guid[16]; union { LPSTR uszGuid; LPWSTR wszGuid; }; union { LPSTR uszPdbFilename; LPWSTR wszPdbFilename; }; } VMMDLL_MAP_MODULEENTRY_DEBUGINFO, *PVMMDLL_MAP_MODULEENTRY_DEBUGINFO; typedef struct tdVMMDLL_MAP_MODULEENTRY_VERSIONINFO { union { LPSTR uszCompanyName; LPWSTR wszCompanyName; }; union { LPSTR uszFileDescription; LPWSTR wszFileDescription; }; union { LPSTR uszFileVersion; LPWSTR wszFileVersion; }; union { LPSTR uszInternalName; LPWSTR wszInternalName; }; union { LPSTR uszLegalCopyright; LPWSTR wszLegalCopyright; }; union { LPSTR uszOriginalFilename; LPWSTR wszFileOriginalFilename; }; union { LPSTR uszProductName; LPWSTR wszProductName; }; union { LPSTR uszProductVersion; LPWSTR wszProductVersion; }; } VMMDLL_MAP_MODULEENTRY_VERSIONINFO, *PVMMDLL_MAP_MODULEENTRY_VERSIONINFO; typedef struct tdVMMDLL_MAP_MODULEENTRY { QWORD vaBase; QWORD vaEntry; DWORD cbImageSize; BOOL fWoW64; union { LPSTR uszText; LPWSTR wszText; }; // U/W dependant DWORD _Reserved3; DWORD _Reserved4; union { LPSTR uszFullName; LPWSTR wszFullName; }; // U/W dependant VMMDLL_MODULE_TP tp; DWORD cbFileSizeRaw; DWORD cSection; DWORD cEAT; DWORD cIAT; DWORD _Reserved2; QWORD _Reserved1[3]; PVMMDLL_MAP_MODULEENTRY_DEBUGINFO pExDebugInfo; // not included by default - use VMMDLL_MODULE_FLAG_DEBUGINFO to include. PVMMDLL_MAP_MODULEENTRY_VERSIONINFO pExVersionInfo; // not included by default - use VMMDLL_MODULE_FLAG_VERSIONINFO to include. } VMMDLL_MAP_MODULEENTRY, *PVMMDLL_MAP_MODULEENTRY; typedef struct tdVMMDLL_MAP_UNLOADEDMODULEENTRY { QWORD vaBase; DWORD cbImageSize; BOOL fWoW64; union { LPSTR uszText; LPWSTR wszText; }; // U/W dependant DWORD _FutureUse1; DWORD dwCheckSum; // user-mode only DWORD dwTimeDateStamp; // user-mode only DWORD _Reserved1; QWORD ftUnload; // kernel-mode only } VMMDLL_MAP_UNLOADEDMODULEENTRY, *PVMMDLL_MAP_UNLOADEDMODULEENTRY; typedef struct tdVMMDLL_MAP_EATENTRY { QWORD vaFunction; DWORD dwOrdinal; DWORD oFunctionsArray; // PIMAGE_EXPORT_DIRECTORY->AddressOfFunctions[oFunctionsArray] DWORD oNamesArray; // PIMAGE_EXPORT_DIRECTORY->AddressOfNames[oNamesArray] DWORD _FutureUse1; union { LPSTR uszFunction; LPWSTR wszFunction; }; // U/W dependant union { LPSTR uszForwardedFunction; LPWSTR wszForwardedFunction; }; // U/W dependant (function or ordinal name if exists). } VMMDLL_MAP_EATENTRY, *PVMMDLL_MAP_EATENTRY; typedef struct tdVMMDLL_MAP_IATENTRY { QWORD vaFunction; union { LPSTR uszFunction; LPWSTR wszFunction; }; // U/W dependant DWORD _FutureUse1; DWORD _FutureUse2; union { LPSTR uszModule; LPWSTR wszModule; }; // U/W dependant struct { BOOL f32; WORD wHint; WORD _Reserved1; DWORD rvaFirstThunk; DWORD rvaOriginalFirstThunk; DWORD rvaNameModule; DWORD rvaNameFunction; } Thunk; } VMMDLL_MAP_IATENTRY, *PVMMDLL_MAP_IATENTRY; typedef enum tdVMMDLL_HEAP_TP { VMMDLL_HEAP_TP_NA = 0, VMMDLL_HEAP_TP_NT = 1, VMMDLL_HEAP_TP_SEG = 2, } VMMDLL_HEAP_TP, *PVMMDLL_HEAP_TP; typedef enum tdVMMDLL_HEAP_SEGMENT_TP { VMMDLL_HEAP_SEGMENT_TP_NA = 0, VMMDLL_HEAP_SEGMENT_TP_NT_SEGMENT = 1, VMMDLL_HEAP_SEGMENT_TP_NT_LFH = 2, VMMDLL_HEAP_SEGMENT_TP_NT_LARGE = 3, VMMDLL_HEAP_SEGMENT_TP_NT_NA = 4, VMMDLL_HEAP_SEGMENT_TP_SEG_HEAP = 5, VMMDLL_HEAP_SEGMENT_TP_SEG_SEGMENT = 6, VMMDLL_HEAP_SEGMENT_TP_SEG_LARGE = 7, VMMDLL_HEAP_SEGMENT_TP_SEG_NA = 8, } VMMDLL_HEAP_SEGMENT_TP, *PVMMDLL_HEAP_SEGMENT_TP; typedef struct tdVMMDLL_MAP_HEAP_SEGMENTENTRY { QWORD va; DWORD cb; VMMDLL_HEAP_SEGMENT_TP tp : 16; DWORD iHeap : 16; } VMMDLL_MAP_HEAP_SEGMENTENTRY, *PVMMDLL_MAP_HEAP_SEGMENTENTRY; typedef struct tdVMMDLL_MAP_HEAPENTRY { QWORD va; VMMDLL_HEAP_TP tp; BOOL f32; DWORD iHeap; DWORD dwHeapNum; } VMMDLL_MAP_HEAPENTRY, *PVMMDLL_MAP_HEAPENTRY; typedef enum tdVMMDLL_HEAPALLOC_TP { VMMDLL_HEAPALLOC_TP_NA = 0, VMMDLL_HEAPALLOC_TP_NT_HEAP = 1, VMMDLL_HEAPALLOC_TP_NT_LFH = 2, VMMDLL_HEAPALLOC_TP_NT_LARGE = 3, VMMDLL_HEAPALLOC_TP_NT_NA = 4, VMMDLL_HEAPALLOC_TP_SEG_VS = 5, VMMDLL_HEAPALLOC_TP_SEG_LFH = 6, VMMDLL_HEAPALLOC_TP_SEG_LARGE = 7, VMMDLL_HEAPALLOC_TP_SEG_NA = 8, } VMMDLL_HEAPALLOC_TP, *PVMMDLL_HEAPALLOC_TP; typedef struct tdVMMDLL_MAP_HEAPALLOCENTRY { QWORD va; DWORD cb; VMMDLL_HEAPALLOC_TP tp; } VMMDLL_MAP_HEAPALLOCENTRY, *PVMMDLL_MAP_HEAPALLOCENTRY; typedef struct tdVMMDLL_MAP_THREADENTRY { DWORD dwTID; DWORD dwPID; DWORD dwExitStatus; UCHAR bState; UCHAR bRunning; UCHAR bPriority; UCHAR bBasePriority; QWORD vaETHREAD; QWORD vaTeb; QWORD ftCreateTime; QWORD ftExitTime; QWORD vaStartAddress; QWORD vaStackBaseUser; // value from _NT_TIB / _TEB QWORD vaStackLimitUser; // value from _NT_TIB / _TEB QWORD vaStackBaseKernel; QWORD vaStackLimitKernel; QWORD vaTrapFrame; QWORD vaRIP; // RIP register (if user mode) QWORD vaRSP; // RSP register (if user mode) QWORD qwAffinity; DWORD dwUserTime; DWORD dwKernelTime; UCHAR bSuspendCount; UCHAR bWaitReason; UCHAR _FutureUse1[2]; DWORD _FutureUse2[11]; QWORD vaImpersonationToken; QWORD vaWin32StartAddress; } VMMDLL_MAP_THREADENTRY, *PVMMDLL_MAP_THREADENTRY; typedef struct tdVMMDLL_MAP_THREAD_CALLSTACKENTRY { DWORD i; BOOL fRegPresent; QWORD vaRetAddr; QWORD vaRSP; QWORD vaBaseSP; DWORD _FutureUse1; DWORD cbDisplacement; union { LPSTR uszModule; LPWSTR wszModule; }; // U/W dependant union { LPSTR uszFunction; LPWSTR wszFunction; }; // U/W dependant } VMMDLL_MAP_THREAD_CALLSTACKENTRY, *PVMMDLL_MAP_THREAD_CALLSTACKENTRY; typedef struct tdVMMDLL_MAP_HANDLEENTRY { QWORD vaObject; DWORD dwHandle; DWORD dwGrantedAccess : 24; DWORD iType : 8; QWORD qwHandleCount; QWORD qwPointerCount; QWORD vaObjectCreateInfo; QWORD vaSecurityDescriptor; union { LPSTR uszText; LPWSTR wszText; }; // U/W dependant DWORD _FutureUse2; DWORD dwPID; DWORD dwPoolTag; DWORD _FutureUse[7]; union { LPSTR uszType; LPWSTR wszType; QWORD _Pad1; }; // U/W dependant } VMMDLL_MAP_HANDLEENTRY, *PVMMDLL_MAP_HANDLEENTRY; typedef enum tdVMMDLL_MAP_POOL_TYPE { VMMDLL_MAP_POOL_TYPE_Unknown = 0, VMMDLL_MAP_POOL_TYPE_NonPagedPool = 1, VMMDLL_MAP_POOL_TYPE_NonPagedPoolNx = 2, VMMDLL_MAP_POOL_TYPE_PagedPool = 3 } VMMDLL_MAP_POOL_TYPE; typedef enum tdVMM_MAP_POOL_TYPE_SUBSEGMENT { VMM_MAP_POOL_TYPE_SUBSEGMENT_UNKNOWN = 0, VMM_MAP_POOL_TYPE_SUBSEGMENT_NA = 1, VMM_MAP_POOL_TYPE_SUBSEGMENT_BIG = 2, VMM_MAP_POOL_TYPE_SUBSEGMENT_LARGE = 3, VMM_MAP_POOL_TYPE_SUBSEGMENT_VS = 4, VMM_MAP_POOL_TYPE_SUBSEGMENT_LFH = 5 } VMM_MAP_POOL_TYPE_SUBSEGMENT; typedef struct tdVMMDLL_MAP_POOLENTRYTAG { union { CHAR szTag[5]; struct { DWORD dwTag; DWORD _Filler; DWORD cEntry; DWORD iTag2Map; }; }; } VMMDLL_MAP_POOLENTRYTAG, *PVMMDLL_MAP_POOLENTRYTAG; typedef struct tdVMMDLL_MAP_POOLENTRY { QWORD va; union { CHAR szTag[5]; struct { DWORD dwTag; BYTE _ReservedZero; BYTE fAlloc; BYTE tpPool; // VMMDLL_MAP_POOL_TYPE BYTE tpSS; // VMMDLL_MAP_POOL_TYPE_SUBSEGMENT }; }; DWORD cb; DWORD _Filler; } VMMDLL_MAP_POOLENTRY, *PVMMDLL_MAP_POOLENTRY; typedef struct tdVMMDLL_MAP_KDEVICEENTRY { QWORD va; // Address of this object in memory. DWORD iDepth; // Depth of the device object. DWORD dwDeviceType; // Device type according to FILE_DEVICE_* union { LPSTR uszDeviceType; LPWSTR wszDeviceType; }; // Device type name. QWORD vaDriverObject; // Address of the driver object. QWORD vaAttachedDevice; // Address of the attached device object (if exists). QWORD vaFileSystemDevice; // Address of the file system device object (if exists). union { LPSTR uszVolumeInfo; LPWSTR wszVolumeInfo; }; // Volume information (if exists) . } VMMDLL_MAP_KDEVICEENTRY, *PVMMDLL_MAP_KDEVICEENTRY; typedef struct tdVMMDLL_MAP_KDRIVERENTRY { QWORD va; // Address of this object in memory. QWORD vaDriverStart; // Address of the loaded driver module in memory. QWORD cbDriverSize; // Size of the loaded driver module in memory. QWORD vaDeviceObject; // Address of the device object. union { LPSTR uszName; LPWSTR wszName; }; // Driver name. union { LPSTR uszPath; LPWSTR wszPath; }; // Driver path. union { LPSTR uszServiceKeyName; LPWSTR wszServiceKeyName; }; // Service key name. QWORD MajorFunction[28]; // Major function array. } VMMDLL_MAP_KDRIVERENTRY, *PVMMDLL_MAP_KDRIVERENTRY; typedef struct tdVMMDLL_MAP_KOBJECTENTRY { QWORD va; // Address of this object in memory. QWORD vaParent; // Address of parent object. DWORD _Filler; DWORD cvaChild; // Number of child object addresses. PQWORD pvaChild; // Array of child object addresses. union { LPSTR uszName; LPWSTR wszName; }; // Object name. union { LPSTR uszType; LPWSTR wszType; }; // Object type } VMMDLL_MAP_KOBJECTENTRY, *PVMMDLL_MAP_KOBJECTENTRY; typedef struct tdVMMDLL_MAP_NETENTRY { DWORD dwPID; DWORD dwState; WORD _FutureUse3[3]; WORD AF; // address family (IPv4/IPv6) struct { BOOL fValid; WORD _Reserved; WORD port; BYTE pbAddr[16]; // ipv4 = 1st 4 bytes, ipv6 = all bytes union { LPSTR uszText; LPWSTR wszText; }; // U/W dependant } Src; struct { BOOL fValid; WORD _Reserved; WORD port; BYTE pbAddr[16]; // ipv4 = 1st 4 bytes, ipv6 = all bytes union { LPSTR uszText; LPWSTR wszText; }; // U/W dependant } Dst; QWORD vaObj; QWORD ftTime; DWORD dwPoolTag; DWORD _FutureUse4; union { LPSTR uszText; LPWSTR wszText; }; // U/W dependant DWORD _FutureUse2[4]; } VMMDLL_MAP_NETENTRY, *PVMMDLL_MAP_NETENTRY; typedef struct tdVMMDLL_MAP_PHYSMEMENTRY { QWORD pa; QWORD cb; } VMMDLL_MAP_PHYSMEMENTRY, *PVMMDLL_MAP_PHYSMEMENTRY; typedef struct tdVMMDLL_MAP_USERENTRY { DWORD _FutureUse1[2]; union { LPSTR uszText; LPWSTR wszText; }; // U/W dependant ULONG64 vaRegHive; union { LPSTR uszSID; LPWSTR wszSID; }; // U/W dependant DWORD _FutureUse2[2]; } VMMDLL_MAP_USERENTRY, *PVMMDLL_MAP_USERENTRY; typedef enum tdVMMDLL_VM_TP { VMMDLL_VM_TP_UNKNOWN = 0, VMMDLL_VM_TP_HV = 1, VMMDLL_VM_TP_HV_WHVP = 2 } VMMDLL_VM_TP; typedef struct tdVMMDLL_MAP_VMENTRY { VMMVM_HANDLE hVM; union { LPSTR uszName; LPWSTR wszName; }; // U/W dependant QWORD gpaMax; VMMDLL_VM_TP tp; BOOL fActive; BOOL fReadOnly; BOOL fPhysicalOnly; DWORD dwPartitionID; DWORD dwVersionBuild; VMMDLL_SYSTEM_TP tpSystem; DWORD dwParentVmmMountID; DWORD dwVmMemPID; } VMMDLL_MAP_VMENTRY, *PVMMDLL_MAP_VMENTRY; typedef struct tdVMMDLL_MAP_SERVICEENTRY { QWORD vaObj; DWORD dwOrdinal; DWORD dwStartType; SERVICE_STATUS ServiceStatus; union { LPSTR uszServiceName; LPWSTR wszServiceName; QWORD _Reserved1; }; // U/W dependant union { LPSTR uszDisplayName; LPWSTR wszDisplayName; QWORD _Reserved2; }; // U/W dependant union { LPSTR uszPath; LPWSTR wszPath; QWORD _Reserved3; }; // U/W dependant union { LPSTR uszUserTp; LPWSTR wszUserTp; QWORD _Reserved4; }; // U/W dependant union { LPSTR uszUserAcct; LPWSTR wszUserAcct; QWORD _Reserved5; }; // U/W dependant union { LPSTR uszImagePath; LPWSTR wszImagePath; QWORD _Reserved6; }; // U/W dependant DWORD dwPID; DWORD _FutureUse1; QWORD _FutureUse2; } VMMDLL_MAP_SERVICEENTRY, *PVMMDLL_MAP_SERVICEENTRY; typedef struct tdVMMDLL_MAP_PTE { DWORD dwVersion; // VMMDLL_MAP_PTE_VERSION DWORD _Reserved1[5]; PBYTE pbMultiText; // NULL or multi-wstr pointed into by VMMDLL_MAP_VADENTRY.wszText DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_PTEENTRY pMap[]; // map entries. } VMMDLL_MAP_PTE, *PVMMDLL_MAP_PTE; typedef struct tdVMMDLL_MAP_VAD { DWORD dwVersion; // VMMDLL_MAP_VAD_VERSION DWORD _Reserved1[4]; DWORD cPage; // # pages in vad map. PBYTE pbMultiText; // NULL or multi-wstr pointed into by VMMDLL_MAP_VADENTRY.wszText DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_VADENTRY pMap[]; // map entries. } VMMDLL_MAP_VAD, *PVMMDLL_MAP_VAD; typedef struct tdVMMDLL_MAP_VADEX { DWORD dwVersion; // VMMDLL_MAP_VADEX_VERSION DWORD _Reserved1[4]; DWORD cMap; // # map entries. VMMDLL_MAP_VADEXENTRY pMap[]; // map entries. } VMMDLL_MAP_VADEX, *PVMMDLL_MAP_VADEX; typedef struct tdVMMDLL_MAP_MODULE { DWORD dwVersion; // VMMDLL_MAP_MODULE_VERSION DWORD _Reserved1[5]; PBYTE pbMultiText; // multi-wstr pointed into by VMMDLL_MAP_MODULEENTRY.wszText DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_MODULEENTRY pMap[]; // map entries. } VMMDLL_MAP_MODULE, *PVMMDLL_MAP_MODULE; typedef struct tdVMMDLL_MAP_UNLOADEDMODULE { DWORD dwVersion; // VMMDLL_MAP_UNLOADEDMODULE_VERSION DWORD _Reserved1[5]; PBYTE pbMultiText; // multi-wstr pointed into by VMMDLL_MAP_MODULEENTRY.wszText DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_UNLOADEDMODULEENTRY pMap[]; // map entries. } VMMDLL_MAP_UNLOADEDMODULE, *PVMMDLL_MAP_UNLOADEDMODULE; typedef struct tdVMMDLL_MAP_EAT { DWORD dwVersion; // VMMDLL_MAP_EAT_VERSION DWORD dwOrdinalBase; DWORD cNumberOfNames; DWORD cNumberOfFunctions; DWORD cNumberOfForwardedFunctions; DWORD _Reserved1[3]; QWORD vaModuleBase; QWORD vaAddressOfFunctions; QWORD vaAddressOfNames; PBYTE pbMultiText; // multi-str pointed into by VMM_MAP_EATENTRY.wszFunction DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_EATENTRY pMap[]; // map entries. } VMMDLL_MAP_EAT, *PVMMDLL_MAP_EAT; typedef struct tdVMMDLL_MAP_IAT { DWORD dwVersion; // VMMDLL_MAP_IAT_VERSION DWORD _Reserved1[5]; QWORD vaModuleBase; PBYTE pbMultiText; // multi-str pointed into by VMM_MAP_EATENTRY.[wszFunction|wszModule] DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_IATENTRY pMap[]; // map entries. } VMMDLL_MAP_IAT, *PVMMDLL_MAP_IAT; typedef struct tdVMMDLL_MAP_HEAP { DWORD dwVersion; // VMMDLL_MAP_HEAP_VERSION DWORD _Reserved1[7]; PVMMDLL_MAP_HEAP_SEGMENTENTRY pSegments; // heap segment entries. DWORD cSegments; // # heap segment entries. DWORD cMap; // # map entries. VMMDLL_MAP_HEAPENTRY pMap[]; // map entries. } VMMDLL_MAP_HEAP, *PVMMDLL_MAP_HEAP; typedef struct tdVMMDLL_MAP_HEAPALLOC { DWORD dwVersion; // VMMDLL_MAP_HEAPALLOC_VERSION DWORD _Reserved1[7]; PVOID _Reserved2[2]; DWORD cMap; // # map entries. VMMDLL_MAP_HEAPALLOCENTRY pMap[]; // map entries. } VMMDLL_MAP_HEAPALLOC, *PVMMDLL_MAP_HEAPALLOC; typedef struct tdVMMDLL_MAP_THREAD { DWORD dwVersion; // VMMDLL_MAP_THREAD_VERSION DWORD _Reserved[8]; DWORD cMap; // # map entries. VMMDLL_MAP_THREADENTRY pMap[]; // map entries. } VMMDLL_MAP_THREAD, *PVMMDLL_MAP_THREAD; typedef struct tdVMMDLL_MAP_THREAD_CALLSTACK { DWORD dwVersion; // VMMDLL_MAP_THREAD_CALLSTACK_VERSION DWORD _Reserved1[6]; DWORD dwPID; DWORD dwTID; DWORD cbText; union { LPSTR uszText; LPWSTR wszText; }; // U/W dependant PBYTE pbMultiText; // multi-str pointed into by VMM_MAP_EATENTRY.[wszFunction|wszModule] DWORD cbMultiText; DWORD cMap; VMMDLL_MAP_THREAD_CALLSTACKENTRY pMap[0]; } VMMDLL_MAP_THREAD_CALLSTACK, *PVMMDLL_MAP_THREAD_CALLSTACK; typedef struct tdVMMDLL_MAP_HANDLE { DWORD dwVersion; // VMMDLL_MAP_HANDLE_VERSION DWORD _Reserved1[5]; PBYTE pbMultiText; // multi-wstr pointed into by VMMDLL_MAP_HANDLEENTRY.wszText DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_HANDLEENTRY pMap[]; // map entries. } VMMDLL_MAP_HANDLE, *PVMMDLL_MAP_HANDLE; typedef struct tdVMMDLL_MAP_POOL { DWORD dwVersion; // VMMDLL_MAP_POOL_VERSION DWORD _Reserved1[6]; DWORD cbTotal; // # bytes to represent this pool map object PDWORD piTag2Map; // dword map array (size: cMap): tag index to map index. PVMMDLL_MAP_POOLENTRYTAG pTag; // tag entries. DWORD cTag; // # tag entries. DWORD cMap; // # map entries. VMMDLL_MAP_POOLENTRY pMap[]; // map entries. } VMMDLL_MAP_POOL, *PVMMDLL_MAP_POOL; typedef struct tdVMMDLL_MAP_KOBJECT { DWORD dwVersion; // VMMDLL_MAP_KOBJECT_VERSION DWORD _Reserved1[5]; PBYTE pbMultiText; // multi-wstr pointed into by VMM_MAP_NETENTRY.wszText DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_KOBJECTENTRY pMap[]; // map entries. } VMMDLL_MAP_KOBJECT, *PVMMDLL_MAP_KOBJECT; typedef struct tdVMMDLL_MAP_KDRIVER { DWORD dwVersion; // VMMDLL_MAP_KDRIVER_VERSION DWORD _Reserved1[5]; PBYTE pbMultiText; // multi-wstr pointed into by VMM_MAP_NETENTRY.wszText DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_KDRIVERENTRY pMap[]; // map entries. } VMMDLL_MAP_KDRIVER, *PVMMDLL_MAP_KDRIVER; typedef struct tdVMMDLL_MAP_KDEVICE { DWORD dwVersion; // VMMDLL_MAP_KDEVICE_VERSION DWORD _Reserved1[5]; PBYTE pbMultiText; // multi-wstr pointed into by VMM_MAP_NETENTRY.wszText DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_KDEVICEENTRY pMap[]; // map entries. } VMMDLL_MAP_KDEVICE, *PVMMDLL_MAP_KDEVICE; typedef struct tdVMMDLL_MAP_NET { DWORD dwVersion; // VMMDLL_MAP_NET_VERSION DWORD _Reserved1; PBYTE pbMultiText; // multi-wstr pointed into by VMM_MAP_NETENTRY.wszText DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_NETENTRY pMap[]; // map entries. } VMMDLL_MAP_NET, *PVMMDLL_MAP_NET; typedef struct tdVMMDLL_MAP_PHYSMEM { DWORD dwVersion; // VMMDLL_MAP_PHYSMEM_VERSION DWORD _Reserved1[5]; DWORD cMap; // # map entries. DWORD _Reserved2; VMMDLL_MAP_PHYSMEMENTRY pMap[]; // map entries. } VMMDLL_MAP_PHYSMEM, *PVMMDLL_MAP_PHYSMEM; typedef struct tdVMMDLL_MAP_USER { DWORD dwVersion; // VMMDLL_MAP_USER_VERSION DWORD _Reserved1[5]; PBYTE pbMultiText; // multi-wstr pointed into by VMMDLL_MAP_USERENTRY.wszText DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_USERENTRY pMap[]; // map entries. } VMMDLL_MAP_USER, *PVMMDLL_MAP_USER; typedef struct tdVMMDLL_MAP_VM { DWORD dwVersion; // VMMDLL_MAP_VM_VERSION DWORD _Reserved1[5]; PBYTE pbMultiText; // multi-wstr pointed into by VMMDLL_MAP_VMENTRY.wszText DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_VMENTRY pMap[]; // map entries. } VMMDLL_MAP_VM, *PVMMDLL_MAP_VM; typedef struct tdVMMDLL_MAP_SERVICE { DWORD dwVersion; // VMMDLL_MAP_SERVICE_VERSION DWORD _Reserved1[5]; PBYTE pbMultiText; // multi-wstr pointed into by VMMDLL_MAP_SERVICEENTRY.wsz* DWORD cbMultiText; DWORD cMap; // # map entries. VMMDLL_MAP_SERVICEENTRY pMap[]; // map entries. } VMMDLL_MAP_SERVICE, *PVMMDLL_MAP_SERVICE; /* * Retrieve the memory map entries based on hardware page tables (PTEs) for the process. * Entries returned are sorted on VMMDLL_MAP_PTEENTRY.va * CALLER FREE: VMMDLL_MemFree(*ppVadMap) * -- hVMM * -- dwPID * -- fIdentifyModules = try identify modules as well (= slower) * -- ppPteMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetPteU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ BOOL fIdentifyModules, _Out_ PVMMDLL_MAP_PTE *ppPteMap); _Success_(return) BOOL VMMDLL_Map_GetPteW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ BOOL fIdentifyModules, _Out_ PVMMDLL_MAP_PTE *ppPteMap); /* * Retrieve memory map entries based on virtual address descriptor (VAD) for the process. * Entries returned are sorted on VMMDLL_MAP_VADENTRY.vaStart * CALLER FREE: VMMDLL_MemFree(*ppVadMap) * -- hVMM * -- dwPID * -- fIdentifyModules = try identify modules as well (= slower) * -- ppVadMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetVadU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ BOOL fIdentifyModules, _Out_ PVMMDLL_MAP_VAD *ppVadMap); _Success_(return) BOOL VMMDLL_Map_GetVadW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ BOOL fIdentifyModules, _Out_ PVMMDLL_MAP_VAD *ppVadMap); /* * Retrieve extended memory map information about a sub-set of the memory map. * CALLER FREE: VMMDLL_MemFree(*ppVadExMap) * -- hVMM * -- oPage = offset in number of pages from process start. * -- cPage = number of pages to process from oPages base. * -- ppVadExMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetVadEx(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ DWORD oPage, _In_ DWORD cPage, _Out_ PVMMDLL_MAP_VADEX *ppVadExMap); /* * Retrieve the modules (.dlls) for the specified process. * CALLER FREE: VMMDLL_MemFree(*ppModuleMap) * -- hVMM * -- dwPID * -- ppModuleMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- flags = optional flags as specified by VMMDLL_MODULE_FLAG_* * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetModuleU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Out_ PVMMDLL_MAP_MODULE *ppModuleMap, _In_ DWORD flags); _Success_(return) BOOL VMMDLL_Map_GetModuleW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Out_ PVMMDLL_MAP_MODULE *ppModuleMap, _In_ DWORD flags); /* * Retrieve a module (.dll) entry given a process and module name. * CALLER FREE: VMMDLL_MemFree(*ppModuleMapEntry) * -- hVMM * -- dwPID * -- [uw]szModuleName = module name (or ""/NULL for 1st module entry). * -- ppModuleMapEntry = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- flags = optional flags as specified by VMMDLL_MODULE_FLAG_* * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetModuleFromNameU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_opt_ LPCSTR uszModuleName, _Out_ PVMMDLL_MAP_MODULEENTRY *ppModuleMapEntry, _In_ DWORD flags); _Success_(return) BOOL VMMDLL_Map_GetModuleFromNameW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_opt_ LPCWSTR wszModuleName, _Out_ PVMMDLL_MAP_MODULEENTRY *ppModuleMapEntry, _In_ DWORD flags); /* * Retrieve the unloaded modules (.dll/.sys) for the specified process. * CALLER FREE: VMMDLL_MemFree(*ppUnloadedModuleMap) * -- hVMM * -- dwPID * -- ppUnloadedModuleMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetUnloadedModuleU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Out_ PVMMDLL_MAP_UNLOADEDMODULE *ppUnloadedModuleMap); _Success_(return) BOOL VMMDLL_Map_GetUnloadedModuleW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Out_ PVMMDLL_MAP_UNLOADEDMODULE *ppUnloadedModuleMap); /* * Retrieve the module exported functions from the export address table (EAT). * CALLER FREE: VMMDLL_MemFree(*ppEatMap) * -- hVMM * -- dwPID * -- [uw]szModuleName * -- ppEatMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetEATU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCSTR uszModuleName, _Out_ PVMMDLL_MAP_EAT *ppEatMap); _Success_(return) BOOL VMMDLL_Map_GetEATW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCWSTR wszModuleName, _Out_ PVMMDLL_MAP_EAT *ppEatMap); /* * Retrieve the module imported functions from the import address table (IAT). * CALLER FREE: VMMDLL_MemFree(*ppIatMap) * -- hVMM * -- dwPID * -- [uw]szModuleName * -- ppIatMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetIATU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCSTR uszModuleName, _Out_ PVMMDLL_MAP_IAT *ppIatMap); _Success_(return) BOOL VMMDLL_Map_GetIATW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCWSTR wszModuleName, _Out_ PVMMDLL_MAP_IAT *ppIatMap); /* * Retrieve the heaps for the specified process. * CALLER FREE: VMMDLL_MemFree(*ppHeapMap) * -- hVMM * -- dwPID * -- ppHeapMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetHeap(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Out_ PVMMDLL_MAP_HEAP *ppHeapMap); /* * Retrieve heap allocations for the specified process heap. * CALLER FREE: VMMDLL_MemFree(*ppHeapAllocMap) * -- hVMM * -- dwPID * -- qwHeapNumOrAddress = number or virtual address of heap to retrieve allocations from. * -- ppHeapAllocMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetHeapAlloc(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ QWORD qwHeapNumOrAddress, _Out_ PVMMDLL_MAP_HEAPALLOC *ppHeapAllocMap); /* * Retrieve the threads for the specified process. * Entries returned are sorted on VMMDLL_MAP_THREADENTRY.dwTID * CALLER FREE: VMMDLL_MemFree(*ppThreadMap) * -- hVMM * -- dwPID * -- ppThreadMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetThread(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Out_ PVMMDLL_MAP_THREAD *ppThreadMap); /* * Retrieve the thread callstack for a specific thread. * Callstack retrieval is: * - supported for x64 user-mode threads. * - a best-effort operation and may not always succeed. * - may download a large amounts of pdb symbol data from Microsoft. * CALLER FREE: VMMDLL_MemFree(*ppThreadCallstack) * -- hVMM * -- dwPID * -- dwTID * -- flags = 0, VMMDLL_FLAG_NOCACHE or VMM_FLAG_FORCECACHE_READ * -- ppThreadCallstack * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetThread_CallstackU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ DWORD dwTID, _In_ DWORD flags, _Out_ PVMMDLL_MAP_THREAD_CALLSTACK *ppThreadCallstack); _Success_(return) BOOL VMMDLL_Map_GetThread_CallstackW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ DWORD dwTID, _In_ DWORD flags, _Out_ PVMMDLL_MAP_THREAD_CALLSTACK *ppThreadCallstack); /* * Retrieve the handles for the specified process. * Entries returned are sorted on VMMDLL_MAP_HANDLEENTRY.dwHandle * CALLER FREE: VMMDLL_MemFree(*ppHandleMap) * -- hVMM * -- dwPID * -- ppHandleMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetHandleU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Out_ PVMMDLL_MAP_HANDLE *ppHandleMap); _Success_(return) BOOL VMMDLL_Map_GetHandleW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Out_ PVMMDLL_MAP_HANDLE *ppHandleMap); /* * Retrieve the physical memory ranges from the operating system physical memory map. * CALLER FREE: VMMDLL_MemFree(*ppPhysMemMap) * -- hVMM * -- ppPhysMemMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree() * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetPhysMem(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_PHYSMEM *ppPhysMemMap); /* * Retrieve the kernel device map - consisting of kernel device objects. * CALLER FREE: VMMDLL_MemFree(*ppKDeviceMap) * -- hVMM * -- ppKDeviceMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetKDeviceU(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_KDEVICE *ppKDeviceMap); _Success_(return) BOOL VMMDLL_Map_GetKDeviceW(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_KDEVICE *ppKDeviceMap); /* * Retrieve the kernel driver map - consisting of kernel driver objects. * CALLER FREE: VMMDLL_MemFree(*ppKDriverMap) * -- hVMM * -- ppKDriverMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetKDriverU(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_KDRIVER *ppKDriverMap); _Success_(return) BOOL VMMDLL_Map_GetKDriverW(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_KDRIVER *ppKDriverMap); /* * Retrieve the kernel object map - consisting of kernel objects such as devices, drivers and other objects. * CALLER FREE: VMMDLL_MemFree(*ppKObjectMap) * -- hVMM * -- ppKObjectMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetKObjectU(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_KOBJECT *ppKObjectMap); _Success_(return) BOOL VMMDLL_Map_GetKObjectW(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_KOBJECT *ppKObjectMap); /* * Retrieve the pool map - consisting of kernel allocated pool entries. * The pool map pMap is sorted by allocation virtual address. * The pool map pTag is sorted by pool tag. * NB! The pool map may contain both false negatives/positives. * NB! The pool map relies on debug symbols. Please ensure supporting files * symsrv.dll, dbghelp.dll and info.db (found in the binary distribution) * is put alongside vmm.dll. (On Linux the .dll files aren't necessary). * CALLER FREE: VMMDLL_MemFree(*ppPoolMap) * -- hVMM * -- ppPoolMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- flags = VMMDLL_POOLMAP_FLAG* * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetPool(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_POOL *ppPoolMap, _In_ DWORD flags); /* * Retrieve the network connection map - consisting of active network connections, * listening sockets and other networking functionality. * CALLER FREE: VMMDLL_MemFree(*ppNetMap) * -- hVMM * -- ppNetMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetNetU(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_NET *ppNetMap); _Success_(return) BOOL VMMDLL_Map_GetNetW(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_NET *ppNetMap); /* * Retrieve the non well known users that are detected in the target system. * NB! There may be more users in the system than the ones that are detected, * only users with mounted registry hives may currently be detected - this is * the normal behaviour for users with active processes. * CALLER FREE: VMMDLL_MemFree(*ppUserMap) * -- hVMM * -- ppUserMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetUsersU(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_USER *ppUserMap); _Success_(return) BOOL VMMDLL_Map_GetUsersW(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_USER *ppUserMap); /* * Retrieve a map of detected child virtual machines (VMs). * NB! May fail if called shortly after vmm init unless option: -waitinitialize * CALLER FREE: VMMDLL_MemFree(*ppVmMap) * -- hVMM * -- ppVmMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetVMU(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_VM *ppVmMap); _Success_(return) BOOL VMMDLL_Map_GetVMW(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_VM *ppVmMap); /* * Retrieve the services currently known by the service control manager (SCM). * CALLER FREE: VMMDLL_MemFree(*ppServiceMap) * -- hVMM * -- ppServiceMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetServicesU(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_SERVICE *ppServiceMap); _Success_(return) BOOL VMMDLL_Map_GetServicesW(_In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_MAP_SERVICE *ppServiceMap); //----------------------------------------------------------------------------- // MEMORY SEARCH FUNCTIONALITY: //----------------------------------------------------------------------------- #define VMMDLL_MEM_SEARCH_VERSION 0xfe3e0003 #define VMMDLL_MEM_SEARCH_MAXLENGTH 32 typedef struct tdVMMDLL_MEM_SEARCH_CONTEXT_SEARCHENTRY { DWORD cbAlign; // byte-align at 2^x - 0, 1, 2, 4, 8, 16, .. bytes. DWORD cb; // number of bytes to search (1-32). BYTE pb[VMMDLL_MEM_SEARCH_MAXLENGTH]; BYTE pbSkipMask[VMMDLL_MEM_SEARCH_MAXLENGTH]; // skip bitmask '0' = match, '1' = wildcard. } VMMDLL_MEM_SEARCH_CONTEXT_SEARCHENTRY, *PVMMDLL_MEM_SEARCH_CONTEXT_SEARCHENTRY; /* * Context to populate and use in the VMMDLL_MemSearch() function. */ typedef struct tdVMMDLL_MEM_SEARCH_CONTEXT { DWORD dwVersion; DWORD _Filler[2]; BOOL fAbortRequested; // may be set by caller to abort processing prematurely. DWORD cMaxResult; // # max result entries. '0' = 1 entry. max 0x10000 entries. DWORD cSearch; // number of search entries. PVMMDLL_MEM_SEARCH_CONTEXT_SEARCHENTRY pSearch; // pointer to an array of cSearch entries. QWORD vaMin; // min address to search (page-aligned). QWORD vaMax; // max address to search (page-aligned), if 0 max memory is assumed. QWORD vaCurrent; // current address (may be read by caller). DWORD _Filler2; DWORD cResult; // number of search hits. QWORD cbReadTotal; // total number of bytes read. PVOID pvUserPtrOpt; // optional pointer set by caller (used for context passing to callbacks) // optional result callback function. // use of callback function disable ordinary result in ppObAddressResult. // return = continue search(TRUE), abort search(FALSE). BOOL(*pfnResultOptCB)(_In_ struct tdVMMDLL_MEM_SEARCH_CONTEXT *ctx, _In_ QWORD va, _In_ DWORD iSearch); // non-recommended features: QWORD ReadFlags; // read flags as in VMMDLL_FLAG_* BOOL fForcePTE; // force PTE method for virtual address reads. BOOL fForceVAD; // force VAD method for virtual address reads. // optional filter callback function for virtual address reads: // for ranges inbetween vaMin:vaMax callback with pte or vad entry. // return: read from range(TRUE), do not read from range(FALSE). BOOL(*pfnFilterOptCB)(_In_ struct tdVMMDLL_MEM_SEARCH_CONTEXT *ctx, _In_opt_ PVMMDLL_MAP_PTEENTRY pePte, _In_opt_ PVMMDLL_MAP_VADENTRY peVad); } VMMDLL_MEM_SEARCH_CONTEXT, *PVMMDLL_MEM_SEARCH_CONTEXT; /* * Search for binary data in an address space specified by the supplied context. * For more information about the different search parameters please see the * struct definition: VMMDLL_MEM_SEARCH_CONTEXT * Search may take a long time. It's not recommended to run this interactively. * To cancel a search prematurely set the fAbortRequested flag in the context * and wait a short while. * CALLER FREE: VMMDLL_MemFree(*ppva) * -- hVMM * -- dwPID - PID of target process, (DWORD)-1 to read physical memory. * -- ctx * -- ppva = pointer to receive addresses found. Free'd with VMMDLL_MemFree(). * -- pcva = pointer to receive number of addresses in ppva. not bytes! * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_MemSearch( _In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Inout_ PVMMDLL_MEM_SEARCH_CONTEXT ctx, _Out_opt_ PQWORD *ppva, _Out_opt_ PDWORD pcva ); //----------------------------------------------------------------------------- // MEMORY YARA SEARCH FUNCTIONALITY: // The yara search functionality requires that vmmyara.[dll|so] is present. // The vmmyara project is found at: https://github.com/ufrisk/vmmyara //----------------------------------------------------------------------------- // =========== START SHARED STRUCTS WITH <vmmdll.h/vmmyara.h> =========== #ifndef VMMYARA_RULE_MATCH_DEFINED #define VMMYARA_RULE_MATCH_DEFINED #define VMMYARA_RULE_MATCH_VERSION 0xfedc0005 #define VMMYARA_RULE_MATCH_TAG_MAX 27 #define VMMYARA_RULE_MATCH_META_MAX 32 #define VMMYARA_RULE_MATCH_STRING_MAX 16 #define VMMYARA_RULE_MATCH_OFFSET_MAX 24 /* * Struct with match information upon a match in VmmYara_RulesScanMemory(). */ typedef struct tdVMMYARA_RULE_MATCH { DWORD dwVersion; // VMMYARA_RULE_MATCH_VERSION DWORD flags; LPSTR szRuleIdentifier; DWORD cTags; LPSTR szTags[VMMYARA_RULE_MATCH_TAG_MAX]; DWORD cMeta; struct { LPSTR szIdentifier; LPSTR szString; } Meta[VMMYARA_RULE_MATCH_META_MAX]; DWORD cStrings; struct { LPSTR szString; DWORD cMatch; SIZE_T cbMatchOffset[VMMYARA_RULE_MATCH_OFFSET_MAX]; } Strings[VMMYARA_RULE_MATCH_STRING_MAX]; } VMMYARA_RULE_MATCH, *PVMMYARA_RULE_MATCH; #endif /* VMMYARA_RULE_MATCH_DEFINED */ #ifndef VMMYARA_SCAN_MEMORY_CALLBACK_DEFINED #define VMMYARA_SCAN_MEMORY_CALLBACK_DEFINED /* * Callback function to be called by VmmYara_RulesScanMemory() upon a match. * -- pvContext = user context set in call to VmmYara_ScanMemory(). * -- pRuleMatch = pointer to match information. * -- pbBuffer = the memory buffer that was scanned. * -- cbBuffer = the size of the memory buffer that was scanned. * -- return = return TRUE to continue scanning, FALSE to stop scanning. */ typedef BOOL(*VMMYARA_SCAN_MEMORY_CALLBACK)( _In_ PVOID pvContext, _In_ PVMMYARA_RULE_MATCH pRuleMatch, _In_reads_bytes_(cbBuffer) PBYTE pbBuffer, _In_ SIZE_T cbBuffer ); #endif /* VMMYARA_SCAN_MEMORY_CALLBACK_DEFINED */ // =========== END SHARED STRUCTS WITH <vmmdll.h/vmmyara.h> =========== #define VMMDLL_YARA_CONFIG_VERSION 0xdec30001 #define VMMDLL_YARA_MEMORY_CALLBACK_CONTEXT_VERSION 0xdec40002 #define VMMDLL_YARA_CONFIG_MAX_RESULT 0x00010000 // max 65k results. typedef struct tdVMMDLL_YARA_CONFIG *PVMMDLL_YARA_CONFIG; // forward declaration. /* * Callback function to tell whether a section of memory should be scanned or not. * -- ctx = pointer to PVMMDLL_YARA_CONFIG context. * -- pePte = pointer to PTE entry if the memory region is backed by PTE map. Otherwise NULL. * -- peVad = pointer to VAD entry if the memory region is backed by VAD map. Otherwise NULL. * -- return = return TRUE to scan the memory region, FALSE to skip it. */ typedef BOOL(*VMMYARA_SCAN_FILTER_CALLBACK)( _In_ PVMMDLL_YARA_CONFIG ctx, _In_opt_ PVMMDLL_MAP_PTEENTRY pePte, _In_opt_ PVMMDLL_MAP_VADENTRY peVad ); /* * Yara search configuration struct. */ typedef struct tdVMMDLL_YARA_CONFIG { DWORD dwVersion; // VMMDLL_YARA_CONFIG_VERSION DWORD _Filler[2]; BOOL fAbortRequested; // may be set by caller to abort processing prematurely. DWORD cMaxResult; // # max result entries. max 0x10000 entries. 0 = max entries. DWORD cRules; // number of rules to use - if compiled rules only 1 is allowed. LPSTR *pszRules; // array of rules to use - either filenames or in-memory rules. QWORD vaMin; QWORD vaMax; QWORD vaCurrent; // current address (may be read by caller). DWORD _Filler2; DWORD cResult; // number of search hits. QWORD cbReadTotal; // total number of bytes read. PVOID pvUserPtrOpt; // optional pointer set by caller (used for context passing to callbacks) // match callback function (recommended but optional). // return = continue search(TRUE), abort search(FALSE). VMMYARA_SCAN_MEMORY_CALLBACK pfnScanMemoryCB; // non-recommended features: QWORD ReadFlags; // read flags as in VMMDLL_FLAG_* BOOL fForcePTE; // force PTE method for virtual address reads. BOOL fForceVAD; // force VAD method for virtual address reads. // optional filter callback function for virtual address reads: // for ranges inbetween vaMin:vaMax callback with pte or vad entry. // return: read from range(TRUE), do not read from range(FALSE). VMMYARA_SCAN_FILTER_CALLBACK pfnFilterOptCB; PVOID pvUserPtrOpt2; // optional pointer set by caller (not used by MemProcFS). QWORD _Reserved; } VMMDLL_YARA_CONFIG, *PVMMDLL_YARA_CONFIG; /* * Yara search callback struct which created by MemProcFS internally and is * passed to the callback function supplied by the caller in VMMDLL_YaraSearch(). */ typedef struct tdVMMDLL_YARA_MEMORY_CALLBACK_CONTEXT { DWORD dwVersion; DWORD dwPID; PVOID pUserContext; QWORD vaObject; QWORD va; PBYTE pb; DWORD cb; LPSTR uszTag[1]; // min 1 char (but may be more). } VMMDLL_YARA_MEMORY_CALLBACK_CONTEXT, *PVMMDLL_YARA_MEMORY_CALLBACK_CONTEXT; /* * Perform a yara search in the address space of a process. * NB! it may take a long time for this function to return. * -- hVMM * -- dwPID - PID of target process, (DWORD)-1 to read physical memory. * -- pYaraConfig * -- ppva = pointer to receive addresses found. Free'd with VMMDLL_MemFree(). * -- pcva = pointer to receive number of addresses in ppva. not bytes! * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_YaraSearch( _In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ PVMMDLL_YARA_CONFIG pYaraConfig, _Out_opt_ PQWORD *ppva, _Out_opt_ PDWORD pcva ); //----------------------------------------------------------------------------- // WINDOWS SPECIFIC PAGE FRAME NUMBER (PFN) FUNCTIONALITY BELOW //----------------------------------------------------------------------------- #define VMMDLL_MAP_PFN_VERSION 1 #define VMMDLL_PFN_FLAG_NORMAL 0 #define VMMDLL_PFN_FLAG_EXTENDED 1 static LPCSTR VMMDLL_PFN_TYPE_TEXT[] = { "Zero", "Free", "Standby", "Modifiy", "ModNoWr", "Bad", "Active", "Transit" }; static LPCSTR VMMDLL_PFN_TYPEEXTENDED_TEXT[] = { "-", "Unused", "ProcPriv", "PageTable", "LargePage", "DriverLock", "Shareable", "File" }; typedef enum tdVMMDLL_MAP_PFN_TYPE { VmmDll_PfnTypeZero = 0, VmmDll_PfnTypeFree = 1, VmmDll_PfnTypeStandby = 2, VmmDll_PfnTypeModified = 3, VmmDll_PfnTypeModifiedNoWrite = 4, VmmDll_PfnTypeBad = 5, VmmDll_PfnTypeActive = 6, VmmDll_PfnTypeTransition = 7 } VMMDLL_MAP_PFN_TYPE; typedef enum tdVMMDLL_MAP_PFN_TYPEEXTENDED { VmmDll_PfnExType_Unknown = 0, VmmDll_PfnExType_Unused = 1, VmmDll_PfnExType_ProcessPrivate = 2, VmmDll_PfnExType_PageTable = 3, VmmDll_PfnExType_LargePage = 4, VmmDll_PfnExType_DriverLocked = 5, VmmDll_PfnExType_Shareable = 6, VmmDll_PfnExType_File = 7, } VMMDLL_MAP_PFN_TYPEEXTENDED; typedef struct tdVMMDLL_MAP_PFNENTRY { DWORD dwPfn; VMMDLL_MAP_PFN_TYPEEXTENDED tpExtended; struct { // Only valid if active non-prototype PFN union { DWORD dwPid; DWORD dwPfnPte[5]; // PFN of paging levels 1-4 (x64) }; QWORD va; // valid if non-zero } AddressInfo; QWORD vaPte; QWORD OriginalPte; union { DWORD _u3; struct { WORD ReferenceCount; // MMPFNENTRY BYTE PageLocation : 3; // Pos 0 - VMMDLL_MAP_PFN_TYPE BYTE WriteInProgress : 1; // Pos 3 BYTE Modified : 1; // Pos 4 BYTE ReadInProgress : 1; // Pos 5 BYTE CacheAttribute : 2; // Pos 6 BYTE Priority : 3; // Pos 0 BYTE Rom_OnProtectedStandby : 1;// Pos 3 BYTE InPageError : 1; // Pos 4 BYTE KernelStack_SystemChargedPage : 1; // Pos 5 BYTE RemovalRequested : 1; // Pos 6 BYTE ParityError : 1; // Pos 7 }; }; union { QWORD _u4; struct { DWORD PteFrame; DWORD PteFrameHigh : 4; // Pos 32 DWORD _Reserved : 21; // Pos 36 DWORD PrototypePte : 1; // Pos 57 DWORD PageColor : 6; // Pos 58 }; }; DWORD _FutureUse[6]; } VMMDLL_MAP_PFNENTRY, *PVMMDLL_MAP_PFNENTRY; typedef struct tdVMMDLL_MAP_PFN { DWORD dwVersion; DWORD _Reserved1[5]; DWORD cMap; // # map entries. VMMDLL_MAP_PFNENTRY pMap[]; // map entries. } VMMDLL_MAP_PFN, *PVMMDLL_MAP_PFN; /* * Retrieve information about scattered PFNs. The PFNs are returned in order of * in which they are stored in the pPfns set. * -- hVMM * -- pPfns * -- cPfns * -- pPfnMap = buffer of minimum byte length *pcbPfnMap or NULL. * -- pcbPfnMap = pointer to byte count of pPhysMemMap buffer. * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetPfn( _In_ VMM_HANDLE hVMM, _In_reads_(cPfns) DWORD pPfns[], _In_ DWORD cPfns, _Out_writes_bytes_opt_(*pcbPfnMap) PVMMDLL_MAP_PFN pPfnMap, _Inout_ PDWORD pcbPfnMap ); /* * Retrieve PFN information: * CALLER FREE: VMMDLL_MemFree(*ppPfnMap) * -- hVMM * -- pPfns = PFNs to retrieve. * -- cPfns = number of PFNs to retrieve. * -- ppPfnMap = ptr to receive result on success. must be free'd with VMMDLL_MemFree(). * -- flags = optional flags as specified by VMMDLL_PFN_FLAG_* * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_Map_GetPfnEx( _In_ VMM_HANDLE hVMM, _In_reads_(cPfns) DWORD pPfns[], _In_ DWORD cPfns, _Out_ PVMMDLL_MAP_PFN *ppPfnMap, _In_ DWORD flags ); //----------------------------------------------------------------------------- // VMM PROCESS FUNCTIONALITY BELOW: // Functionality below is mostly relating to Windows processes. //----------------------------------------------------------------------------- /* * Retrieve an active process given it's name. Please note that if multiple * processes with the same name exists only one will be returned. If required to * parse all processes with the same name please iterate over the PID list by * calling VMMDLL_PidList together with VMMDLL_ProcessGetInformation. * -- hVMM * -- szProcName = process name case insensitive. * -- pdwPID = pointer that will receive PID on success. * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_PidGetFromName(_In_ VMM_HANDLE hVMM, _In_ LPCSTR szProcName, _Out_ PDWORD pdwPID); /* * List the PIDs in the system. * -- hVMM * -- pPIDs = DWORD array of at least number of PIDs in system, or NULL. * -- pcPIDs = size of (in number of DWORDs) pPIDs array on entry, number of PIDs in system on exit. * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_PidList(_In_ VMM_HANDLE hVMM, _Out_writes_opt_(*pcPIDs) PDWORD pPIDs, _Inout_ PSIZE_T pcPIDs); #define VMMDLL_PROCESS_INFORMATION_MAGIC 0xc0ffee663df9301e #define VMMDLL_PROCESS_INFORMATION_VERSION 7 typedef enum tdVMMDLL_PROCESS_INTEGRITY_LEVEL { VMMDLL_PROCESS_INTEGRITY_LEVEL_UNKNOWN = 0, VMMDLL_PROCESS_INTEGRITY_LEVEL_UNTRUSTED = 1, VMMDLL_PROCESS_INTEGRITY_LEVEL_LOW = 2, VMMDLL_PROCESS_INTEGRITY_LEVEL_MEDIUM = 3, VMMDLL_PROCESS_INTEGRITY_LEVEL_MEDIUMPLUS = 4, VMMDLL_PROCESS_INTEGRITY_LEVEL_HIGH = 5, VMMDLL_PROCESS_INTEGRITY_LEVEL_SYSTEM = 6, VMMDLL_PROCESS_INTEGRITY_LEVEL_PROTECTED = 7, } VMMDLL_PROCESS_INTEGRITY_LEVEL; typedef struct tdVMMDLL_PROCESS_INFORMATION { ULONG64 magic; WORD wVersion; WORD wSize; VMMDLL_MEMORYMODEL_TP tpMemoryModel; // as given by VMMDLL_MEMORYMODEL_* enum VMMDLL_SYSTEM_TP tpSystem; // as given by VMMDLL_SYSTEM_* enum BOOL fUserOnly; // only user mode pages listed DWORD dwPID; DWORD dwPPID; DWORD dwState; CHAR szName[16]; CHAR szNameLong[64]; ULONG64 paDTB; ULONG64 paDTB_UserOpt; // may not exist struct { ULONG64 vaEPROCESS; ULONG64 vaPEB; ULONG64 _Reserved1; BOOL fWow64; DWORD vaPEB32; // WoW64 only DWORD dwSessionId; ULONG64 qwLUID; CHAR szSID[MAX_PATH]; VMMDLL_PROCESS_INTEGRITY_LEVEL IntegrityLevel; } win; } VMMDLL_PROCESS_INFORMATION, *PVMMDLL_PROCESS_INFORMATION; /* * Retrieve various process information from a PID. Process information such as * name, page directory bases and the process state may be retrieved. * -- hVMM * -- dwPID * -- pProcessInformation = if null, size is given in *pcbProcessInfo * -- pcbProcessInformation = size of pProcessInfo (in bytes) on entry and exit * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_ProcessGetInformation( _In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Inout_opt_ PVMMDLL_PROCESS_INFORMATION pProcessInformation, _In_ PSIZE_T pcbProcessInformation ); /* * Retrieve various information from all processes (including terminated). * CALLER FREE : VMMDLL_MemFree(*ppProcessInformationAll) * -- hVMM * -- ptr to receive result array of pcProcessInformation items on success. * Must be free'd with VMMDLL_MemFree(). * -- ptr to DWORD to receive number of items processes on success. * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_ProcessGetInformationAll( _In_ VMM_HANDLE hVMM, _Out_ PVMMDLL_PROCESS_INFORMATION *ppProcessInformationAll, _Out_ PDWORD pcProcessInformation ); #define VMMDLL_PROCESS_INFORMATION_OPT_STRING_PATH_KERNEL 1 #define VMMDLL_PROCESS_INFORMATION_OPT_STRING_PATH_USER_IMAGE 2 #define VMMDLL_PROCESS_INFORMATION_OPT_STRING_CMDLINE 3 /* * Retrieve a string value belonging to a process. The function allocates a new * string buffer and returns the requested string in it. The string is always * NULL terminated. On failure NULL is returned. * NB! CALLER IS RESPONSIBLE FOR VMMDLL_MemFree return value! * CALLER FREE: VMMDLL_MemFree(return) * -- hVMM * -- dwPID * -- fOptionString = string value to retrieve as given by VMMDLL_PROCESS_INFORMATION_OPT_STRING_* * -- return - fail: NULL, success: the string - NB! must be VMMDLL_MemFree'd by caller! */ EXPORTED_FUNCTION _Success_(return != NULL) LPSTR VMMDLL_ProcessGetInformationString(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ DWORD fOptionString); /* * Retrieve information about: Data Directories, Sections, Export Address Table * and Import Address Table (IAT). * If the pData == NULL upon entry the number of entries of the pData array must * have in order to be able to hold the data is returned. * -- hVMM * -- dwPID * -- [uw]szModule * -- pData * -- cData * -- pcData * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_ProcessGetDirectoriesU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCSTR uszModule, _Out_writes_(16) PIMAGE_DATA_DIRECTORY pDataDirectories); _Success_(return) BOOL VMMDLL_ProcessGetDirectoriesW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCWSTR wszModule, _Out_writes_(16) PIMAGE_DATA_DIRECTORY pDataDirectories); EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_ProcessGetSectionsU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCSTR uszModule, _Out_writes_opt_(cSections) PIMAGE_SECTION_HEADER pSections, _In_ DWORD cSections, _Out_ PDWORD pcSections); _Success_(return) BOOL VMMDLL_ProcessGetSectionsW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCWSTR wszModule, _Out_writes_opt_(cSections) PIMAGE_SECTION_HEADER pSections, _In_ DWORD cSections, _Out_ PDWORD pcSections); /* * Retrieve the virtual address of a given function inside a process/module. * -- hVMM * -- dwPID * -- [uw]szModuleName * -- szFunctionName * -- return = virtual address of function, zero on fail. */ EXPORTED_FUNCTION _Success_(return != 0) ULONG64 VMMDLL_ProcessGetProcAddressU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCSTR uszModuleName, _In_ LPCSTR szFunctionName); _Success_(return != 0) ULONG64 VMMDLL_ProcessGetProcAddressW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCWSTR wszModuleName, _In_ LPCSTR szFunctionName); /* * Retrieve the base address of a given module. * -- hVMM * -- dwPID * -- [uw]szModuleName * -- return = virtual address of module base, zero on fail. */ EXPORTED_FUNCTION _Success_(return != 0) ULONG64 VMMDLL_ProcessGetModuleBaseU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCSTR uszModuleName); _Success_(return != 0) ULONG64 VMMDLL_ProcessGetModuleBaseW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCWSTR wszModuleName); //----------------------------------------------------------------------------- // WINDOWS SPECIFIC DEBUGGING / SYMBOL FUNCTIONALITY BELOW: //----------------------------------------------------------------------------- /* * Load a .pdb symbol file and return its associated module name upon success. * -- hVMM * -- dwPID * -- vaModuleBase * -- szModuleName = buffer to receive module name upon success. * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_PdbLoad( _In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ ULONG64 vaModuleBase, _Out_writes_(MAX_PATH) LPSTR szModuleName ); /* * Retrieve a symbol virtual address given a module name and a symbol name. * NB! not all modules may exist - initially only module "nt" is available. * NB! if multiple modules have the same name the 1st to be added will be used. * -- hVMM * -- szModule * -- cbSymbolAddressOrOffset = symbol virtual address or symbol offset. * -- szSymbolName = buffer to receive symbol name upon success. * -- pdwSymbolDisplacement = displacement from the beginning of the symbol. * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_PdbSymbolName( _In_ VMM_HANDLE hVMM, _In_ LPCSTR szModule, _In_ QWORD cbSymbolAddressOrOffset, _Out_writes_(MAX_PATH) LPSTR szSymbolName, _Out_opt_ PDWORD pdwSymbolDisplacement ); /* * Retrieve a symbol virtual address given a module name and a symbol name. * NB! not all modules may exist - initially only module "nt" is available. * NB! if multiple modules have the same name the 1st to be added will be used. * -- hVMM * -- szModule * -- szSymbolName * -- pvaSymbolAddress * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_PdbSymbolAddress( _In_ VMM_HANDLE hVMM, _In_ LPCSTR szModule, _In_ LPCSTR szSymbolName, _Out_ PULONG64 pvaSymbolAddress ); /* * Retrieve a type size given a module name and a type name. * NB! not all modules may exist - initially only module "nt" is available. * NB! if multiple modules have the same name the 1st to be added will be used. * -- hVMM * -- szModule * -- szTypeName * -- pcbTypeSize * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_PdbTypeSize( _In_ VMM_HANDLE hVMM, _In_ LPCSTR szModule, _In_ LPCSTR szTypeName, _Out_ PDWORD pcbTypeSize ); /* * Locate the offset of a type child - typically a sub-item inside a struct. * NB! not all modules may exist - initially only module "nt" is available. * NB! if multiple modules have the same name the 1st to be added will be used. * -- hVMM * -- szModule * -- uszTypeName * -- uszTypeChildName * -- pcbTypeChildOffset * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_PdbTypeChildOffset( _In_ VMM_HANDLE hVMM, _In_ LPCSTR szModule, _In_ LPCSTR uszTypeName, _In_ LPCSTR uszTypeChildName, _Out_ PDWORD pcbTypeChildOffset ); //----------------------------------------------------------------------------- // WINDOWS SPECIFIC REGISTRY FUNCTIONALITY BELOW: //----------------------------------------------------------------------------- #define VMMDLL_REGISTRY_HIVE_INFORMATION_MAGIC 0xc0ffee653df8d01e #define VMMDLL_REGISTRY_HIVE_INFORMATION_VERSION 4 typedef struct td_VMMDLL_REGISTRY_HIVE_INFORMATION { ULONG64 magic; WORD wVersion; WORD wSize; BYTE _FutureReserved1[0x34]; ULONG64 vaCMHIVE; ULONG64 vaHBASE_BLOCK; DWORD cbLength; CHAR uszName[128]; CHAR uszNameShort[32 + 1]; CHAR uszHiveRootPath[MAX_PATH]; QWORD _FutureReserved[0x10]; } VMMDLL_REGISTRY_HIVE_INFORMATION, *PVMMDLL_REGISTRY_HIVE_INFORMATION; /* * Retrieve information about the registry hives in the target system. * -- pHives = buffer of cHives * sizeof(VMMDLL_REGISTRY_HIVE_INFORMATION) to receive info about all hives. NULL to receive # hives in pcHives. * -- cHives * -- pcHives = if pHives == NULL: # total hives. if pHives: # read hives. * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_WinReg_HiveList( _In_ VMM_HANDLE hVMM, _Out_writes_(cHives) PVMMDLL_REGISTRY_HIVE_INFORMATION pHives, _In_ DWORD cHives, _Out_ PDWORD pcHives ); /* * Read a contigious arbitrary amount of registry hive memory and report the * number of bytes read in pcbRead. * NB! Address space does not include regf registry hive file header! * -- hVMM * -- vaCMHive * -- ra * -- pb * -- cb * -- pcbReadOpt * -- flags = flags as in VMMDLL_FLAG_* * -- return = success/fail. NB! reads may report as success even if 0 bytes are * read - it's recommended to verify pcbReadOpt parameter. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_WinReg_HiveReadEx( _In_ VMM_HANDLE hVMM, _In_ ULONG64 vaCMHive, _In_ DWORD ra, _Out_ PBYTE pb, _In_ DWORD cb, _Out_opt_ PDWORD pcbReadOpt, _In_ ULONG64 flags ); /* * Write a virtually contigious arbitrary amount of memory to a registry hive. * NB! Address space does not include regf registry hive file header! * -- hVMM * -- vaCMHive * -- ra * -- pb * -- cb * -- return = TRUE on success, FALSE on partial or zero write. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_WinReg_HiveWrite( _In_ VMM_HANDLE hVMM, _In_ ULONG64 vaCMHive, _In_ DWORD ra, _In_ PBYTE pb, _In_ DWORD cb ); /* * Enumerate registry sub keys - similar to WINAPI function 'RegEnumKeyExW.' * Please consult WINAPI function documentation for information. * May be called with HKLM base or virtual address of CMHIVE base examples: * 1) 'HKLM\SOFTWARE\Key\SubKey' * 2) 'HKLM\ORPHAN\SAM\Key\SubKey' (orphan key) * 3) '0x<vaCMHIVE>\ROOT\Key\SubKey' * 4) '0x<vaCMHIVE>\ORPHAN\Key\SubKey' (orphan key) * -- hVMM * -- uszFullPathKey * -- dwIndex = sub-key index 0..N (-1 for key). * -- lpName * -- lpcchName * -- lpftLastWriteTime * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_WinReg_EnumKeyExU( _In_ VMM_HANDLE hVMM, _In_ LPCSTR uszFullPathKey, _In_ DWORD dwIndex, _Out_writes_opt_(*lpcchName) LPSTR lpName, _Inout_ LPDWORD lpcchName, _Out_opt_ PFILETIME lpftLastWriteTime ); /* * Enumerate registry values given a registry key - similar to WINAPI function * 'EnumValueW'. Please consult WINAPI function documentation for information. * May be called in two ways: * May be called with HKLM base or virtual address of CMHIVE base examples: * 1) 'HKLM\SOFTWARE\Key\SubKey' * 2) 'HKLM\ORPHAN\SAM\Key\SubKey' (orphan key) * 3) '0x<vaCMHIVE>\ROOT\Key\SubKey' * 4) '0x<vaCMHIVE>\ORPHAN\Key\SubKey' (orphan key) * -- hVMM * -- uszFullPathKey * -- dwIndex * -- lpValueName * -- lpcchValueName * -- lpType * -- lpData * -- lpcbData * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_WinReg_EnumValueU( _In_ VMM_HANDLE hVMM, _In_ LPCSTR uszFullPathKey, _In_ DWORD dwIndex, _Out_writes_opt_(*lpcchValueName) LPSTR lpValueName, _Inout_ LPDWORD lpcchValueName, _Out_opt_ LPDWORD lpType, _Out_writes_opt_(*lpcbData) LPBYTE lpData, _Inout_opt_ LPDWORD lpcbData ); /* * Query a registry value given a registry key/value path - similar to WINAPI * function 'RegQueryValueEx'. * Please consult WINAPI function documentation for information. * May be called with HKLM base or virtual address of CMHIVE base examples: * 1) 'HKLM\SOFTWARE\Key\SubKey\Value' * 2) 'HKLM\ORPHAN\SAM\Key\SubKey\' (orphan key and default value) * 3) '0x<vaCMHIVE>\ROOT\Key\SubKey\Value' * 4) '0x<vaCMHIVE>\ORPHAN\Key\SubKey\Value' (orphan key value) * -- hVMM * -- uszFullPathKeyValue * -- lpType * -- lpData * -- lpcbData * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_WinReg_QueryValueExU( _In_ VMM_HANDLE hVMM, _In_ LPCSTR uszFullPathKeyValue, _Out_opt_ LPDWORD lpType, _Out_writes_opt_(*lpcbData) LPBYTE lpData, _When_(lpData == NULL, _Out_opt_) _When_(lpData != NULL, _Inout_opt_) LPDWORD lpcbData ); /* * Enumerate registry sub keys - similar to WINAPI function 'RegEnumKeyExW.' * Please consult WINAPI function documentation for information. * May be called with HKLM base or virtual address of CMHIVE base examples: * 1) 'HKLM\SOFTWARE\Key\SubKey' * 2) 'HKLM\ORPHAN\SAM\Key\SubKey' (orphan key) * 3) '0x<vaCMHIVE>\ROOT\Key\SubKey' * 4) '0x<vaCMHIVE>\ORPHAN\Key\SubKey' (orphan key) * -- hVMM * -- wszFullPathKey * -- dwIndex = sub-key index 0..N (-1 for key). * -- lpName * -- lpcchName * -- lpftLastWriteTime * -- return */ _Success_(return) BOOL VMMDLL_WinReg_EnumKeyExW( _In_ VMM_HANDLE hVMM, _In_ LPCWSTR wszFullPathKey, _In_ DWORD dwIndex, _Out_writes_opt_(*lpcchName) LPWSTR lpName, _Inout_ LPDWORD lpcchName, _Out_opt_ PFILETIME lpftLastWriteTime ); /* * Enumerate registry values given a registry key - similar to WINAPI function * 'EnumValueW'. Please consult WINAPI function documentation for information. * May be called in two ways: * May be called with HKLM base or virtual address of CMHIVE base examples: * 1) 'HKLM\SOFTWARE\Key\SubKey' * 2) 'HKLM\ORPHAN\SAM\Key\SubKey' (orphan key) * 3) '0x<vaCMHIVE>\ROOT\Key\SubKey' * 4) '0x<vaCMHIVE>\ORPHAN\Key\SubKey' (orphan key) * -- hVMM * -- wszFullPathKey * -- dwIndex * -- lpValueName * -- lpcchValueName * -- lpType * -- lpData * -- lpcbData * -- return */ _Success_(return) BOOL VMMDLL_WinReg_EnumValueW( _In_ VMM_HANDLE hVMM, _In_ LPCWSTR wszFullPathKey, _In_ DWORD dwIndex, _Out_writes_opt_(*lpcchValueName) LPWSTR lpValueName, _Inout_ LPDWORD lpcchValueName, _Out_opt_ LPDWORD lpType, _Out_writes_opt_(*lpcbData) LPBYTE lpData, _Inout_opt_ LPDWORD lpcbData ); /* * Query a registry value given a registry key/value path - similar to WINAPI * function 'RegQueryValueEx'. * Please consult WINAPI function documentation for information. * May be called with HKLM base or virtual address of CMHIVE base examples: * 1) 'HKLM\SOFTWARE\Key\SubKey\Value' * 2) 'HKLM\ORPHAN\SAM\Key\SubKey\' (orphan key and default value) * 3) '0x<vaCMHIVE>\ROOT\Key\SubKey\Value' * 4) '0x<vaCMHIVE>\ORPHAN\Key\SubKey\Value' (orphan key value) * -- hVMM * -- wszFullPathKeyValue * -- lpType * -- lpData * -- lpcbData * -- return */ _Success_(return) BOOL VMMDLL_WinReg_QueryValueExW( _In_ VMM_HANDLE hVMM, _In_ LPCWSTR wszFullPathKeyValue, _Out_opt_ LPDWORD lpType, _Out_writes_opt_(*lpcbData) LPBYTE lpData, _When_(lpData == NULL, _Out_opt_) _When_(lpData != NULL, _Inout_opt_) LPDWORD lpcbData ); //----------------------------------------------------------------------------- // WINDOWS SPECIFIC UTILITY FUNCTIONS BELOW: //----------------------------------------------------------------------------- typedef struct tdVMMDLL_WIN_THUNKINFO_IAT { BOOL fValid; BOOL f32; // if TRUE fn is a 32-bit/4-byte entry, otherwise 64-bit/8-byte entry. ULONG64 vaThunk; // address of import address table 'thunk'. ULONG64 vaFunction; // value if import address table 'thunk' == address of imported function. ULONG64 vaNameModule; // address of name string for imported module. ULONG64 vaNameFunction; // address of name string for imported function. } VMMDLL_WIN_THUNKINFO_IAT, *PVMMDLL_WIN_THUNKINFO_IAT; /* * Retrieve information about the import address table IAT thunk for an imported * function. This includes the virtual address of the IAT thunk which is useful * for hooking. * -- hVMM * -- dwPID * -- [uw]szModuleName * -- szImportModuleName * -- szImportFunctionName * -- pThunkIAT * -- return */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_WinGetThunkInfoIATU(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCSTR uszModuleName, _In_ LPCSTR szImportModuleName, _In_ LPCSTR szImportFunctionName, _Out_ PVMMDLL_WIN_THUNKINFO_IAT pThunkInfoIAT); _Success_(return) BOOL VMMDLL_WinGetThunkInfoIATW(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ LPCWSTR wszModuleName, _In_ LPCSTR szImportModuleName, _In_ LPCSTR szImportFunctionName, _Out_ PVMMDLL_WIN_THUNKINFO_IAT pThunkInfoIAT); //----------------------------------------------------------------------------- // VMM VM FUNCTIONALITY BELOW: //----------------------------------------------------------------------------- /* * Retrieve a VMM handle given a VM handle. * This is not allowed on physical memory only VMs. * This VMM handle should be closed by calling VMMDLL_Close(). * -- hVMM * -- hVM * -- return */ EXPORTED_FUNCTION _Success_(return != NULL) VMM_HANDLE VMMDLL_VmGetVmmHandle(_In_ VMM_HANDLE hVMM, _In_ VMMVM_HANDLE hVM); /* * Initialize a scatter handle which is used to efficiently read/write memory in * virtual machines (VMs). * CALLER CLOSE: VMMDLL_Scatter_CloseHandle(return) * -- hVMM * -- hVM = virtual machine handle; acquired from VMMDLL_Map_GetVM*) * -- flags = optional flags as given by VMMDLL_FLAG_* * -- return = handle to be used in VMMDLL_Scatter_* functions. */ EXPORTED_FUNCTION _Success_(return != NULL) VMMDLL_SCATTER_HANDLE VMMDLL_VmScatterInitialize(_In_ VMM_HANDLE hVMM, _In_ VMMVM_HANDLE hVM); /* * Read virtual machine (VM) guest physical address (GPA) memory. * -- hVMM * -- hVM = virtual machine handle. * -- qwGPA * -- pb * -- cb * -- return = success/fail (depending if all requested bytes are read or not). */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_VmMemRead(_In_ VMM_HANDLE hVMM, _In_ VMMVM_HANDLE hVM, _In_ ULONG64 qwGPA, _Out_writes_(cb) PBYTE pb, _In_ DWORD cb); /* * Write virtual machine (VM) guest physical address (GPA) memory. * -- hVMM * -- hVM = virtual machine handle. * -- qwGPA * -- pb * -- cb * -- return = TRUE on success, FALSE on partial or zero write. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_VmMemWrite(_In_ VMM_HANDLE hVMM, _In_ VMMVM_HANDLE hVM, _In_ ULONG64 qwGPA, _In_reads_(cb) PBYTE pb, _In_ DWORD cb); /* * Scatter read virtual machine (VM) guest physical address (GPA) memory. * Non contiguous 4096-byte pages. Not cached. * -- hVmm * -- hVM = virtual machine handle. * -- ppMEMsGPA * -- cpMEMsGPA * -- flags = (reserved future use). * -- return = the number of successfully read items. */ EXPORTED_FUNCTION DWORD VMMDLL_VmMemReadScatter(_In_ VMM_HANDLE hVMM, _In_ VMMVM_HANDLE hVM, _Inout_ PPMEM_SCATTER ppMEMsGPA, _In_ DWORD cpMEMsGPA, _In_ DWORD flags); /* * Scatter write virtual machine (VM) guest physical address (GPA) memory. * Non contiguous 4096-byte pages. Not cached. * -- hVmm * -- hVM = virtual machine handle. * -- ppMEMsGPA * -- cpMEMsGPA * -- return = the number of hopefully successfully written items. */ EXPORTED_FUNCTION DWORD VMMDLL_VmMemWriteScatter(_In_ VMM_HANDLE hVMM, _In_ VMMVM_HANDLE hVM, _Inout_ PPMEM_SCATTER ppMEMsGPA, _In_ DWORD cpMEMsGPA); /* * Translate a virtual machine (VM) guest physical address (GPA) to: * (1) Physical Address (PA) _OR_ (2) Virtual Address (VA) in 'vmmem' process. * -- hVMM * -- HVM * -- qwGPA = guest physical address to translate. * -- pPA = translated physical address (if exists). * -- pVA = translated virtual address inside 'vmmem' process (if exists). * -- return = success/fail. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_VmMemTranslateGPA(_In_ VMM_HANDLE H, _In_ VMMVM_HANDLE hVM, _In_ ULONG64 qwGPA, _Out_opt_ PULONG64 pPA, _Out_opt_ PULONG64 pVA); //----------------------------------------------------------------------------- // VMM UTIL FUNCTIONALITY BELOW: //----------------------------------------------------------------------------- /* * Fill a human readable hex ascii memory dump into the caller supplied sz buffer. * -- pb * -- cb * -- cbInitialOffset = offset, must be max 0x1000 and multiple of 0x10. * -- sz = buffer to fill, NULL to retrieve buffer size in pcsz parameter. * -- pcsz = IF sz==NULL :: size of buffer (including space for terminating NULL) on exit * IF sz!=NULL :: size of buffer on entry, size of characters (excluding terminating NULL) on exit. */ EXPORTED_FUNCTION _Success_(return) BOOL VMMDLL_UtilFillHexAscii( _In_reads_opt_(cb) PBYTE pb, _In_ DWORD cb, _In_ DWORD cbInitialOffset, _Out_writes_opt_(*pcsz) LPSTR sz, _Inout_ PDWORD pcsz ); /* * Retrieve license information - Licensed To. * -- CALLER FREE: VMMDLL_MemFree(return) * -- return = NULL on fail, otherwise a string that must be free'd by caller. */ EXPORTED_FUNCTION _Success_(return != NULL) LPSTR VMMDLL_LicensedTo(); //----------------------------------------------------------------------------- // DEFAULT (WINDOWS ONLY) COMPATIBILITY FUNCTION DEFINITIONS BELOW: //----------------------------------------------------------------------------- #ifdef _WIN32 #define VMMDLL_VfsList VMMDLL_VfsListW #define VMMDLL_VfsRead VMMDLL_VfsReadW #define VMMDLL_VfsWrite VMMDLL_VfsWriteW #define VMMDLL_ProcessGetDirectories VMMDLL_ProcessGetDirectoriesW #define VMMDLL_ProcessGetSections VMMDLL_ProcessGetSectionsW #define VMMDLL_ProcessGetProcAddress VMMDLL_ProcessGetProcAddressW #define VMMDLL_ProcessGetModuleBase VMMDLL_ProcessGetModuleBaseW #define VMMDLL_Map_GetPte VMMDLL_Map_GetPteW #define VMMDLL_Map_GetVad VMMDLL_Map_GetVadW #define VMMDLL_Map_GetModule VMMDLL_Map_GetModuleW #define VMMDLL_Map_GetModuleFromName VMMDLL_Map_GetModuleFromNameW #define VMMDLL_Map_GetUnloadedModule VMMDLL_Map_GetUnloadedModuleW #define VMMDLL_Map_GetEAT VMMDLL_Map_GetEATW #define VMMDLL_Map_GetIAT VMMDLL_Map_GetIATW #define VMMDLL_Map_GetHandle VMMDLL_Map_GetHandleW #define VMMDLL_Map_GetNet VMMDLL_Map_GetNetW #define VMMDLL_Map_GetUsers VMMDLL_Map_GetUsersW #define VMMDLL_Map_GetServices VMMDLL_Map_GetServicesW #define VMMDLL_WinGetThunkInfoIAT VMMDLL_WinGetThunkInfoIATW #endif /* _WIN32 */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __VMMDLL_H__ */

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Evan7198/mcp_server_pcileech'

If you have feedback or need assistance with the MCP directory API, please join our Discord server