def get_loader(archive: BinaryIO) -> str: path = os.path.join(os.path.dirname(archive.name), loader_name) try: import uncompyle6 # type: ignore except ImportError as e: raise MissingPackageError("uncompyle6") from e try: with io.StringIO() as decompiled: uncompyle6.decompile_file(path, outstream=decompiled) return decompiled.getvalue() except ImportError as e: raise LoaderRequiredError(path) from e
def main_source(file, source): global bindata, source_file source_file = file if source == '': source = '_source.py' arch = pyinstxtractor.PyInstArchive(file) if arch.open(): if arch.checkFile() and arch.getCArchiveInfo(): arch.parseTOC() arch.extractFiles() arch.close() print('[*] Successfully extracted pyinstaller archive: {0}'.format(file)) arch.close() if os.path.isfile(file.replace('.exe', '')) != True: print('[*] Not found {} file!'.format(file.replace('.exe', ''))) file = input('[?] Select a "Possible entry point" file from the top list -> ')+'.exe' try: os.remove(file.replace('exe', 'pyc')) except: pass os.rename(file.replace('.exe', ''), file.replace('exe', 'pyc')) pycfile = file.replace('exe', 'pyc') archive = zipfile.ZipFile('base_library.zip', 'r') bindata = binascii.unhexlify(binascii.hexlify(archive.read('abc.pyc')).split(b'e3')[0]) archive.close() open('newf5a99.pyc', 'w').close() with open('newf5a99.pyc', 'r+b') as new: new.write(bindata) with open(pycfile, 'rb') as old: new.write(old.read()) os.remove(pycfile) os.rename('newf5a99.pyc', pycfile) if source == '_source.py': if os.path.isdir('../'+file.replace('.exe', '')+source) != True: os.mkdir('../'+file.replace('.exe', '')+source) with open('../'+file.replace('.exe', '')+source+'/'+file.replace('.exe', '')+'_source.py', "w") as fileobj: uncompyle6.decompile_file(pycfile, fileobj) else: if os.path.isdir('../'+source) != True: os.mkdir('../'+source) with open('../'+source+'/'+source, "w") as fileobj: uncompyle6.decompile_file(pycfile, fileobj) return file
def decompile_modules(self): for module_count, module in enumerate(self.files, 1): with open(module[:-1], 'w') as writable_decompiler: decompiled_result = io.StringIO() try: uncompyle6.decompile_file(module, outstream=decompiled_result) except: writable_decompiler.write( "# MyFellowDumper\n# Failed to decompile file") print(f"Failed to decompile: {writable_decompiler.name}", f"({module_count}/{self.files_numb})") continue writable_decompiler.write(decompiled_result.getvalue()) print(f"Decompiled module: {writable_decompiler.name}", f"({module_count}/{self.files_numb})")
def all_source(fi, source): if source == '': source = '_source.py' files = os.listdir('PYZ-00.pyz_extracted/') files = list(set(fi).intersection(files)) if source == '_source.py': if os.path.isdir('../' + file.replace('.exe', '') + source + '/libs') != True: os.mkdir('../' + file.replace('.exe', '') + source + '/libs') for i in files: print('[*] Processing {}'.format(i)) open('../' + file.replace('.exe', '') + source + '/libs/' + i, 'w').close() with open('../' + file.replace('.exe', '') + source + '/libs/' + i, 'r+b') as new: new.write(bindata) with open('PYZ-00.pyz_extracted/' + i, 'rb') as old: new.write( binascii.unhexlify(binascii.hexlify(old.read())[24:])) with open('../' + file.replace('.exe', '') + source + '/libs/' + i.replace('.pyc', '.py'), "w", encoding='utf-8') as fileobj: uncompyle6.decompile_file( '../' + file.replace('.exe', '') + source + '/libs/' + i, fileobj) os.remove('../' + file.replace('.exe', '') + source + '/libs/' + i) print('[+] Successfully decompiling {}'.format(i)) else: if os.path.isdir('../' + source + '/libs') != True: os.mkdir('../' + source + '/libs') for i in files: print('[*] Processing {}'.format(i)) open('../' + source + '/libs/' + i, 'w').close() with open('../' + source + '/libs/' + i, 'r+b') as new: new.write(bindata) with open('PYZ-00.pyz_extracted/' + i, 'rb') as old: new.write( binascii.unhexlify(binascii.hexlify(old.read())[24:])) with open('../' + source + '/libs/' + i.replace('.pyc', '.py'), "w", encoding='utf-8') as fileobj: uncompyle6.decompile_file('../' + source + '/libs/' + i, fileobj) os.remove('../' + source + '/libs/' + i) print('[+] Successfully decompiling {}'.format(i))
def sourcecode(index): fetch_posts() global posts for each in posts: if (each['index'] == index): data = each['data'] unhexed_data = binascii.unhexlify(data) f = open('temp/temp.pyc', 'wb+') f.write(unhexed_data) f.close() with open("temp/temp.py", "wb") as fileobj: uncompyle6.decompile_file("temp/temp.pyc", fileobj) fileobj.close() with open('temp/temp.py', 'r') as file: data2 = file.read() return "<xmp>" + data2 + "</xmp>" else: continue return "That contract does not exist on the blockchain"
import os import uncompyle6 your_directory = '' for dirpath, b, filenames in os.walk('./'): # sample.pyc path for filename in filenames: if not filename.endswith('.pyc'): continue filepath = dirpath + '/' + filename original_filename = filename.split('.')[0] original_filepath = dirpath + '/' + original_filename + '.py' with open(original_filepath, 'w') as f: uncompyle6.decompile_file(filepath, f)
try: extension = file_.name.split(".")[1] except IndexError: extension = None if file_.name in secrets or (extension and extension == "pyc"): items.append(file_) if not items: print("No files found, you are good!") for item in items: print(f"DECOMPILING REPO https://github.com/{item.repository.full_name}") print(f"OWNER TYPE: {item.repository.owner.type}") try: contents = base64.b64decode(item.content) with tempfile.NamedTemporaryFile(suffix=".pyc") as f: f.write(contents) f.seek(0) out = io.StringIO() uncompyle6.decompile_file(f.name, out) out.seek(0) print(out.read()) except Exception as e: print(e) print( f"COULD NOT DECOMPILE REPO https://github.com/{item.repository.full_name}" ) continue print("\n\n\n")
def main(dbg=None, sys_argv=list(sys.argv)): """Routine which gets run if we were invoked directly""" global __title__ # Save the original just for use in the restart that works via exec. orig_sys_argv = list(sys_argv) opts, dbg_opts, sys_argv = Moptions.process_options( __title__, VERSION, sys_argv) if opts.server is not None: if opts.server == 'tcp': connection_opts = {'IO': 'TCP', 'PORT': opts.port} else: connection_opts = {'IO': 'FIFO'} intf = Mserver.ServerInterface(connection_opts=connection_opts) dbg_opts['interface'] = intf if 'FIFO' == intf.server_type: print('Starting FIFO server for process %s.' % os.getpid()) elif 'TCP' == intf.server_type: print('Starting TCP server listening on port %s.' % intf.inout.PORT) pass elif opts.client: Mclient.main(opts, sys_argv) return dbg_opts['orig_sys_argv'] = orig_sys_argv if dbg is None: dbg = Mdebugger.Trepan(dbg_opts) dbg.core.add_ignore(main) pass Moptions._postprocess_options(dbg, opts) # process_options has munged sys.argv to remove any options that # options that belong to this debugger. The original options to # invoke the debugger and script are in global sys_argv if len(sys_argv) == 0: # No program given to debug. Set to go into a command loop # anyway mainpyfile = None else: mainpyfile = sys_argv[0] # Get script filename. if not osp.isfile(mainpyfile): mainpyfile = Mclifns.whence_file(mainpyfile) is_readable = Mfile.readable(mainpyfile) if is_readable is None: print("%s: Python script file '%s' does not exist" % ( __title__, mainpyfile, )) sys.exit(1) elif not is_readable: print("%s: Can't read Python script file '%s'" % ( __title__, mainpyfile, )) sys.exit(1) return if Mfile.is_compiled_py(mainpyfile): try: from xdis import load_module, PYTHON_VERSION, IS_PYPY (python_version, timestamp, magic_int, co, is_pypy, source_size) = load_module(mainpyfile, code_objects=None, fast_load=True) assert is_pypy == IS_PYPY assert python_version == PYTHON_VERSION, \ "bytecode is for version %s but we are version %s" % ( python_version, PYTHON_VERSION) # We should we check version magic_int py_file = co.co_filename if osp.isabs(py_file): try_file = py_file else: mainpydir = osp.dirname(mainpyfile) tag = sys.implementation.cache_tag dirnames = [ osp.join(mainpydir, tag), mainpydir ] + os.environ['PATH'].split(osp.pathsep) + ['.'] try_file = Mclifns.whence_file(py_file, dirnames) if osp.isfile(try_file): mainpyfile = try_file pass else: # Move onto the except branch raise IOError( "Python file name embedded in code %s not found" % try_file) except IOError: try: from uncompyle6 import decompile_file except ImportError: print( "%s: Compiled python file '%s', but uncompyle6 not found" % (__title__, mainpyfile), file=sys.stderr) sys.exit(1) return short_name = osp.basename(mainpyfile).strip('.pyc') fd = tempfile.NamedTemporaryFile(suffix='.py', prefix=short_name + "_", delete=False) old_write = fd.file.write def write_wrapper(*args, **kwargs): if isinstance(args[0], str): new_args = list(args) new_args[0] = args[0].encode('utf-8') old_write(*new_args, **kwargs) else: old_write(*args, **kwargs) fd.file.write = write_wrapper # from io import StringIO # linemap_io = StringIO() try: decompile_file(mainpyfile, fd.file, mapstream=fd) except: print("%s: error decompiling '%s'" % (__title__, mainpyfile), file=sys.stderr) sys.exit(1) return # # Get the line associations between the original and # # decompiled program # mapline = linemap_io.getvalue() # fd.write(mapline + "\n\n") # linemap = eval(mapline[3:]) mainpyfile = fd.name fd.close() # Since we are actually running the recreated source, # there is little no need to remap line numbers. # The mapping is given at the end of the file. # However we should consider adding this information # and original file name. print( "%s: couldn't find Python source so we recreated it at '%s'" % (__title__, mainpyfile), file=sys.stderr) pass # If mainpyfile is an optimized Python script try to find and # use non-optimized alternative. mainpyfile_noopt = pyficache.pyc2py(mainpyfile) if mainpyfile != mainpyfile_noopt \ and Mfile.readable(mainpyfile_noopt): print("%s: Compiled Python script given and we can't use that." % __title__) print("%s: Substituting non-compiled name: %s" % ( __title__, mainpyfile_noopt, )) mainpyfile = mainpyfile_noopt pass # Replace trepan's dir with script's dir in front of # module search path. sys.path[0] = dbg.main_dirname = osp.dirname(mainpyfile) # XXX If a signal has been received we continue in the loop, otherwise # the loop exits for some reason. dbg.sig_received = False # if not mainpyfile: # print('For now, you need to specify a Python script name!') # sys.exit(2) # pass while True: # Run the debugged script over and over again until we get it # right. try: if dbg.program_sys_argv and mainpyfile: normal_termination = dbg.run_script(mainpyfile) if not normal_termination: break else: dbg.core.execution_status = 'No program' dbg.core.processor.process_commands() pass dbg.core.execution_status = 'Terminated' dbg.intf[-1].msg("The program finished - quit or restart") dbg.core.processor.process_commands() except Mexcept.DebuggerQuit: break except Mexcept.DebuggerRestart: dbg.core.execution_status = 'Restart requested' if dbg.program_sys_argv: sys.argv = list(dbg.program_sys_argv) part1 = ('Restarting %s with arguments:' % dbg.core.filename(mainpyfile)) args = ' '.join(dbg.program_sys_argv[1:]) dbg.intf[-1].msg( Mmisc.wrapped_lines(part1, args, dbg.settings['width'])) else: break except SystemExit: # In most cases SystemExit does not warrant a post-mortem session. break pass # Restore old sys.argv sys.argv = orig_sys_argv return
def main(dbg=None, sys_argv=list(sys.argv)): """Routine which gets run if we were invoked directly""" # Save the original just for use in the restart that works via exec. orig_sys_argv = list(sys_argv) opts, dbg_opts, sys_argv = Moptions.process_options( __title__, __version__, sys_argv) if opts.server: connection_opts = {"IO": "TCP", "PORT": opts.port} intf = Mserver.ServerInterface(connection_opts=connection_opts) dbg_opts["interface"] = intf if "FIFO" == intf.server_type: print("Starting FIFO server for process %s." % os.getpid()) elif "TCP" == intf.server_type: print("Starting TCP server listening on port %s." % intf.inout.PORT) pass elif opts.client: Mclient.main(opts, sys_argv) return dbg_opts["orig_sys_argv"] = orig_sys_argv if dbg is None: dbg = Mdebugger.Debugger(dbg_opts) dbg.core.add_ignore(main) pass Moptions._postprocess_options(dbg, opts) # process_options has munged sys.argv to remove any options that # options that belong to this debugger. The original options to # invoke the debugger and script are in global sys_argv if len(sys_argv) == 0: # No program given to debug. Set to go into a command loop # anyway mainpyfile = None else: mainpyfile = sys_argv[0] # Get script filename. if not osp.isfile(mainpyfile): mainpyfile = Mclifns.whence_file(mainpyfile) is_readable = Mfile.readable(mainpyfile) if is_readable is None: sys.stderr.write( "%s: Python script file '%s' does not exist\n" % (__title__, mainpyfile)) sys.exit(1) elif not is_readable: sys.stderr.write("%s: Can't read Python script file '%s'\n" % ( __title__, mainpyfile, )) sys.exit(1) return if Mfile.is_compiled_py(mainpyfile): try: from xdis import load_module from xdis_version import load_module, PYTHON_VERSION_TRIPLE, IS_PYPY, version_tuple_to_str ( python_version, timestamp, magic_int, co, is_pypy, source_size, ) = load_module(mainpyfile, code_objects=None, fast_load=True) assert is_pypy == IS_PYPY assert ( python_version == PYTHON_VERSION_TRIPLE ), "bytecode is for version %s but we are version %s" % ( python_version, version_tuple_to_str(), ) # We should we check version magic_int py_file = co.co_filename if osp.isabs(py_file): try_file = py_file else: mainpydir = osp.dirname(mainpyfile) dirnames = ([mainpydir] + os.environ["PATH"].split(os.pathsep) + ["."]) try_file = Mclifns.whence_file(py_file, dirnames) if osp.isfile(try_file): mainpyfile = try_file pass else: # Move onto the except branch raise IOError( "Python file name embedded in code %s not found" % try_file) except: try: from uncompyle6 import decompile_file except ImportError: sys.stderr.write( "%s: Compiled python file '%s', but uncompyle6 not found\n" % (__title__, mainpyfile)) sys.exit(1) return short_name = osp.basename(mainpyfile).strip(".pyc") fd = tempfile.NamedTemporaryFile( suffix=".py", prefix=short_name + "_", dir=dbg.settings["tempdir"], delete=False, ) try: decompile_file(mainpyfile, outstream=fd) mainpyfile = fd.name fd.close() except: sys.stderr.write("%s: error uncompyling '%s'\n" % (__title__, mainpyfile)) sys.exit(1) pass # If mainpyfile is an optimized Python script try to find and # use non-optimized alternative. mainpyfile_noopt = pyficache.resolve_name_to_path(mainpyfile) if mainpyfile != mainpyfile_noopt \ and Mfile.readable(mainpyfile_noopt): sys.stderr.write( "%s: Compiled Python script given and we can't use that.\n" % __title__) sys.stderr.write("%s: Substituting non-compiled name: %s\n" % (__title__, mainpyfile_noopt)) mainpyfile = mainpyfile_noopt pass # Replace trepan's dir with script's dir in front of # module search path. sys.path[0] = dbg.main_dirname = osp.dirname(mainpyfile) # XXX If a signal has been received we continue in the loop, otherwise # the loop exits for some reason. dbg.sig_received = False # if not mainpyfile: # print('For now, you need to specify a Python script name!') # sys.exit(2) # pass while True: # Run the debugged script over and over again until we get it # right. try: if dbg.program_sys_argv and mainpyfile: normal_termination = dbg.run_script(mainpyfile) if not normal_termination: break else: dbg.core.execution_status = "No program" dbg.core.processor.process_commands() pass dbg.core.execution_status = "Terminated" dbg.intf[-1].msg("The program finished - quit or restart") dbg.core.processor.process_commands() except Mexcept.DebuggerQuit: break except Mexcept.DebuggerRestart: dbg.core.execution_status = "Restart requested" if dbg.program_sys_argv: sys.argv = list(dbg.program_sys_argv) part1 = "Restarting %s with arguments:" % dbg.core.filename( mainpyfile) args = " ".join(dbg.program_sys_argv[1:]) dbg.intf[-1].msg( Mmisc.wrapped_lines(part1, args, dbg.settings["width"])) else: break except SystemExit: # In most cases SystemExit does not warrant a post-mortem session. break except: # FIXME: Should be handled above without this mess exception_name = str(sys.exc_info()[0]) if exception_name == str(Mexcept.DebuggerQuit): break elif exception_name == str(Mexcept.DebuggerRestart): dbg.core.execution_status = "Restart requested" if dbg.program_sys_argv: sys.argv = list(dbg.program_sys_argv) part1 = "Restarting %s with arguments:" % dbg.core.filename( mainpyfile) args = " ".join(dbg.program_sys_argv[1:]) dbg.intf[-1].msg( Mmisc.wrapped_lines(part1, args, dbg.settings["width"])) pass else: raise pass # Restore old sys.argv sys.argv = orig_sys_argv return
def decompile_pyc( arg_tuple: Tuple[pathlib.Path, Dict[str, int], Dict[str, Union[bool, os.PathLike]]] ) -> str: """Decompile a single Python bytecode file. Parameters ---------- arg_tuple: Tuple[pathlib.Path, Dict[str, int], Dict[str, Union[bool, os.PathLike]]] A tuple containing the arguments for this function. This is a tuple because pebble's Pool.map() function couldn't pass multiple arguments to a subprocessed function call. The tuple entries correspond to the following arguments: pyc_file : pathlib.Path The path to the compiled Python file alternate_opmap : Dict[str, int], optional If this bytecode file was produced by an interpreter with remapped opcodes, you must provide the opmap as a OPNAME: OPCODE dictionary logging_options: Dict[str, Union[bool, os.PathLike], optional A dictionary of logging options. This is only needed when pydecipher is performing multi-processed decompilation. The keys can be the following strings: verbose: bool True will enable verbose logging. quiet: bool True will silence all console logging. log_path: pathlib.Path If a path object is passed in as the log_path, the running instance of pydecipher will continue logging to that file. Returns ------- str There are several different return values: * **no_action**: This file was not decompiled. * **success**: This file was successfully decompiled. * **error**: This file could not be decompiled 100% successfully. * **opcode_error**: The error message returned by uncompyle6 indicates this file may have remapped opcodes """ pyc_file: pathlib.Path = arg_tuple[0] alternate_opmap: Dict[str, int] = arg_tuple[1] or None logging_options: Dict[str, Union[bool, os.PathLike]] = arg_tuple[2] or None if not pyc_file.is_file(): return "no_action" # Because this function runs in a new pydecipher process entirely, logging # options set during runtime (from command-line flags) do not carry over # automatically. We must pass these through manually, and reset the options # for this specific process. if logging_options and not pydecipher.log_path: pydecipher.set_logging_options(**logging_options) hijacked_stdout: io.StringIO = io.StringIO() hijacked_stderr: io.StringIO = io.StringIO() with redirect_stdout(hijacked_stdout), redirect_stderr(hijacked_stderr): # Chop off c in pyc new_file_name: pathlib.Path = pathlib.Path( str(pyc_file.resolve())[:-1]) # This prohibits the overwriting of existing files. # if new_file_name.exists() and new_file_name.stat().st_size: # return "no_action" logger.debug( f"[*] Decompiling file {pyc_file} of size {pyc_file.stat().st_size}" ) if not alternate_opmap: try: uncompyle6.decompile_file(str(pyc_file), outstream=sys.stdout) except uncompyle6.semantics.parser_error.ParserError as e: logger.warning(f"[!] Failed to decompile file {pyc_file}") if REMAPPED_OPCODE_ERROR_REGEX.match(str(e.error)): logger.error( f"[!] {pyc_file.name} failed to decompile with an error that indicate its opcode " "mappings may have been remapped to prevent analysis.") return "opcode_error" return "error" except Exception as e: e: Exception logger.error( f"[!] Failed to decompile file {pyc_file} with error: {e}") stdout_val: str = hijacked_stdout.getvalue() if stdout_val: with new_file_name.open("w") as file_ptr: file_ptr.write(stdout_val) return "error" else: with new_file_name.open("w") as file_ptr: file_ptr.write(hijacked_stdout.getvalue()) logger.info(f"[+] Successfully decompiled {pyc_file}") return "success" else: filename: str co: CodeType # can also be xdis.Code* objects version: float timestamp: int # seconds since epoch magic_int: int is_pypy: bool source_size: int sip_hash: str try: ( filename, co, version, timestamp, magic_int, is_pypy, source_size, sip_hash, ) = xdis.main.disassemble_file(str(pyc_file), outstream=open(os.devnull, "w"), alternate_opmap=alternate_opmap) output_file: TextIO with new_file_name.open(mode="w") as output_file: uncompyle6.main.decompile( version, co, timestamp=timestamp, source_size=source_size, magic_int=magic_int, is_pypy=is_pypy, out=output_file, ) except Exception as e: e: Exception logger.info( f"[!] Failed to decompile file {pyc_file} with error: {e}") return "error" else: logger.info(f"[+] Successfully decompiled {pyc_file}") return "success"
import uncompyle6 import sys import os dir_path = sys.argv[1] for filename in os.listdir(dir_path): if filename.endswith('.pyc'): pyc_full_path = os.path.join(dir_path + filename) decompiled_full_path = os.path.join(dir_path + filename + '_decompiled') with open(decompiled_full_path, 'w') as f: uncompyle6.decompile_file(pyc_full_path, f)
import uncompyle6 import os os.system('cp Hello flag.pyc') file = open('decompiled.py', 'w') data = uncompyle6.decompile_file("flag.pyc", file)