Noisec / Nobfu-obfuscator

Python obfuscator & anti-debugging protector
MIT License
4 stars 0 forks source link

i tried making a deobfuscator #1

Open A3ima opened 1 year ago

A3ima commented 1 year ago
import bz2
import os
import quopri
import random
import base64
import random
import platform
import traceback
import itertools
import re
import autopep8

def try_deobfuscate(code, techniques):
    for technique in techniques:
        try:
            code = technique(code)
        except Exception as e:
            return None
    return code

def deobfuscate(obfuscated_code):
    obfuscated_code = remove_dbgprot(obfuscated_code)
    obfuscated_code = unify_deobfuscate(obfuscated_code)
    techniques = [rev_deobfuscate, quoted_decode, comppy_deobfuscate, b64unpack]

    for layer_count in range(1, 50):
        technique_orders = list(itertools.product(techniques, repeat=layer_count))
        for order in technique_orders:
            deobfuscated_code = try_deobfuscate(obfuscated_code, order)
            if deobfuscated_code is not None:
                return deobfuscated_code

    raise Exception("Deobfuscation failed for all technique orders.")

def remove_dbgprot(code):
    if code.startswith("exec(\"\"\""):
        code = code.split("exec(\"\"\"\n", 1)[1]
        code = code.rsplit("\"\"\"", 1)[0]
    return code

def unify_deobfuscate(code):
    for quote_type in ['"""', "'''"]:
        if code.startswith(f"exec({quote_type}"):
            code = code[len(f"exec({quote_type}"):]
            code = code[:-len(quote_type)]
            code = code.replace('\\n', '\n').replace('\\t', '\t')
            break
    return code

def rev_deobfuscate(input_str):
    if input_str.startswith("data=r"):
        input_str = input_str.split("\n", 1)[1]
        input_str = input_str[:-1]
        revedcode = input_str[::-1]
        return revedcode
    else:
        raise Exception("Not a valid reverse obfuscation")

def comppy_deobfuscate(code):
    if code.startswith("import bz2"):
        decompresser_start = code.index("exec(bz2.decompress(") + len("exec(bz2.decompress(")
        decompresser_end = code.index("))", decompresser_start)
        compressed = eval(code[decompresser_start:decompresser_end])
        decompressed = bz2.decompress(compressed).decode('utf-8')
        return decompressed
    else:
        raise Exception("Not a valid comppy obfuscation")

def quoted_decode(code):
    if code.startswith("import quopri"):
        encoded_start = code.index("exec(quopri.decodestring(") + len("exec(quopri.decodestring(")
        encoded_end = code.index(").decode('utf-8'))", encoded_start)
        encoded = eval(code[encoded_start:encoded_end])
        decoded = quopri.decodestring(encoded).decode('ascii')
        return decoded
    else:
        raise Exception("Not a valid quoted obfuscation")

def b64unpack(code):
    encoded_start = code.find("decoded = '")
    if encoded_start != -1:
        encoded_start += len("decoded = '")
        encoded_end = code.index("'", encoded_start)
        encoded = code[encoded_start:encoded_end]

        n = 0
        while "decoded = base64.b64decode(decoded.encode()).decode()" in code:
            n += 1
            code = code.replace("decoded = base64.b64decode(decoded.encode()).decode()", "", 1)

        decoded = encoded
        for i in range(n):
            decoded = base64.b64decode(decoded.encode()).decode()

        return decoded
    else:
        raise Exception("Not a valid b64unpack obfuscation")

def fix_formatting(code):
    formatted_code = autopep8.fix_code(code, options={'aggressive': 2})
    return formatted_code

def main():
    file_path = ""  # Change this to your obfuscated Python file path
    with open(file_path, "r") as f:
        obfuscated_code = f.read()

    formatted_code = fix_formatting(obfuscated_code)

    try:
        deobfuscated_code = deobfuscate(formatted_code)
    except Exception as e:
        print("Deobfuscation failed. Showing the original code:")
        print(formatted_code)
    else:
        print("Deobfuscated code:")
        print(deobfuscated_code)

if __name__ == "__main__":
    main()
Noisec commented 1 year ago

Nice, but no chance against 200mb obf.ed files 😂 But also it was just an fun project, so anyway, it doesn't make much sense to make a 200mb obf.ed python file with this, it would use a lot of cpu, but if it's not 200mb, then simpler deobfuscators like this will be able to decipher it, or if the random obfuscation was so bad, then even a human can undo it.

Noisec commented 1 year ago

oukay

A3ima commented 1 year ago

i can make it work against 200mb obf files

A3ima commented 1 year ago

anyways, if ur going to improve this fun proj lmk, il update the deobfucator, and if ur ever going to be serious about building an obfuscator lmk, il help out