/usr/lib/python2.7/dist-packages/rekall/plugins/addrspaces/xpress.py is in python-rekall-core 1.6.0+dfsg-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | # Rekall Memory Forensics
# Copyright (c) 2008 Volatile Systems
# Copyright (c) 2008 Brendan Dolan-Gavitt <bdolangavitt@wesleyan.edu>
# Copyright 2013 Google Inc. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# The source code in this file was inspired by the work of Matthieu Suiche,
# http://sandman.msuiche.net/, and the information presented released as
# part of the Microsoft Interoperability Initiative:
# http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-DRSR%5D.pdf
# A special thanks to Matthieu for all his help!
"""
@author: Brendan Dolan-Gavitt
@license: GNU General Public License 2.0 or later
@contact: bdolangavitt@wesleyan.edu
"""
#pylint: disable-msg=C0111
from struct import unpack
from struct import error as StructError
def recombine(outbuf):
return "".join(outbuf[k] for k in sorted(outbuf.keys()))
def xpress_decode(inputBuffer):
outputBuffer = {}
outputIndex = 0
inputIndex = 0
indicatorBit = 0
nibbleIndex = 0
# we are decoding the entire input here, so I have changed
# the check to see if we're at the end of the output buffer
# with a check to see if we still have any input left.
while inputIndex < len(inputBuffer):
if (indicatorBit == 0):
# in pseudocode this was indicatorBit = ..., but that makes no
# sense, so I think this was intended...
try:
indicator = unpack("<L", inputBuffer[inputIndex:inputIndex + 4])[0]
except StructError:
return recombine(outputBuffer)
inputIndex += 4
indicatorBit = 32
indicatorBit = indicatorBit - 1
# check whether the bit specified by indicatorBit is set or not
# set in indicator. For example, if indicatorBit has value 4
# check whether the 4th bit of the value in indicator is set
if not (indicator & (1 << indicatorBit)):
try:
outputBuffer[outputIndex] = inputBuffer[inputIndex]
except IndexError:
return recombine(outputBuffer)
inputIndex += 1
outputIndex += 1
else:
# Get the length. This appears to use a scheme whereby if
# the value at the current width is all ones, then we assume
# that it is actually wider. First we try 3 bits, then 3
# bits plus a nibble, then a byte, and finally two bytes (an
# unsigned short). Also, if we are using a nibble, then every
# other time we get the nibble from the high part of the previous
# byte used as a length nibble.
# Thus if a nibble byte is F2, we would first use the low part (2),
# and then at some later point get the nibble from the high part (F).
try:
length = unpack("<H", inputBuffer[inputIndex:inputIndex + 2])[0]
except StructError:
return recombine(outputBuffer)
inputIndex += 2
offset = length / 8
length = length % 8
if length == 7:
if nibbleIndex == 0:
nibbleIndex = inputIndex
length = ord(inputBuffer[inputIndex]) % 16
inputIndex += 1
else:
# get the high nibble of the last place a nibble sized
# length was used thus we don't waste that extra half
# byte :p
length = ord(inputBuffer[nibbleIndex]) / 16
nibbleIndex = 0
if length == 15:
length = ord(inputBuffer[inputIndex])
inputIndex += 1
if length == 255:
try:
length = unpack("<H", inputBuffer[inputIndex:inputIndex + 2])[0]
except StructError:
return recombine(outputBuffer)
inputIndex = inputIndex + 2
length = length - (15 + 7)
length = length + 15
length = length + 7
length = length + 3
while length != 0:
try:
outputBuffer[outputIndex] = outputBuffer[outputIndex - offset - 1]
except KeyError:
return recombine(outputBuffer)
outputIndex += 1
length -= 1
return recombine(outputBuffer)
try:
import pyxpress #pylint: disable-msg=F0401
xpress_decode = pyxpress.decode
except ImportError:
pass
if __name__ == "__main__":
import sys
dec_data = xpress_decode(open(sys.argv[1]).read())
sys.stdout.write(dec_data)
|