[go: up one dir, main page]

Menu

[r79]: / memutil.py  Maximize  Restore  History

Download this file

135 lines (116 with data), 4.8 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
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python
from struct import unpack
# Offsets
# Add other Windows versions here as time permits
# Vista values taken from Andreas Schuster's post:
# http://computer.forensikblog.de/en/2007/01/eprocess_6_0_6000_16386.html
offsets = {
"XPSP2": {
"EPROC_SIZE": 0x260, # Size of EPROCESS structure
"PDBA_OFFSET": 0x18, # Page Directory Base Address
"PEB_OFFSET": 0x1B0, # Offset to Process Environment Block
"VAD_ROOT_OFFSET": 0x11c, # Offset to VadRoot
"HANDLE_TABLE_OFFSET": 0x0c4, # Offset to Handle Table
"PEB_IMG_BASE": 0x08, # Offset within PEB of Image Base Address
"PEB_LDR_DATA": 0x0c # Offset within PEB of _PEB_LDR_DATA
},
"2KSP4": {
"EPROC_SIZE": 0x290,
"PDBA_OFFSET": 0x18,
"PEB_OFFSET": 0x1B0,
"VAD_ROOT_OFFSET": 0x194,
"HANDLE_TABLE_OFFSET": 0x128,
"PEB_IMG_BASE": 0x08
},
"XP": {
"EPROC_SIZE": 0x258,
"PDBA_OFFSET": 0x18,
"PEB_OFFSET": 0x1B0,
"VAD_ROOT_OFFSET": 0x11c,
"HANDLE_TABLE_OFFSET": 0x0c4,
"PEB_IMG_BASE": 0x08
},
"Vista": {
"EPROC_SIZE": 0x26C,
"PDBA_OFFSET": 0x18,
"PEB_OFFSET": 0x188,
"VAD_ROOT_OFFSET": 0x238,
"PEB_IMG_BASE": 0x08 # FIXME: UNVERIFIED (but probably correct)
}
}
# Mask for base address in Page Directory Entries as well as Page
# Table Entries
PT_MASK = 0xFFFFF000
PD_MASK_4M = 0xFFC00000
# Page directory flags
PAGE_PRESENT = 0x00000001
PAGE_4M = 0x00000080
# Virtual address masks
PD_ENTRY_MASK = 0xFFC00000
PT_ENTRY_MASK = 0x003FF000
PAGE_OFFSET_MASK_4K = 0x00000FFF
PAGE_OFFSET_MASK_4M = 0x003FFFFF
class Unsupported(Exception):
"""Exception thrown when requested operation is not suppored yet."""
class PagedOutException(Exception):
"""Empty exception class to indicate that requested page is swapped out."""
def read_range(memdump,pdba,start,end,step=4096,zero_invalid_pages=True):
"""Read the contents of a memory range. This is done a page at a time,
as adjacent virtual memory addresses may reference completely different
areas of physical memory.
Arguments:
memdump - file pointer to the memory dump image
pdba - address of the page directory
start - virtual address of the start of the region
end - virtual address of the end of the region
step - how many bytes to read at a time [default: a 4k page, or 4096 bytes]
zero_invalid_pages - fill any invalid (paged out) areas with zeroes
Returns: a string containing the contents of the memory range
"""
accum = ''
for addr in range(start, end, step):
if end - addr < step:
bytes_to_read = end - addr
else:
bytes_to_read = step
try:
real_addr = virt2phys(memdump,pdba,addr)
#print "DEBUG: reading memory at %08x virt, %08x phys" % (addr,real_addr)
memdump.seek(real_addr)
accum += memdump.read(bytes_to_read)
except PagedOutException:
if zero_invalid_pages:
#print "WARN: skipping memory page at 0x%08x as it is paged out." % addr
accum += ('\0' * bytes_to_read)
else:
raise PagedOutException
return accum
def virt2phys(memdump, pdba, addr):
"""Convert a virtual address to a physical one.
A file pointer to a memory dump, the offset to a page directory,
and a virtual address are required. The return value is a 32-bit
unsigned integer giving the physical address of the page."""
orig_pos = memdump.tell()
pd_num = (addr & PD_ENTRY_MASK) >> 22
pt_num = (addr & PT_ENTRY_MASK) >> 12
memdump.seek(pdba + (pd_num*4))
page_directory_entry = unpack("<L", memdump.read(4))[0]
# Check if page table is present
if (page_directory_entry & PAGE_PRESENT) == 0:
raise PagedOutException("Page table is paged out")
# Check if it is a 4M page
if (page_directory_entry & PAGE_4M):
page_offset = (addr & PAGE_OFFSET_MASK_4M)
page_base = page_directory_entry & PD_MASK_4M
return page_base + page_offset
#raise Unsupported("4M Pages are not yet supported")
else:
page_offset = (addr & PAGE_OFFSET_MASK_4K)
ptba = page_directory_entry & PT_MASK
memdump.seek(ptba + (pt_num*4))
page_table_entry = unpack("<L", memdump.read(4))[0]
if (page_table_entry & PAGE_PRESENT) == 0:
raise PagedOutException("Memory page is paged out")
page_base = page_table_entry & PT_MASK
memdump.seek(orig_pos)
return page_base + page_offset