diff options
Diffstat (limited to 'venv/lib/python3.11/site-packages/jsbeautifier/unpackers')
22 files changed, 693 insertions, 0 deletions
diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__init__.py b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__init__.py new file mode 100644 index 0000000..01c254f --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__init__.py @@ -0,0 +1,73 @@ +# +# General code for JSBeautifier unpackers infrastructure. See README.specs +# written by Stefano Sanfilippo <a.little.coder@gmail.com> +# + +"""General code for JSBeautifier unpackers infrastructure.""" + +import pkgutil +import re +from jsbeautifier.unpackers import evalbased + +# NOTE: AT THE MOMENT, IT IS DEACTIVATED FOR YOUR SECURITY: it runs js! +BLACKLIST = ["jsbeautifier.unpackers.evalbased"] + + +class UnpackingError(Exception): + """Badly packed source or general error. Argument is a + meaningful description.""" + + pass + + +def getunpackers(): + """Scans the unpackers dir, finds unpackers and add them to UNPACKERS list. + An unpacker will be loaded only if it is a valid python module (name must + adhere to naming conventions) and it is not blacklisted (i.e. inserted + into BLACKLIST.""" + path = __path__ + prefix = __name__ + "." + unpackers = [] + interface = ["unpack", "detect", "PRIORITY"] + for _importer, modname, _ispkg in pkgutil.iter_modules(path, prefix): + if "tests" not in modname and modname not in BLACKLIST: + try: + module = __import__(modname, fromlist=interface) + except ImportError: + raise UnpackingError("Bad unpacker: %s" % modname) + else: + unpackers.append(module) + + return sorted(unpackers, key=lambda mod: mod.PRIORITY) + + +UNPACKERS = getunpackers() + + +def run(source, evalcode=False): + """Runs the applicable unpackers and return unpacked source as a string.""" + for unpacker in [mod for mod in UNPACKERS if mod.detect(source)]: + source = unpacker.unpack(source) + if evalcode and evalbased.detect(source): + source = evalbased.unpack(source) + return source + + +def filtercomments(source): + """NOT USED: strips trailing comments and put them at the top.""" + trailing_comments = [] + comment = True + + while comment: + if re.search(r"^\s*\/\*", source): + comment = source[0, source.index("*/") + 2] + elif re.search(r"^\s*\/\/", source): + comment = re.search(r"^\s*\/\/", source).group(0) + else: + comment = None + + if comment: + source = re.sub(r"^\s+", "", source[len(comment) :]) + trailing_comments.append(comment) + + return "\n".join(trailing_comments) + source diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/__init__.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..824dc1c --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/__init__.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/evalbased.cpython-311.pyc b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/evalbased.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..38644e1 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/evalbased.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/javascriptobfuscator.cpython-311.pyc b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/javascriptobfuscator.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..8ee047d --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/javascriptobfuscator.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/myobfuscate.cpython-311.pyc b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/myobfuscate.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..cf2948e --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/myobfuscate.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/packer.cpython-311.pyc b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/packer.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..c0abc98 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/packer.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/urlencode.cpython-311.pyc b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/urlencode.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..ba90614 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/__pycache__/urlencode.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/evalbased.py b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/evalbased.py new file mode 100644 index 0000000..74f1f0f --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/evalbased.py @@ -0,0 +1,44 @@ +# +# Unpacker for eval() based packers, a part of javascript beautifier +# by Einar Lielmanis <einar@beautifier.io> +# +# written by Stefano Sanfilippo <a.little.coder@gmail.com> +# +# usage: +# +# if detect(some_string): +# unpacked = unpack(some_string) +# + +"""Unpacker for eval() based packers: runs JS code and returns result. +Works only if a JS interpreter (e.g. Mozilla's Rhino) is installed and +properly set up on host.""" + +from subprocess import PIPE, Popen + +PRIORITY = 3 + + +def detect(source): + """Detects if source is likely to be eval() packed.""" + return source.strip().lower().startswith("eval(function(") + + +def unpack(source): + """Runs source and return resulting code.""" + return jseval("print %s;" % source[4:]) if detect(source) else source + + +# In case of failure, we'll just return the original, without crashing on user. + + +def jseval(script): + """Run code in the JS interpreter and return output.""" + try: + interpreter = Popen(["js"], stdin=PIPE, stdout=PIPE) + except OSError: + return script + result, errors = interpreter.communicate(script) + if interpreter.poll() or errors: + return script + return result diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/javascriptobfuscator.py b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/javascriptobfuscator.py new file mode 100644 index 0000000..bd3a331 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/javascriptobfuscator.py @@ -0,0 +1,61 @@ +# +# simple unpacker/deobfuscator for scripts messed up with +# javascriptobfuscator.com +# +# written by Einar Lielmanis <einar@beautifier.io> +# rewritten in Python by Stefano Sanfilippo <a.little.coder@gmail.com> +# +# Will always return valid javascript: if `detect()` is false, `code` is +# returned, unmodified. +# +# usage: +# +# if javascriptobfuscator.detect(some_string): +# some_string = javascriptobfuscator.unpack(some_string) +# + +"""deobfuscator for scripts messed up with JavascriptObfuscator.com""" + +import re + +PRIORITY = 1 + + +def smartsplit(code): + """Split `code` at " symbol, only if it is not escaped.""" + strings = [] + pos = 0 + while pos < len(code): + if code[pos] == '"': + word = "" # new word + pos += 1 + while pos < len(code): + if code[pos] == '"': + break + if code[pos] == "\\": + word += "\\" + pos += 1 + word += code[pos] + pos += 1 + strings.append('"%s"' % word) + pos += 1 + return strings + + +def detect(code): + """Detects if `code` is JavascriptObfuscator.com packed.""" + # prefer `is not` idiom, so that a true boolean is returned + return re.search(r"^var _0x[a-f0-9]+ ?\= ?\[", code) is not None + + +def unpack(code): + """Unpacks JavascriptObfuscator.com packed code.""" + if detect(code): + matches = re.search(r"var (_0x[a-f\d]+) ?\= ?\[(.*?)\];", code) + if matches: + variable = matches.group(1) + dictionary = smartsplit(matches.group(2)) + code = code[len(matches.group(0)) :] + for key, value in enumerate(dictionary): + code = code.replace(r"%s[%s]" % (variable, key), value) + return code diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/myobfuscate.py b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/myobfuscate.py new file mode 100644 index 0000000..0cbc7f8 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/myobfuscate.py @@ -0,0 +1,90 @@ +# +# deobfuscator for scripts messed up with myobfuscate.com +# by Einar Lielmanis <einar@beautifier.io> +# +# written by Stefano Sanfilippo <a.little.coder@gmail.com> +# +# usage: +# +# if detect(some_string): +# unpacked = unpack(some_string) +# + +# CAVEAT by Einar Lielmanis + +# +# You really don't want to obfuscate your scripts there: they're tracking +# your unpackings, your script gets turned into something like this, +# as of 2011-08-26: +# +# var _escape = 'your_script_escaped'; +# var _111 = document.createElement('script'); +# _111.src = 'http://api.www.myobfuscate.com/?getsrc=ok' + +# '&ref=' + encodeURIComponent(document.referrer) + +# '&url=' + encodeURIComponent(document.URL); +# var 000 = document.getElementsByTagName('head')[0]; +# 000.appendChild(_111); +# document.write(unescape(_escape)); +# + +"""Deobfuscator for scripts messed up with MyObfuscate.com""" + +import re +import base64 + +# Python 2 retrocompatibility +# pylint: disable=F0401 +# pylint: disable=E0611 +try: + from urllib import unquote +except ImportError: + from urllib.parse import unquote + +from jsbeautifier.unpackers import UnpackingError + +PRIORITY = 1 + +CAVEAT = """// +// Unpacker warning: be careful when using myobfuscate.com for your projects: +// scripts obfuscated by the free online version call back home. +// + +""" + +SIGNATURE = ( + r'["\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F' + r"\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x61\x62\x63\x64\x65" + r"\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75" + r"\x76\x77\x78\x79\x7A\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x2B" + r'\x2F\x3D","","\x63\x68\x61\x72\x41\x74","\x69\x6E\x64\x65\x78' + r'\x4F\x66","\x66\x72\x6F\x6D\x43\x68\x61\x72\x43\x6F\x64\x65","' + r'\x6C\x65\x6E\x67\x74\x68"]' +) + + +def detect(source): + """Detects MyObfuscate.com packer.""" + return SIGNATURE in source + + +def unpack(source): + """Unpacks js code packed with MyObfuscate.com""" + if not detect(source): + return source + payload = unquote(_filter(source)) + match = re.search(r"^var _escape\='<script>(.*)<\/script>'", payload, re.DOTALL) + polished = match.group(1) if match else source + return CAVEAT + polished + + +def _filter(source): + """Extracts and decode payload (original file) from `source`""" + try: + varname = re.search(r"eval\(\w+\(\w+\((\w+)\)\)\);", source).group(1) + reverse = re.search(r"var +%s *\= *'(.*)';" % varname, source).group(1) + except AttributeError: + raise UnpackingError("Malformed MyObfuscate data.") + try: + return base64.b64decode(reverse[::-1].encode("utf8")).decode("utf8") + except TypeError: + raise UnpackingError("MyObfuscate payload is not base64-encoded.") diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/packer.py b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/packer.py new file mode 100644 index 0000000..117ff58 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/packer.py @@ -0,0 +1,161 @@ +# +# Unpacker for Dean Edward's p.a.c.k.e.r, a part of javascript beautifier +# by Einar Lielmanis <einar@beautifier.io> +# +# written by Stefano Sanfilippo <a.little.coder@gmail.com> +# +# usage: +# +# if detect(some_string): +# unpacked = unpack(some_string) +# + +"""Unpacker for Dean Edward's p.a.c.k.e.r""" + +import re +import string +import sys +from jsbeautifier.unpackers import UnpackingError + +PRIORITY = 1 + + +def detect(source): + global beginstr + global endstr + beginstr = "" + endstr = "" + begin_offset = -1 + """Detects whether `source` is P.A.C.K.E.R. coded.""" + mystr = re.search( + r"eval[ ]*\([ ]*function[ ]*\([ ]*p[ ]*,[ ]*a[ ]*,[ ]*c[" + " ]*,[ ]*k[ ]*,[ ]*e[ ]*,[ ]*", + source, + ) + if mystr: + begin_offset = mystr.start() + beginstr = source[:begin_offset] + if begin_offset != -1: + """Find endstr""" + source_end = source[begin_offset:] + if source_end.split("')))", 1)[0] == source_end: + try: + endstr = source_end.split("}))", 1)[1] + except IndexError: + endstr = "" + else: + endstr = source_end.split("')))", 1)[1] + return mystr is not None + + +def unpack(source): + """Unpacks P.A.C.K.E.R. packed js code.""" + payload, symtab, radix, count = _filterargs(source) + + if count != len(symtab): + raise UnpackingError("Malformed p.a.c.k.e.r. symtab.") + + try: + unbase = Unbaser(radix) + except TypeError: + raise UnpackingError("Unknown p.a.c.k.e.r. encoding.") + + def lookup(match): + """Look up symbols in the synthetic symtab.""" + word = match.group(0) + return symtab[unbase(word)] or word + + payload = payload.replace("\\\\", "\\").replace("\\'", "'") + if sys.version_info.major == 2: + source = re.sub(r"\b\w+\b", lookup, payload) + else: + source = re.sub(r"\b\w+\b", lookup, payload, flags=re.ASCII) + return _replacestrings(source) + + +def _filterargs(source): + """Juice from a source file the four args needed by decoder.""" + juicers = [ + (r"}\('(.*)', *(\d+|\[\]), *(\d+), *'(.*)'\.split\('\|'\), *(\d+), *(.*)\)\)"), + (r"}\('(.*)', *(\d+|\[\]), *(\d+), *'(.*)'\.split\('\|'\)"), + ] + for juicer in juicers: + args = re.search(juicer, source, re.DOTALL) + if args: + a = args.groups() + if a[1] == "[]": + a = list(a) + a[1] = 62 + a = tuple(a) + try: + return a[0], a[3].split("|"), int(a[1]), int(a[2]) + except ValueError: + raise UnpackingError("Corrupted p.a.c.k.e.r. data.") + + # could not find a satisfying regex + raise UnpackingError( + "Could not make sense of p.a.c.k.e.r data (unexpected code structure)" + ) + + +def _replacestrings(source): + global beginstr + global endstr + """Strip string lookup table (list) and replace values in source.""" + match = re.search(r'var *(_\w+)\=\["(.*?)"\];', source, re.DOTALL) + + if match: + varname, strings = match.groups() + startpoint = len(match.group(0)) + lookup = strings.split('","') + variable = "%s[%%d]" % varname + for index, value in enumerate(lookup): + source = source.replace(variable % index, '"%s"' % value) + return source[startpoint:] + return beginstr + source + endstr + + +class Unbaser(object): + """Functor for a given base. Will efficiently convert + strings to natural numbers.""" + + ALPHABET = { + 62: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", + 95: ( + " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" + ), + } + + def __init__(self, base): + self.base = base + + # fill elements 37...61, if necessary + if 36 < base < 62: + if not hasattr(self.ALPHABET, self.ALPHABET[62][:base]): + self.ALPHABET[base] = self.ALPHABET[62][:base] + # attrs = self.ALPHABET + # print ', '.join("%s: %s" % item for item in attrs.items()) + # If base can be handled by int() builtin, let it do it for us + if 2 <= base <= 36: + self.unbase = lambda string: int(string, base) + else: + # Build conversion dictionary cache + try: + self.dictionary = dict( + (cipher, index) for index, cipher in enumerate(self.ALPHABET[base]) + ) + except KeyError: + raise TypeError("Unsupported base encoding.") + + self.unbase = self._dictunbaser + + def __call__(self, string): + return self.unbase(string) + + def _dictunbaser(self, string): + """Decodes a value to an integer.""" + ret = 0 + for index, cipher in enumerate(string[::-1]): + ret += (self.base**index) * self.dictionary[cipher] + return ret diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__init__.py b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__init__.py new file mode 100644 index 0000000..dfe67ba --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__init__.py @@ -0,0 +1,2 @@ +# Empty file :) +# pylint: disable=C0111 diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/__init__.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..612fa57 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/__init__.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/testjavascriptobfuscator.cpython-311.pyc b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/testjavascriptobfuscator.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..6c1abb8 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/testjavascriptobfuscator.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/testmyobfuscate.cpython-311.pyc b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/testmyobfuscate.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..c62db76 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/testmyobfuscate.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/testpacker.cpython-311.pyc b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/testpacker.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..86d19bf --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/testpacker.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/testurlencode.cpython-311.pyc b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/testurlencode.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..93bd7db --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/__pycache__/testurlencode.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/testjavascriptobfuscator.py b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/testjavascriptobfuscator.py new file mode 100644 index 0000000..d40db2d --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/testjavascriptobfuscator.py @@ -0,0 +1,59 @@ +# +# written by Stefano Sanfilippo <a.little.coder@gmail.com> +# + +"""Tests for JavaScriptObfuscator unpacker.""" + +import unittest +from jsbeautifier.unpackers.javascriptobfuscator import unpack, detect, smartsplit + +# pylint: disable=R0904 + + +class TestJavascriptObfuscator(unittest.TestCase): + """JavascriptObfuscator.com test case.""" + + def test_smartsplit(self): + """Test smartsplit() function.""" + split = smartsplit + + def equals(data, result): + return self.assertEqual(split(data), result) + + equals("", []) + equals('"a", "b"', ['"a"', '"b"']) + equals('"aaa","bbbb"', ['"aaa"', '"bbbb"']) + equals('"a", "b\\""', ['"a"', '"b\\""']) + + def test_detect(self): + """Test detect() function.""" + + def positive(source): + return self.assertTrue(detect(source)) + + def negative(source): + return self.assertFalse(detect(source)) + + negative("") + negative("abcd") + negative("var _0xaaaa") + positive('var _0xaaaa = ["a", "b"]') + positive('var _0xaaaa=["a", "b"]') + positive('var _0x1234=["a","b"]') + + def test_unpack(self): + """Test unpack() function.""" + + def decodeto(ob, original): + return self.assertEqual(unpack(ob), original) + + decodeto("var _0x8df3=[];var a=10;", "var a=10;") + decodeto( + 'var _0xb2a7=["\x74\x27\x65\x73\x74"];var i;for(i=0;i<10;++i)' + "{alert(_0xb2a7[0]);} ;", + "var i;for(i=0;i<10;++i){alert" '("t\'est");} ;', + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/testmyobfuscate.py b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/testmyobfuscate.py new file mode 100644 index 0000000..d69df82 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/testmyobfuscate.py @@ -0,0 +1,48 @@ +# +# written by Stefano Sanfilippo <a.little.coder@gmail.com> +# + +"""Tests for MyObfuscate unpacker.""" + +import unittest +import os +from jsbeautifier.unpackers.myobfuscate import detect, unpack +from jsbeautifier.unpackers.tests import __path__ as path + +INPUT = os.path.join(path[0], "test-myobfuscate-input.js") +OUTPUT = os.path.join(path[0], "test-myobfuscate-output.js") + +# pylint: disable=R0904 + + +class TestMyObfuscate(unittest.TestCase): + # pylint: disable=C0103 + """MyObfuscate obfuscator testcase.""" + + @classmethod + def setUpClass(cls): + """Load source files (encoded and decoded version) for tests.""" + with open(INPUT, "r") as data: + cls.input = data.read() + with open(OUTPUT, "r") as data: + cls.output = data.read() + + def test_detect(self): + """Test detect() function.""" + + def detected(source): + return self.assertTrue(detect(source)) + + detected(self.input) + + def test_unpack(self): + """Test unpack() function.""" + + def check(inp, out): + return self.assertEqual(unpack(inp), out) + + check(self.input, self.output) + + +if __name__ == "__main__": + unittest.main() diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/testpacker.py b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/testpacker.py new file mode 100644 index 0000000..1de9934 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/testpacker.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# +# written by Stefano Sanfilippo <a.little.coder@gmail.com> +# + +"""Tests for P.A.C.K.E.R. unpacker.""" + +import unittest +from jsbeautifier.unpackers.packer import detect, unpack + +# pylint: disable=R0904 + + +class TestPacker(unittest.TestCase): + """P.A.C.K.E.R. testcase.""" + + def test_detect(self): + """Test detect() function.""" + + def positive(source): + return self.assertTrue(detect(source)) + + def negative(source): + return self.assertFalse(detect(source)) + + negative("") + negative("var a = b") + positive("eval(function(p,a,c,k,e,r") + positive("eval ( function(p, a, c, k, e, r") + + def test_unpack(self): + """Test unpack() function.""" + + def check(inp, out): + return detect(inp) and self.assertEqual(unpack(inp), out) + + check( + "eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String)" + "){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=" + "function(){return'\\\\w+'};c=1};while(c--)if(k[c])p=p.replace(" + "new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c]);return p}('0 2=1'," + "62,3,'var||a'.split('|'),0,{}))", + "var a=1", + ) + + check( + "function test (){alert ('This is a test!')}; " + "eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String))" + "{while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function" + "(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp(" + "'\\b'+e(c)+'\\b','g'),k[c]);return p}('0 2=\\'{Íâ–+›ï;ã†Ù¥#\\'',3,3," + "'var||a'.split('|'),0,{}))", + "function test (){alert ('This is a test!')}; var a='{Íâ–+›ï;ã†Ù¥#'", + ) + + check( + "eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('2 0=\"4 3!\";2 1=0.5(/b/6);a.9(\"8\").7=1;',12,12,'str|n|var|W3Schools|Visit|search|i|innerHTML|demo|getElementById|document|w3Schools'.split('|'),0,{}))", + 'var str="Visit W3Schools!";var n=str.search(/w3Schools/i);document.getElementById("demo").innerHTML=n;', + ) + + check( + "a=b;\r\nwhile(1){\ng=h;{return'\\w+'};break;eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('$(5).4(3(){$('.1').0(2);$('.6').0(d);$('.7').0(b);$('.a').0(8);$('.9').0(c)});',14,14,'html|r5e57|8080|function|ready|document|r1655|rc15b|8888|r39b0|r6ae9|3128|65309|80'.split('|'),0,{}))c=abx;", + "a=b;\r\nwhile(1){\ng=h;{return'\\w+'};break;$(document).ready(function(){$('.r5e57').html(8080);$('.r1655').html(80);$('.rc15b').html(3128);$('.r6ae9').html(8888);$('.r39b0').html(65309)});c=abx;", + ) + + check( + "eval(function(p,a,c,k,e,r){e=function(c){return c.toString(36)};if('0'.replace(0,e)==0){while(c--)r[e(c)]=k[c];k=[function(e){return r[e]||e}];e=function(){return'[0-9ab]'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('$(5).a(6(){ $('.8').0(1); $('.b').0(4); $('.9').0(2); $('.7').0(3)})',[],12,'html|52136|555|65103|8088|document|function|r542c|r8ce6|rb0de|ready|rfab0'.split('|'),0,{}))", + "$(document).ready(function(){ $('.r8ce6').html(52136); $('.rfab0').html(8088); $('.rb0de').html(555); $('.r542c').html(65103)})", + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/testurlencode.py b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/testurlencode.py new file mode 100644 index 0000000..10e236d --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/tests/testurlencode.py @@ -0,0 +1,46 @@ +# +# written by Stefano Sanfilippo <a.little.coder@gmail.com> +# + +"""Tests for urlencoded unpacker.""" + +import unittest + +from jsbeautifier.unpackers.urlencode import detect, unpack + +# pylint: disable=R0904 + + +class TestUrlencode(unittest.TestCase): + """urlencode test case.""" + + def test_detect(self): + """Test detect() function.""" + + def encoded(source): + return self.assertTrue(detect(source)) + + def unencoded(source): + return self.assertFalse(detect(source)) + + unencoded("") + unencoded("var a = b") + encoded("var%20a+=+b") + encoded("var%20a=b") + encoded("var%20%21%22") + + def test_unpack(self): + """Test unpack function.""" + + def equals(source, result): + return self.assertEqual(unpack(source), result) + + equals("", "") + equals("abcd", "abcd") + equals("var a = b", "var a = b") + equals("var%20a=b", "var a=b") + equals("var%20a+=+b", "var a = b") + + +if __name__ == "__main__": + unittest.main() diff --git a/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/urlencode.py b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/urlencode.py new file mode 100644 index 0000000..d0d492a --- /dev/null +++ b/venv/lib/python3.11/site-packages/jsbeautifier/unpackers/urlencode.py @@ -0,0 +1,36 @@ +# +# Trivial bookmarklet/escaped script detector for the javascript beautifier +# written by Einar Lielmanis <einar@beautifier.io> +# rewritten in Python by Stefano Sanfilippo <a.little.coder@gmail.com> +# +# Will always return valid javascript: if `detect()` is false, `code` is +# returned, unmodified. +# +# usage: +# +# some_string = urlencode.unpack(some_string) +# + +"""Bookmarklet/escaped script unpacker.""" + +# Python 2 retrocompatibility +# pylint: disable=F0401 +# pylint: disable=E0611 +try: + from urllib import unquote_plus +except ImportError: + from urllib.parse import unquote_plus + +PRIORITY = 0 + + +def detect(code): + """Detects if a scriptlet is urlencoded.""" + # the fact that script doesn't contain any space, but has %20 instead + # should be sufficient check for now. + return " " not in code and ("%20" in code or code.count("%") > 3) + + +def unpack(code): + """URL decode `code` source string.""" + return unquote_plus(code) if detect(code) else code |