2015-08-13 70 views
0

首先,我想說我知道你不應該在生產環境中這樣做。別擔心,它只是爲了瞭解我可以在運行時更改python代碼的程度。修改python pytecode

我有一個函數inject_code需要一個代碼對象。它還需要一些我感興趣的變量名稱。這些可以是fast s或name s,但是我知道它們是什麼以及它們的內部標識。

目前,我正在搜索STORE_FASTSTORE_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]]

但是,一旦完成,大多數跳轉操作碼的目標都是錯誤的,因爲我插入了一些新的操作碼。

如何制定跳躍的新目標?

另外,我應該如何重新調整字節和行縮進?

如果您想要測試代碼的簡單方法,可以在此處添加它。但我不確定隱藏默認的語法。

回答