作为程序员,经常有查看源代码的需求。如果没有代码,能反汇编也不至于两眼摸黑。Python 这方面的支持做的挺不错。
inspect 🔗
inspect 定义了很多有用的函数,比如:getsource
>>> import netaddr
>>> import inspect
>>> print(inspect.getsource(netaddr.cidr_to_glob))
def cidr_to_glob(cidr):
"""
A function that accepts an IP subnet in a glob-style format and returns
a list of CIDR subnets that exactly matches the specified glob.
:param cidr: an IP object CIDR subnet.
:return: a list of one or more IP addresses and subnets.
"""
ip = IPNetwork(cidr)
globs = iprange_to_globs(ip[0], ip[-1])
if len(globs) != 1:
# There should only ever be a one to one mapping between a CIDR and
# an IP glob range.
raise AddrConversionError('bad CIDR to IP glob conversion!')
return globs[0]
>>>
dis 🔗
dis 用来反汇编 Python 字节码。
>>> import dis
>>> def add(a, b): return a+b
...
>>> dis.dis(add)
1 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
6 BINARY_ADD
7 RETURN_VALUE
>>>
gdb 🔗
无论 dis 还是 inspect 都不能处理 C 实现的的函数。比如:
>>> from fcntl import flock
>>> dis.dis(flock)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dis.py", line 49, in dis
type(x).__name__
TypeError: don't know how to disassemble builtin_function_or_method objects
这种情况下,gdb 就成了不二之选。先把 debug 包给装上:
$ sudo debuginfo-install `rpm -q python`
先 attach 到被调试的 python 进程,假设 pid 是 11170. 然后 ‘pi’ 进入 Python 交互环境。
$ gdb python 11170
(gdb) pi
接下来,反汇编:
>>> from fcntl import flock
>>> frame=gdb.selected_frame()
>>> arch=frame.architecture()
>>> arch.disassemble(flock)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: argument 1 must be integer<K>, not builtin_function_or_method
>>> flock.__str__
<method-wrapper '__str__' of builtin_function_or_method object at 0x7fad357181b8>
>>> arch.disassemble(0x7fad357181b8)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
gdb.MemoryError: Cannot access memory at address 0x7fad357181b8
>>>
看来,不咋行。还是老老实实看源代码吧!