Package rekall :: Package plugins :: Package addrspaces :: Module xpress
[frames] | no frames]

Source Code for Module rekall.plugins.addrspaces.xpress

  1  # Rekall Memory Forensics 
  2  # Copyright (c) 2008 Volatile Systems 
  3  # Copyright (c) 2008 Brendan Dolan-Gavitt <bdolangavitt@wesleyan.edu> 
  4  # Copyright 2013 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  #  The source code in this file was inspired by the work of Matthieu Suiche, 
 22  #  http://sandman.msuiche.net/, and the information presented released as 
 23  #  part of the Microsoft Interoperability Initiative: 
 24  #  http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-DRSR%5D.pdf 
 25  #  A special thanks to Matthieu for all his help! 
 26   
 27  """ 
 28  @author:       Brendan Dolan-Gavitt 
 29  @license:      GNU General Public License 2.0 or later 
 30  @contact:      bdolangavitt@wesleyan.edu 
 31  """ 
 32   
 33  #pylint: disable-msg=C0111 
 34   
 35  from struct import unpack 
 36  from struct import error as StructError 
 37   
38 -def recombine(outbuf):
39 return "".join(outbuf[k] for k in sorted(outbuf.keys()))
40
41 -def xpress_decode(inputBuffer):
42 outputBuffer = {} 43 outputIndex = 0 44 inputIndex = 0 45 indicatorBit = 0 46 nibbleIndex = 0 47 48 # we are decoding the entire input here, so I have changed 49 # the check to see if we're at the end of the output buffer 50 # with a check to see if we still have any input left. 51 while inputIndex < len(inputBuffer): 52 if (indicatorBit == 0): 53 # in pseudocode this was indicatorBit = ..., but that makes no 54 # sense, so I think this was intended... 55 try: 56 indicator = unpack("<L", inputBuffer[inputIndex:inputIndex + 4])[0] 57 except StructError: 58 return recombine(outputBuffer) 59 60 inputIndex += 4 61 indicatorBit = 32 62 63 indicatorBit = indicatorBit - 1 64 # check whether the bit specified by indicatorBit is set or not 65 # set in indicator. For example, if indicatorBit has value 4 66 # check whether the 4th bit of the value in indicator is set 67 if not (indicator & (1 << indicatorBit)): 68 try: 69 outputBuffer[outputIndex] = inputBuffer[inputIndex] 70 except IndexError: 71 return recombine(outputBuffer) 72 73 inputIndex += 1 74 outputIndex += 1 75 else: 76 # Get the length. This appears to use a scheme whereby if 77 # the value at the current width is all ones, then we assume 78 # that it is actually wider. First we try 3 bits, then 3 79 # bits plus a nibble, then a byte, and finally two bytes (an 80 # unsigned short). Also, if we are using a nibble, then every 81 # other time we get the nibble from the high part of the previous 82 # byte used as a length nibble. 83 # Thus if a nibble byte is F2, we would first use the low part (2), 84 # and then at some later point get the nibble from the high part (F). 85 86 try: 87 length = unpack("<H", inputBuffer[inputIndex:inputIndex + 2])[0] 88 except StructError: 89 return recombine(outputBuffer) 90 91 inputIndex += 2 92 offset = length / 8 93 length = length % 8 94 if length == 7: 95 if nibbleIndex == 0: 96 nibbleIndex = inputIndex 97 length = ord(inputBuffer[inputIndex]) % 16 98 inputIndex += 1 99 else: 100 # get the high nibble of the last place a nibble sized 101 # length was used thus we don't waste that extra half 102 # byte :p 103 length = ord(inputBuffer[nibbleIndex]) / 16 104 nibbleIndex = 0 105 106 if length == 15: 107 length = ord(inputBuffer[inputIndex]) 108 inputIndex += 1 109 if length == 255: 110 try: 111 length = unpack("<H", inputBuffer[inputIndex:inputIndex + 2])[0] 112 except StructError: 113 return recombine(outputBuffer) 114 inputIndex = inputIndex + 2 115 length = length - (15 + 7) 116 length = length + 15 117 length = length + 7 118 length = length + 3 119 120 while length != 0: 121 try: 122 outputBuffer[outputIndex] = outputBuffer[outputIndex - offset - 1] 123 except KeyError: 124 return recombine(outputBuffer) 125 outputIndex += 1 126 length -= 1 127 128 return recombine(outputBuffer)
129 130 try: 131 import pyxpress #pylint: disable-msg=F0401 132 133 xpress_decode = pyxpress.decode 134 except ImportError: 135 pass 136 137 if __name__ == "__main__": 138 import sys 139 dec_data = xpress_decode(open(sys.argv[1]).read()) 140 sys.stdout.write(dec_data) 141