astrXbian/.install/.kodi/addons/plugin.video.vstream/resources/lib/jsunfuck.py

237 lines
8.5 KiB
Python

# !/usr/bin/python
# -*- coding: utf-8 -*-
# vStream https://github.com/Kodi-vStream/venom-xbmc-addons
"""
Modified version from
Copyright (C) 2016 tknorris
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/>.
"""
import re
import string
from resources.lib.util import Quote, Unquote
class JSUnfuck(object):
numbers = None
words = {
"(![]+[])": "false",
"([]+{})": "[object Object]",
"(!![]+[])": "true",
"([][[]]+[])": "undefined",
"(+{}+[])": "NaN",
"([![]]+[][[]])": "falseundefined",
"([][f+i+l+t+e+r]+[])": "function filter() { [native code] }",
"(!![]+[][f+i+l+t+e+r])": "truefunction filter() { [native code] }",
"(+![]+([]+[])[c+o+n+s+t+r+u+c+t+o+r])": "0function String() { [native code] }",
"(+![]+[![]]+([]+[])[c+o+n+s+t+r+u+c+t+o+r])": "0falsefunction String() { [native code] }",
"([]+[][s+o+r+t][c+o+n+s+t+r+u+c+t+o+r](r+e+t+u+r+n+ +l+o+c+a+t+i+o+n)())": "https://123movies.to",
"([]+[])[f+o+n+t+c+o+l+o+r]()": '<font color="undefined"></font>',
"(+(+!![]+e+1+0+0+0)+[])": "Infinity",
"(+[![]]+[][f+i+l+t+e+r])": 'NaNfunction filter() { [native code] }',
'(+[![]]+[+(+!+[]+(!+[]+[])[3]+[1]+[0]+[0]+[0])])': 'NaNInfinity',
'([]+[])[i+t+a+l+i+c+s]()': '<i></i>',
'[[]][c+o+n+c+a+t]([[]])+[]': ',',
'([][f+i+l+l]+[])': 'function fill() { [native code]}',
'(!![]+[][f+i+l+l])': 'truefunction fill() { [native code]}',
'((+[])[c+o+n+s+t+r+u+c+t+o+r]+[])': 'function Number() {[native code]} _display:45:1',
'(+(+!+[]+[1]+e+[2]+[0])+[])': '1.1e+21',
'([]+[])[c+o+n+s+t+r+u+c+t+o+r][n+a+m+e]': 'S+t+r+i+n+g',
'([][e+n+t+r+i+e+s]()+[])': '[object Array Iterator]',
'([]+[])[l+i+n+k](")': '<a href="&quot;"></a>',
'(![]+[0])[i+t+a+l+i+c+s]()': '<i>false0</i>',
# dummy to force array dereference
'DUMMY1': '6p',
'DUMMY2': '2x',
'DUMMY3': '%3C',
'DUMMY4': '%5B',
'DUMMY5': '6q',
'DUMMY6': '4h',
}
uniqs = {
'[t+o+S+t+r+i+n+g]': 1,
'[][f+i+l+t+e+r][c+o+n+s+t+r+u+c+t+o+r](r+e+t+u+r+n+ +e+s+c+a+p+e)()': 2,
'[][f+i+l+t+e+r][c+o+n+s+t+r+u+c+t+o+r](r+e+t+u+r+n+ +u+n+e+s+c+a+p+e)()': 3,
'[][s+o+r+t][c+o+n+s+t+r+u+c+t+o+r](r+e+t+u+r+n+ +e+s+c+a+p+e)()': 2,
'[][s+o+r+t][c+o+n+s+t+r+u+c+t+o+r](r+e+t+u+r+n+ +u+n+e+s+c+a+p+e)()': 3,
}
def __init__(self, js):
self.js = js
def decode(self, replace_plus=True):
while True:
start_js = self.js
self.repl_words(self.words)
self.repl_numbers()
self.repl_arrays(self.words)
self.repl_uniqs(self.uniqs)
if start_js == self.js:
break
if replace_plus:
self.js = self.js.replace('+', '')
self.js = re.sub('\[[A-Za-z]*\]', '', self.js)
self.js = re.sub('\[(\d+)\]', '\\1', self.js)
# foutu ici pr le moment
self.js = self.js.replace('(+)', '0')
self.js = self.js.replace('(+!!)', '1')
return self.js
def repl_words(self, words):
while True:
start_js = self.js
for key, value in sorted(words.items(), key=lambda x: len(x[0]), reverse=True):
self.js = self.js.replace(key, value)
if self.js == start_js:
break
def repl_arrays(self, words):
for word in sorted(words.values(), key=lambda x: len(x), reverse=True):
for index in range(0, 100):
try:
repl = word[index]
self.js = self.js.replace('%s[%d]' % (word, index), repl)
except:
pass
def repl_numbers(self):
if self.numbers is None:
self.numbers = self.__gen_numbers()
while True:
start_js = self.js
for key, value in sorted(self.numbers.items(), key=lambda x: len(x[0]), reverse=True):
self.js = self.js.replace(key, value)
if self.js == start_js:
break
def repl_uniqs(self, uniqs):
for key, value in uniqs.items():
if key in self.js:
if value == 1:
self.__handle_tostring()
elif value == 2:
self.__handle_escape(key)
elif value == 3:
self.__handle_unescape(key)
def __handle_tostring(self):
for match in re.finditer('(\d+)\[t\+o\+S\+t\+r\+i\+n\+g\](\d+)', self.js):
repl = to_base(match.group(1), match.group(2))
self.js = self.js.replace(match.group(0), repl)
def __handle_escape(self, key):
while True:
start_js = self.js
offset = self.js.find(key) + len(key)
if self.js[offset] == '(' and self.js[offset + 2] == ')':
c = self.js[offset + 1]
self.js = self.js.replace('%s(%s)' % (key, c), Quote(c))
if start_js == self.js:
break
def __handle_unescape(self, key):
start = 0
while True:
start_js = self.js
offset = self.js.find(key, start)
if offset == -1:
break
offset += len(key)
expr = ''
extra = ''
last_c = self.js[offset - 1]
abort = False
for i, c in enumerate(self.js[offset:]):
extra += c
if c == ')':
break
elif (i > 0 and c == '(') or (c == '[' and last_c != '+'):
abort = True
break
elif c == '%' or c in string.hexdigits:
expr += c
last_c = c
if not abort:
self.js = self.js.replace(key + extra, Unquote(expr))
if start_js == self.js:
break
else:
start = offset
def __gen_numbers(self):
n = {'(+[]+[])': '0', '(+![]+([]+[]))': '0', '[+[]]': '[0]',
'(+!![]+[])': '1', '[+!+[]]': '[1]', '[+!![]]': '[1]',
'[+!+[]+[+[]]]': '[10]', '+(1+1)': '11', '(+20)': '20'}
for i in range(2, 20):
key = '+!![]' * (i - 1)
key = '!+[]' + key
n['(' + key + ')'] = str(i)
key += '+[]'
n['(' + key + ')'] = str(i)
n['[' + key + ']'] = '[' + str(i) + ']'
for i in range(2, 10):
key = '!+[]+' * (i - 1) + '!+[]'
n['(' + key + ')'] = str(i)
n['[' + key + ']'] = '[' + str(i) + ']'
key = '!+[]' + '+!![]' * (i - 1)
n['[' + key + ']'] = '[' + str(i) + ']'
for i in range(0, 10):
key = '(+(+!+[]+[%d]))' % (i)
n[key] = str(i + 10)
key = '[+!+[]+[%s]]' % (i)
n[key] = '[' + str(i + 10) + ']'
for tens in range(2, 10):
for ones in range(0, 10):
key = '!+[]+' * (tens) + '[%d]' % (ones)
n['(' + key + ')'] = str(tens * 10 + ones)
n['[' + key + ']'] = '[' + str(tens * 10 + ones) + ']'
for hundreds in range(1, 10):
for tens in range(0, 10):
for ones in range(0, 10):
key = '+!+[]' * hundreds + '+[%d]+[%d]))' % (tens, ones)
if hundreds > 1:
key = key[1:]
key = '(+(' + key
n[key] = str(hundreds * 100 + tens * 10 + ones)
return n
def to_base(n, base, digits="0123456789abcdefghijklmnopqrstuvwxyz"):
n, base = int(n), int(base)
if n < base:
return digits[n]
else:
return to_base(n // base, base, digits).lstrip(digits[0]) + digits[n % base]