def dis(x=None): """Disassemble classes, methods, functions, or code. With no argument, disassemble the last traceback. """ if x is None: dismodule.distb() return if hasattr(x, '__func__'): x = x.__func__ if hasattr(x, '__code__'): x = getattr(x, '__code__') if isinstance(x, FunctionType): x = sys.get_func_code(x) if hasattr(x, '__dict__'): items = sorted(x.__dict__.items()) for name, x1 in items: if isinstance(x1, (types.MethodType, types.FunctionType, types.CodeType, type)): print("Disassembly of %s:" % name) try: dis(x1) except TypeError as msg: print("Sorry:", msg) print() elif hasattr(x, 'co_code'): dismodule.disassemble(x) elif isinstance(x, (bytes, bytearray)): dismodule.disassemble_string(x) else: raise TypeError("don't know how to disassemble %s objects" % type(x).__name__)
def all_interpret(code_obj): i = 0 code = code_obj.co_code while 0 <= i < len(code): print i c = code[i] op = ord(c) if op >= HAVE_ARGUMENT: oparg = ord(code[i + 1]) + ord(code[i + 2]) * 256 i += 3 try: dis.disassemble_string(code[i - 3: i]) if op == opmap['LOAD_FAST']: print '\tLocal LOAD [%s]' % code_obj.co_varnames[oparg] elif op == opmap['STORE_FAST']: print '\tLocal STORE [%s]' % code_obj.co_varnames[oparg] elif op == opmap['LOAD_CONST']: print '\t%s' % code_obj.co_consts[oparg] elif op == opmap['STORE_GLOBAL']: print '\tGlobal STORE [%s]' % code_obj.co_names[oparg] elif op == opmap['LOAD_GLOBAL']: print '\tGLOBAL LOAD [%s]' % code_obj.co_names[oparg] except: pass else: i += 1 try: dis.disassemble_string(code[i - 1: i]) except: pass
def dis(x=None): """Disassemble classes, methods, functions, or code. With no argument, disassemble the last traceback. """ if x is None: dismodule.distb() return if hasattr(x, '__func__'): x = x.__func__ if hasattr(x, '__code__'): x = getattr(x, '__code__') if isinstance(x, FunctionType): x = sys.get_func_code(x) if hasattr(x, '__dict__'): items = sorted(x.__dict__.items()) for name, x1 in items: if isinstance( x1, (types.MethodType, types.FunctionType, types.CodeType, type)): print("Disassembly of %s:" % name) try: dis(x1) except TypeError as msg: print("Sorry:", msg) print() elif hasattr(x, 'co_code'): dismodule.disassemble(x) elif isinstance(x, (bytes, bytearray)): dismodule.disassemble_string(x) else: raise TypeError("don't know how to disassemble %s objects" % type(x).__name__)
if hasattr(x, '__dict__'): items = x.__dict__.items() items.sort() for name, x1 in items: if type(x1) in (types.MethodType, types.FunctionType, types.CodeType, types.ClassType): print "Disassembly of %s:" % name try: dis(x1) except TypeError, msg: print "Sorry:", msg print elif hasattr(x, 'co_code'): dismodule.disassemble(x) elif isinstance(x, str): dismodule.disassemble_string(x) else: raise TypeError, \ "don't know how to disassemble %s objects" % \ type(x).__name__ def getargspec(func): """Get the names and default values of a function's arguments. A tuple of four things is returned: (args, varargs, varkw, defaults). 'args' is a list of the argument names (it may contain nested lists). 'varargs' and 'varkw' are the names of the * and ** arguments or None. 'defaults' is an n-tuple of the default values of the last n arguments. """
x = sys.get_func_code(x) if hasattr(x, "__dict__"): items = x.__dict__.items() items.sort() for name, x1 in items: if type(x1) in (types.MethodType, types.FunctionType, types.CodeType, types.ClassType): print "Disassembly of %s:" % name try: dis(x1) except TypeError, msg: print "Sorry:", msg print elif hasattr(x, "co_code"): dismodule.disassemble(x) elif isinstance(x, str): dismodule.disassemble_string(x) else: raise TypeError, "don't know how to disassemble %s objects" % type(x).__name__ def getargspec(func): """Get the names and default values of a function's arguments. A tuple of four things is returned: (args, varargs, varkw, defaults). 'args' is a list of the argument names (it may contain nested lists). 'varargs' and 'varkw' are the names of the * and ** arguments or None. 'defaults' is an n-tuple of the default values of the last n arguments. """ if inspect.ismethod(func): func = func.im_func
def interactive_interpret(code_obj): i = 0 stack = [] values = {} code = code_obj.co_code jump = False divide = False while 0 <= i < len(code): try: if not jump and not divide: ins = raw_input('\n' + str(i)) if ins.startswith('+'): i += int(ins[1:]) elif ins.startswith('='): i = int(ins[1:]) jump = False print stack[::-1] print values c = code[i] op = ord(c) if op >= HAVE_ARGUMENT: oparg = ord(code[i + 1]) + ord(code[i + 2]) * 256 i += 3 dis.disassemble_string(code[i - 3: i]) if op == opmap['JUMP_ABSOLUTE']: i = oparg jump = True elif op == opmap['JUMP_FORWARD']: i += oparg jump = True elif op == opmap['LOAD_FAST']: stack.append(values.get(code_obj.co_varnames[oparg], code_obj.co_varnames[oparg])) print '\tLocal LOAD [%s]' % code_obj.co_varnames[oparg] elif op == opmap['STORE_FAST']: if code_obj.co_varnames[oparg] == 'DIVIDER': divide = True values[code_obj.co_varnames[oparg]] = stack.pop() print '\tLocal STORE [%s]' % code_obj.co_varnames[oparg] elif op == opmap['LOAD_CONST']: stack.append(code_obj.co_consts[oparg]) print '\t%s' % code_obj.co_consts[oparg] elif op == opmap['STORE_GLOBAL']: values[code_obj.co_names[oparg]] = stack.pop() print '\tGlobal STORE [%s]' % code_obj.co_names[oparg] elif op == opmap['LOAD_GLOBAL']: stack.append(values.get(code_obj.co_names[oparg], code_obj.co_names[oparg])) print '\tGLOBAL LOAD [%s]' % code_obj.co_names[oparg] elif op == opmap['COMPARE_OP']: result = eval("%s%s%s" % (stack.pop(), cmp_op[oparg], stack.pop())) stack.append(result) elif op == opmap['POP_JUMP_IF_TRUE'] and stack.pop(): divide = False i = oparg jump = True elif op == opmap['POP_JUMP_IF_FALSE'] and not stack.pop(): divide = False i = oparg jump = True elif op == opmap['LOAD_ATTR']: stack.append(stack.pop() + '.' + code_obj.co_names[oparg]) elif op == opmap['CALL_FUNCTION']: ret = [] for _ in range(oparg + 1): ret.append(str(stack.pop())) stack.append('%s(%s)' % (ret[-1], ', '.join(ret[-2::-1]))) elif op == opmap['FOR_ITER']: exhausted = raw_input('=====Exhausted? (y/n)=====') == 'y' if exhausted: stack.pop() i += oparg else: stack.append('iter_value') elif op == opmap['BUILD_SLICE']: ret = [] for _ in range(oparg): ret.append(str(stack.pop())) stack.append('[%s]' % ':'.join(ret)) elif op == opmap['IMPORT_NAME']: stack.pop() stack.pop() stack.append(code_obj.co_names[oparg]) print 'Import:: %s' % code_obj.co_names[oparg] elif op == opmap['STORE_NAME']: values[code_obj.co_names[oparg]] = stack.pop() print '\tName STORE [%s]' % code_obj.co_names[oparg] elif op == opmap['LOAD_NAME']: stack.append(values.get(code_obj.co_names[oparg], code_obj.co_names[oparg])) print '\tName LOAD [%s]' % code_obj.co_names[oparg] else: i += 1 if op == opmap['PRINT_ITEM']: print 'PRINT: %s' % stack.pop() elif op == opmap['POP_TOP']: stack.pop() elif op == opmap['GET_ITER']: stack.append('iter(%s)' % stack.pop()) elif opname[op].startswith('BINARY'): stack.append('%s(%s, %s)' % (opname[op], stack.pop(), stack.pop())) elif op == opmap['INPLACE_ADD']: stack.append('%s + %s' % (stack.pop(), stack.pop())) elif op == opmap['SLICE+3']: ret = [] for _ in range(3): ret.append(stack.pop()) stack.append('%s[%d:%d]' % (ret[-1], ret[-2], ret[-3])) dis.disassemble_string(code[i - 1: i]) except: pass
#https://mp.weixin.qq.com/s/1TcCCBV8noAhahupI1Xi2Q import marshal import dis f = open('py.pyc', 'rb') f.read(8) code = marshal.load(f) print code.co_consts print code.co_names count = code.co_consts[6] print count.co_varnames print count.co_consts dis.disassemble_string(count.co_code)