-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathLZNT1decompress.py
executable file
·88 lines (75 loc) · 2.32 KB
/
LZNT1decompress.py
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
import struct
import sys
def unpack_from(fmt, buf, offset=0):
"""Unpack binary data, using struct.unpack(...)"""
slice = buffer(buf, offset, struct.calcsize(fmt))
return struct.unpack(fmt, slice)
class lznt1Error(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
def _dCompressBlock(x):
size = len(x)
u = ''
while len(x):
p = x[0]
if p == 0: # These are symbol are tokens
u += x[1:9]
x = x[9:]
else: # There is a phrase token
idx = 8
x = x[1:]
while idx and len(x):
ustart = len(u)
if not (p & 1):
u += chr(x[0])
x = x[1:]
else:
pt = unpack_from('H', x)[0]
pt = pt & 0xffff
i = (len(u)-1) # Current Pos
l_mask = 0xfff
p_shift = 12
while i >= 0x10:
l_mask >>= 1
p_shift -= 1
i >>= 1
length = (pt & l_mask) + 3
bp = (pt >> p_shift) + 1
if length >= bp:
tmp = u[-bp:]
while length >= len(tmp):
u += tmp
length -= len(tmp)
u += tmp[:length]
else:
insert = u[-bp : -bp + length]
u = u + insert
x = x[2:]
p >>= 1
idx -= 1
return u
def dCompressBuf(blob):
good = True
unc = ''
while good:
try:
hdr = blob[0:2]
blob = blob[2:]
length = struct.unpack('H', hdr)[0]
length &= 0xfff
length += 1
if length > len(blob):
raise lznt1Error("invalid block len")
good = False
else:
y = blob[:length]
blob = blob[length:]
unc += _dCompressBlock(y)
except:
good = False
return unc
data = bytearray.fromhex("414141414141")
#print "raw data : " + data
print "decomp data : "+ dCompressBuf(data)