修改python pytecode

时间:2015-08-13 17:04:49

标签: python python-2.7 bytecode-manipulation

首先,我想说我知道你不应该在生产环境中这样做。别担心,这只是为了看看我可以在运行时更改python代码的程度。

我有一个函数public void dataWriter(String data, String fileName) throws IOException { File file = getFileStreamPath(fileName); if (!file.exists()) { file.createNewFile(); } try (FileOutputStream writer = openFileOutput(file.getName(), Context.MODE_PRIVATE)) // Error "cannot find symbol, variable MODE_PRIVATE" { for (String string = null, data)//error "variable data is already defined in dataWriter" { { writer.write(string.getBytes()); writer.flush(); } } } catch (Exception e) { } } ,它接受​​一个代码对象。它还包含一些我感兴趣的变量名称。这些可以是inject_codefast,但我知道它们与内部ID一样。

目前,我正在搜索字节码中的nameSTORE_FAST命令。找到后,我将以下指令添加到字节码:

STORE_NAME

我正在使用此代码执行此操作:

LOAD_FAST/NAME   VAR_ID
PRINT_ITEM
PRINT_NEWLINE

变量vars遵循以下结构:import dis, opcode, struct def inject_code(code, vars): co_code = code.co_code new_code = "" i = 0 n = len(co_code) fast_name = [opcode.opmap["STORE_NAME"], opcode.opmap["STORE_FAST"]] while i < n: c = co_code[i] op = ord(c) i+=1 arg = "" new_opcode = "" if op >= opcode.HAVE_ARGUMENT: arg = co_code[i:i+2] i+=2 if op in fast_name: cur_map = vars[fast_name.index(op)] arg_id = struct.unpack("<H", arg)[0] if arg_id in cur_map: new_opcode = chr(opcode.opmap[("LOAD_NAME", "LOAD_FAST")[fast_name.index(op)]])+arg new_opcode += chr(opcode.opmap["PRINT_ITEM"]) new_opcode += chr(opcode.opmap["PRINT_NEWLINE"]) new_code += c+arg+new_opcode dis.dis(new_code) return new_code

例如:[NAME_VARIABLE_IDS, FAST_VARIABLE_IDS]

但是,一旦完成此操作,大多数跳转操作码的目标都是错误的,因为我插入了一些新的操作码。

如何计算跳跃的新目标?

另外,我应该如何重新排列字节和行缩进?

如果您想要一种简单的方法来测试代码,我可以在这里添加它。但是我不确定默认隐藏的语法。

1 个答案:

答案 0 :(得分:0)

您需要使用字节码汇编程序来处理所有这些内容:

https://pypi.python.org/pypi/BytecodeAssembler