Trees | Indices | Help |
|
---|
|
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 4042 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
Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Mon Oct 9 03:29:49 2017 | http://epydoc.sourceforge.net |