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