mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[+] module for work with NT Object tree manager:
* get object type - ntobj.getType(p) * build object list from handle table - ntobj.getListByHandleTable(pHandleTable, pType=0, bContainHeaders=True) git-svn-id: https://pykd.svn.codeplex.com/svn@59102 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
c486a6c782
commit
0fdc0e1c1f
140
samples/ntobj.py
Normal file
140
samples/ntobj.py
Normal file
@ -0,0 +1,140 @@
|
||||
#
|
||||
# Work with NT Object tree manager
|
||||
#
|
||||
# To use:
|
||||
#
|
||||
# ntobj.getType(p)
|
||||
# query object header by object pointer
|
||||
#
|
||||
# ntobj.getListByHandleTable(pHandleTable, pType=0, bContainHeaders=True)
|
||||
# build object list from handle table
|
||||
#
|
||||
|
||||
from pykd import *
|
||||
|
||||
def getTypeWin7(p):
|
||||
"""
|
||||
Get object header by object pointer
|
||||
|
||||
Implementation for Win7+
|
||||
"""
|
||||
pHeader = containingRecord(p, "nt", "_OBJECT_HEADER", "Body")
|
||||
pTypeIndexTable = getOffset("nt", "ObTypeIndexTable")
|
||||
return ptrPtr(pTypeIndexTable + (ptrSize() * pHeader->TypeIndex))
|
||||
|
||||
def getTypeLegacy(p):
|
||||
"""
|
||||
Get object header by object pointer
|
||||
|
||||
Implementation for before Win7
|
||||
"""
|
||||
pHeader = containingRecord(p, "nt", "_OBJECT_HEADER", "Body")
|
||||
return ptrPtr(pHeader->Type)
|
||||
|
||||
# Select platform-specific function for getting object header
|
||||
if (ptrWord(getOffset("nt", "NtBuildNumber")) >= 7600):
|
||||
getType = getTypeWin7
|
||||
else:
|
||||
getType = getTypeLegacy
|
||||
|
||||
HANDLE_VALUE_INC = 4
|
||||
HT_PAGE_SIZE = 4096
|
||||
HT_ENTRY_SIZE = (2 * ptrSize())
|
||||
HT_LOWLEVEL_COUNT = HT_PAGE_SIZE // HT_ENTRY_SIZE
|
||||
HT_MIDLEVEL_COUNT = HT_PAGE_SIZE // ptrSize()
|
||||
|
||||
def getListByHandleTable(pHandleTable, pType=0, bContainHeaders=True):
|
||||
"""
|
||||
Build list of objects from target handle table
|
||||
|
||||
Parameter pType if not 0 used for getting object of specific type,
|
||||
otherwise get object of all types
|
||||
|
||||
Parameter bContainHeaders used to interpret table contents:
|
||||
if bContainHeaders=True then table contains pointers to nt!_OBJECT_HEADER,
|
||||
otherwise table contains pointers to objects
|
||||
"""
|
||||
|
||||
def getByHandleEntry(hEntry, bContainHeader):
|
||||
"""
|
||||
Query object pointer by handle entry from handle table
|
||||
"""
|
||||
|
||||
if (0 == hEntry):
|
||||
return 0
|
||||
|
||||
HandleEntry = typedVar("nt", "_HANDLE_TABLE_ENTRY", addr64(hEntry))
|
||||
if (0xFFFFFFFE == HandleEntry.NextFreeTableEntry):
|
||||
return 0
|
||||
|
||||
p = ptrPtr(HandleEntry.getAddress()) & 0xFFFFFFFFFFFFFFF8
|
||||
if (0 == p):
|
||||
return 0
|
||||
|
||||
if (bContainHeader):
|
||||
pHeader = typedVar("nt", "_OBJECT_HEADER", addr64(p))
|
||||
p = pHeader.Body.getAddress()
|
||||
return p
|
||||
|
||||
def getListByHandleTableL0(pTableContent, nMaxHandleIndex, pType, bContainHeaders):
|
||||
"""
|
||||
Build list of objects from target handle table level 0
|
||||
"""
|
||||
lstObjects = list()
|
||||
nTableLevel0Count = nMaxHandleIndex // HANDLE_VALUE_INC
|
||||
for HandleEntryIndex in range(nTableLevel0Count):
|
||||
|
||||
pHandleEntry = pTableContent + (HT_ENTRY_SIZE * HandleEntryIndex)
|
||||
p = getByHandleEntry(pHandleEntry, bContainHeaders)
|
||||
if (0 == p):
|
||||
continue
|
||||
|
||||
if (0 == pType):
|
||||
lstObjects.append(p)
|
||||
else:
|
||||
pCurrentType = getType(p)
|
||||
if (addr64(pType) == pCurrentType):
|
||||
lstObjects.append(p)
|
||||
|
||||
return lstObjects
|
||||
|
||||
def getListByHandleTableL1(pTableContent, nMaxHandleIndex, pType, bContainHeaders):
|
||||
"""
|
||||
Build list of objects from target handle table level 1
|
||||
"""
|
||||
lstObjects = list()
|
||||
nTableLevel1Count = (nMaxHandleIndex // HANDLE_VALUE_INC) // HT_LOWLEVEL_COUNT
|
||||
for Index in range(nTableLevel1Count):
|
||||
pTableLevel0 = ptrPtr(pTableContent + (Index * ptrSize()))
|
||||
lstObjects += getListByHandleTableL0(pTableLevel0, HT_LOWLEVEL_COUNT * HANDLE_VALUE_INC, pType, bContainHeaders)
|
||||
|
||||
return lstObjects
|
||||
|
||||
def getListByHandleTableL2(pTableContent, nMaxHandleIndex, pType, bContainHeaders):
|
||||
"""
|
||||
Build list of objects from target handle table level 2
|
||||
"""
|
||||
lstObjects = list()
|
||||
nTableLevel2Count = ((nMaxHandleIndex // HANDLE_VALUE_INC) // HT_LOWLEVEL_COUNT) // HT_MIDLEVEL_COUNT
|
||||
for Index in range(nTableLevel2Count):
|
||||
pTableLevel1 = ptrPtr(pTableContent + (Index * ptrSize()))
|
||||
lstObjects += getListByHandleTableL1(pTableLevel1, HT_MIDLEVEL_COUNT * HT_LOWLEVEL_COUNT * HANDLE_VALUE_INC, pType, bContainHeaders)
|
||||
|
||||
return lstObjects
|
||||
|
||||
|
||||
|
||||
pHandleTable = typedVar("nt", "_HANDLE_TABLE", pHandleTable)
|
||||
nMaxHandleIndex = pHandleTable.NextHandleNeedingPool & 0xFFFFFFFF
|
||||
nTableLevel = (pHandleTable.TableCode & 3)
|
||||
pTableContent = pHandleTable.TableCode - nTableLevel
|
||||
|
||||
if (0 == nTableLevel):
|
||||
return getListByHandleTableL0(pTableContent, nMaxHandleIndex, pType, bContainHeaders)
|
||||
elif (1 == nTableLevel):
|
||||
return getListByHandleTableL1(pTableContent, nMaxHandleIndex, pType, bContainHeaders)
|
||||
elif (2 == nTableLevel):
|
||||
return getListByHandleTableL2(pTableContent, nMaxHandleIndex, pType, bContainHeaders)
|
||||
|
||||
dprintln("ERROR: Unknown handle table level: %u" % nTableLevel)
|
||||
return list()
|
Loading…
Reference in New Issue
Block a user