Python opcode.EXTENDED_ARG Examples
The following are 16
code examples of opcode.EXTENDED_ARG().
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
You may also want to check out all available functions/classes of the module
opcode
, or try the search function
.
Example #1
Source File: pydevd_modify_bytecode.py From PyDev.Debugger with Eclipse Public License 1.0 | 6 votes |
def _unpack_opargs(code, inserted_code_list, current_index): """ Modified version of `_unpack_opargs` function from module `dis`. We have to use it, because sometimes code can be in an inconsistent state: if EXTENDED_ARG operator was introduced into the code, but it hasn't been inserted into `code_list` yet. In this case we can't use standard `_unpack_opargs` and we should check whether there are some new operators in `inserted_code_list`. """ extended_arg = 0 for i in range(0, len(code), 2): op = code[i] if op >= HAVE_ARGUMENT: if not extended_arg: # in case if we added EXTENDED_ARG, but haven't inserted it to the source code yet. for code_index in range(current_index, len(inserted_code_list)): inserted_offset, inserted_code = inserted_code_list[code_index] if inserted_offset == i and inserted_code[0] == EXTENDED_ARG: extended_arg = inserted_code[1] << 8 arg = code[i + 1] | extended_arg extended_arg = (arg << 8) if op == EXTENDED_ARG else 0 else: arg = None yield (i, op, arg)
Example #2
Source File: pydevd_modify_bytecode.py From PyDev.Debugger with Eclipse Public License 1.0 | 5 votes |
def _add_attr_values_from_insert_to_original(original_code, insert_code, insert_code_list, attribute_name, op_list): """ This function appends values of the attribute `attribute_name` of the inserted code to the original values, and changes indexes inside inserted code. If some bytecode instruction in the inserted code used to call argument number i, after modification it calls argument n + i, where n - length of the values in the original code. So it helps to avoid variables mixing between two pieces of code. :param original_code: code to modify :param insert_code: code to insert :param insert_code_obj: bytes sequence of inserted code, which should be modified too :param attribute_name: name of attribute to modify ('co_names', 'co_consts' or 'co_varnames') :param op_list: sequence of bytecodes whose arguments should be changed :return: modified bytes sequence of the code to insert and new values of the attribute `attribute_name` for original code """ orig_value = getattr(original_code, attribute_name) insert_value = getattr(insert_code, attribute_name) orig_names_len = len(orig_value) code_with_new_values = list(insert_code_list) offset = 0 while offset < len(code_with_new_values): op = code_with_new_values[offset] if op in op_list: new_val = code_with_new_values[offset + 1] + orig_names_len if new_val > MAX_BYTE: code_with_new_values[offset + 1] = new_val & MAX_BYTE code_with_new_values = code_with_new_values[:offset] + [EXTENDED_ARG, new_val >> 8] + \ code_with_new_values[offset:] offset += 2 else: code_with_new_values[offset + 1] = new_val offset += 2 new_values = orig_value + insert_value return bytes(code_with_new_values), new_values
Example #3
Source File: pydevd_modify_bytecode.py From PyDev.Debugger with Eclipse Public License 1.0 | 5 votes |
def add_jump_instruction(jump_arg, code_to_insert): """ Note: although it's adding a POP_JUMP_IF_TRUE, it's actually no longer used now (we could only return the return and possibly the load of the 'None' before the return -- not done yet because it needs work to fix all related tests). """ extended_arg_list = [] if jump_arg > MAX_BYTE: extended_arg_list += [EXTENDED_ARG, jump_arg >> 8] jump_arg = jump_arg & MAX_BYTE # remove 'RETURN_VALUE' instruction and add 'POP_JUMP_IF_TRUE' with (if needed) 'EXTENDED_ARG' return list(code_to_insert.co_code[:-RETURN_VALUE_SIZE]) + extended_arg_list + [opmap['POP_JUMP_IF_TRUE'], jump_arg]
Example #4
Source File: test_bytecode_modification.py From PyDev.Debugger with Eclipse Public License 1.0 | 5 votes |
def compare_bytes_sequence(self, code1, code2, inserted_code_size): """ Compare code after modification and the real code Since we add POP_JUMP_IF_TRUE instruction, we can't compare modified code and the real code. That's why we allow some inaccuracies while code comparison :param code1: result code after modification :param code2: a real code for checking :param inserted_code_size: size of inserted code """ seq1 = [(offset, op, arg) for offset, op, arg in dis._unpack_opargs(code1)] seq2 = [(offset, op, arg) for offset, op, arg in dis._unpack_opargs(code2)] assert len(seq1) == len(seq2), "Bytes sequences have different lengths %s != %s" % (len(seq1), len(seq2)) for i in range(len(seq1)): of, op1, arg1 = seq1[i] _, op2, arg2 = seq2[i] if op1 != op2: if op1 == 115 and op2 == 1: # it's ok, because we added POP_JUMP_IF_TRUE manually, but it's POP_TOP in the real code # inserted code - 2 (removed return instruction) - real code inserted # Jump should be done to the beginning of inserted fragment self.assertEqual(arg1, of - (inserted_code_size - 2)) continue elif op1 == EXTENDED_ARG and op2 == 12: # we added a real UNARY_NOT to balance EXTENDED_ARG added by new jump instruction # i.e. inserted code size was increased as well inserted_code_size += 2 continue self.assertEqual(op1, op2, "Different operators at offset {}".format(of)) if arg1 != arg2: if op1 in (100, 101, 106, 116): # Sometimes indexes of variable names and consts may be different, when we insert them, it's ok continue else: self.assertEqual(arg1, arg2, "Different arguments at offset {}".format(of))
Example #5
Source File: teleportation.py From NoobSec-Toolkit with GNU General Public License v2.0 | 5 votes |
def decode_codeobj(codeobj): # adapted from dis.dis extended_arg = 0 if is_py3k: codestr = codeobj.co_code else: codestr = [ord(ch) for ch in codeobj.co_code] free = None i = 0 while i < len(codestr): op = codestr[i] opname = opcode.opname[op] i += 1 argval = None if op >= opcode.HAVE_ARGUMENT: oparg = codestr[i] + codestr[i + 1] * 256 + extended_arg i += 2 extended_arg = 0 if op == opcode.EXTENDED_ARG: extended_arg = oparg * 65536 continue if op in opcode.hasconst: argval = codeobj.co_consts[oparg] elif op in opcode.hasname: argval = codeobj.co_names[oparg] elif op in opcode.hasjrel: argval = i + oparg elif op in opcode.haslocal: argval = codeobj.co_varnames[oparg] elif op in opcode.hascompare: argval = opcode.cmp_op[oparg] elif op in opcode.hasfree: if free is None: free = codeobj.co_cellvars + codeobj.co_freevars argval = free[oparg] yield (opname, argval)
Example #6
Source File: teleportation.py From NoobSec-Toolkit with GNU General Public License v2.0 | 5 votes |
def decode_codeobj(codeobj): # adapted from dis.dis extended_arg = 0 if is_py3k: codestr = codeobj.co_code else: codestr = [ord(ch) for ch in codeobj.co_code] free = None i = 0 while i < len(codestr): op = codestr[i] opname = opcode.opname[op] i += 1 argval = None if op >= opcode.HAVE_ARGUMENT: oparg = codestr[i] + codestr[i + 1] * 256 + extended_arg i += 2 extended_arg = 0 if op == opcode.EXTENDED_ARG: extended_arg = oparg * 65536 continue if op in opcode.hasconst: argval = codeobj.co_consts[oparg] elif op in opcode.hasname: argval = codeobj.co_names[oparg] elif op in opcode.hasjrel: argval = i + oparg elif op in opcode.haslocal: argval = codeobj.co_varnames[oparg] elif op in opcode.hascompare: argval = opcode.cmp_op[oparg] elif op in opcode.hasfree: if free is None: free = codeobj.co_cellvars + codeobj.co_freevars argval = free[oparg] yield (opname, argval)
Example #7
Source File: injector.py From addon with GNU General Public License v3.0 | 5 votes |
def instructions(code_obj): # easy for python 3.4+ if sys.version_info >= (3, 4): for inst in dis.Bytecode(code_obj): yield inst else: # otherwise we have to manually parse code = code_obj.co_code NewInstruction = namedtuple('Instruction', ('opcode', 'arg')) if six.PY2: code = map(ord, code) i, L = 0, len(code) extended_arg = 0 while i < L: op = code[i] i += 1 if op < opcode.HAVE_ARGUMENT: yield NewInstruction(op, None) continue oparg = code[i] + (code[i + 1] << 8) + extended_arg extended_arg = 0 i += 2 if op == opcode.EXTENDED_ARG: extended_arg = oparg << 16 continue yield NewInstruction(op, oparg)
Example #8
Source File: injector.py From addon with GNU General Public License v3.0 | 5 votes |
def write_instruction(op, arg): if sys.version_info < (3, 6): if arg is None: return [chr(op)] elif arg <= 65536: return [chr(op), chr(arg & 255), chr((arg >> 8) & 255)] elif arg <= 4294967296: return [ chr(opcode.EXTENDED_ARG), chr((arg >> 16) & 255), chr((arg >> 24) & 255), chr(op), chr(arg & 255), chr((arg >> 8) & 255) ] else: raise ValueError("Invalid oparg: {0} is too large".format(oparg)) else: # python 3.6+ uses wordcode instead of bytecode and they already supply all the EXTENDEND_ARG ops :) if arg is None: return [chr(op), 0] return [chr(op), arg & 255] # the code below is for case when extended args are to be determined automatically # if op == opcode.EXTENDED_ARG: # return [] # this will be added automatically # elif arg < 1 << 8: # return [chr(op), arg] # elif arg < 1 << 32: # subs = [1<<24, 1<<16, 1<<8] # allowed op extension sizes # for sub in subs: # if arg >= sub: # fit = int(arg / sub) # return [chr(opcode.EXTENDED_ARG), fit] + write_instruction(op, arg - fit * sub) # else: # raise ValueError("Invalid oparg: {0} is too large".format(oparg))
Example #9
Source File: injector.py From xbmc-addons-chinese with GNU General Public License v2.0 | 5 votes |
def instructions(code_obj): # easy for python 3.4+ if sys.version_info >= (3, 4): for inst in dis.Bytecode(code_obj): yield inst else: # otherwise we have to manually parse code = code_obj.co_code NewInstruction = namedtuple('Instruction', ('opcode', 'arg')) if six.PY2: code = map(ord, code) i, L = 0, len(code) extended_arg = 0 while i < L: op = code[i] i+= 1 if op < opcode.HAVE_ARGUMENT: yield NewInstruction(op, None) continue oparg = code[i] + (code[i+1] << 8) + extended_arg extended_arg = 0 i += 2 if op == opcode.EXTENDED_ARG: extended_arg = oparg << 16 continue yield NewInstruction(op, oparg)
Example #10
Source File: injector.py From xbmc-addons-chinese with GNU General Public License v2.0 | 5 votes |
def write_instruction(op, arg): if sys.version_info < (3, 6): if arg is None: return [chr(op)] elif arg <= 65536: return [chr(op), chr(arg & 255), chr((arg >> 8) & 255)] elif arg <= 4294967296: return [chr(opcode.EXTENDED_ARG), chr((arg >> 16) & 255), chr((arg >> 24) & 255), chr(op), chr(arg & 255), chr((arg >> 8) & 255)] else: raise ValueError("Invalid oparg: {0} is too large".format(oparg)) else: # python 3.6+ uses wordcode instead of bytecode and they already supply all the EXTENDEND_ARG ops :) if arg is None: return [chr(op), 0] return [chr(op), arg & 255] # the code below is for case when extended args are to be determined automatically # if op == opcode.EXTENDED_ARG: # return [] # this will be added automatically # elif arg < 1 << 8: # return [chr(op), arg] # elif arg < 1 << 32: # subs = [1<<24, 1<<16, 1<<8] # allowed op extension sizes # for sub in subs: # if arg >= sub: # fit = int(arg / sub) # return [chr(opcode.EXTENDED_ARG), fit] + write_instruction(op, arg - fit * sub) # else: # raise ValueError("Invalid oparg: {0} is too large".format(oparg))
Example #11
Source File: tb.py From owasp-pysec with Apache License 2.0 | 5 votes |
def disassemble(co): code = co.co_code labels = dis.findlabels(code) linestarts = dict(dis.findlinestarts(co)) n = len(code) i = 0 extended_arg = 0 free = None lineno = None while i < n: c = code[i] op = ord(c) lineno = linestarts.get(i, lineno) is_label = i in labels ist = i i += 1 if op >= opcode.HAVE_ARGUMENT: oparg = ord(code[i]) + ord(code[i + 1]) * 256 + extended_arg extended_arg = 0 i += 2 if op == opcode.EXTENDED_ARG: extended_arg = oparg * 65536L if op in opcode.hasconst: arg = co.co_consts[oparg] elif op in opcode.hasname: arg = co.co_names[oparg] elif op in opcode.hasjrel: arg = i + oparg elif op in opcode.haslocal: arg = co.co_varnames[oparg] elif op in opcode.hascompare: arg = opcode.cmp_op[oparg] elif op in opcode.hasfree: if free is None: free = co.co_cellvars + co.co_freevars arg = free[oparg] else: arg = NOVAL else: arg = NOVAL yield ist, lineno, is_label, opcode.opname[op], arg
Example #12
Source File: injector.py From bazarr with GNU General Public License v3.0 | 5 votes |
def instructions(code_obj): # easy for python 3.4+ if sys.version_info >= (3, 4): for inst in dis.Bytecode(code_obj): yield inst else: # otherwise we have to manually parse code = code_obj.co_code NewInstruction = namedtuple('Instruction', ('opcode', 'arg')) if six.PY2: code = map(ord, code) i, L = 0, len(code) extended_arg = 0 while i < L: op = code[i] i += 1 if op < opcode.HAVE_ARGUMENT: yield NewInstruction(op, None) continue oparg = code[i] + (code[i + 1] << 8) + extended_arg extended_arg = 0 i += 2 if op == opcode.EXTENDED_ARG: extended_arg = oparg << 16 continue yield NewInstruction(op, oparg)
Example #13
Source File: injector.py From bazarr with GNU General Public License v3.0 | 5 votes |
def write_instruction(op, arg): if sys.version_info < (3, 6): if arg is None: return [chr(op)] elif arg <= 65536: return [chr(op), chr(arg & 255), chr((arg >> 8) & 255)] elif arg <= 4294967296: return [ chr(opcode.EXTENDED_ARG), chr((arg >> 16) & 255), chr((arg >> 24) & 255), chr(op), chr(arg & 255), chr((arg >> 8) & 255) ] else: raise ValueError("Invalid oparg: {0} is too large".format(oparg)) else: # python 3.6+ uses wordcode instead of bytecode and they already supply all the EXTENDEND_ARG ops :) if arg is None: return [chr(op), 0] return [chr(op), arg & 255] # the code below is for case when extended args are to be determined automatically # if op == opcode.EXTENDED_ARG: # return [] # this will be added automatically # elif arg < 1 << 8: # return [chr(op), arg] # elif arg < 1 << 32: # subs = [1<<24, 1<<16, 1<<8] # allowed op extension sizes # for sub in subs: # if arg >= sub: # fit = int(arg / sub) # return [chr(opcode.EXTENDED_ARG), fit] + write_instruction(op, arg - fit * sub) # else: # raise ValueError("Invalid oparg: {0} is too large".format(oparg))
Example #14
Source File: teleportation.py From backdoorme with MIT License | 5 votes |
def decode_codeobj(codeobj): # adapted from dis.dis extended_arg = 0 if is_py3k: codestr = codeobj.co_code else: codestr = [ord(ch) for ch in codeobj.co_code] free = None i = 0 while i < len(codestr): op = codestr[i] opname = opcode.opname[op] i += 1 argval = None if op >= opcode.HAVE_ARGUMENT: oparg = codestr[i] + codestr[i + 1] * 256 + extended_arg i += 2 extended_arg = 0 if op == opcode.EXTENDED_ARG: extended_arg = oparg * 65536 continue if op in opcode.hasconst: argval = codeobj.co_consts[oparg] elif op in opcode.hasname: argval = codeobj.co_names[oparg] elif op in opcode.hasjrel: argval = i + oparg elif op in opcode.haslocal: argval = codeobj.co_varnames[oparg] elif op in opcode.hascompare: argval = opcode.cmp_op[oparg] elif op in opcode.hasfree: if free is None: free = codeobj.co_cellvars + codeobj.co_freevars argval = free[oparg] yield (opname, argval)
Example #15
Source File: merger.py From equip with Apache License 2.0 | 4 votes |
def emit(self, op, oparg, arg=None, lineno=-1): """ Writes the bytecode and lnotab. """ bytecode_inc, line_inc = 0, -1 if op >= opcode.HAVE_ARGUMENT and oparg > 0xffff: self.append_code(opcode.EXTENDED_ARG) self.append_code((oparg >> 16) & 0xff) self.append_code((oparg >> 24) & 0xff) bytecode_inc += 3 self.append_code(op) bytecode_inc += 1 if op >= opcode.HAVE_ARGUMENT: self.append_code(oparg & 0xff) self.append_code((oparg >> 8) & 0xff) bytecode_inc += 2 # We also adjust the lnotabs field if self.prev_lineno == -1: line_inc = 0 else: line_inc = lineno - self.prev_lineno if line_inc == 0 and bytecode_inc == 0: self.lnotab.append(0) # bytecode increment self.lnotab.append(0) # lineno increment else: while bytecode_inc > 255: self.lnotab.append(255) self.lnotab.append(0) bytecode_inc -= 255 while line_inc > 255: self.lnotab.append(0) self.lnotab.append(255) line_inc -= 255 # Add the remainder self.lnotab.append(bytecode_inc) self.lnotab.append(line_inc) self.prev_lineno = lineno
Example #16
Source File: pydevd_modify_bytecode.py From PyDev.Debugger with Eclipse Public License 1.0 | 4 votes |
def _update_label_offsets(code_obj, breakpoint_offset, breakpoint_code_list): """ Update labels for the relative and absolute jump targets :param code_obj: code to modify :param breakpoint_offset: offset for the inserted code :param breakpoint_code_list: size of the inserted code :return: bytes sequence with modified labels; list of tuples (resulting offset, list of code instructions) with information about all inserted pieces of code """ inserted_code = list() # the list with all inserted pieces of code inserted_code.append((breakpoint_offset, breakpoint_code_list)) code_list = list(code_obj) j = 0 while j < len(inserted_code): current_offset, current_code_list = inserted_code[j] offsets_for_modification = [] for offset, op, arg in _unpack_opargs(code_list, inserted_code, j): if arg is not None: if op in dis.hasjrel: # has relative jump target label = offset + 2 + arg if offset < current_offset < label: # change labels for relative jump targets if code was inserted inside offsets_for_modification.append(offset) elif op in dis.hasjabs: # change label for absolute jump if code was inserted before it if current_offset < arg: offsets_for_modification.append(offset) for i in range(0, len(code_list), 2): op = code_list[i] if i in offsets_for_modification and op >= dis.HAVE_ARGUMENT: new_arg = code_list[i + 1] + len(current_code_list) if new_arg <= MAX_BYTE: code_list[i + 1] = new_arg else: # handle bytes overflow if i - 2 > 0 and code_list[i - 2] == EXTENDED_ARG and code_list[i - 1] < MAX_BYTE: # if new argument > 255 and EXTENDED_ARG already exists we need to increase it's argument code_list[i - 1] += 1 else: # if there isn't EXTENDED_ARG operator yet we have to insert the new operator extended_arg_code = [EXTENDED_ARG, new_arg >> 8] inserted_code.append((i, extended_arg_code)) code_list[i + 1] = new_arg & MAX_BYTE code_list = code_list[:current_offset] + current_code_list + code_list[current_offset:] for k in range(len(inserted_code)): offset, inserted_code_list = inserted_code[k] if current_offset < offset: inserted_code[k] = (offset + len(current_code_list), inserted_code_list) j += 1 return bytes(code_list), inserted_code