import dis import io import marshal import os import sys import textwrap from bytecode import fix_spacing, format_bytecode def disassemble_pyc_file(pyc_file) -> str: with open(pyc_file, "rb") as f: header = f.read(16) magic_number = header[:2] if 3394 != int.from_bytes(magic_number, "little"): print(f"{pyc_file} not compiled with Python 3.7") return None bytecode = marshal.load(f) original_stdout = sys.stdout string_output = io.StringIO() sys.stdout = string_output dis.dis(bytecode) sys.stdout = original_stdout disassembled_pyc = string_output.getvalue() byte_code = fix_spacing(textwrap.dedent(str(disassembled_pyc)).strip()) formatted_bytecode = format_bytecode(bytecode=byte_code) return formatted_bytecode def convert_pyc_to_bytecode(file_path: str): formatted_bytecode = disassemble_pyc_file(file_path) if formatted_bytecode is None: return with open(file_path + "b", "w") as bytecode_file: print(f"Converted {file_path} to bytecode") bytecode_file.write(formatted_bytecode) if __name__ == "__main__": path = sys.argv[1] if os.path.isfile(path) and path.endswith(".pyc"): convert_pyc_to_bytecode(path) elif os.path.isdir(path): for root, _, files in os.walk(path): for file in files: file_path = os.path.join(root, file) if not file.endswith(".pyc"): continue convert_pyc_to_bytecode(file_path)