You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何执行Python中dis.dis()输出的反汇编代码?

执行Python反汇编代码的方法

首先得明确一点:Python标准库的dis模块并没有内置你期望的dis.run()函数,但我们可以自己实现类似的功能——把反汇编的文本指令转换成可执行的字节码,让Python虚拟机执行。

为什么不能直接执行反汇编文本?

反汇编输出是字节码的人类可读表示,Python解释器只能执行二进制格式的字节码(对应CodeObject对象)。打个比方,反汇编文本就像是字节码的“说明书”,你得照着说明书还原出真实的“机器零件”(字节码),才能让解释器运行它。

实现步骤与示例代码

下面是一个针对你给出的示例,专门编写的解析并执行反汇编文本的函数:

import dis
import types

def run_disassembly(disasm_text):
    # 解析反汇编文本,提取每一行的指令信息
    instructions = []
    for line in disasm_text.strip().split('\n'):
        line_parts = line.split()
        if len(line_parts) < 3:
            continue
        # 提取操作码名称(比如LOAD_GLOBAL)
        op_name = line_parts[2]
        # 转换成对应的字节码数值
        op_code = dis.opmap[op_name]
        
        # 处理指令参数(如果有的话)
        arg = None
        if len(line_parts) > 3:
            arg_raw = line_parts[3]
            # 去掉参数外层的括号,比如(print) -> print
            if arg_raw.startswith('(') and arg_raw.endswith(')'):
                arg_content = arg_raw[1:-1]
                # 区分字符串常量和索引值
                if arg_content.startswith("'") and arg_content.endswith("'"):
                    arg = arg_content[1:-1]
                else:
                    arg = int(arg_content)
        instructions.append((op_code, arg))
    
    # 构建对应常量池和全局变量表(和你的反汇编示例匹配)
    const_pool = (None, 'hello')
    global_names = ('print',)
    
    # 生成可执行的CodeObject
    code_obj = types.CodeType(
        0,          # 位置参数数量
        0,          # 仅位置参数数量
        0,          # 仅关键字参数数量
        0,          # 本地变量数量
        256,        # 栈大小
        0,          # 标志位
        # 把指令转换成二进制字节码
        b''.join([
            op_code.to_bytes(1, byteorder='little') + 
            (arg.to_bytes(2, byteorder='little') if isinstance(arg, int) else b'')
            for op_code, arg in instructions
        ]),
        const_pool, # 常量池
        global_names,# 全局变量名表
        (),         # 本地变量名表
        '<disasm>', # 文件名标识
        '<run_disasm>', # 函数名标识
        1,          # 起始行号
        b''         # 行号映射表
    )
    
    # 执行生成的CodeObject
    exec(code_obj)

# 测试你的示例反汇编代码
sample_disasm = '''
3 0 LOAD_GLOBAL 0 (print)
2 LOAD_CONST 1 ('hello')
4 CALL_FUNCTION 1
6 POP_TOP
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
'''
run_disassembly(sample_disasm)

关于反汇编代码与.pyc文件的关系

  • .pyc文件是Python源码编译后生成的序列化CodeObject,本质上和我们上面构建的code_obj是同一类东西,只是以二进制文件的形式存储。
  • 反汇编代码是.pyc文件(或CodeObject)的文本“翻译版”,所以只要能把反汇编文本准确转换回CodeObject,就可以像执行.pyc文件一样执行它——甚至你可以把生成的CodeObject序列化保存为.pyc文件,之后直接加载执行。

注意事项

  • 上面的示例是针对你的特定场景简化的,实际开发中需要处理更多指令类型、参数类型(比如本地变量、闭包引用等),以及更复杂的常量池和变量表。
  • 不同Python版本的字节码指令可能有差异,所以解析反汇编文本时需要对应版本的dis.opmap字典。

内容的提问来源于stack exchange,提问作者USERNAME GOES HERE

火山引擎 最新活动