1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """This file implements ObjectRenderers for the JsonRenderer.
23
24 The JsonRenderer aims to serialize and recreate objects exactly at they were
25 upon unserializing them. This means that the environment loading the serialized
26 data must have access to all the necessary files (i.e. the complete memory image
27 file).
28
29 For example consider an _EPROCESS() instance. In memory, python merely stores
30 the following items in the object:
31
32 - obj_offset: The offset in the address space.
33 - obj_profile: The profile this object came from.
34 - obj_vm: The address space the object will be read from.
35
36 When the object is read, the address space is read at obj_offset, the data is
37 decoded and possibly other members are created using the profile. We do not know
38 the value of the object without reading it from the image.
39
40 Contrast this with the WebConsoleRenderer which needs to be deserialized in an
41 environment which does not have access to the original image. In this case we
42 must store all kinds of additional metadata about each object, since the decoder
43 is unable to directly get this information.
44
45 Example:
46
47 zeus2x4.vmem.E01 23:46:28> x = session.profile._EPROCESS(0x81e8a368)
48 zeus2x4.vmem.E01 23:46:32> encoder = json_renderer.JsonEncoder()
49 zeus2x4.vmem.E01 23:46:34> print encoder.Encode(x)
50 {'offset': 2179507048,
51 'profile': ('*', u'nt/GUID/1B2D0DFE2FB942758D615C901BE046922'),
52 'type': u'_EPROCESS,_EPROCESS,Struct,BaseAddressComparisonMixIn,BaseObject',
53 'type_name': ('*', u'_EPROCESS'),
54 'vm': {'base': {'filename': ('*',
55 u'/home/scudette/images/zeus2x4.vmem.E01'),
56 'type': u'EWFAddressSpace,CachingAddressSpaceMixIn,FDAddressSpace,BaseAddressSpace'},
57 'dtb': 233472,
58 'type': u'IA32PagedMemory,PagedReader,BaseAddressSpace'}}
59
60 zeus2x4.vmem.E01 23:47:25> decoder = json_renderer.JsonDecoder(session=session)
61 zeus2x4.vmem.E01 23:48:10> print decoder.Decode(encoder.Encode(x)).ImageFileName
62 alg.exe
63
64 Since the decoder is able to exactly recreate the original object, this object
65 can then be subsequently used to dereference the memory image - we can recover
66 the _EPROCESS.ImageFileName attribute and print the process name - even though
67 the actual name was never encoded.
68 """
69 import arrow
70
71 from rekall import addrspace
72 from rekall import obj
73 from rekall import session
74 from rekall.ui import json_renderer
75 from rekall_lib import utils
104
115
128
131 renders_type = "SlottedObject"
132
134 return dict((k, getattr(item, k))
135 for k in item.__slots__ if not k.startswith("_"))
136
148
149
150 -class IA32PagedMemoryObjectRenderer(BaseAddressSpaceObjectRenderer):
151 renders_type = "IA32PagedMemory"
152
153 - def GetState(self, item, **options):
154 state = super(IA32PagedMemoryObjectRenderer, self).GetState(
155 item, **options)
156 state["dtb"] = item.dtb
157
158 return state
159
189
207
210 """Encode a python set()."""
211 renders_type = ("set", "frozenset")
212
215
217 return set(state["data"])
218
221 """Encode a None Object."""
222 renders_type = "NoneObject"
223
226
232
235 renders_type = "UnixTimeStamp"
236
238 return item.get("string_value", "")
239
241 return dict(epoch=item.v(),
242 string_value=unicode(item))
243
246
249 renders_type = "Arrow"
250
252 return dict(epoch=item.float_timestamp,
253 string_value=item.isoformat())
254
256 return arrow.Arrow.fromtimestamp(state["epoch"])
257
260 """Encode a Pointer."""
261 renders_type = "Pointer"
262
269
279
282 """Encode an attributed string."""
283 renders_type = "AttributedString"
284
286 state = super(JsonAttributedStringRenderer, self).GetState(
287 item, **options)
288
289 state["value"] = utils.SmartUnicode(item.value)
290 state["highlights"] = item.highlights
291 return state
292
295 """Encode a hex dumped string."""
296 renders_type = "HexDumpedString"
297
299 state = super(JsonHexdumpRenderer, self).GetState(item, **options)
300 state["value"] = unicode(item.value.encode("hex"))
301 state["highlights"] = item.highlights
302
303 return state
304
307 renders_type = "Instruction"
308
310 return dict(value=unicode(item))
311
314 """For enumerations store both their value and the enum name."""
315 renders_type = ["Enumeration", "BitField"]
316
318 return dict(enum=unicode(item),
319 value=int(item))
320
322 return item.get("enum", "")
323
334
338 """Serialize RangedCollection objects."""
339 renders_type = ["RangedCollection"]
340
342
343
344 encoded = []
345 for start, end, data in item:
346 encoded.append((start, end, self._encode_value(data)))
347
348 return dict(data=encoded, mro="RangedCollection")
349
351 result = utils.RangedCollection()
352 for start, end, encoded_data in state["data"]:
353 result.insert(
354 start, end, self._decode_value(encoded_data, options))
355
356 return result
357