0
首先,我想說我知道你不應該在生產環境中這樣做。別擔心,它只是爲了瞭解我可以在運行時更改python代碼的程度。修改python pytecode
我有一個函數inject_code
需要一個代碼對象。它還需要一些我感興趣的變量名稱。這些可以是fast
s或name
s,但是我知道它們是什麼以及它們的內部標識。
目前,我正在搜索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
變量瓦爾遵循這種結構:[NAME_VARIABLE_IDS, FAST_VARIABLE_IDS]
如:[[0,2],[1,3]]
但是,一旦完成,大多數跳轉操作碼的目標都是錯誤的,因爲我插入了一些新的操作碼。
如何制定跳躍的新目標?
另外,我應該如何重新調整字節和行縮進?
如果您想要測試代碼的簡單方法,可以在此處添加它。但我不確定隱藏默認的語法。