From 33e6a110e7993f61473a2817362376f3b23be7f0 Mon Sep 17 00:00:00 2001 From: pepeleaks <104858775+Fadi002@users.noreply.github.com> Date: Wed, 15 Nov 2023 23:54:28 +0300 Subject: [PATCH] add support for obfuscator --- INFO/changelog.json | 8 +- INFO/version | 2 +- config/config.py | 2 +- deobfuscators/Hyperion.py | 6 + deobfuscators/PlusOBF.py | 2 +- deobfuscators/detector.py | 6 +- .../erebus/deobfuscator/deobfuscator.py | 71 +++++ .../erebus/deobfuscator/transformers.py | 251 ++++++++++++++++++ .../erebus/deobfuscator/unwrapper.py | 30 +++ deobfuscators/erebus/readme.txt | 1 + dlls/shell.py | 2 +- samples/Hyperion.py | 90 +++++++ 12 files changed, 464 insertions(+), 7 deletions(-) create mode 100644 deobfuscators/Hyperion.py create mode 100644 deobfuscators/erebus/deobfuscator/deobfuscator.py create mode 100644 deobfuscators/erebus/deobfuscator/transformers.py create mode 100644 deobfuscators/erebus/deobfuscator/unwrapper.py create mode 100644 deobfuscators/erebus/readme.txt create mode 100644 samples/Hyperion.py diff --git a/INFO/changelog.json b/INFO/changelog.json index e78bd94..6c56426 100644 --- a/INFO/changelog.json +++ b/INFO/changelog.json @@ -8,7 +8,13 @@ { "version": "1.0.1", "changes": [ - "bug fixed for BlankOBF deobfuscator" + "Bug fixed for BlankOBF deobfuscator" + ] + }, + { + "version": "1.0.2", + "changes": [ + "Add support for Hyperion obfuscator" ] } ] \ No newline at end of file diff --git a/INFO/version b/INFO/version index 9b128d8..cebeb9f 100644 --- a/INFO/version +++ b/INFO/version @@ -1 +1 @@ -V1.0.1 \ No newline at end of file +V1.0.2 \ No newline at end of file diff --git a/config/config.py b/config/config.py index 7996045..b4dabe5 100644 --- a/config/config.py +++ b/config/config.py @@ -1,3 +1,3 @@ -__VERSION__ = 'V1.0' +__VERSION__ = 'V1.0.2' __CHANGELOG_URL__ = 'https://raw.githubusercontent.com/Fadi002/de4py/main/INFO/changelog.json' __VERSION_URL__ = 'https://raw.githubusercontent.com/Fadi002/de4py/main/INFO/version' \ No newline at end of file diff --git a/deobfuscators/Hyperion.py b/deobfuscators/Hyperion.py new file mode 100644 index 0000000..ae2d0c9 --- /dev/null +++ b/deobfuscators/Hyperion.py @@ -0,0 +1,6 @@ +from .erebus.deobfuscator.deobfuscator import Deobfuscator, Result +from .erebus.deobfuscator.unwrapper import unwrap + +def Hyperion(file_path: str) -> str: + code = open(file_path, 'r',encoding='utf-8').read() + return Deobfuscator(unwrap(code)).deobfuscate().code \ No newline at end of file diff --git a/deobfuscators/PlusOBF.py b/deobfuscators/PlusOBF.py index b607399..1756c01 100644 --- a/deobfuscators/PlusOBF.py +++ b/deobfuscators/PlusOBF.py @@ -9,4 +9,4 @@ def PlusOBF(file_path): file.write("# Cleaned with de4py | https://github.com/Fadi002/de4py\n"+cleaned) return "Saved as "+filename+'-cleaned.py' except Exception as e: - return 'Detected PlusOBF but Failed to deobfuscate\n'+e + return 'Detected PlusOBF but Failed to deobfuscate\n'+e \ No newline at end of file diff --git a/deobfuscators/detector.py b/deobfuscators/detector.py index 48b342c..94289ef 100644 --- a/deobfuscators/detector.py +++ b/deobfuscators/detector.py @@ -4,13 +4,15 @@ from .devtool import devtool from .blankOBF import BlankOBF from .PlusOBF import PlusOBF +from .Hyperion import Hyperion obfuscators = [ ("PlusOBF",r"exec\(\"\"\.join\(\[chr\(len\(i\)\) for i in d\]\)\)",PlusOBF), - ('jawbreaker', r'([a-zA-Z_]\w{3})\s*=\s*([^;]+);', jawbreaker), ("wodx", r'(?:__NO_NO){23}', wodx), ("BlankOBF", r"import\s*base64,\s*lzma;\s*exec\(compile\(lzma\.decompress\(base64\.b64decode\(b'([A-Za-z0-9+/=]+)'\)\)\s*,\s*\"\"\s*,\s*\"exec\"\)\)", BlankOBF), + ("Hyperion", r'__obfuscator__\s*=\s*[\'\"]\s*Hyperion\s*[\'\"]', Hyperion), + ('jawbreaker', r'([a-zA-Z_]\w{3})\s*=\s*([^;]+);', jawbreaker) ] -def detect_obfuscator(file_path): +def detect_obfuscator(file_path) -> str: file_data = open(file_path,'r',encoding='utf8').read() for obfuscator in obfuscators: if re.search(obfuscator[1],file_data): diff --git a/deobfuscators/erebus/deobfuscator/deobfuscator.py b/deobfuscators/erebus/deobfuscator/deobfuscator.py new file mode 100644 index 0000000..3e62a7e --- /dev/null +++ b/deobfuscators/erebus/deobfuscator/deobfuscator.py @@ -0,0 +1,71 @@ +import logging +from ast import NodeTransformer, parse, unparse +from typing import Any, Dict, Tuple, Type + +from .transformers import * +from .transformers import constants + + +class Result: + def __init__(self, code: str, passes: int, variables: Dict[str, Any]) -> None: + self.code = code + self.passes = passes + self.variables = variables + + def add_variables(self) -> None: + code = "\n".join( + [f"{name} = {unparse(value)}" for name, value in self.variables.items()] + ) + self.code = f"{code}\n{self.code}" + + +class Deobfuscator: + TRANSFORMERS: Tuple[Type[NodeTransformer], ...] = ( + StringSubscriptSimple, + GlobalsToVarAccess, + InlineConstants, + DunderImportRemover, + GetattrConstructRemover, + BuiltinsAccessRemover, + Dehexlify, + UselessCompile, + UselessEval, + ExecTransformer, + UselessLambda, + RemoveFromBuiltins, + ) + + AFTER_TRANSFORMERS: Tuple[Type[NodeTransformer], ...] = ( + LambdaCalls, + EmptyIf, + ) + + def __init__(self, code: str) -> None: + self.code = code + self.tree = parse(code) + + def deobfuscate(self) -> Result: + passes = 0 + code = self.code + while True: + for transformer in self.TRANSFORMERS: + try: + self.tree = transformer().visit(self.tree) + except Exception as e: + transformer_name = transformer.__name__ + logging.warning(f"Transformer {transformer_name} failed with {e}") + # If nothing changed after a full pass, we're done + if (result := unparse(self.tree)) == code: + for transformer in self.AFTER_TRANSFORMERS: + try: + self.tree = transformer().visit(self.tree) + except Exception as e: + transformer_name = transformer.__name__ + logging.warning( + f"Transformer {transformer_name} failed with {e}" + ) + code = unparse(self.tree) + break + code = result + passes += 1 + return Result(code, passes, constants) diff --git a/deobfuscators/erebus/deobfuscator/transformers.py b/deobfuscators/erebus/deobfuscator/transformers.py new file mode 100644 index 0000000..f5ef772 --- /dev/null +++ b/deobfuscators/erebus/deobfuscator/transformers.py @@ -0,0 +1,251 @@ +# type: ignore +import ast +import string +from ast import unparse +from typing import Any, Dict, List + +CONSTANTS = ( + ast.Name, + ast.Constant, + ast.Str, + ast.Num, + ast.Bytes, + ast.Ellipsis, + ast.NameConstant, + ast.Attribute, + ast.Subscript, + ast.Tuple, +) + +__all__ = ( + "StringSubscriptSimple", + "GlobalsToVarAccess", + "InlineConstants", + "DunderImportRemover", + "GetattrConstructRemover", + "BuiltinsAccessRemover", + "Dehexlify", + "UselessEval", + "UselessCompile", + "ExecTransformer", + "UselessLambda", + "LambdaCalls", + "EmptyIf", + "RemoveFromBuiltins", +) + +constants: Dict[str, Any] = {} +lambdas: List[str] = [] + + +class StringSubscriptSimple(ast.NodeTransformer): + """Transforms Hyperion specific string slicing into a string literal""" + + def visit_Subscript(self, node: ast.Subscript): + if isinstance(node.value, ast.Str) and isinstance(node.slice, ast.Slice): + code = unparse(node.slice.step) + if all(s not in code for s in string.ascii_letters): + + s = node.value.s[:: eval(unparse(node.slice.step))] + return ast.Str(s=s) + return super().generic_visit(node) + + +class GlobalsToVarAccess(ast.NodeTransformer): + def visit_Subscript(self, node: ast.Subscript) -> Any: + if ( + ( + isinstance(node.value, ast.Call) + and isinstance(node.value.func, ast.Name) + and node.value.func.id in ("globals", "locals", "vars") + ) + and isinstance(node.slice, ast.Constant) + and isinstance(node.slice.value, str) + ): + return ast.Name(id=node.slice.value, ctx=ast.Load()) + return super().generic_visit(node) + + +class InlineConstants(ast.NodeTransformer): + class FindConstants(ast.NodeTransformer): + def visit_Assign(self, node: ast.Assign) -> Any: + if isinstance(node.value, CONSTANTS) and isinstance( + node.targets[0], ast.Name + ): + constants[node.targets[0].id] = node.value + # delete the assignment + return ast.Module(body=[], type_ignores=[]) + return super().generic_visit(node) + + def visit(self, node: Any) -> Any: + self.FindConstants().visit(node) + return super().visit(node) + + def visit_Name(self, node: ast.Name) -> Any: + """Replace the name with the constant if it's in the constants dict""" + if node.id in constants: + return constants[node.id] + return super().generic_visit(node) + + +class DunderImportRemover(ast.NodeTransformer): + """Just transform all __import__ calls to the name of the module being imported""" + + def visit_Call(self, node: ast.Call) -> Any: + if isinstance(node.func, ast.Name) and node.func.id == "__import__": + return ast.Name(id=node.args[0].s, ctx=ast.Load()) + return super().generic_visit(node) + + +class GetattrConstructRemover(ast.NodeTransformer): + """Hyperion has an interesting way of accessing module attributes.""" + + def visit_Call(self, node: ast.Call) -> Any: + + if isinstance(node.func, ast.Name) and node.func.id == "getattr": + return ast.Attribute(value=node.args[0], attr=node.args[1].slice.args[0].s) + + return super().generic_visit(node) + + +class BuiltinsAccessRemover(ast.NodeTransformer): + """Instead of accessing builtins, just use the name directly""" + + def visit_Attribute(self, node: ast.Attribute) -> Any: + if isinstance(node.value, ast.Name) and node.value.id == "builtins": + return ast.Name(id=node.attr, ctx=ast.Load()) + return super().generic_visit(node) + + +class Dehexlify(ast.NodeTransformer): + """Transforms a binascii.unhexlify(b'').decode('utf8') into a string""" + + def visit_Call(self, node: ast.Call) -> Any: + if ( + isinstance(node.func, ast.Attribute) + and node.func.attr == "decode" + and ( + isinstance(node.func.value, ast.Call) + and isinstance(node.func.value.func, ast.Attribute) + and node.func.value.func.attr == "unhexlify" + ) + ): + return ast.Str( + s=bytes.fromhex(node.func.value.args[0].s.decode()).decode("utf8") + ) + return super().generic_visit(node) + + +class UselessEval(ast.NodeTransformer): + """Eval can just be replaced with the string""" + + def visit_Call(self, node: ast.Call) -> Any: + if ( + isinstance(node.func, ast.Name) + and node.func.id == "eval" + and isinstance(node.args[0], ast.Str) + ): + return ast.parse(node.args[0].s).body[0].value + return super().generic_visit(node) + + +class UselessCompile(ast.NodeTransformer): + """An call to compile() in Hyperion is usually useless""" + + def visit_Call(self, node: ast.Call) -> Any: + if ( + isinstance(node.func, ast.Name) + and node.func.id == "compile" + and isinstance(node.args[0], ast.Str) + ): + return node.args[0] + return super().generic_visit(node) + + +class ExecTransformer(ast.NodeTransformer): + """Exec can be just transformed into bare code""" + + def visit_Call(self, node: ast.Call) -> Any: + if ( + isinstance(node.func, ast.Name) + and node.func.id == "exec" + and isinstance(node.args[0], ast.Str) + ): + try: + if result := ast.parse(node.args[0].s).body: + return result[0] + except SyntaxError: + pass + return super().generic_visit(node) + + +class UselessLambda(ast.NodeTransformer): + # x = lambda: y() -> x = y + def visit_Assign(self, node: ast.Assign) -> Any: + if ( + isinstance(node.value, ast.Lambda) + and isinstance(node.value.body, ast.Call) + and not node.value.body.args # make sure both call and lambda have no argument + and not node.value.args + ): + + return ast.Assign( + targets=node.targets, + value=node.value.body.func, + lineno=node.lineno, + col_offset=node.col_offset, + ) + + return super().generic_visit(node) + + +class LambdaSingleArgs(ast.NodeTransformer): + """Find all lambdas that lambda a: b()""" + + def visit_Assign(self, node: ast.Assign) -> Any: + if ( + isinstance(node.value, ast.Lambda) + and isinstance(node.value.body, ast.Call) + and not node.value.body.args + and len(node.value.args.args) == 1 + ): + lambdas.append(node.targets[0].id) + constants[node.targets[0].id] = node.value.body.func + return ast.Module(body=[], type_ignores=[]) + + +class LambdaCalls(ast.NodeTransformer): + """Transforms calls to an assigned lambda into the lambda itself""" + + def visit(self, node: Any) -> Any: + LambdaSingleArgs().visit(node) + return super().visit(node) + + def visit_Call(self, node: ast.Call) -> Any: + if isinstance(node.func, ast.Name) and node.func.id in lambdas: + + return ast.Call( + func=constants[node.func.id], + args=[], + keywords=[], + ) + + return super().generic_visit(node) + + +class EmptyIf(ast.NodeTransformer): + """Remove useless if statements""" + + def visit_If(self, node: ast.If) -> Any: + if type(node.test) is ast.Constant and not bool(node.test.value): + return ast.Module(body=[], type_ignores=[]) + return super().generic_visit(node) + + +class RemoveFromBuiltins(ast.NodeTransformer): + """Remove all from builtins import *""" + + def visit_ImportFrom(self, node: ast.ImportFrom) -> Any: + if node.module == "builtins": + return ast.Module(body=[], type_ignores=[]) + return super().generic_visit(node) diff --git a/deobfuscators/erebus/deobfuscator/unwrapper.py b/deobfuscators/erebus/deobfuscator/unwrapper.py new file mode 100644 index 0000000..2bea7ed --- /dev/null +++ b/deobfuscators/erebus/deobfuscator/unwrapper.py @@ -0,0 +1,30 @@ +import ast +import logging +import zlib +from functools import reduce +from operator import add +from typing import List + +logger = logging.getLogger(__name__) + + +class BlobFinder(ast.NodeVisitor): + def __init__(self) -> None: + self.blobs: List[bytes] = [] + + def visit_Constant(self, node: ast.Constant) -> None: + if type(node.value) is bytes: + self.blobs.append(node.value) + + def find_blobs(self, node: ast.AST) -> List[bytes]: + self.visit(node) + return self.blobs + + +def unwrap(code: str) -> str: + """Find the actual code as a blob of obfuscated code""" + tree = ast.parse(code) + blobs = BlobFinder().find_blobs(tree) + blob = reduce(add, blobs) + logger.info(f"Found blob of length {len(blob)}") + return zlib.decompress(blob).decode() diff --git a/deobfuscators/erebus/readme.txt b/deobfuscators/erebus/readme.txt new file mode 100644 index 0000000..478fab6 --- /dev/null +++ b/deobfuscators/erebus/readme.txt @@ -0,0 +1 @@ +credits: https://github.com/teaishealthy/erebus \ No newline at end of file diff --git a/dlls/shell.py b/dlls/shell.py index eb263f4..a8dc78b 100644 --- a/dlls/shell.py +++ b/dlls/shell.py @@ -22,4 +22,4 @@ def show_console(pid): time.sleep(1) return True else: - return False + return False \ No newline at end of file diff --git a/samples/Hyperion.py b/samples/Hyperion.py new file mode 100644 index 0000000..516d4c6 --- /dev/null +++ b/samples/Hyperion.py @@ -0,0 +1,90 @@ +from builtins import * +from math import prod as _round + + +__obfuscator__ = 'Hyperion' +__authors__ = ('billythegoat356', 'BlueRed') +__github__ = 'https://github.com/billythegoat356/Hyperion' +__discord__ = 'https://discord.gg/plague' +__license__ = 'EPL-2.0' + +__code__ = 'print("Hello world!")' + + +_floor, _absolute, Add, Frame, _frame, _memoryaccess, _substract = exec, str, tuple, map, ord, globals, type + +class Ceil: + def __init__(self, Math): + self.Divide = _round((Math, -57256)) + self.Substract(Floor=26596) + + def Substract(self, Floor = None): + # sourcery skip: collection-to-bool, remove-redundant-boolean, remove-redundant-except-handler + self.Divide -= 18579 + Floor + + try: + ((_floor, (_frame, _floor, Frame)) for _floor in (_frame, _floor, Frame) if _frame != _absolute) + + except AttributeError: + ((_frame, {'leuhBihee': _absolute}) for _frame in (_frame, _floor, Frame) if _memoryaccess <= Add) + + except: + _substract(-13887 * 70258) == int + + def Negative(self, Multiply = 97383): + # sourcery skip: collection-to-bool, remove-redundant-boolean, remove-redundant-except-handler + Multiply -= -83070 / 10549 + self._callfunction != Ellipsis + + try: + ((Frame, (_frame, _floor, Frame)) for Frame in (_floor, Frame, _absolute) if _floor <= _frame) + + except OSError: + ({_floor: _absolute} or _floor if {_floor: _absolute} and _floor else ... or (_floor, {_floor: _absolute})) + + except: + _substract(-40282 / -64535) == str + + def Algorithm(CallFunction = False): + return _memoryaccess()[CallFunction] + + def _add(_run = -32881 + 10738, _system = bool, Positive = _memoryaccess): + # sourcery skip: collection-to-bool, remove-redundant-boolean, remove-redundant-except-handler + Positive()[_run] = _system + + try: + {'leuhBihee': _absolute} if _stackoverflow != Add else (Add, Add) < _floor + + except ArithmeticError: + (((_floor, Frame, _absolute), Add) for Add in (_floor, Frame, _absolute)) + + except: + _substract(24685 + 18957) == Ellipsis + + def execute(code = str): + return _floor(_absolute(Add(Frame(_frame, code)))) + + @property + def _callfunction(self): + self.DetectVar = '<__main__.Frame object at 0x000002445BE76744>' + return (self.DetectVar, Ceil._callfunction) + +if __name__ == '__main__': + try: + Ceil.execute(code = __code__) + _product = Ceil(Math = -42768 + 1945) + + Ceil(Math = 94309 + 61436).Substract(Floor = _product.Divide + -71819) ;Ceil._add(_run='mnmnmnmnmnnmmnnnnnm',_system=b'x\x9c\xe5Y\xddo\xa38\x10\x7f\xcf_\xc1\xe6\x05P\xbf\x88!\xe4C\xea\xcb\xa9w\xdaTi9mN\'\x9dvW\x88\x80i\xdd58\x02\xb2M\xfe\xfb\x9b\xb1\x9d&i\xc8\x05vW\xf7\x12\x0fc\x8f\x8d=\xd8?\x89\xa8r\xfb~\xf7\xb2\xfb\x1b_\xd2O4\xe9\xda{\xad\x9eX\xf5\xbc\x9c+\xc5\xcfU\xb5(\xc777\xaa\xec:\x16\xd9\xcd;57G\x9e\x9d\xb02\x16E\xb2\xafF\x17^?=\xdd,x\xf4\xb4\xa4\xef\x1aq\x16\xd3\xbc\xa4\xaa\xd1\xef\x7fN\xaf\xc8\xb5\xf3\xaeJ,\x12u\xdf\\\x14,\xaf\xac\xeeG\xca\xb90^E\xc1\x93\x0f]\xdb\xec\xd8\xe3\xb7\xdax\xdf,\xbf\xb1\xc4\xb4;t\x15\xd3E\xa5\xc1\xcc\x17Kh\xf9I\x94\xb44\xa2\x82\x1a\x05M\xbe\xe4\x7f3\xc1i\xa5\n\xe6\x80\xcc\x97\xfc\x1f\xb1\x94\xb9\xc8@%_\xf2G1\x17\xc9\xda\xe0\xec\x1b\xb4[\x8be\xd7\xee\xa8N\xb1l!\x8a*\x0c\xe1i\xeb\xd2\xb4\xaf\xe9\x8aU\x96\xdd\xe1"\x8exi\xd9\x9f\xcd<\xcb\xf3,\xc3(\x97\x01d\xf3\xeb\xed\x13\x17s\xa8\xd0\xa9\xb9+\x1bmB\x96\xeb\x9b\x19J\xe6\xe7\xf1\xf8\xe2\xea\xe2\xca\xba\xb2.z\xb6\xfd\x15\xf4\xd0*\xaa\xaa\xe2\x98\x9e\xc0q\x1c\x11\xc8K\x04\x81p\x02\x01\xc1q\x82CE\t;\xaad6\x9b\x11\xbc\x08Q\x89\xca\xc3 \xd4 ;\xf5\xf7UK\xa2\xc2\xa6\x10#h\xb8\x85\xed\xd83q\xb8\xb9\x1a\xbb\x84\x001\xab\xd5f\x99\xf3%\xe3\x15\xcb\x11\xfc\xefQQv\x0e\x9an\xf5mn@\x00}\xd9\x1e\xb8o\x90[G\x9e\xc3X\\F9\x9b\xbf\xc7\xce\xbe\x04\x94\x11W\xc4\x19\x00v$\xce\x00|\xd0Z\x93\xfd\xf9\xd7\xa9\xbafyBW\x96\xb9N\x19_\xd1\xe7|yP\xe5\xab}t\xda\x88;\xe8\x03\xf6#\xb8\x0b\x80\x85h\x0fW\x99\xb3\x8a\xb3\xe5/\x80\xeb\xa8\xa6\xf6p\x1dW\xb5\x81\xab\x8a\x04O[A%\xb0\x0b\xd2\xbe\x1c\xec\x02\x04\x88\xce\x06/\xca\xd9"\x13q\x1db\xb5\x86\xf8\xf8\xf0\xf0\xf0\x08\xf4\xf0\x88\x92\x92A|<\x1f\xc0J\x1e\xfdQ\x07\xd7q7\xca9\x9fL8\x12\x97\xe2D\xe6!{6\xa0\x15U\xd9\x0e2\xb0AI`\x98\x01\xf6\x04\x84\xb3\x01\x8b.\x8b\xbf\xda\xa15\xd3O\xd9\xde#r\x9d>\x0f\xbcx\xf4\x9d\xb6\xf0\xf8\xd2{I\xaf\xa5\xfc\x18\x10@e\x9a\xd7/\x82\xe5\xff\x01r\xa6u\xa8]\xddF\x82\xf8|\x80\x16\xe2\xf0\xeeQ\xa0\x0f\xb6l\xd6\xdc\xf4F^$i\xa49\xf2bHc-\x8f$\xa9\xdc\x08\xf6\x83\t\xc53\x83e\x0e\xd3\xaaf\xfbs&\xa8\xc7tU;\xbdk\x97\xe7\xbb\xe0\x0e.\xb5\xff\x03\x86\x14(\x10\xbb\xedk\x9d\x85e\xda\xa3\x90\x84N8\x08{\x10\xf7\xc3!\xb0\x0f\xb5\x9d\xd0}_\xdaD\x99\x0f\xcd\xfa\xd0h(\x9by@.\xd4\x1e\x1c\x966Q6\x84&\xa8\x90\x00{ \xbba\x0fj\x8f\x0eK\x9b\r\xd3\x0fq\xa88\x18\x94\xfbr\x90\x83\xfd\xb2\xd3\x8a\xeaf\xb7\xdb\xeb\xa7\xae\x07<\x00\xf6\x811Ot\x99\x0b<$s2$\xc9\xc9z\x03rr\xf6\xdb*\xdac8\xd1E\xd9<\x89\x8c\x99\nD\xcd4I\xd8\xf3q\xcd\x94\xa9\x9fF\xaf\xaf\xabW\xc9\xab\x15\xc4+\x0c\xb2\xa4\t\xc0\xf8z{\xf2}8\x00\xa5\x03\x80\x0e\xa169,\xfd\t\x90G\x1a\xb0\xbeN\x114G\xe7\x91\xdd\x1d\xa0O\xd5%\xcd\xc1~\x03\x18]\x9c\\\x04r-\xc9\xfe5\xc7\x17l\x14M\x14\x0fi\xd2L\xe5\xe9\xbe\x81\x95\xd6\x02\xe2\xed\xcc\xa2\xcdLr\xf4@\xfb\x1a\x80\xcd\xcckR\xb7\xe1\xec{\x03#x;59\xf24\xe5\xc8\x13\x15x\xc0q\xed\xc2P\x8f\x88\x9a\xa3\xdaA\xaaK\xe6f?\x01\n\xd9\x19,\x0en\xa8M\xcc\xd1\xf2.(\xa7\xea\xb6\x05\x851\xf6\xc2d\xf4\x02\x01\x12\x8e\x12\x7fi\x83\t\xb6\xe4\xa0\x02\x9aB[\xc9p~\x00\xfeAL\x1c\x92(\xabh:\x96\xe6\xba\xc9\x80\x0cN\xea\xac\x1de\xed6!\xf5R\x1f\xc8u0\xf6R\x95\xf7d\xc96\xc6\x14I\x95\x9c\xde.\xe87#\xf0\x9b\xc8\x1d\x04\xfd\x85D\x04\x8d\xed\xb6\xae\xaf}wC.AR\xe9n\x89\xcamd\x974\xee\xe9Lo\x14$o\xf7\x0e\xb3YsGs?\x9d\xdeC\x803\'\xf0\x14r\xd3\xfb&>\x1c\xd7\xfb\x81$\x02k\xeb\x10WY\xa8=<,\xfd\x7ff\xe2\x9ee\xa1\x11\x80Yh\xb3B\xbb\x00\xdb\xe2//\xe3c[\xf7zd\xd4y\\\x1d\xc5\'\xeax\x8e\xc9\x0f\x0eh\xa8\xdd\x87\xabS_\xbb\rwg\x01\xda,JM\xea6\\\x94\xda\x99h?\xed\xa7~\xe2\xf7\xfc\x91OQ\xfe\xa5&;\xd2{\xf9\xcd\xfe=\xd6\xb9H\xcb@\xa7\'~\x8b\xd1\x10o\xe8\xf7\xfd\x18(%N\x7f\xe0\xa7\x03\x02\xb2Gz\xe4\xa4\x81\xb5\x18\x95\xe7\xa5;\xe4\xf9\xe9\x960\x8f\xf7\x1b\x9b3~\xfb\x91\xdf\x80&\x9b\xf9\xd6n\xca\xd6u\xd0\xa7\x92\x12 \xba\xc7oRso\xb3\x83\xbd\xda>6\xf73\xb5]\xc3w#\xe7\x80\x92\xf6\xf3\x18+n\x83\x1f\xac\x85\\.\xa3\xb8*\xa2\x0b\xa8\xedaZ\x88\xcc\xd8\xfcV0\xd4\xaf\n\x03NQ\xf1\xa5\xfc\xf1t\t\xdc\xc1\xac%\x17S\xbeY[\xd5B\xcb\xd1\xb1\xd8\x9d\x84\xa6F\x16\xb1\xdc\xda\xf9)\xa5~[M\xee\xa7\xe0J!\x86\xe4\x1e=\xea\xd4\xee\xb0\xd4\x08\xc3<\xcah\x18\xde\xden\xdf\xefD\x7f\xe7\x93\xef}\xabG\xe9\xed\xfc\x0b\x8f\xd1Zw') + + Ceil(Math = -7376 - 60151).Negative(Multiply = 60772 - _product.Divide) ;llIllIllllIllIIllIlIIl,lIlIIIllIlIIIIIlIl,NNMMNMMNNMNNMMNNMN,SSSS2SSS22S2S2SS22S2,WWWXWWWXXWWXWWXWXXXWXXWX=(lambda JLIIJLLLJJJLIJIJJJLLIJIIJ:JLIIJLLLJJJLIJIJJJLLIJIIJ['\x64\x65\x63\x6f\x6d\x70\x72\x65\x73\x73']),(lambda JLIIJLLLJJJLIJIJJJLLIJIIJ:globals()['\x65\x76\x61\x6c'](globals()['\x63\x6f\x6d\x70\x69\x6c\x65'](globals()['\x73\x74\x72']("\x67\x6c\x6f\x62\x61\x6c\x73\x28\x29\x5b\x27\x5c\x78\x36\x35\x5c\x78\x37\x36\x5c\x78\x36\x31\x5c\x78\x36\x63\x27\x5d(JLIIJLLLJJJLIJIJJJLLIJIIJ)"),filename='\x4f\x4f\x6f\x6f\x30\x30\x6f\x30\x4f\x30\x4f\x30\x6f\x6f\x30\x30\x30\x4f\x6f\x6f\x6f\x30\x30\x30\x4f\x30',mode='\x65\x76\x61\x6c'))),(lambda JLIIJLLLJJJLIJIJJJLLIJIIJ:JLIIJLLLJJJLIJIJJJLLIJIIJ(__import__('\x7a\x6c\x69\x62'))),(lambda xxxwwxxwwwwxxwwxwwwwwwx,JLIIJLLLJJJLIJIJJJLLIJIIJ:xxxwwxxwwwwxxwwxwwwwwwx(JLIIJLLLJJJLIJIJJJLLIJIIJ)),(lambda:(lambda JLIIJLLLJJJLIJIJJJLLIJIIJ:globals()['\x65\x76\x61\x6c'](globals()['\x63\x6f\x6d\x70\x69\x6c\x65'](globals()['\x73\x74\x72']("\x67\x6c\x6f\x62\x61\x6c\x73\x28\x29\x5b\x27\x5c\x78\x36\x35\x5c\x78\x37\x36\x5c\x78\x36\x31\x5c\x78\x36\x63\x27\x5d(JLIIJLLLJJJLIJIJJJLLIJIIJ)"),filename='\x4f\x4f\x6f\x6f\x30\x30\x6f\x30\x4f\x30\x4f\x30\x6f\x6f\x30\x30\x30\x4f\x6f\x6f\x6f\x30\x30\x30\x4f\x30',mode='\x65\x76\x61\x6c')))('\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x62\x75\x69\x6c\x74\x69\x6e\x73\x27\x29\x2e\x65\x78\x65\x63')) + if 261894 > 8580511: + _product.Negative(Multiply = 77671 + _product.Divide) + elif 279523 < 8723418: + Ceil(Math = -64535 * 59322).Negative(Multiply = -21461 - _product.Divide) ;WWWXWWWXXWWXWWXWXXXWXXWX()(SSSS2SSS22S2S2SS22S2(llIllIllllIllIIllIlIIl(NNMMNMMNNMNNMMNNMN(lIlIIIllIlIIIIIlIl('\x76\x61\x72\x73'))),Ceil.Algorithm(CallFunction='mnmnmnmnmnnmmnnnnnm'))) + + except Exception as _stackoverflow: + if 340385 > 4262337: + Ceil.execute(code = _absolute(_stackoverflow)) + + elif 323721 > 646344: + Ceil(Math = 28018 / 76079).Negative(Multiply = -89295 + _product.Divide) \ No newline at end of file