Files
MemProcFS/vmmpyc/vmmpyc_processmaps.c
2026-01-04 15:00:03 +01:00

531 lines
26 KiB
C

// vmmpyc_processmaps.c : implementation of process infomaps functionality for vmmpyc.
//
// (c) Ulf Frisk, 2021-2026
// Author: Ulf Frisk, pcileech@frizk.net
//
#include "vmmpyc.h"
PyObject *g_pPyType_ProcessMaps = NULL;
// ((BOOL)) -> [{...}]
static PyObject*
VmmPycProcessMaps_pte(PyObj_ProcessMaps *self, PyObject *args)
{
PyObject *pyList, *pyDict;
BOOL result, fIdentifyModules;
DWORD i;
PVMMDLL_MAP_PTEENTRY pe;
PVMMDLL_MAP_PTE pPteMap = NULL;
CHAR sz[5];
if(!self->fValid) { return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.pte(): Not initialized."); }
if(!PyArg_ParseTuple(args, "|p", &fIdentifyModules)) {
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.pte(): Illegal argument.");
}
if(!(pyList = PyList_New(0))) { return PyErr_NoMemory(); }
Py_BEGIN_ALLOW_THREADS;
result = VMMDLL_Map_GetPteU(self->pyVMM->hVMM, self->dwPID, fIdentifyModules, &pPteMap);
Py_END_ALLOW_THREADS;
if(!result || (pPteMap->dwVersion != VMMDLL_MAP_PTE_VERSION)) {
Py_DECREF(pyList);
VMMDLL_MemFree(pPteMap);
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.pte(): Failed.");
}
for(i = 0; i < pPteMap->cMap; i++) {
if((pyDict = PyDict_New())) {
pe = pPteMap->pMap + i;
PyDict_SetItemString_DECREF(pyDict, "va", PyLong_FromUnsignedLongLong(pe->vaBase));
PyDict_SetItemString_DECREF(pyDict, "size", PyLong_FromUnsignedLongLong(pe->cPages << 12));
PyDict_SetItemString_DECREF(pyDict, "pages", PyLong_FromUnsignedLongLong(pe->cPages));
PyDict_SetItemString_DECREF(pyDict, "pages-sw", PyLong_FromUnsignedLong(pe->cSoftware));
PyDict_SetItemString_DECREF(pyDict, "wow64", PyBool_FromLong((long)pe->fWoW64));
PyDict_SetItemString_DECREF(pyDict, "tag", PyUnicode_FromString(pe->uszText));
PyDict_SetItemString_DECREF(pyDict, "flags-pte", PyLong_FromUnsignedLongLong(pe->fPage));
sz[0] = (pe->fPage & VMMDLL_MEMMAP_FLAG_PAGE_NS) ? '-' : 's';
sz[1] = 'r';
sz[2] = (pe->fPage & VMMDLL_MEMMAP_FLAG_PAGE_W) ? 'w' : '-';
sz[3] = (pe->fPage & VMMDLL_MEMMAP_FLAG_PAGE_NX) ? '-' : 'x';
sz[4] = 0;
PyDict_SetItemString_DECREF(pyDict, "flags", PyUnicode_FromString(sz));
PyList_Append_DECREF(pyList, pyDict);
}
}
VMMDLL_MemFree(pPteMap);
return pyList;
}
VOID VmmPycProcessMaps_vad_Protection(_In_ PVMMDLL_MAP_VADENTRY pVad, _Out_writes_(6) LPSTR sz)
{
BYTE vh = (BYTE)pVad->Protection >> 3;
BYTE vl = (BYTE)pVad->Protection & 7;
sz[0] = pVad->fPrivateMemory ? 'p' : '-'; // PRIVATE MEMORY
sz[1] = (vh & 2) ? ((vh & 1) ? 'm' : 'g') : ((vh & 1) ? 'n' : '-'); // -/NO_CACHE/GUARD/WRITECOMBINE
sz[2] = ((vl == 1) || (vl == 3) || (vl == 4) || (vl == 6)) ? 'r' : '-'; // COPY ON WRITE
sz[3] = (vl & 4) ? 'w' : '-'; // WRITE
sz[4] = (vl & 2) ? 'x' : '-'; // EXECUTE
sz[5] = ((vl == 5) || (vl == 7)) ? 'c' : '-'; // COPY ON WRITE
if(sz[1] != '-' && sz[2] == '-' && sz[3] == '-' && sz[4] == '-' && sz[5] == '-') { sz[1] = '-'; }
}
LPSTR VmmPycProcessMaps_vad_Type(_In_ PVMMDLL_MAP_VADENTRY pVad)
{
if(pVad->fImage) {
return "Image";
} else if(pVad->fFile) {
return "File ";
} else if(pVad->fHeap) {
return "Heap ";
} else if(pVad->fStack) {
return "Stack";
} else if(pVad->fTeb) {
return "Teb ";
} else if(pVad->fPageFile) {
return "Pf ";
} else {
return " ";
}
}
// ((BOOL)) -> [{...}]
static PyObject*
VmmPycProcessMaps_vad(PyObj_ProcessMaps *self, PyObject *args)
{
PyObject *pyList, *pyDict;
BOOL result, fIdentifyModules = FALSE;
DWORD i;
PVMMDLL_MAP_VADENTRY pe;
PVMMDLL_MAP_VAD pVadMap = NULL;
CHAR szVadProtection[7] = { 0 };
if(!self->fValid) { return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.vad(): Not initialized."); }
if(!PyArg_ParseTuple(args, "|p", &fIdentifyModules)) {
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.vad(): Illegal argument.");
}
if(!(pyList = PyList_New(0))) { return PyErr_NoMemory(); }
Py_BEGIN_ALLOW_THREADS;
result = VMMDLL_Map_GetVadU(self->pyVMM->hVMM, self->dwPID, fIdentifyModules, &pVadMap);
Py_END_ALLOW_THREADS;
if(!result || (pVadMap->dwVersion != VMMDLL_MAP_VAD_VERSION)) {
Py_DECREF(pyList);
VMMDLL_MemFree(pVadMap);
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.vad(): Failed.");
}
for(i = 0; i < pVadMap->cMap; i++) {
if((pyDict = PyDict_New())) {
pe = pVadMap->pMap + i;
VmmPycProcessMaps_vad_Protection(pe, szVadProtection);
PyDict_SetItemString_DECREF(pyDict, "start", PyLong_FromUnsignedLongLong(pe->vaStart));
PyDict_SetItemString_DECREF(pyDict, "end", PyLong_FromUnsignedLongLong(pe->vaEnd));
PyDict_SetItemString_DECREF(pyDict, "cvadex-pages", PyLong_FromUnsignedLong(pe->cVadExPages));
PyDict_SetItemString_DECREF(pyDict, "cvadex-pages-base", PyLong_FromUnsignedLong(pe->cVadExPagesBase));
PyDict_SetItemString_DECREF(pyDict, "subsection", PyLong_FromUnsignedLongLong(pe->vaSubsection));
PyDict_SetItemString_DECREF(pyDict, "prototype", PyLong_FromUnsignedLongLong(pe->vaPrototypePte));
PyDict_SetItemString_DECREF(pyDict, "prototype-len", PyLong_FromUnsignedLong(pe->cbPrototypePte));
PyDict_SetItemString_DECREF(pyDict, "mem_commit", PyBool_FromLong((long)pe->MemCommit));
PyDict_SetItemString_DECREF(pyDict, "commit_charge", PyLong_FromUnsignedLong(pe->CommitCharge));
PyDict_SetItemString_DECREF(pyDict, "protection", PyUnicode_FromString(szVadProtection));
PyDict_SetItemString_DECREF(pyDict, "type", PyUnicode_FromFormat("%s", VmmPycProcessMaps_vad_Type(pe)));
PyDict_SetItemString_DECREF(pyDict, "tag", PyUnicode_FromString(pe->uszText));
PyList_Append_DECREF(pyList, pyDict);
}
}
VMMDLL_MemFree(pVadMap);
return pyList;
}
CHAR VmmPycProcessMaps_vad_ex_Type(_In_ VMMDLL_PTE_TP tp)
{
switch(tp) {
case VMMDLL_PTE_TP_HARDWARE: return 'A';
case VMMDLL_PTE_TP_TRANSITION: return 'T';
case VMMDLL_PTE_TP_PROTOTYPE: return 'P';
case VMMDLL_PTE_TP_DEMANDZERO: return 'Z';
case VMMDLL_PTE_TP_COMPRESSED: return 'C';
case VMMDLL_PTE_TP_PAGEFILE: return 'F';
default: return '-';
}
}
// (DWORD, DWORD) -> [{...}]
static PyObject*
VmmPycProcessMaps_vad_ex(PyObj_ProcessMaps *self, PyObject *args)
{
PyObject *pyList, *pyDict;
BOOL result;
DWORD oPage, cPage, i;
PVMMDLL_MAP_VADEXENTRY pe;
PVMMDLL_MAP_VADEX pVadExMap = NULL;
if(!self->fValid) { return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.vad_ex(): Not initialized."); }
if(!PyArg_ParseTuple(args, "II", &oPage, &cPage)) {
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.vad_ex(): Illegal argument.");
}
if(!(pyList = PyList_New(0))) { return PyErr_NoMemory(); }
Py_BEGIN_ALLOW_THREADS;
result =
VMMDLL_Map_GetVadEx(self->pyVMM->hVMM, self->dwPID, oPage, cPage, &pVadExMap);
Py_END_ALLOW_THREADS;
if(!result || (pVadExMap->dwVersion != VMMDLL_MAP_VADEX_VERSION)) {
Py_DECREF(pyList);
VMMDLL_MemFree(pVadExMap);
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.vad_ex(): Failed.");
}
for(i = 0; i < pVadExMap->cMap; i++) {
if((pyDict = PyDict_New())) {
pe = pVadExMap->pMap + i;
PyDict_SetItemString_DECREF(pyDict, "tp", PyUnicode_FromFormat("%c", VmmPycProcessMaps_vad_ex_Type(pe->tp)));
PyDict_SetItemString_DECREF(pyDict, "pml", PyLong_FromUnsignedLong(pe->iPML));
PyDict_SetItemString_DECREF(pyDict, "pteflags", PyLong_FromUnsignedLong(pe->pteFlags));
PyDict_SetItemString_DECREF(pyDict, "va", PyLong_FromUnsignedLongLong(pe->va));
PyDict_SetItemString_DECREF(pyDict, "pa", PyLong_FromUnsignedLongLong(pe->pa));
PyDict_SetItemString_DECREF(pyDict, "pte", PyLong_FromUnsignedLongLong(pe->pte));
PyDict_SetItemString_DECREF(pyDict, "vad-va", PyLong_FromUnsignedLongLong(pe->vaVadBase));
PyDict_SetItemString_DECREF(pyDict, "proto-tp", PyUnicode_FromFormat("%c", VmmPycProcessMaps_vad_ex_Type(pe->proto.tp)));
PyDict_SetItemString_DECREF(pyDict, "proto-pa", PyLong_FromUnsignedLongLong(pe->proto.pa));
PyDict_SetItemString_DECREF(pyDict, "proto-pte", PyLong_FromUnsignedLongLong(pe->proto.pte));
PyList_Append_DECREF(pyList, pyDict);
}
}
VMMDLL_MemFree(pVadExMap);
return pyList;
}
// () -> [{...}]
static PyObject*
VmmPycProcessMaps_unloaded_module(PyObj_ProcessMaps *self, PyObject *args)
{
PyObject *pyList, *pyDict;
BOOL result;
ULONG64 i;
PVMMDLL_MAP_UNLOADEDMODULE pUnloadedMap = NULL;
PVMMDLL_MAP_UNLOADEDMODULEENTRY pe;
if(!self->fValid) { return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.unloaded_module(): Not initialized."); }
if(!(pyList = PyList_New(0))) { return PyErr_NoMemory(); }
Py_BEGIN_ALLOW_THREADS;
result = VMMDLL_Map_GetUnloadedModuleU(self->pyVMM->hVMM, self->dwPID, &pUnloadedMap);
Py_END_ALLOW_THREADS;
if(!result || (pUnloadedMap->dwVersion != VMMDLL_MAP_UNLOADEDMODULE_VERSION)) {
Py_DECREF(pyList);
VMMDLL_MemFree(pUnloadedMap);
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.unloaded_module(): Failed.");
}
for(i = 0; i < pUnloadedMap->cMap; i++) {
if((pyDict = PyDict_New())) {
pe = pUnloadedMap->pMap + i;
PyDict_SetItemString_DECREF(pyDict, "va", PyLong_FromUnsignedLongLong(pe->vaBase));
PyDict_SetItemString_DECREF(pyDict, "size", PyLong_FromUnsignedLong(pe->cbImageSize));
PyDict_SetItemString_DECREF(pyDict, "wow64", PyBool_FromLong((long)pe->fWoW64));
PyDict_SetItemString_DECREF(pyDict, "name", PyUnicode_FromString(pe->uszText));
PyDict_SetItemString_DECREF(pyDict, "dwCheckSum", PyLong_FromUnsignedLong(pe->dwCheckSum));
PyDict_SetItemString_DECREF(pyDict, "dwTimeDateStamp", PyLong_FromUnsignedLong(pe->dwTimeDateStamp));
PyDict_SetItemString_DECREF(pyDict, "ft", PyLong_FromUnsignedLongLong(pe->ftUnload));
PyList_Append_DECREF(pyList, pyDict);
}
}
VMMDLL_MemFree(pUnloadedMap);
return pyList;
}
// () -> {'heap': {...}, 'segment': [...]}
static PyObject*
VmmPycProcessMaps_heap(PyObj_ProcessMaps *self, PyObject *args)
{
PyObject *pyDictResult, *pyDictHeap, *pyListSegment, *pyDict;
BOOL result;
DWORD i;
PVMMDLL_MAP_HEAPENTRY peH;
PVMMDLL_MAP_HEAP_SEGMENTENTRY peS;
PVMMDLL_MAP_HEAP pHeapMap = NULL;
if(!self->fValid) { return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.heap(): Not initialized."); }
if(!(pyListSegment = PyList_New(0))) { return PyErr_NoMemory(); }
if(!(pyDictHeap = PyDict_New())) { return PyErr_NoMemory(); }
if(!(pyDictResult = PyDict_New())) { return PyErr_NoMemory(); }
PyDict_SetItemString_DECREF(pyDictResult, "heap", pyDictHeap);
PyDict_SetItemString_DECREF(pyDictResult, "segment", pyListSegment);
Py_BEGIN_ALLOW_THREADS;
result = VMMDLL_Map_GetHeap(self->pyVMM->hVMM, self->dwPID, &pHeapMap);
Py_END_ALLOW_THREADS;
if(!result || (pHeapMap->dwVersion != VMMDLL_MAP_HEAP_VERSION)) {
Py_DECREF(pyDictResult);
VMMDLL_MemFree(pHeapMap);
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.heap(): Failed.");
}
for(i = 0; i < pHeapMap->cMap; i++) {
if((pyDict = PyDict_New())) {
peH = pHeapMap->pMap + i;
PyDict_SetItemString_DECREF(pyDict, "va", PyLong_FromUnsignedLongLong(peH->va));
PyDict_SetItemString_DECREF(pyDict, "tp", PyLong_FromUnsignedLong(peH->tp));
PyDict_SetItemString_DECREF(pyDict, "heapid", PyLong_FromUnsignedLong(peH->iHeap));
PyDict_SetItemDWORD_DECREF(pyDictHeap, peH->iHeap, pyDict);
}
}
for(i = 0; i < pHeapMap->cSegments; i++) {
if((pyDict = PyDict_New())) {
peS = pHeapMap->pSegments + i;
PyDict_SetItemString_DECREF(pyDict, "va", PyLong_FromUnsignedLongLong(peS->va));
PyDict_SetItemString_DECREF(pyDict, "tp", PyLong_FromUnsignedLong(peS->tp));
PyDict_SetItemString_DECREF(pyDict, "heapid", PyLong_FromUnsignedLong(peS->iHeap));
PyDict_SetItemString_DECREF(pyDict, "size", PyLong_FromUnsignedLong(peS->cb));
PyList_Append_DECREF(pyListSegment, pyDict);
}
}
VMMDLL_MemFree(pHeapMap);
return pyDictResult;
}
// (QWORD) -> [...]
static PyObject*
VmmPycProcessMaps_heapalloc(PyObj_ProcessMaps *self, PyObject *args)
{
PyObject *pyListResult, *pyDict;
BOOL result;
DWORD i;
QWORD vaHeap;
PVMMDLL_MAP_HEAPALLOCENTRY peA;
PVMMDLL_MAP_HEAPALLOC pHeapAllocMap = NULL;
if(!self->fValid) { return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.heapalloc(): Not initialized."); }
if(!PyArg_ParseTuple(args, "K", &vaHeap)) {
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.heapalloc(): Illegal argument.");
}
if(!(pyListResult = PyList_New(0))) { return PyErr_NoMemory(); }
Py_BEGIN_ALLOW_THREADS;
result = VMMDLL_Map_GetHeapAlloc(self->pyVMM->hVMM, self->dwPID, vaHeap, &pHeapAllocMap);
Py_END_ALLOW_THREADS;
if(!result || (pHeapAllocMap->dwVersion != VMMDLL_MAP_HEAPALLOC_VERSION)) {
Py_DECREF(pyListResult);
VMMDLL_MemFree(pHeapAllocMap);
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.heapalloc(): Failed.");
}
for(i = 0; i < pHeapAllocMap->cMap; i++) {
if((pyDict = PyDict_New())) {
peA = pHeapAllocMap->pMap + i;
PyDict_SetItemString_DECREF(pyDict, "va", PyLong_FromUnsignedLongLong(peA->va));
PyDict_SetItemString_DECREF(pyDict, "tp", PyLong_FromUnsignedLong(peA->tp));
PyDict_SetItemString_DECREF(pyDict, "size", PyLong_FromUnsignedLong(peA->cb));
PyList_Append_DECREF(pyListResult, pyDict);
}
}
VMMDLL_MemFree(pHeapAllocMap);
return pyListResult;
}
// () -> [{...}]
static PyObject*
VmmPycProcessMaps_thread(PyObj_ProcessMaps *self, PyObject *args)
{
PyObject *pyList, *pyDict;
BOOL result;
DWORD i;
PVMMDLL_MAP_THREADENTRY pe;
PVMMDLL_MAP_THREAD pThreadMap = NULL;
if(!self->fValid) { return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.thread(): Not initialized."); }
CHAR szTimeUTC[MAX_PATH];
if(!(pyList = PyList_New(0))) { return PyErr_NoMemory(); }
Py_BEGIN_ALLOW_THREADS;
result = VMMDLL_Map_GetThread(self->pyVMM->hVMM, self->dwPID, &pThreadMap);
Py_END_ALLOW_THREADS;
if(!result || (pThreadMap->dwVersion != VMMDLL_MAP_THREAD_VERSION)) {
Py_DECREF(pyList);
VMMDLL_MemFree(pThreadMap);
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.thread(): Failed.");
}
for(i = 0; i < pThreadMap->cMap; i++) {
if((pyDict = PyDict_New())) {
pe = pThreadMap->pMap + i;
PyDict_SetItemString_DECREF(pyDict, "tid", PyLong_FromUnsignedLong(pe->dwTID));
PyDict_SetItemString_DECREF(pyDict, "pid", PyLong_FromUnsignedLong(pe->dwPID));
PyDict_SetItemString_DECREF(pyDict, "exitstatus", PyLong_FromUnsignedLong(pe->dwExitStatus));
PyDict_SetItemString_DECREF(pyDict, "state", PyLong_FromUnsignedLong(pe->bState));
PyDict_SetItemString_DECREF(pyDict, "running", PyLong_FromUnsignedLong(pe->bRunning));
PyDict_SetItemString_DECREF(pyDict, "priority", PyLong_FromUnsignedLong(pe->bPriority));
PyDict_SetItemString_DECREF(pyDict, "basepriority", PyLong_FromUnsignedLong(pe->bBasePriority));
PyDict_SetItemString_DECREF(pyDict, "waitreason", PyLong_FromUnsignedLong(pe->bWaitReason));
PyDict_SetItemString_DECREF(pyDict, "va-ethread", PyLong_FromUnsignedLongLong(pe->vaETHREAD));
PyDict_SetItemString_DECREF(pyDict, "va-teb", PyLong_FromUnsignedLongLong(pe->vaTeb));
PyDict_SetItemString_DECREF(pyDict, "va-start", PyLong_FromUnsignedLongLong(pe->vaStartAddress));
PyDict_SetItemString_DECREF(pyDict, "va-win32start", PyLong_FromUnsignedLongLong(pe->vaWin32StartAddress));
PyDict_SetItemString_DECREF(pyDict, "va-stackbase", PyLong_FromUnsignedLongLong(pe->vaStackBaseUser));
PyDict_SetItemString_DECREF(pyDict, "va-stacklimit", PyLong_FromUnsignedLongLong(pe->vaStackLimitUser));
PyDict_SetItemString_DECREF(pyDict, "va-stackbase-kernel", PyLong_FromUnsignedLongLong(pe->vaStackBaseKernel));
PyDict_SetItemString_DECREF(pyDict, "va-stacklimit-kernel", PyLong_FromUnsignedLongLong(pe->vaStackLimitKernel));
PyDict_SetItemString_DECREF(pyDict, "va-trapframe", PyLong_FromUnsignedLongLong(pe->vaTrapFrame));
PyDict_SetItemString_DECREF(pyDict, "va-impersonation-token", PyLong_FromUnsignedLongLong(pe->vaImpersonationToken));
PyDict_SetItemString_DECREF(pyDict, "reg-rip", PyLong_FromUnsignedLongLong(pe->vaRIP));
PyDict_SetItemString_DECREF(pyDict, "reg-rsp", PyLong_FromUnsignedLongLong(pe->vaRSP));
PyDict_SetItemString_DECREF(pyDict, "time-create", PyLong_FromUnsignedLongLong(pe->ftCreateTime));
PyDict_SetItemString_DECREF(pyDict, "time-exit", PyLong_FromUnsignedLongLong(pe->ftExitTime));
Util_FileTime2String(pe->ftCreateTime, szTimeUTC);
PyDict_SetItemString_DECREF(pyDict, "time-create-str", PyUnicode_FromFormat("%s", szTimeUTC));
Util_FileTime2String(pe->ftExitTime, szTimeUTC);
PyDict_SetItemString_DECREF(pyDict, "time-exit-str", PyUnicode_FromFormat("%s", szTimeUTC));
PyList_Append_DECREF(pyList, pyDict);
}
}
VMMDLL_MemFree(pThreadMap);
return pyList;
}
// () -> [{...}]
static PyObject*
VmmPycProcessMaps_thread_callstack(PyObj_ProcessMaps *self, PyObject *args)
{
PyObject *pyList, *pyDict;
BOOL result;
DWORD i, dwTID, dwFlags = 0;
PVMMDLL_MAP_THREAD_CALLSTACKENTRY pe;
PVMMDLL_MAP_THREAD_CALLSTACK pThreadCallstackMap = NULL;
if(!self->fValid) { return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.thread_callstack(): Not initialized."); }
if(!PyArg_ParseTuple(args, "I|I", &dwTID, &dwFlags)) {
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.thread_callstack(): Illegal argument.");
}
if(!(pyList = PyList_New(0))) { return PyErr_NoMemory(); }
Py_BEGIN_ALLOW_THREADS;
result = VMMDLL_Map_GetThread_CallstackU(self->pyVMM->hVMM, self->dwPID, dwTID, dwFlags, &pThreadCallstackMap);
Py_END_ALLOW_THREADS;
if(!result || (pThreadCallstackMap->dwVersion != VMMDLL_MAP_THREAD_CALLSTACK_VERSION)) {
Py_DECREF(pyList);
VMMDLL_MemFree(pThreadCallstackMap);
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.thread_callstack(): Failed.");
}
for(i = 0; i < pThreadCallstackMap->cMap; i++) {
if((pyDict = PyDict_New())) {
pe = pThreadCallstackMap->pMap + i;
PyDict_SetItemString_DECREF(pyDict, "pid", PyLong_FromUnsignedLong(self->dwPID));
PyDict_SetItemString_DECREF(pyDict, "tid", PyLong_FromUnsignedLong(dwTID));
PyDict_SetItemString_DECREF(pyDict, "i", PyLong_FromUnsignedLong(pe->i));
PyDict_SetItemString_DECREF(pyDict, "va-retaddr", PyLong_FromUnsignedLongLong(pe->vaRetAddr));
PyDict_SetItemString_DECREF(pyDict, "va-rsp", PyLong_FromUnsignedLongLong(pe->vaRSP));
PyDict_SetItemString_DECREF(pyDict, "va-base-sp", PyLong_FromUnsignedLongLong(pe->vaBaseSP));
PyDict_SetItemString_DECREF(pyDict, "displacement", PyLong_FromUnsignedLong(pe->cbDisplacement));
PyDict_SetItemString_DECREF(pyDict, "type", PyUnicode_FromString(pe->uszModule));
PyDict_SetItemString_DECREF(pyDict, "type", PyUnicode_FromString(pe->uszFunction));
PyList_Append_DECREF(pyList, pyDict);
}
}
VMMDLL_MemFree(pThreadCallstackMap);
return pyList;
}
// () -> [{...}]
static PyObject*
VmmPycProcessMaps_handle(PyObj_ProcessMaps *self, PyObject *args)
{
PyObject *pyList, *pyDict;
BOOL result;
ULONG64 i;
PVMMDLL_MAP_HANDLE pHandleMap = NULL;
PVMMDLL_MAP_HANDLEENTRY pe;
if(!self->fValid) { return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.handle(): Not initialized."); }
if(!(pyList = PyList_New(0))) { return PyErr_NoMemory(); }
Py_BEGIN_ALLOW_THREADS;
result = VMMDLL_Map_GetHandleU(self->pyVMM->hVMM, self->dwPID, &pHandleMap);
Py_END_ALLOW_THREADS;
if(!result || (pHandleMap->dwVersion != VMMDLL_MAP_HANDLE_VERSION)) {
Py_DECREF(pyList);
VMMDLL_MemFree(pHandleMap);
return PyErr_Format(PyExc_RuntimeError, "ProcessMaps.handle(): Failed.");
}
for(i = 0; i < pHandleMap->cMap; i++) {
if((pyDict = PyDict_New())) {
pe = pHandleMap->pMap + i;
PyDict_SetItemString_DECREF(pyDict, "va-object", PyLong_FromUnsignedLongLong(pe->vaObject));
PyDict_SetItemString_DECREF(pyDict, "handle", PyLong_FromUnsignedLong(pe->dwHandle));
PyDict_SetItemString_DECREF(pyDict, "access", PyLong_FromUnsignedLong(pe->dwGrantedAccess));
PyDict_SetItemString_DECREF(pyDict, "typeindex", PyLong_FromUnsignedLong(pe->iType));
PyDict_SetItemString_DECREF(pyDict, "pid", PyLong_FromUnsignedLong(pe->dwPID));
PyDict_SetItemString_DECREF(pyDict, "pooltag", PyLong_FromUnsignedLong(pe->dwPoolTag));
PyDict_SetItemString_DECREF(pyDict, "chandle", PyLong_FromUnsignedLongLong(pe->qwHandleCount));
PyDict_SetItemString_DECREF(pyDict, "cpointer", PyLong_FromUnsignedLongLong(pe->qwPointerCount));
PyDict_SetItemString_DECREF(pyDict, "va-object-creatinfo", PyLong_FromUnsignedLongLong(pe->vaObjectCreateInfo));
PyDict_SetItemString_DECREF(pyDict, "va-securitydescriptor", PyLong_FromUnsignedLongLong(pe->vaSecurityDescriptor));
PyDict_SetItemString_DECREF(pyDict, "tag", PyUnicode_FromString(pe->uszText));
PyDict_SetItemString_DECREF(pyDict, "type", PyUnicode_FromString(pe->uszType));
PyList_Append_DECREF(pyList, pyDict);
}
}
VMMDLL_MemFree(pHandleMap);
return pyList;
}
//-----------------------------------------------------------------------------
// VmmPycProcessMaps INITIALIZATION AND CORE FUNCTIONALITY BELOW:
//-----------------------------------------------------------------------------
PyObj_ProcessMaps*
VmmPycProcessMaps_InitializeInternal(_In_ PyObj_Vmm *pyVMM, _In_ DWORD dwPID)
{
PyObj_ProcessMaps *pyObj;
if(!(pyObj = PyObject_New(PyObj_ProcessMaps, (PyTypeObject*)g_pPyType_ProcessMaps))) { return NULL; }
Py_INCREF(pyVMM); pyObj->pyVMM = pyVMM;
pyObj->fValid = TRUE;
pyObj->dwPID = dwPID;
return pyObj;
}
static PyObject*
VmmPycProcessMaps_repr(PyObj_ProcessMaps *self)
{
return self->fValid ?
PyUnicode_FromFormat("ProcessMaps:%i", self->dwPID) :
PyUnicode_FromFormat("ProcessMaps:NotValid");
}
static int
VmmPycProcessMaps_init(PyObj_ProcessMaps *self, PyObject *args, PyObject *kwds)
{
PyErr_SetString(PyExc_TypeError, "ProcessMaps.init(): Not allowed.");
return -1;
}
static void
VmmPycProcessMaps_dealloc(PyObj_ProcessMaps *self)
{
self->fValid = FALSE;
Py_XDECREF(self->pyVMM);
PyObject_Del(self);
}
_Success_(return)
BOOL VmmPycProcessMaps_InitializeType(PyObject *pModule)
{
static PyMethodDef PyMethods[] = {
{"pte", (PyCFunction)VmmPycProcessMaps_pte, METH_VARARGS, "Retrieve the PTE memory map."},
{"vad", (PyCFunction)VmmPycProcessMaps_vad, METH_VARARGS, "Retrieve the VAD memory map."},
{"vad_ex", (PyCFunction)VmmPycProcessMaps_vad_ex, METH_VARARGS, "Retrieve extended VAD map (with additional information about each page)."},
{"unloaded_module", (PyCFunction)VmmPycProcessMaps_unloaded_module, METH_VARARGS, "Retrieve the unloaded modules."},
{"heap", (PyCFunction)VmmPycProcessMaps_heap, METH_VARARGS, "Retrieve the heaps."},
{"heapalloc", (PyCFunction)VmmPycProcessMaps_heapalloc, METH_VARARGS, "Retrieve heap allocations for a specified heap."},
{"thread", (PyCFunction)VmmPycProcessMaps_thread, METH_VARARGS, "Retrieve the threads."},
{"thread_callstack", (PyCFunction)VmmPycProcessMaps_thread_callstack, METH_VARARGS, "Retrieve the callstack for a specific thread."},
{"handle", (PyCFunction)VmmPycProcessMaps_handle, METH_VARARGS, "Retrieve the handles."},
{NULL, NULL, 0, NULL}
};
static PyMemberDef PyMembers[] = {
{"pid", T_ULONG, offsetof(PyObj_ProcessMaps, dwPID), READONLY, "PID"},
{NULL}
};
static PyGetSetDef PyGetSet[] = {
{NULL}
};
static PyType_Slot PyTypeSlot[] = {
{Py_tp_init, VmmPycProcessMaps_init},
{Py_tp_dealloc, VmmPycProcessMaps_dealloc},
{Py_tp_repr, VmmPycProcessMaps_repr},
{Py_tp_methods, PyMethods},
{Py_tp_members, PyMembers},
{Py_tp_getset, PyGetSet},
{0, 0}
};
static PyType_Spec PyTypeSpec = {
.name = "vmmpyc.VmmProcessMaps",
.basicsize = sizeof(PyObj_ProcessMaps),
.itemsize = 0,
.flags = Py_TPFLAGS_DEFAULT,
.slots = PyTypeSlot,
};
if((g_pPyType_ProcessMaps = PyType_FromSpec(&PyTypeSpec))) {
if(PyModule_AddObject(pModule, "VmmProcessMaps", g_pPyType_ProcessMaps) < 0) {
Py_DECREF(g_pPyType_ProcessMaps);
g_pPyType_ProcessMaps = NULL;
}
}
return g_pPyType_ProcessMaps ? TRUE : FALSE;
}