Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
311 lines (265 sloc) 7.97 KB
#!/usr/bin/env python
#
# Python version of the jjdecode function written by Syed Zainudeen
# http://csc.cs.utm.my/syed/images/files/jjdecode/jjdecode.html
#
# +NCR/CRC! [ReVeRsEr] - crackinglandia@gmail.com
# Thanks to Jose Miguel Esparza (@EternalTodo) for the final push to make it work!
#
import re
class JJDecoder(object):
def __init__(self, jj_encoded_data):
self.encoded_str = jj_encoded_data
def clean(self):
return re.sub('^\s+|\s+$', '', self.encoded_str)
def checkPalindrome(self, Str):
startpos = -1
endpos = -1
gv, gvl = -1, -1
index = Str.find('"\'\\"+\'+",')
if index == 0:
startpos = Str.find('$$+"\\""+') + 8
endpos = Str.find('"\\"")())()')
gv = Str[Str.find('"\'\\"+\'+",')+9:Str.find('=~[]')]
gvl = len(gv)
else:
gv = Str[0:Str.find('=')]
gvl = len(gv)
startpos = Str.find('"\\""+') + 5
endpos = Str.find('"\\"")())()')
return (startpos, endpos, gv, gvl)
def decode(self):
self.encoded_str = self.clean()
startpos, endpos, gv, gvl = self.checkPalindrome(self.encoded_str)
if startpos == endpos:
raise Exception('No data!')
data = self.encoded_str[startpos:endpos]
b = ['___+', '__$+', '_$_+', '_$$+', '$__+', '$_$+', '$$_+', '$$$+', '$___+', '$__$+', '$_$_+', '$_$$+', '$$__+', '$$_$+', '$$$_+', '$$$$+']
str_l = '(![]+"")[' + gv + '._$_]+'
str_o = gv + '._$+'
str_t = gv + '.__+'
str_u = gv + '._+'
str_hex = gv + '.'
str_s = '"'
gvsig = gv + '.'
str_quote = '\\\\\\"'
str_slash = '\\\\\\\\'
str_lower = '\\\\"+'
str_upper = '\\\\"+' + gv + '._+'
str_end = '"+'
out = ''
while data != '':
# l o t u
if data.find(str_l) == 0:
data = data[len(str_l):]
out += 'l'
continue
elif data.find(str_o) == 0:
data = data[len(str_o):]
out += 'o'
continue
elif data.find(str_t) == 0:
data = data[len(str_t):]
out += 't'
continue
elif data.find(str_u) == 0:
data = data[len(str_u):]
out += 'u'
continue
# 0123456789abcdef
if data.find(str_hex) == 0:
data = data[len(str_hex):]
for i in range(len(b)):
if data.find(b[i]) == 0:
data = data[len(b[i]):]
out += '%x' % i
break
continue
# start of s block
if data.find(str_s) == 0:
data = data[len(str_s):]
# check if "R
if data.find(str_upper) == 0: # r4 n >= 128
data = data[len(str_upper):] # skip sig
ch_str = ''
for i in range(2): # shouldn't be more than 2 hex chars
# gv + "."+b[ c ]
if data.find(gvsig) == 0:
data = data[len(gvsig):]
for k in range(len(b)): # for every entry in b
if data.find(b[k]) == 0:
data = data[len(b[k]):]
ch_str = '%x' % k
break
else:
break
out += chr(int(ch_str, 16))
continue
elif data.find(str_lower) == 0: # r3 check if "R // n < 128
data = data[len(str_lower):] # skip sig
ch_str = ''
ch_lotux = ''
temp = ''
b_checkR1 = 0
for j in range(3): # shouldn't be more than 3 octal chars
if j > 1: # lotu check
if data.find(str_l) == 0:
data = data[len(str_l):]
ch_lotux = 'l'
break
elif data.find(str_o) == 0:
data = data[len(str_o):]
ch_lotux = 'o'
break
elif data.find(str_t) == 0:
data = data[len(str_t):]
ch_lotux = 't'
break
elif data.find(str_u) == 0:
data = data[len(str_u):]
ch_lotux = 'u'
break
# gv + "."+b[ c ]
if data.find(gvsig) == 0:
temp = data[len(gvsig):]
for k in range(8): # for every entry in b octal
if temp.find(b[k]) == 0:
if int(ch_str + str(k), 8) > 128:
b_checkR1 = 1
break
ch_str += str(k)
data = data[len(gvsig):] # skip gvsig
data = data[len(b[k]):]
break
if b_checkR1 == 1:
if data.find(str_hex) == 0: # 0123456789abcdef
data = data[len(str_hex):]
# check every element of hex decode string for a match
for i in range(len(b)):
if data.find(b[i]) == 0:
data = data[len(b[i]):]
ch_lotux = '%x' % i
break
break
else:
break
out += chr(int(ch_str,8)) + ch_lotux
continue
else: # "S ----> "SR or "S+
# if there is, loop s until R 0r +
# if there is no matching s block, throw error
match = 0;
n = None
# searching for matching pure s block
while True:
n = ord(data[0])
if data.find(str_quote) == 0:
data = data[len(str_quote):]
out += '"'
match += 1
continue
elif data.find(str_slash) == 0:
data = data[len(str_slash):]
out += '\\'
match += 1
continue
elif data.find(str_end) == 0: # reached end off S block ? +
if match == 0:
raise '+ no match S block: ' + data
data = data[len(str_end):]
break # step out of the while loop
elif data.find(str_upper) == 0: # r4 reached end off S block ? - check if "R n >= 128
if match == 0:
raise 'no match S block n>128: ' + data
data = data[len(str_upper):] # skip sig
ch_str = ''
ch_lotux = ''
for j in range(10): # shouldn't be more than 10 hex chars
if j > 1: # lotu check
if data.find(str_l) == 0:
data = data[len(str_l):]
ch_lotux = 'l'
break
elif data.find(str_o) == 0:
data = data[len(str_o):]
ch_lotux = 'o'
break
elif data.find(str_t) == 0:
data = data[len(str_t):]
ch_lotux = 't'
break
elif data.find(str_u) == 0:
data = data[len(str_u):]
ch_lotux = 'u'
break
# gv + "."+b[ c ]
if data.find(gvsig) == 0:
data = data[len(gvsig):] # skip gvsig
for k in range(len(b)): # for every entry in b
if data.find(b[k]) == 0:
data = data[len(b[k]):]
ch_str += '%x' % k
break
else:
break # done
out += chr(int(ch_str, 16))
break # step out of the while loop
elif data.find(str_lower) == 0: # r3 check if "R // n < 128
if match == 0:
raise 'no match S block n<128: ' + data
data = data[len(str_lower):] # skip sig
ch_str = ''
ch_lotux = ''
temp = ''
b_checkR1 = 0
for j in range(3): # shouldn't be more than 3 octal chars
if j > 1: # lotu check
if data.find(str_l) == 0:
data = data[len(str_l):]
ch_lotux = 'l'
break
elif data.find(str_o) == 0:
data = data[len(str_o):]
ch_lotux = 'o'
break
elif data.find(str_t) == 0:
data = data[len(str_t):]
ch_lotux = 't'
break
elif data.find(str_u) == 0:
data = data[len(str_u):]
ch_lotux = 'u'
break
# gv + "."+b[ c ]
if data.find(gvsig) == 0:
temp = data[len(gvsig):]
for k in range(8): # for every entry in b octal
if temp.find(b[k]) == 0:
if int(ch_str + str(k), 8) > 128:
b_checkR1 = 1
break
ch_str += str(k)
data = data[len(gvsig):] # skip gvsig
data = data[len(b[k]):]
break
if b_checkR1 == 1:
if data.find(str_hex) == 0: # 0123456789abcdef
data = data[len(str_hex):]
# check every element of hex decode string for a match
for i in range(len(b)):
if data.find(b[i]) == 0:
data = data[len(b[i]):]
ch_lotux = '%x' % i
break
else:
break
out += chr(int(ch_str, 8)) + ch_lotux
break # step out of the while loop
elif (0x21 <= n and n <= 0x2f) or (0x3A <= n and n <= 0x40) or ( 0x5b <= n and n <= 0x60 ) or ( 0x7b <= n and n <= 0x7f ):
out += data[0]
data = data[1:]
match += 1
continue
print 'No match : ' + data
break
return out