修改 python pytecode
Modifying python pytecode
首先,我想说我知道您不应该在生产环境中这样做。别担心,这只是为了看看我可以在多大程度上更改 python 代码,而它是 运行.
我有一个接受代码对象的函数 inject_code
。它还包含一些我觉得有趣的变量名。这些可以是 fast
s 或 name
s 但我知道它们是什么以及它们的内部 ID。
目前,我正在字节码中搜索 STORE_FAST
或 STORE_NAME
命令。找到后,我将以下指令添加到字节码中:
LOAD_FAST/NAME VAR_ID
PRINT_ITEM
PRINT_NEWLINE
我正在使用此代码来执行此操作:
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
变量 vars 遵循以下结构:[NAME_VARIABLE_IDS, FAST_VARIABLE_IDS]
例如:[[0,2],[1,3]]
但是,完成此操作后,大多数跳转操作码的目标都是错误的,因为我插入了一些新的操作码。
如何计算新的跳跃目标?
此外,我应该如何重新对齐字节和行缩进?
如果你想要一种测试代码的简单方法,我可以在这里添加。但是我不确定默认隐藏的语法。
你需要使用字节码汇编器来处理所有这些东西:
首先,我想说我知道您不应该在生产环境中这样做。别担心,这只是为了看看我可以在多大程度上更改 python 代码,而它是 运行.
我有一个接受代码对象的函数 inject_code
。它还包含一些我觉得有趣的变量名。这些可以是 fast
s 或 name
s 但我知道它们是什么以及它们的内部 ID。
目前,我正在字节码中搜索 STORE_FAST
或 STORE_NAME
命令。找到后,我将以下指令添加到字节码中:
LOAD_FAST/NAME VAR_ID
PRINT_ITEM
PRINT_NEWLINE
我正在使用此代码来执行此操作:
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
变量 vars 遵循以下结构:[NAME_VARIABLE_IDS, FAST_VARIABLE_IDS]
例如:[[0,2],[1,3]]
但是,完成此操作后,大多数跳转操作码的目标都是错误的,因为我插入了一些新的操作码。
如何计算新的跳跃目标?
此外,我应该如何重新对齐字节和行缩进?
如果你想要一种测试代码的简单方法,我可以在这里添加。但是我不确定默认隐藏的语法。
你需要使用字节码汇编器来处理所有这些东西: