1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 from rekall import obj
23
24 from rekall.plugins.windows import common
25 from rekall.plugins.windows.gui import win32k_core
26
27
29 """Pool scanner for atom tables"""
30
43
44
45 -class AtomScan(win32k_core.Win32kPluginMixin, common.PoolScannerPlugin):
46 """Pool scanner for _RTL_ATOM_TABLE"""
47
48 __name = "atomscan"
49
50 __args = [
51 dict(name="sort_by", choices=["atom", "refcount", "offset"],
52 default="offset", help="Sort by [offset | atom | refcount]")
53 ]
54
55 table_header = [
56 dict(name="offset_p", style="address"),
57 dict(name="offset_v", style="address"),
58 dict(name="atom", style="address"),
59 dict(name="refs", width=6),
60 dict(name="pinned", width=6),
61 dict(name="name"),
62 ]
63
64 scanner_defaults = dict(
65 scan_physical=True
66 )
67
69 for run in self.generate_memory_ranges():
70 scanner = PoolScanAtom(
71 profile=self.win32k_profile, session=self.session,
72 address_space=run.address_space)
73
74 for pool_header in scanner.scan(run.start, run.length):
75
76
77
78
79
80
81
82 version = self.profile.metadata('version')
83 fixup = 0
84
85 if self.profile.metadata('arch') == 'I386':
86 if version > 5.1:
87 fixup = 8
88 else:
89 if version > 5.1:
90 fixup = 16
91
92 atom_table = self.win32k_profile._RTL_ATOM_TABLE(
93 offset=pool_header.obj_end + fixup,
94 vm=pool_header.obj_vm)
95
96
97
98
99 if not atom_table.is_valid():
100 continue
101
102
103
104
105 atoms = []
106 for atom in atom_table.atoms(vm=self.kernel_address_space):
107 if atom.is_string_atom():
108 atoms.append(atom)
109
110 if self.plugin_args.sort_by == "atom":
111 attr = "Atom"
112 elif self.plugin_args.sort_by == "refcount":
113 attr = "ReferenceCount"
114 else:
115 attr = "obj_offset"
116
117 for atom in sorted(atoms, key=lambda x: getattr(x, attr)):
118 yield dict(offset_p=atom_table.obj_offset,
119 offset_v=atom.obj_offset,
120 atom=atom.Atom,
121 refs=atom.ReferenceCount,
122 pinned=atom.Pinned,
123 name=atom.Name)
124
125
126 -class Atoms(win32k_core.Win32kPluginMixin,
127 common.WindowsCommandPlugin):
128 """Print session and window station atom tables.
129
130 From:
131 http://msdn.microsoft.com/en-us/library/windows/desktop/ms649053.aspx
132
133 An atom table is a system-defined table that stores strings and
134 corresponding identifiers. An application places a string in an atom table
135 and receives a 16-bit integer, called an atom, that can be used to access
136 the string. A string that has been placed in an atom table is called an atom
137 name.
138
139 The global atom table is available to all applications. When an application
140 places a string in the global atom table, the system generates an atom that
141 is unique throughout the system. Any application that has the atom can
142 obtain the string it identifies by querying the global atom table.
143
144 (The global atom tables are only global within each session).
145 """
146
147 __name = "atoms"
148
149
150 table_header = [
151 dict(name="offset_p", style="address"),
152 dict(name="session", width=10),
153 dict(name="windows_station", width=18),
154 dict(name="atom", style="address"),
155 dict(name="ref_count", width=10),
156 dict(name="hindex", width=10),
157 dict(name="pinned", width=10),
158 dict(name="name"),
159 ]
160
162 """Generate all the atoms in the windows station atom table."""
163 table = station.pGlobalAtomTable
164
165
166
167
168 if table.Signature != 0x6D6F7441:
169 return
170
171 for atom in sorted(table.atoms(), key=lambda x: x.Atom):
172
173 if not atom.is_string_atom():
174 continue
175
176 yield table, atom
177
179 """Generate all (Session) Global User Atoms."""
180
181 table = self.win32k_profile.get_constant_object(
182 "UserAtomTableHandle",
183 target="Pointer",
184 target_args=dict(
185 target="_RTL_ATOM_TABLE",
186 ),
187 vm=session.obj_vm,
188 )
189
190 for atom in sorted(table.atoms(), key=lambda x: x.Atom):
191
192 if not atom.is_string_atom():
193 continue
194
195 yield table, atom
196
208
210 for table, atom, window_station, session_id in self.find_atoms():
211 yield dict(offset_p=table,
212 session=session_id,
213 windows_station=window_station.Name,
214 atom=atom.Atom,
215 ref_count=atom.ReferenceCount,
216 hindex=atom.HandleIndex,
217 pinned=atom.Pinned,
218 name=atom.Name)
219