1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 """Interactive plugins.
20
21 This file contains a bunch of plugins which are useful when interactively
22 examining a memory image.
23 """
24 import itertools
25
26
27 from rekall import obj
28 from rekall.plugins.windows import common
29 from rekall_lib import utils
30
31
33 """A plugin to analyze a memory location."""
34 name = "analyze_struct"
35
36 __args = [
37 dict(name="offset", positional=True, type="SymbolAddress",
38 required=True,
39 help="A virtual address to analyze."),
40
41 dict(name="search", type="IntParser", default=0x100,
42 help="How far back to search for pool tag."),
43
44 dict(name="size", type="IntParser", default=0x100,
45 help="How many elements to identify."),
46 ]
47
48 table_header = [
49 dict(name="divider", type="Divider"),
50 dict(name="offset", style="address"),
51 dict(name="pool_offset", style="address"),
52 dict(name="content")
53 ]
54
56 """Search backwards from offset for a pool header."""
57 pool_alignment = self.session.profile.get_constant("PoolAlignment")
58 offset = int(offset) - offset % pool_alignment
59
60
61 for o in itertools.count(offset, -pool_alignment):
62 if o < offset-search:
63 break
64
65 pool_header = self.session.profile._POOL_HEADER(o)
66
67
68
69 if pool_header.BlockSize < (offset - o) / pool_alignment + 1:
70 continue
71
72
73
74
75
76 if pool_header.PreviousSize > 0:
77 previous_pool_header = self.session.profile._POOL_HEADER(
78 o - pool_alignment * pool_header.PreviousSize)
79
80 if previous_pool_header.BlockSize == pool_header.PreviousSize:
81 return pool_header
82
83
84 next_pool_header = self.session.profile._POOL_HEADER(
85 o + pool_alignment * pool_header.BlockSize)
86
87 if next_pool_header.PreviousSize == pool_header.BlockSize:
88 return pool_header
89
90 return obj.NoneObject("No pool tag found")
91
93 offset = int(offset)
94 resolver = self.session.address_resolver
95 result = []
96
97 for member in self.session.profile.Array(offset, target="Pointer",
98 count=size/8):
99 address_info = ["Data:%#x" % member.v()]
100 relative_offset = member.obj_offset - offset
101 result.append((relative_offset, address_info))
102
103
104 pool = self.SearchForPoolHeader(member.v(), search=search)
105 if pool:
106 address_info.append("Tag:%s" % pool.Tag)
107 proc = pool.m("ProcessBilled")
108
109
110 if proc.Peb:
111 address_info.append("ProcessBilled:%s" % proc.name)
112
113 address_info.append("@ %#x (%#x)" % (member.v(), pool.size))
114
115 else:
116
117 sym_offset, symbol = resolver.get_nearest_constant_by_address(
118 member.v())
119
120 if symbol and sym_offset == member.v():
121 address_info.append("Const:%s" % ", ".join(symbol))
122
123
124 list_member = member.cast("_LIST_ENTRY")
125 if list_member.obj_offset == list_member.Flink.Blink.v():
126 address_info.append("_LIST_ENTRY")
127 address_info.append("@ %#x" % list_member.Flink.v())
128
129 if list_member.obj_offset == list_member.Flink.v():
130 address_info.append("Empty")
131
132 return result
133
160