【zz】python之dis.dis反汇编功能扩展



原文:http://blog.csdn.net/balabalamerobert/archive/2007/06/22/1662025.aspx

扩展python自带的dis.dis反汇编功能,能够方便快捷地看到任何一个函数、类、module对应的字节码指令。

sdis.py:

import dis as pydis
import types

code = None
def read(filename):
     f = open(filename)
     content = f.read()
    global code
     code = compile(content, filename, ‘exec’)
     f.close()

def find_code(code, name):
    for item in code.co_consts:
        if isinstance(item, types.CodeType):
            if item.co_name == name:
                return item
    return None
    
def dis(code_name=None):
    if code_name is None:
         co = code
         pydis.dis(co)
        return
     names = code_name.split(".")
     co = code
    for name in names:
         co = find_code(co, name)
        if not co:
            print ‘%s is not a valid name’ % code_name
    if co:
        print ("   byte code for %s  " % code_name).center(60, ‘‘)
         pydis.dis(co)

原理非常简单,sdis将python源文件读入并进行编译,从《Python源码剖析》系列中我们已经得知,编译的结果是一个code对象,在 code对象中,包含了一个co_consts,其中有别的code对象。类、函数、module在demo.py中层怎样的嵌套结构,code对象在 co_consts中也呈现出相同的嵌套结构。有了这个工具,对python的反汇编就方便多了,下面是几个例子:

Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sdis
>>> import demo
2
>>> sdis.read(‘demo.py’)
>>> sdis.dis() #这个是module一级的反汇编结果
1           0 LOAD_CONST               0 (<code object f at 00BE7530, file "demo.py", line 1>)
              3 MAKE_FUNCTION            0
              6 STORE_NAME               0 (f)

4           9 LOAD_CONST               1 (<code object g at 00BE7650, file "demo.py", line 4>)
             12 MAKE_FUNCTION            0
             15 STORE_NAME               1 (g)

9          18 LOAD_CONST               2 (‘MyClass’)
             21 LOAD_NAME                2 (object)
             24 BUILD_TUPLE              1
             27 LOAD_CONST               3 (<code object MyClass at 00BE76E0, fi
le "demo.py", line 9>)
             30 MAKE_FUNCTION            0
             33 CALL_FUNCTION            0
             36 BUILD_CLASS
             37 STORE_NAME               3 (MyClass)

13          40 LOAD_CONST               4 (1)
             43 STORE_NAME               4 (a)

14          46 LOAD_NAME                4 (a)
             49 LOAD_CONST               4 (1)
             52 INPLACE_ADD
             53 STORE_NAME               4 (a)

15          56 LOAD_NAME                4 (a)
             59 PRINT_ITEM
             60 PRINT_NEWLINE
             61 LOAD_CONST               5 (None)
             64 RETURN_VALUE
>>>
>>> sdis.dis(‘MyClass.init‘)
**

byte code for MyClass.init *
11           0 LOAD_CONST               0 (None)
              3 RETURN_VALUE
>>>
>>> sdis.dis(‘g.fun’)
** byte code for g.fun *
7           0 LOAD_CONST               0 (None)
              3 RETURN_VALUE
>>>