Package rekall :: Package plugins :: Package renderers :: Module base_objects
[frames] | no frames]

Source Code for Module rekall.plugins.renderers.base_objects

  1  # -*- coding: utf-8 -*- 
  2   
  3  # Rekall Memory Forensics 
  4  # Copyright 2014 Google Inc. All Rights Reserved. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or (at 
  9  # your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, but 
 12  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 14  # General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the Free Software 
 18  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 19  # 
 20   
 21  """This module implements base object renderers.""" 
 22   
 23  from rekall.ui import renderer as renderer_module 
 24  from rekall.ui import text 
 25  from rekall_lib import utils 
 26   
 27   
28 -class PluginObjectTextRenderer(text.TextObjectRenderer):
29 renders_type = "Plugin" 30
31 - def render_full(self, target, **_):
32 return text.Cell(repr(target))
33
34 - def render_compact(self, target, **_):
35 return text.Cell(target.name)
36 37
38 -class BaseObjectTextRenderer(text.TextObjectRenderer):
39 renders_type = "BaseObject" 40
41 - def render_address(self, target, **options):
42 return text.Cell( 43 self.format_address(target.obj_offset, **options) 44 )
45
46 - def render_full(self, target, **options):
47 result = text.Cell(unicode(target.v()), **options) 48 return result
49
50 - def render_value(self, target, **_):
51 return text.Cell(unicode(target.v()))
52 53
54 -class StringTextRenderer(BaseObjectTextRenderer):
55 renders_type = "String" 56
57 - def render_full(self, target, **_):
58 return text.Cell( 59 utils.SmartUnicode(target).split("\x00")[0] or u"")
60 61 render_value = render_full 62 render_compact = render_full
63 64
65 -class NoneObjectTextRenderer(BaseObjectTextRenderer):
66 """NoneObjects will be rendered with a single dash '-'.""" 67 renders_type = "NoneObject" 68
69 - def render_row(self, target, **_):
70 return text.Cell("-")
71 72
73 -class NoneTextRenderer(NoneObjectTextRenderer):
74 renders_type = "NoneType"
75 76
77 -class UnixTimestampObjectRenderer(BaseObjectTextRenderer):
78 renders_type = "UnixTimeStamp" 79
80 - def render_row(self, target, details=False, **options):
81 if details: 82 return text.Cell(repr(target)) 83 84 if target != None: 85 return text.Cell(unicode(target)) 86 87 return text.Cell("-")
88 89
90 -class ArrotTimestampObjectRenderer(BaseObjectTextRenderer):
91 renders_type = "Arrow" 92 93 timeformat = "YYYY-MM-DD HH:mm:ss" 94
95 - def render_row(self, target, details=False, **options):
96 if details: 97 return text.Cell(target.isoformat()) 98 99 if target != None: 100 return text.Cell(target.format(self.timeformat)) 101 102 return text.Cell("-")
103 104
105 -class PythonBoolTextRenderer(text.TextObjectRenderer):
106 renders_type = "bool" 107
108 - def render_full(self, target, **_):
109 color = "GREEN" if target else "RED" 110 return text.Cell( 111 value=unicode(target), 112 highlights=[(0, -1, color, None)])
113 114 render_value = render_full 115 render_compact = render_full
116 117
118 -class NativeTypeTextRenderer(BaseObjectTextRenderer):
119 renders_type = "NativeType" 120
121 - def render_address(self, target, width=None, **options):
122 return text.Cell( 123 self.format_address(target.v(), **options), 124 width=width)
125 126
127 -class BaseBoolTextRenderer(PythonBoolTextRenderer):
128 renders_type = "Bool" 129
130 - def render_row(self, target, **kwargs):
131 return super(BaseBoolTextRenderer, self).render_row(bool(target), 132 **kwargs)
133 134
135 -class FlagsTextRenderer(BaseObjectTextRenderer):
136 renders_type = "Flags" 137
138 - def render_full(self, target, **_):
139 flags = [] 140 value = target.v() 141 for k, v in sorted(target.maskmap.items()): 142 if value & v: 143 flags.append(k) 144 145 return text.Cell(u', '.join(flags))
146
147 - def render_value(self, target, **_):
148 return text.Cell(unicode(self.v()))
149
150 - def render_compact(self, target, **_):
151 lines = self.render_full(target).lines 152 if not lines: 153 return text.Cell("-") 154 155 elided = lines[0] 156 if len(elided) > 40: 157 elided = elided[:39] + u"…" 158 159 return text.Cell(elided)
160 161
162 -class EnumerationTextRenderer(BaseObjectTextRenderer):
163 renders_type = "Enumeration" 164
165 - def render_full(self, target, **_):
166 value = target.v() 167 name = target.choices.get(utils.SmartStr(value), target.default) or ( 168 u"UNKNOWN (%s)" % utils.SmartUnicode(value)) 169 170 return text.Cell(name)
171 172 render_compact = render_full
173 174
175 -class DatetimeTextRenderer(text.TextObjectRenderer):
176 renders_type = "datetime" 177
178 - def render_row(self, target, **_):
179 return text.Cell(target.strftime("%Y-%m-%d %H:%M:%S%z"))
180 181
182 -class PointerTextRenderer(NativeTypeTextRenderer):
183 renders_type = "Pointer" 184
185 - def render_value(self, *args, **kwargs):
186 return self.render_address(*args, **kwargs)
187
188 - def render_full(self, target, **_):
189 target_obj = target.deref() 190 if target_obj == None: 191 return text.Cell("-") 192 193 delegate_cls = renderer_module.ObjectRenderer.ForTarget( 194 target_obj, renderer=self.renderer) 195 196 return delegate_cls(session=self.session, 197 renderer=self.renderer).render_full(target_obj)
198
199 - def render_compact(self, target, **options):
200 return text.Cell( 201 "(%s *) %s" % ( 202 target.target, 203 self.format_address(target.v(), **options)) 204 )
205 206
207 -class ListRenderer(text.TextObjectRenderer):
208 """Renders a list of other objects.""" 209 renders_type = ("list", "set", "frozenset", "ListRepetition") 210
211 - def __init__(self, *args, **kwargs):
212 """We make a sub table for key, values.""" 213 super(ListRenderer, self).__init__(*args, **kwargs) 214 self.table = text.TextTable( 215 columns=[ 216 dict(name="x"), 217 ], 218 auto_widths=True, 219 renderer=self.renderer, 220 session=self.session)
221
222 - def render_row(self, target, **options):
223 result = [] 224 for i, item in enumerate(target): 225 result.append(self.table.get_row("- %s:" % i)) 226 result.append(self.table.get_row(item)) 227 228 return text.StackedCell(*result, **options)
229 230
231 -class TupleRenderer(text.TextObjectRenderer):
232 """Special handling for named tuples.""" 233 renders_type = ("tuple", ) 234
235 - def render_row(self, target, **options):
236 if not target: 237 return None 238 239 if hasattr(target, "_fields"): 240 new_target = {} 241 for field in target._fields: 242 new_target[field] = getattr(target, field) 243 244 object_renderer = self.ForTarget(new_target, self.renderer)( 245 session=self.session, renderer=self.renderer) 246 247 return object_renderer.render_row(new_target, **options) 248 249 result = [] 250 width = options.pop("width", None) 251 result = [] 252 for item in target: 253 object_renderer = self.ForTarget(item, self.renderer)( 254 session=self.session, renderer=self.renderer) 255 256 options["wrap"] = False 257 cell = object_renderer.render_row(item, **options) 258 result.append("\\n".join(cell.lines).strip()) 259 260 return text.Cell(", ".join(result), width=width)
261 262
263 -class VoidTextRenderer(PointerTextRenderer):
264 renders_type = "Void" 265
266 - def render_full(self, target, **options):
267 return text.Cell( 268 "(void *) %s" % self.format_address(target.v(), **options))
269 270 render_compact = render_full
271 272
273 -class FunctionTextRenderer(BaseObjectTextRenderer):
274 renders_type = "Function" 275
276 - def render_full(self, target, width=None, **_):
277 table = text.TextTable( 278 columns=[ 279 dict(name="Address", style="address"), 280 dict(name="OpCode", width=16), 281 dict(name="Op", width=width) 282 ], 283 renderer=self.renderer, 284 session=self.session) 285 286 result = [] 287 for instruction in target.disassemble(): 288 result.append(unicode(table.get_row( 289 instruction.address, instruction.hexbytes, instruction.text))) 290 291 return text.Cell("\n".join(result))
292
293 - def render_compact(self, target, **options):
294 return text.Cell(self.format_address(target.obj_offset, **options))
295 296 render_value = render_compact
297 298
299 -class StructTextRenderer(text.TextObjectRenderer):
300 renders_type = "Struct" 301 DEFAULT_STYLE = "compact" 302 renderers = ["TextRenderer", "TestRenderer"] 303 COLUMNS = None 304 table = None 305
306 - def __init__(self, *args, **kwargs):
307 self.columns = kwargs.pop("columns", self.COLUMNS) 308 309 super(StructTextRenderer, self).__init__(*args, **kwargs) 310 311 if self.columns: 312 self.table = text.TextTable( 313 columns=self.columns, 314 renderer=self.renderer, 315 session=self.session)
316
317 - def render_full(self, target, **_):
318 """Full render of a struct outputs every field.""" 319 result = repr(target) + "\n" 320 width_name = 0 321 322 fields = [] 323 # Print all the fields sorted by offset within the struct. 324 for k in target.members: 325 width_name = max(width_name, len(k)) 326 obj = getattr(target, k) 327 if obj == None: 328 obj = target.m(k) 329 330 fields.append( 331 (getattr(obj, "obj_offset", target.obj_offset) - 332 target.obj_offset, k, utils.SmartUnicode(repr(obj)))) 333 334 fields.sort() 335 336 result = result + u"\n".join( 337 [u" 0x%02X %s%s %s" % (offset, k, " " * (width_name - len(k)), v) 338 for offset, k, v in fields]) + "\n" 339 340 return text.Cell(result)
341
342 - def render_header(self, **kwargs):
343 style = kwargs.get("style", self.DEFAULT_STYLE) 344 345 if style == "compact" and self.table: 346 return self.table.render_header() 347 else: 348 return super(StructTextRenderer, self).render_header(**kwargs)
349
350 - def render_compact(self, target, **_):
351 """Compact render outputs only a few select columns, or repr.""" 352 if not self.table: 353 return self.render_repr(target) 354 355 values = [] 356 for column in self.columns: 357 name = column.get("name") 358 if not name: 359 raise ValueError( 360 "Column spec %r doesn't specify 'name'." % column) 361 362 values.append(getattr(target, name)) 363 364 return self.table.get_row(*values)
365
366 - def render_repr(self, target, **_):
367 """Explicitly just render the repr.""" 368 return text.Cell(repr(target))
369 370
371 -class AttributeDictTextRenderer(text.TextObjectRenderer):
372 renders_type = "dict" 373 renderers = ["TextRenderer", "TestRenderer"] 374
375 - def __init__(self, *args, **kwargs):
376 """We make a sub table for key, values.""" 377 super(AttributeDictTextRenderer, self).__init__(*args, **kwargs) 378 self.table = text.TextTable( 379 columns=[ 380 dict(name="Key"), 381 dict(name="Value"), 382 ], 383 auto_widths=True, 384 renderer=self.renderer, 385 session=self.session)
386
387 - def render_row(self, item, **options):
388 result = [] 389 for key, value in sorted(item.iteritems()): 390 result.append(self.table.get_row(key, value)) 391 392 return text.StackedCell(*result)
393 394
395 -class HexIntegerTextRenderer(text.TextObjectRenderer):
396 renders_type = "HexInteger" 397 renderers = ["TextRenderer", "TestRenderer"] 398
399 - def render_row(self, item, **options):
400 return text.Cell(hex(item), align="r")
401 402
403 -class TextHexdumpRenderer(text.TextObjectRenderer):
404 renders_type = "HexDumpedString" 405 renderers = ["TextRenderer", "TestRenderer"] 406
407 - def render_row(self, item, hex_width=None, **options):
408 if hex_width is None: 409 hex_width = (item.options.get("hex_width") or 410 self.session.GetParameter("hexdump_width", 8)) 411 412 data = item.value 413 highlights = item.highlights or [] 414 hex_highlights = [] 415 for x, y, f, b in highlights: 416 hex_highlights.append((3 * x, 3 * y, f, b)) 417 418 hexcell = text.Cell( 419 width=hex_width * 3, highlights=hex_highlights, 420 colorizer=self.renderer.colorizer) 421 datacell = text.Cell( 422 width=hex_width, highlights=highlights, 423 colorizer=self.renderer.colorizer) 424 425 for _, hexdata, translated_data in utils.Hexdump(data, width=hex_width): 426 hexcell.append_line(hexdata) 427 datacell.append_line("".join(translated_data)) 428 429 return text.JoinedCell(hexcell, datacell)
430