[go: up one dir, main page]

Menu

[r80]: / misc / objwalk.py  Maximize  Restore  History

Download this file

103 lines (81 with data), 3.7 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
#!/usr/bin/env python
from struct import unpack
from memutil import virt2phys, PagedOutException, offsets, read_range
from hexutil import hd
from general import getUnicodeString
def unpack_le(str):
"""Silly helper function to convert 4 characters to a little-endian unsigned int"""
return unpack("<L", str)[0]
def get_object_dir_list(memdump,pdba,list_head):
next = list_head
objs = []
entries_seen = []
while True:
entries_seen.append(next)
try:
next_real = virt2phys(memdump,pdba,next)
except PagedOutException:
break
print "Reading directory entry at %08x (%08x)" % (next,next_real)
memdump.seek(next_real)
(next, obj) = unpack("<LL",memdump.read(8))
print "Found object reference %08x" % obj
if obj: objs.append(obj)
if next == list_head or next == 0 or next in entries_seen:
break
return objs
def get_object_type(memdump,pdba,objaddr):
try:
objaddr_real = virt2phys(memdump,pdba,objaddr)
print "DEBUG: getting type for object at %08x (%08x)" % (objaddr,objaddr_real)
memdump.seek(objaddr_real - 0x18 + 0x08) # _OBJECT_HEADER+0x08 (Type)
obj_type_addr_virt = unpack_le(memdump.read(4))
obj_type_addr_real = virt2phys(memdump,pdba,obj_type_addr_virt)
memdump.seek(obj_type_addr_real+0x40) # _OBJECT_TYPE+0x40 (Name)
(namelen,namelenmax,name) = unpack("<HHL", memdump.read(8))
except PagedOutException:
return "[memory error while reading type information]"
return getUnicodeString(memdump,pdba,name,namelen)
def autodetect_dir_root(memdump, pdba):
"""Quick function to get the address of the directory root using the KPCR method.
NOTE: only works on XP and above."""
KPCR_BASE = 0xffdff000
KdVersionBlockOffset = virt2phys(memdump,pdba,KPCR_BASE)
memdump.seek(KdVersionBlockOffset+0x34)
KdVersionBlockVirt = unpack_le(memdump.read(4))
KdVersionBlockReal = virt2phys(memdump,pdba,KdVersionBlockVirt)
memdump.seek(KdVersionBlockReal+0x20)
DebuggerDataListVirt = unpack_le(memdump.read(4))
DebuggerDataListReal = virt2phys(memdump,pdba,DebuggerDataListVirt)
memdump.seek(DebuggerDataListReal)
KdDebuggerData64Virt = unpack_le(memdump.read(4))
KdDebuggerData64Real = virt2phys(memdump,pdba,KdDebuggerData64Virt)
memdump.seek(KdDebuggerData64Real+0x98)
ObpObjectDirectoryRoot = unpack_le(memdump.read(4))
return ObpObjectDirectoryRoot
if __name__ == "__main__":
from general import parser
parser.add_option("-d", "--dirroot", dest="dir_root",
help="virtual offset of the root directory object [default: autodetect]")
(options, args) = parser.parse_args()
if len(args) != 2:
import sys
parser.print_help()
sys.exit(1)
memdump = open(args[0], 'rb')
eproc_offset = int(args[1], 0)
offs = offsets[options.osname]
memdump.seek(eproc_offset)
eproc_struct = memdump.read(offs["EPROC_SIZE"])
pdba = unpack_le(eproc_struct[offs["PDBA_OFFSET"]:offs["PDBA_OFFSET"]+4])
if not options.dir_root:
dir_root = autodetect_dir_root(memdump,pdba)
else:
dir_root = int(options.dir_root,0)
print "Object Directory Root: %08x (%08x)" % (dir_root,virt2phys(memdump,pdba,dir_root))
print "Object type:", get_object_type(memdump,pdba,dir_root)
objs = get_object_dir_list(memdump,pdba,dir_root)
for obj in objs:
typestr = get_object_type(memdump,pdba,obj).encode('ascii','replace')
print "Type:", typestr
memdump.close()