예제 #1
0
 def test_dec(self):
     compiled = get_compiled_binary(fp)
     try:
         src, result_src = roundtrip_test(fp)
         self.assertEqual(src, result_src)
     except Exception as ae:
         if use_trace and not unpyc3.get_trace():
             try:
                 unpyc3.set_trace(print)
                 unpyc3.decompile(compiled)
             except Exception:
                 pass
             finally:
                 unpyc3.set_trace(None)
         raise ae
예제 #2
0
def roundtrip_test(fp: str) -> (str, str):
    compileall.compile_file(fp)
    compiled = get_compiled_binary(fp)
    with open(fp) as f:
        src = f.read().lstrip(" ").rstrip(" ").replace("\r",
                                                       "").rstrip(os.linesep)
        print(src)
        result = unpyc3.decompile(compiled)
        rsrc = (os.linesep.join(
            (str(r) for r in result)).replace("\r", "").rstrip(os.linesep))
        return src, rsrc
예제 #3
0
    def test(self):
        root = os.path.dirname(full_path)
        filename = os.path.basename(full_path)
        try:
            result = unpyc3.decompile(full_path)
            result_src = os.linesep.join(
                (str(r) for r in result)).replace('\r', '')
            with io.open(full_path.replace('.pyc', '.py'), 'w') as f:
                f.write(result_src)
            co = compile(result_src, '<string>', 'exec')
        except Exception as ae:

            with io.open(full_path, 'rb') as x:
                x.read(16)
                dis.dis(marshal.load(x))

            raise ae
예제 #4
0
    def test(self):
        root = os.path.dirname(full_path)
        filename = os.path.basename(full_path)
        try:
            result = unpyc3.decompile(full_path)
            result_src = os.linesep.join(
                (str(r) for r in result)).replace("\r", "")
            with io.open(full_path.replace(".pyc", ".py"), "w") as f:
                f.write(result_src)
            co = compile(result_src, "<string>", "exec")
        except Exception as ae:

            with io.open(full_path, "rb") as x:
                x.read(16)
                dis.dis(marshal.load(x))

            raise ae
예제 #5
0
        result_set.update(((self._res_id_group_map.get(r, 0), r) for r in res_dict))

if __name__ == "__main__":
    import unpyc3
    import sys
    
    if len(sys.argv) == 1:
        import types
        import difflib
        # run through and compile all functions
        for k,func in TestClass.__dict__.items():
            if isinstance(func,types.FunctionType):
                code = unpyc3.Code(func.__code__)
                source = str(code.get_suite(include_declarations=False, look_for_docstring=True))
                #compiled = compile(source, '<string>', 'exec')
        # now 
        import unpyc3_tests
        code = unpyc3.decompile(unpyc3_tests)
        compiled = compile(str(code), '<string>', 'exec')
        code2 = unpyc3.decompile(compiled)
        # d = difflib.Differ()
        # result = list(d.compare(str(code), str(code2)))
        # from pprint import pprint
        # pprint(result)
        diff = difflib.unified_diff(str(code), str(code2), fromfile='original', tofile='converted')
        sys.stdout.writelines(diff)
    else:
        pass
    #compiled2 = compile(str(code2), '<string>', 'exec')
        
예제 #6
0
def decompile(srcFolder, destFolder, subFolder, pycFile, pyFile,
              prefix_filenames, large_codeobjects_threshold, comment_style,
              decompiler, py37dec_timeout, split_result_folders):
    decompile_results = DecompileResultData(
        os.path.realpath(os.path.join(srcFolder, subFolder, pycFile)))
    timer = Timer()
    remove_pyc = True if srcFolder == destFolder else False
    pycFullFilename = os.path.join(srcFolder, subFolder, pycFile)

    try:
        if decompiler == 'unpyc3':
            # For unpyc3, just call the decompile() method from that module
            src_code = ''
            lines = unpyc3.decompile(pycFullFilename)
            for line in lines:
                src_code += str(line) + '\n'
        else:
            # For py37dec, run the executable in a subprocess.  At least one file from TS4 still takes
            # too long (and too much virtual memory) to process, so a timeout is specified.
            subprocess_result = subprocess.run(
                [PY37DEC_LOCATION,
                 pycFullFilename.replace('\\', '/')],
                capture_output=True,
                encoding='utf-8',
                timeout=py37dec_timeout)
            decompile_results.decompile_time = timer.elapsed_time()
            if subprocess_result.returncode != 0:
                # Non-zero return code from the py37dec executable indicates a crash failure
                # in the executable.  Summarize and build an empty .py file.
                if prefix_filenames:
                    pyFile = '[FAILED] ' + pyFile
                if split_result_folders:
                    pyFolder = os.path.join(destFolder, 'decompile_failure',
                                            subFolder)
                else:
                    pyFolder = os.path.join(destFolder, subFolder)
                os.makedirs(pyFolder, exist_ok=True)
                decompile_results.pyFilename = os.path.realpath(
                    os.path.join(pyFolder, pyFile))
                with open(decompile_results.pyFilename, 'w',
                          encoding='UTF-8') as fp:
                    if comment_style == 1:
                        fp.write('# {}: Decompile failed\n'.format(decompiler))
                    elif comment_style == 2:
                        fp.write('"""\npy37dec: Decompilation failure\n\n')
                        fp.write(subprocess_result.stderr)
                        fp.write('"""\n')
                decompile_results.result = 3
                if remove_pyc:
                    os.remove(pycFullFilename)
                return decompile_results
            # Rc = 0 from subprocess, so read the source code lines from the subproccess stdout
            src_code = subprocess_result.stdout
    except subprocess.TimeoutExpired:
        # This exception will only occur if a py37dec subprocess is killed off due to a timeout.
        decompile_results.decompile_time = timer.elapsed_time()
        if prefix_filenames:
            pyFile = '[TIMEOUT] ' + pyFile
        if split_result_folders:
            pyFolder = os.path.join(destFolder, 'timeout', subFolder)
        else:
            pyFolder = os.path.join(destFolder, subFolder)
        os.makedirs(pyFolder, exist_ok=True)
        decompile_results.pyFilename = os.path.realpath(
            os.path.join(pyFolder, pyFile))
        decompile_results.result = 4
        with open(decompile_results.pyFilename, 'w', encoding='UTF-8') as fp:
            if comment_style == 1:
                fp.write('# py37dec: Timeout\n')
            elif comment_style == 2:
                fp.write('"""\npy37dec: Timeout of {} seconds exceeded\n"""\n'.
                         format(py37dec_timeout))
        if remove_pyc:
            os.remove(pycFullFilename)
        return decompile_results
    except:
        # A normal exception will occur if unpyc3 fails and throws an exception during the
        # decompilation process.
        if prefix_filenames:
            pyFile = '[FAILED] ' + pyFile
        if split_result_folders:
            pyFolder = os.path.join(destFolder, 'decompile_failure', subFolder)
        else:
            pyFolder = os.path.join(destFolder, subFolder)
        os.makedirs(pyFolder, exist_ok=True)
        decompile_results.pyFilename = os.path.realpath(
            os.path.join(pyFolder, pyFile))
        with open(decompile_results.pyFilename, 'w', encoding='UTF-8') as fp:
            if comment_style == 1:
                fp.write('# {}: Decompile failed\n'.format(decompiler))
            elif comment_style == 2:
                fp.write('"""\nunpyc3: Decompilation failure\n\n')
                fp.write(traceback.format_exc())
                fp.write('"""\n')
        decompile_results.result = 3
        if remove_pyc:
            os.remove(pycFullFilename)
        return decompile_results

    decompile_results.decompile_time = timer.elapsed_time()

    synErr = None
    try:
        # Try compiling the generated source, a syntax error in the source code
        # will throw an exception.
        py_codeobj = compile(src_code, pyFile, 'exec')

        # Get the code object from the .pyc file
        pyc_codeobj = get_codeobj_from_pyc(decompile_results.pycFilename)

        # Compare the code objects recursively
        issues = compare_codeobjs(pyc_codeobj, py_codeobj,
                                  large_codeobjects_threshold)
        decompile_results.analyze_time = timer.elapsed_time(
        ) - decompile_results.decompile_time

        if not issues:
            # There were no issues returned from the code object comparison, so this code
            # is identical to the original sources.
            if prefix_filenames:
                pyFile = '[PERFECT] ' + pyFile
            if split_result_folders:
                pyFolder = os.path.join(destFolder, 'perfect', subFolder)
            else:
                pyFolder = os.path.join(destFolder, subFolder)
            decompile_results.pyFilename = os.path.realpath(
                os.path.join(pyFolder, pyFile))
            decompile_results.result = 0
        else:
            # There were comparison issues with the code objects, this source code differs
            # from the original.  It may function identically or improperly (or not at all) but
            # only human inspection of the resulting code can determine how good the results are.
            if prefix_filenames:
                pyFile = '[GOOD] ' + pyFile
            if split_result_folders:
                pyFolder = os.path.join(destFolder, 'good', subFolder)
            else:
                pyFolder = os.path.join(destFolder, subFolder)
            decompile_results.pyFilename = os.path.realpath(
                os.path.join(pyFolder, pyFile))
            decompile_results.result = 1
    except:
        # An exception from the compile or comparison will end up here, this is generally
        # due to a syntax error in the decompilation results.
        if prefix_filenames:
            pyFile = '[SYNTAX] ' + pyFile
        if split_result_folders:
            pyFolder = os.path.join(destFolder, 'syntax', subFolder)
        else:
            pyFolder = os.path.join(destFolder, subFolder)
        decompile_results.pyFilename = os.path.realpath(
            os.path.join(pyFolder, pyFile))
        decompile_results.result = 2
        synErr = traceback.format_exc(1)
    # Create the destination folder for this .py file and write it, adding comments
    # if requested (1 = brief, 2 = detailed).
    os.makedirs(pyFolder, exist_ok=True)
    with open(decompile_results.pyFilename, 'w', encoding='UTF-8') as fp:
        if comment_style == 1:
            if synErr:
                fp.write('# {}: Syntax error in decompiled file\n'.format(
                    decompiler))
            elif issues:
                fp.write(
                    '# {}: Decompiled file contains inaccuracies\n'.format(
                        decompiler))
            else:
                fp.write('# {}: 100% Accurate decompile result\n'.format(
                    decompiler))
        elif comment_style == 2:
            if synErr:
                fp.write('"""\n{}:\n{}"""\n'.format(decompiler, synErr))
            elif issues:
                fp.write('"""\n{}:\n{}"""\n'.format(decompiler, issues))
            else:
                fp.write('# {}: 100% Accurate decompile result\n'.format(
                    decompiler))
        fp.write(src_code)

    if remove_pyc:
        os.remove(pycFullFilename)
    return decompile_results
예제 #7
0
    def test_func30():
        result_set.update(
            ((self._res_id_group_map.get(r, 0), r) for r in res_dict))


if __name__ == "__main__":
    import unpyc3
    import sys

    if len(sys.argv) == 1:
        import types
        import difflib
        # run through and compile all functions
        for k, func in TestClass.__dict__.items():
            if isinstance(func, types.FunctionType):
                code = unpyc3.Code(func.__code__)
                source = str(
                    code.get_suite(include_declarations=False,
                                   look_for_docstring=True))

        import unpyc3_tests
        code = unpyc3.decompile(unpyc3_tests)
        compiled = compile(str(code), '<string>', 'exec')
        code2 = unpyc3.decompile(compiled)
        diff = difflib.unified_diff(str(code),
                                    str(code2),
                                    fromfile='original',
                                    tofile='converted')
        sys.stdout.writelines(diff)
try:
    for file in FILES_IN_ZIP:
        FROM_COPY_DIR = PATH_DIR+file+".zip"
        TO_PATH_DIR = NEW_DIR+file+".zip"
        copyfile(FROM_COPY_DIR, TO_PATH_DIR)
        zip_ref = zipfile.ZipFile(TO_PATH_DIR, 'r')
        if not os.path.exists(NEW_DIR+file): os.makedirs(NEW_DIR+file)
        zip_ref.extractall(NEW_DIR+file)
        zip_ref.close()
        os.remove(TO_PATH_DIR)
except:
    sys.exit("Error in Unzipping files! Try With Another Destination Folder")

for root, dirs, files in os.walk(NEW_DIR):
    for file in files:
        print(root + SLASH + file + ' --> DECOMPILED!')
        if file.endswith(".pyo"):
            if not os.path.exists(root):
                os.makedirs(root)
            f1 = open(root+SLASH+file.replace(".pyo",".py"),"w+")
            try:
                print(decompile(root+SLASH+file), file=f1)
                os.remove(root+SLASH+file)
                f1.close()
            except:
                f1.close()
                os.remove(root+SLASH+file.replace(".pyo",".py"))
            continue
        else:
            continue
예제 #9
0
def decomp(o):
    import unpyc3
    print(unpyc3.decompile(o))