0

Firstly, I would like to say that I know that you shouldn't be doing this in a production environment. Don't worry, it's just to see to what extent I can change python code whilst it's running.

I have a function inject_code that takes in a code object. It also takes in some variable names that I find interesting. These can be fasts or names but I know which they are as well as their internal id.

At the moment, I am searching the bytecode for a STORE_FAST or a STORE_NAME command. Once found, I am adding the following instructions to the bytecode:

LOAD_FAST/NAME   VAR_ID
PRINT_ITEM
PRINT_NEWLINE

I'm using this code to do it:

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

the variable vars follows this structure: [NAME_VARIABLE_IDS, FAST_VARIABLE_IDS]

eg: [[0,2],[1,3]]

However, once this has been done, the targets for most jump opcodes is wrong because I've inserted some new opcodes.

How do I work out the new targets of jumps?

Also, how should I realign the byte and line indents?

If you want an easy way of testing the code, I can add it here. But I'm not sure of the syntax for hiding by default.

muddyfish
  • 3,530
  • 30
  • 37

1 Answers1

0

You need to use the bytecode assembler to handle all that stuff:

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

Patrick Maupin
  • 8,024
  • 2
  • 23
  • 42