#!/usr/bin/env python
from memutil import virt2phys, offsets
from vadutil import VAD
from struct import unpack
def unpack_le(str):
"""Silly helper function to convert 4 characters to a little-endian unsigned int"""
return unpack("<L", str)[0]
if __name__ == "__main__":
from optparse import OptionParser
usage = "usage: %prog [options] <memory dump> <EPROCESS offset>"
parser = OptionParser(usage=usage)
parser.add_option("-d", "--dotfile", dest="dotfile",
help="write VAD tree as GraphViz Dotfile in FILE",
metavar='FILE')
parser.add_option("-t", "--tree",
action="store_true", dest="make_tree", default=False,
help="print VAD tree in tree format to stdout")
parser.add_option("-b", "--table",
action="store_true", dest="make_table", default=False,
help="print VAD tree in tabular format to stdout")
parser.add_option("-o", "--operating-system", dest="osname", default="XPSP2",
help=("operating system memory dump comes from"
" [default: %%default, options: %s]" % ",".join(offsets.keys())))
(options, args) = parser.parse_args()
if len(args) != 2:
import sys
parser.print_help()
sys.exit(1)
print "Done parsing arguments."
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])
vad_root_addr = unpack_le(eproc_struct[offs["VAD_ROOT_OFFSET"]:offs["VAD_ROOT_OFFSET"]+4])
vad_root = VAD(None, pdba, memdump, vad_root_addr)
print "Successfully walked/read entire VAD tree"
if options.make_table:
print "Table view:"
vad_root.print_as_table()
if options.make_tree:
print "Tree view:"
vad_root.print_as_tree()
if options.dotfile:
print "Writing dotfile to %s" % options.dotfile
f = open(options.dotfile, 'w')
f.write(vad_root.make_dot())
f.close()
memdump.close()