gpt4 book ai didi

python - 反汇编 Python 代码到字典

转载 作者:太空宇宙 更新时间:2023-11-04 06:17:54 26 4
gpt4 key购买 nike

我想为 Python 程序开发一个小型调试工具。对于“动态切片”功能,我需要找到在语句中访问的变量,并找到这些变量的访问类型(读取或写入)。

但 Python 中内置的唯一反汇编功能是 dis.disassemble ,这只是将反汇编打印到标准输出:

>>> dis.disassemble(compile('x = a + b', '', 'single'))
1 0 LOAD_NAME 0 (a)
3 LOAD_NAME 1 (b)
6 BINARY_ADD
7 STORE_NAME 2 (x)
10 LOAD_CONST 0 (None)
13 RETURN_VALUE

我希望能够将反汇编转换为描述每条指令使用哪些变量的集合字典,如下所示:

>>> my_disassemble('x = a + b')
{'LOAD_NAME': set(['a', 'b']), 'STORE_NAME': set(['x'])}

我该怎么做?

最佳答案

阅读the source code for the dis module并且您会发现很容易进行自己的反汇编并生成您喜欢的任何输出格式。下面是一些在代码对象中生成指令序列及其参数的代码:

from opcode import *

def disassemble(co):
"""
Disassemble a code object and generate its instructions.
"""
code = co.co_code
n = len(code)
extended_arg = 0
i = 0
free = None
while i < n:
c = code[i]
op = ord(c)
i = i+1
if op < HAVE_ARGUMENT:
yield opname[op],
else:
oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg
extended_arg = 0
i = i+2
if op == EXTENDED_ARG:
extended_arg = oparg*65536L
if op in hasconst:
arg = co.co_consts[oparg]
elif op in hasname:
arg = co.co_names[oparg]
elif op in hasjrel:
arg = repr(i + oparg)
elif op in haslocal:
arg = co.co_varnames[oparg]
elif op in hascompare:
arg = cmp_op[oparg]
elif op in hasfree:
if free is None:
free = co.co_cellvars + co.co_freevars
arg = free[oparg]
else:
arg = oparg
yield opname[op], arg

这是一个示例反汇编。

>>> def f(x):
... return x + 1
...
>>> list(disassemble(f.func_code))
[('LOAD_FAST', 'x'), ('LOAD_CONST', 1), ('BINARY_ADD',), ('RETURN_VALUE',)]

您可以轻松地将其转换为您想要的集合字典数据结构:

>>> from collections import defaultdict
>>> d = defaultdict(set)
>>> for op in disassemble(f.func_code):
... if len(op) == 2:
... d[op[0]].add(op[1])
...
>>> d
defaultdict(<type 'set'>, {'LOAD_FAST': set(['x']), 'LOAD_CONST': set([1])})

(或者您可以直接生成集合字典数据结构。)

请注意,在您的应用程序中,您实际上可能不需要查找每个操作码的名称。相反,您可以在 opcode.opmap 字典中查找所需的操作码并创建命名常量,也许像这样:

LOAD_FAST = opmap['LOAD_FAST'] # actual value is 124
...
for var in disassembly[LOAD_FAST]:
...

更新:在 Python 3.4 中,您可以使用新的 dis.get_instructions :

>>> def f(x):
... return x + 1
>>> import dis
>>> list(dis.get_instructions(f))
[Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='x',
argrepr='x', offset=0, starts_line=1, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=1,
argrepr='1', offset=3, starts_line=None, is_jump_target=False),
Instruction(opname='BINARY_ADD', opcode=23, arg=None, argval=None,
argrepr='', offset=6, starts_line=None, is_jump_target=False),
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None,
argrepr='', offset=7, starts_line=None, is_jump_target=False)]

关于python - 反汇编 Python 代码到字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14324309/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com