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