[go: up one dir, main page]

Menu

[r33]: / pdb_list.py  Maximize  Restore  History

Download this file

126 lines (102 with data), 4.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env python
import sys,struct
# TODO: implement support for parsing paged out entries
# TODO: add option parsing to disable globals and large pages
# Flags taken from Intel(R) 64 and IA-32 Architectures Software Developer's
# Manual, Vol. 3A, section 3.7.6
PDE_FLAGS = { 'P' : 0x01, # Page is present (not swapped out)
'RW' : 0x02, # Read/Write flag
'US' : 0x04, # User/Supervisor flag
'PWT' : 0x08, # Write-through flag
'PCD' : 0x10, # Cache disabled flag
'A' : 0x20, # Accessed flag
'R' : 0x40, # Reserved [always 0]
'PS' : 0x80, # Indicates a 4MB page
'G' : 0x100 } # Global flag
PDE4M_FLAGS = { 'P' : 0x01, # Page is present (not swapped out)
'RW' : 0x02, # Read/Write flag
'US' : 0x04, # User/Supervisor flag
'PWT' : 0x08, # Write-through flag
'PCD' : 0x10, # Cache disabled flag
'A' : 0x20, # Accessed flag
'D' : 0x40, # Dirty
'PS' : 0x80, # Indicates a 4MB page
'G' : 0x100, # Global flag
'PAT' : 0x1000 } # Page Table Attribute Index
PTE_FLAGS = { 'P' : 0x01, # Page is present (not swapped out)
'RW' : 0x02, # Read/Write flag
'US' : 0x04, # User/Supervisor flag
'PWT' : 0x08, # Write-through flag
'PCD' : 0x10, # Cache disabled flag
'A' : 0x20, # Accessed flag
'D' : 0x40, # Dirty flag
'PTA' : 0x80, # Page Table Attribute Index
'G' : 0x100 } # Global flag
PDB_OFF = 0x18
# For optparse
options = None
# For both PDEs and PTEs, first 22 bits are a pointer
PT_PTR_MASK = 0xFFFFF000
# 4MB PDEs only the first 10 bits are used
PT4M_PTR_MASK = 0xFFC00000
def get_flags(value, flags):
return [ k for (k,v) in flags.items() if (value & v) > 0 ]
def parse_pte(memdump,pte,pdenum,ptenum):
if pte & PTE_FLAGS['G'] and options.noglobals:
return
page_addr = pte & PT_PTR_MASK
if options.debug: print "DEBUG: PTE = %s" % hex(pte)
print (("0x%08X|0x%08X|%d|%d|" % (page_addr, page_addr+0x1000,
pdenum,ptenum) +
",".join(get_flags(pte,PTE_FLAGS))))
def parse_4kb_pde(memdump,pde,pdenum):
if options.debug: print "DEBUG: PDE = %s" % hex(pde)
pt_addr = pde & PT_PTR_MASK
memdump.seek(pt_addr)
ptes = struct.unpack("<1024L", memdump.read(0x1000))
for (pte,ptenum) in zip(ptes,range(len(ptes))):
if not (pte & PTE_FLAGS['P']): continue
parse_pte(memdump,pte,pdenum,ptenum)
def parse_4mb_pde(memdump,pde,pdenum):
if options.nobigpages: return
page_addr = pde & PT4M_PTR_MASK
if options.debug: print "DEBUG: PDE4M = %s" % hex(pde)
print (("0x%08X|0x%08X|%d||" % (page_addr, page_addr+0x400000,pdenum)) +
",".join(get_flags(pde,PDE4M_FLAGS)))
def main(memdump, eproc_off):
# Read the base address of Page Directory
memdump.seek(eproc_off + PDB_OFF)
pdba = struct.unpack('<L', memdump.read(4))[0]
memdump.seek(pdba)
pdes = struct.unpack("<1024L", memdump.read(0x1000))
print "start|end|pde|pte|flags"
for (pde,pdenum) in zip(pdes,range(len(pdes))):
if not (pde & PDE_FLAGS['P']): continue
if pde & PDE_FLAGS['PS']:
parse_4mb_pde(memdump,pde,pdenum)
else:
parse_4kb_pde(memdump,pde,pdenum)
if __name__ == "__main__":
# Parse options
#if len(sys.argv) < 3:
# from os.path import basename
# print "usage: %s <memory dump> <_EPROCESS offset>" % basename(sys.argv[0])
# sys.exit(1)
from optparse import OptionParser
parser = OptionParser(usage="usage: %prog [options] <memory dump> <_EPROCESS offset>")
parser.add_option("-g", "--noglobals", action="store_true",
dest="noglobals", default=False,
help="do not print information about global pages")
parser.add_option("-4", "--no4mpages", action="store_true",
dest="nobigpages", default=False,
help="do not print information about 4M pages")
parser.add_option("-d", "--debug", action="store_true",
dest="debug", default=False,
help="do not print information about 4M pages")
(options, args) = parser.parse_args()
if len(args) != 2:
parser.error("incorrect number of arguments")
print options
memdump = open(args[0])
eproc_off = int(args[1],0)
main(memdump, eproc_off)