Version 5.2.11

This commit is contained in:
ufrisk
2022-12-14 23:25:53 +01:00
parent 9bb85a67b3
commit a07e137a2a
10 changed files with 112 additions and 59 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1981,6 +1981,22 @@ BOOL VMMDLL_ProcessGetInformation(
_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

View File

@@ -3,8 +3,8 @@
#define VERSION_MAJOR 5
#define VERSION_MINOR 2
#define VERSION_REVISION 10
#define VERSION_BUILD 96
#define VERSION_REVISION 11
#define VERSION_BUILD 97
#define VER_FILE_DESCRIPTION_STR "MemProcFS : Plugin vmemd"
#define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD

View File

@@ -3,8 +3,8 @@
#define VERSION_MAJOR 5
#define VERSION_MINOR 2
#define VERSION_REVISION 10
#define VERSION_BUILD 96
#define VERSION_REVISION 11
#define VERSION_BUILD 97
#define VER_FILE_DESCRIPTION_STR "MemProcFS"
#define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD

View File

@@ -9,10 +9,10 @@
#include "pdb.h"
#include "util.h"
typedef struct tdOB_MMPFN_CONTEXT {
OB ObHdr;
typedef struct tdMMPFN_CONTEXT {
BOOL fValid;
SRWLOCK LockSRW;
QWORD vaPfnDatabase;
CRITICAL_SECTION Lock;
POB_CONTAINER pObCProcTableDTB;
struct {
WORD cb;
@@ -23,30 +23,34 @@ typedef struct tdOB_MMPFN_CONTEXT {
WORD ou4;
} _MMPFN;
DWORD iPfnMax;
} OB_MMPFN_CONTEXT, *POB_MMPFN_CONTEXT;
} MMPFN_CONTEXT, *PMMPFN_CONTEXT;
#define MMPFN_PFN_TO_VA(ctx, i) (ctx->vaPfnDatabase + (QWORD)i * ctx->_MMPFN.cb)
VOID MmPfn_CallbackCleanup_ObContext(POB_MMPFN_CONTEXT ctx)
VOID MmPfn_Close(_In_ VMM_HANDLE H)
{
PMMPFN_CONTEXT ctx = (PMMPFN_CONTEXT)H->vmm.pMmPfnContext;
if(!ctx) { return; }
H->vmm.pMmPfnContext = NULL;
Ob_DECREF(ctx->pObCProcTableDTB);
DeleteCriticalSection(&ctx->Lock);
LocalFree(ctx);
}
VOID MmPfn_Refresh(_In_ VMM_HANDLE H)
{
POB_MMPFN_CONTEXT ctx = (POB_MMPFN_CONTEXT)H->vmm.pObPfnContext;
PMMPFN_CONTEXT ctx = (PMMPFN_CONTEXT)H->vmm.pMmPfnContext;
if(!ctx) { return; }
ObContainer_SetOb(ctx->pObCProcTableDTB, NULL);
}
_Success_(return)
BOOL MmPfn_Initialize_X64_Static(_In_ VMM_HANDLE H, _In_ PVMM_PROCESS pSystemProcess, _In_ POB_MMPFN_CONTEXT ctx)
VOID MmPfn_InitializeContext_StaticX64(_In_ VMM_HANDLE H, _In_ PVMM_PROCESS pSystemProcess, _In_ PMMPFN_CONTEXT ctx)
{
DWORD i, j, dwVersionBuild = H->vmm.kernel.dwVersionBuild;
DWORD iPte, iPfnSystem, dwVersionBuild = H->vmm.kernel.dwVersionBuild;
QWORD vaPteSystem, paDtbSystem, vaDtbSystem;
POB_SET psvaOb = NULL;
PVMMOB_MAP_PTE pObMapPte = NULL;
PVMM_MAP_PTEENTRY pe1, pe2;
if(dwVersionBuild < 6000) { return FALSE; }
if(dwVersionBuild < 6000) { return; }
// 1: static offsets
ctx->vaPfnDatabase = 0xFFFFFA8000000000;
ctx->_MMPFN.oOriginalPte = 0x020;
ctx->_MMPFN.oPteAddress = 0x010;
@@ -60,50 +64,80 @@ BOOL MmPfn_Initialize_X64_Static(_In_ VMM_HANDLE H, _In_ PVMM_PROCESS pSystemPro
ctx->_MMPFN.ou2 = 0x018;
ctx->_MMPFN.ou3 = 0x020;
}
if(dwVersionBuild < 14393) { return TRUE; }
// search for MmPfnDatabase virtual address on 14393+
if(VmmMap_GetPte(H, pSystemProcess, &pObMapPte, FALSE) && pObMapPte->cMap) {
for(i = pObMapPte->cMap; i; i--) {
pe1 = pObMapPte->pMap + i;
if(pe1->cPages > 0x10000000) {
for(j = i; j; j--) {
pe2 = pObMapPte->pMap + j;
if((pe1->vaBase & 0xfffffff000000000) != (pe2->vaBase & 0xfffffff000000000)) { break; }
if((pe2->vaBase & 0x0000000fffffffff) == 0) {
ctx->vaPfnDatabase = pe2->vaBase;
Ob_DECREF(pObMapPte);
return TRUE;
}
}
if(dwVersionBuild < 14393) {
ctx->fValid = TRUE;
return;
}
// 2: MmPfnDatabase virtual address is randomized on 14393+
// Search for candidates amongst PTEs starting at 4GB boundaries:
// Verify candidates by using known kernel PML4 PFN as oracle:
if(!VmmMap_GetPte(H, pSystemProcess, &pObMapPte, FALSE)) { goto fail; }
if(!(psvaOb = ObSet_New(H))) { goto fail; }
// 2.1: search for candidates starting 4GB boundaries:
iPfnSystem = (DWORD)(H->vmm.kernel.paDTB >> 12);
for(iPte = 0; iPte < pObMapPte->cMap; iPte++) {
if(!(DWORD)pObMapPte->pMap[iPte].vaBase) {
ObSet_Push(psvaOb, pObMapPte->pMap[iPte].vaBase + iPfnSystem * ctx->_MMPFN.cb);
}
}
// 2.2: verify candidate is correct by using kernel PML4 PTE as oracle:
VmmCachePrefetchPages3(H, pSystemProcess, psvaOb, ctx->_MMPFN.cb, 0);
while((vaPteSystem = ObSet_Pop(psvaOb))) {
if(VmmRead(H, pSystemProcess, vaPteSystem + ctx->_MMPFN.oPteAddress, (PBYTE)&vaDtbSystem, 8) && VMM_KADDR64_8(vaDtbSystem)) {
vaDtbSystem = vaDtbSystem & ~0xfff;
if(VmmVirt2Phys(H, pSystemProcess, vaDtbSystem, &paDtbSystem) && (paDtbSystem == pSystemProcess->paDTB)) {
ctx->vaPfnDatabase = vaPteSystem - iPfnSystem * ctx->_MMPFN.cb;
ctx->fValid = TRUE;
break;
}
}
}
fail:
Ob_DECREF(pObMapPte);
return FALSE;
Ob_DECREF(psvaOb);
}
VOID MmPfn_Initialize(_In_ VMM_HANDLE H, _In_ PVMM_PROCESS pSystemProcess)
VOID MmPfn_InitializeContext(_In_ VMM_HANDLE H)
{
BOOL f;
POB_MMPFN_CONTEXT ctx;
if(!(ctx = Ob_AllocEx(H, OB_TAG_PFN_CONTEXT, LMEM_ZEROINIT, sizeof(OB_MMPFN_CONTEXT), (OB_CLEANUP_CB)MmPfn_CallbackCleanup_ObContext, NULL))) { return; }
InitializeCriticalSection(&ctx->Lock);
ctx->pObCProcTableDTB = ObContainer_New();
f = PDB_GetSymbolPTR(H, PDB_HANDLE_KERNEL, "MmPfnDatabase", pSystemProcess, &ctx->vaPfnDatabase) &&
PMMPFN_CONTEXT ctx = NULL;
PVMM_PROCESS pObSystemProcess = NULL;
if(!(pObSystemProcess = VmmProcessGet(H, 4))) { goto fail; }
if(!(ctx = LocalAlloc(LMEM_ZEROINIT, sizeof(MMPFN_CONTEXT)))) { goto fail; }
if(!(ctx->pObCProcTableDTB = ObContainer_New())) { goto fail; }
ctx->iPfnMax = (DWORD)(H->dev.paMax >> 12);
ctx->fValid = PDB_GetSymbolPTR(H, PDB_HANDLE_KERNEL, "MmPfnDatabase", pObSystemProcess, &ctx->vaPfnDatabase) &&
PDB_GetTypeSizeShort(H, PDB_HANDLE_KERNEL, "_MMPFN", &ctx->_MMPFN.cb) &&
PDB_GetTypeChildOffsetShort(H, PDB_HANDLE_KERNEL, "_MMPFN", "OriginalPte", &ctx->_MMPFN.oOriginalPte) &&
PDB_GetTypeChildOffsetShort(H, PDB_HANDLE_KERNEL, "_MMPFN", "PteAddress", &ctx->_MMPFN.oPteAddress) &&
PDB_GetTypeChildOffsetShort(H, PDB_HANDLE_KERNEL, "_MMPFN", "u2", &ctx->_MMPFN.ou2) &&
PDB_GetTypeChildOffsetShort(H, PDB_HANDLE_KERNEL, "_MMPFN", "u3", &ctx->_MMPFN.ou3) &&
PDB_GetTypeChildOffsetShort(H, PDB_HANDLE_KERNEL, "_MMPFN", "u4", &ctx->_MMPFN.ou4);
if(!f && (H->vmm.tpMemoryModel == VMM_MEMORYMODEL_X64)) {
f = MmPfn_Initialize_X64_Static(H, pSystemProcess, ctx);
if(!ctx->fValid && (H->vmm.tpMemoryModel == VMM_MEMORYMODEL_X64)) {
MmPfn_InitializeContext_StaticX64(H, pObSystemProcess, ctx);
}
if(f && ctx->pObCProcTableDTB) {
ctx->iPfnMax = (DWORD)(H->dev.paMax >> 12);
H->vmm.pObPfnContext = Ob_INCREF(ctx);
H->vmm.pMmPfnContext = ctx;
fail:
Ob_DECREF(pObSystemProcess);
if(ctx && (ctx != H->vmm.pMmPfnContext)) {
Ob_DECREF(ctx->pObCProcTableDTB);
LocalFree(ctx);
}
Ob_DECREF(ctx);
}
_Success_(return != NULL)
PMMPFN_CONTEXT MmPfn_GetContext(_In_ VMM_HANDLE H)
{
PMMPFN_CONTEXT ctx;
static SRWLOCK LockSRW = SRWLOCK_INIT;
if(!H->vmm.pMmPfnContext) {
AcquireSRWLockExclusive(&LockSRW);
if(!H->vmm.pMmPfnContext) {
MmPfn_InitializeContext(H);
}
ReleaseSRWLockExclusive(&LockSRW);
}
ctx = (PMMPFN_CONTEXT)H->vmm.pMmPfnContext;
return (ctx && ctx->fValid) ? ctx : NULL;
}
/*
@@ -113,7 +147,7 @@ VOID MmPfn_Initialize(_In_ VMM_HANDLE H, _In_ PVMM_PROCESS pSystemProcess)
* -- ctx
* -- return
*/
POB_MAP MmPfn_ProcDTB_Create(_In_ VMM_HANDLE H, _In_ POB_MMPFN_CONTEXT ctx)
POB_MAP MmPfn_ProcDTB_Create(_In_ VMM_HANDLE H, _In_ PMMPFN_CONTEXT ctx)
{
POB_MAP pmOb = NULL;
PVMM_PROCESS pObProcess = NULL;
@@ -135,23 +169,23 @@ POB_MAP MmPfn_ProcDTB_Create(_In_ VMM_HANDLE H, _In_ POB_MMPFN_CONTEXT ctx)
* -- ctx
* -- return
*/
DWORD MmPfn_GetPidFromDTB(_In_ VMM_HANDLE H, _In_ POB_MMPFN_CONTEXT ctx, _In_ PVMM_PROCESS pSystemProcess, _In_ QWORD qwPfnDTB)
DWORD MmPfn_GetPidFromDTB(_In_ VMM_HANDLE H, _In_ PMMPFN_CONTEXT ctx, _In_ PVMM_PROCESS pSystemProcess, _In_ QWORD qwPfnDTB)
{
DWORD dwPID = 0;
POB_MAP pmObDtbPfn2Pid = NULL;
if(!(pmObDtbPfn2Pid = ObContainer_GetOb(ctx->pObCProcTableDTB))) {
EnterCriticalSection(&ctx->Lock);
AcquireSRWLockExclusive(&ctx->LockSRW);
if(!(pmObDtbPfn2Pid = ObContainer_GetOb(ctx->pObCProcTableDTB))) {
pmObDtbPfn2Pid = MmPfn_ProcDTB_Create(H, ctx);
}
LeaveCriticalSection(&ctx->Lock);
ReleaseSRWLockExclusive(&ctx->LockSRW);
}
dwPID = 0x7fffffff & (DWORD)(SIZE_T)ObMap_GetByKey(pmObDtbPfn2Pid, qwPfnDTB);
Ob_DECREF(pmObDtbPfn2Pid);
return dwPID;
}
VOID MmPfn_Map_GetPfn_GetVaX64(_In_ VMM_HANDLE H, _In_ POB_MMPFN_CONTEXT ctx, _In_ PVMM_PROCESS pSystemProcess, _In_ POB_SET psPte, _In_ POB_SET psPrefetch, _In_ BYTE iPML)
VOID MmPfn_Map_GetPfn_GetVaX64(_In_ VMM_HANDLE H, _In_ PMMPFN_CONTEXT ctx, _In_ PVMM_PROCESS pSystemProcess, _In_ POB_SET psPte, _In_ POB_SET psPrefetch, _In_ BYTE iPML)
{
BOOL f;
BYTE tp, pbPfn[0x30];
@@ -222,7 +256,7 @@ restart_new_pml_level:
}
}
VOID MmPfn_Map_GetPfn_GetVaX86PAE(_In_ VMM_HANDLE H, _In_ POB_MMPFN_CONTEXT ctx, _In_ PVMM_PROCESS pSystemProcess, _In_ POB_SET psPte, _In_ POB_SET psPrefetch, _In_ BYTE iPML)
VOID MmPfn_Map_GetPfn_GetVaX86PAE(_In_ VMM_HANDLE H, _In_ PMMPFN_CONTEXT ctx, _In_ PVMM_PROCESS pSystemProcess, _In_ POB_SET psPte, _In_ POB_SET psPrefetch, _In_ BYTE iPML)
{
BOOL f;
BYTE tp, pbPfn[0x30];
@@ -268,7 +302,7 @@ VOID MmPfn_Map_GetPfn_GetVaX86PAE(_In_ VMM_HANDLE H, _In_ POB_MMPFN_CONTEXT ctx,
}
}
VOID MmPfn_Map_GetPfn_GetVaX86(_In_ VMM_HANDLE H, _In_ POB_MMPFN_CONTEXT ctx, _In_ PVMM_PROCESS pSystemProcess, _In_ POB_SET psPte, _In_ POB_SET psPrefetch)
VOID MmPfn_Map_GetPfn_GetVaX86(_In_ VMM_HANDLE H, _In_ PMMPFN_CONTEXT ctx, _In_ PVMM_PROCESS pSystemProcess, _In_ POB_SET psPte, _In_ POB_SET psPrefetch)
{
BOOL f;
BYTE tp, pbPfn[0x30];
@@ -316,7 +350,7 @@ VOID MmPfn_Map_GetPfn_GetVaX86(_In_ VMM_HANDLE H, _In_ POB_MMPFN_CONTEXT ctx, _I
_Success_(return)
BOOL MmPfn_Map_GetPfnScatter(_In_ VMM_HANDLE H, _In_ POB_SET psPfn, _Out_ PMMPFNOB_MAP *ppObPfnMap, _In_ BOOL fExtended)
{
POB_MMPFN_CONTEXT ctx = (POB_MMPFN_CONTEXT)H->vmm.pObPfnContext;
PMMPFN_CONTEXT ctx;
BOOL f32 = H->vmm.f32;
BYTE pbPfn[0x30] = { 0 };
PVMM_PROCESS pObSystemProcess = NULL;
@@ -329,14 +363,14 @@ BOOL MmPfn_Map_GetPfnScatter(_In_ VMM_HANDLE H, _In_ POB_SET psPfn, _Out_ PMMPFN
QWORD va;
BYTE pb[0x1000];
} PageCache;
if(!ctx) { goto fail; }
// initialization
PageCache.va = 0;
if(!(ctx = MmPfn_GetContext(H))) { goto fail; }
if(!(cPfn = ObSet_Size(psPfn))) { goto fail; }
if(!(pObSystemProcess = VmmProcessGet(H, 4))) { goto fail; }
if(!(psObPrefetch = ObSet_New(H))) { goto fail; }
if(!(pObPfnMap = Ob_AllocEx(H, OB_TAG_MAP_PFN, LMEM_ZEROINIT, sizeof(MMPFNOB_MAP) + cPfn * sizeof(MMPFN_MAP_ENTRY), NULL, NULL))) { goto fail; }
pObPfnMap->cMap = cPfn;
PageCache.va = 0;
if(fExtended) {
if(!(psObEnrichAddress = ObSet_New(H))) { goto fail; }
}

View File

@@ -83,11 +83,12 @@ typedef struct tdMMPFNOB_MAP {
} MMPFNOB_MAP, *PMMPFNOB_MAP;
/*
* Initialize the PFN (page frame number) subsystem.
* Close / Shutdown the PFN subsystem. This function should never be called when
* there may be an active thread in the PFN subsystem. This function should only
* be called on shutdown.
* -- H
* -- pSystemProcess
*/
VOID MmPfn_Initialize(_In_ VMM_HANDLE H, _In_ PVMM_PROCESS pSystemProcess);
VOID MmPfn_Close(_In_ VMM_HANDLE H);
/*
* Refresh the PFN (page frame number) subsystem.

View File

@@ -40,6 +40,7 @@ typedef enum tdSTATISTICS_ID {
STATISTICS_ID_VMMDLL_PidList,
STATISTICS_ID_VMMDLL_PidGetFromName,
STATISTICS_ID_VMMDLL_ProcessGetInformation,
STATISTICS_ID_VMMDLL_ProcessGetInformationAll,
STATISTICS_ID_VMMDLL_ProcessGetInformationString,
STATISTICS_ID_VMMDLL_Log,
STATISTICS_ID_VMMDLL_Map_GetPte,
@@ -121,6 +122,7 @@ static LPCSTR STATISTICS_ID_STR[STATISTICS_ID_MAX] = {
[STATISTICS_ID_VMMDLL_PidList] = "VMMDLL_PidList",
[STATISTICS_ID_VMMDLL_PidGetFromName] = "VMMDLL_PidGetFromName",
[STATISTICS_ID_VMMDLL_ProcessGetInformation] = "VMMDLL_ProcessGetInformation",
[STATISTICS_ID_VMMDLL_ProcessGetInformationAll] = "VMMDLL_ProcessGetInformationAll",
[STATISTICS_ID_VMMDLL_ProcessGetInformationString] = "VMMDLL_ProcessGetInformationString",
[STATISTICS_ID_VMMDLL_Log] = "VMMDLL_Log",
[STATISTICS_ID_VMMDLL_Map_GetPte] = "VMMDLL_Map_GetPte",

View File

@@ -1990,7 +1990,7 @@ BOOL VMMDLL_ProcessGetInformation(
* -- ptr to DWORD to receive number of items processes on success.
* -- return = success/fail.
*/
_Success_(return)
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_ProcessGetInformationAll(
_In_ VMM_HANDLE hVMM,
_Out_ PVMMDLL_PROCESS_INFORMATION *ppProcessInformationAll,