Python跨版本字节码反汇编器和打包程序
项目描述
xdis
一个跨Python字节码反汇编器,字节码/wordcode和魔术数字操作库/包。
简介
Python dis 模块允许您从与您运行的Python相同版本的Python反汇编字节码。但不同版本的字节码怎么办呢?
这正是这个包的目的。它可以“打包加载”不同版本的Python的字节码。命令行程序 pydisasm 将使用用户指定的各种格式显示使用最现代Python反汇编约定的反汇编输出。其中一些格式(如“extended”和“extended-format”)是我所知的任何Python反汇编器中最先进的,因为它们可以显示操作符的表达式树。请参阅下面的[反汇编器示例][#disassembler-example]。
此外,如果您需要修改和编写字节码,这里提供的例程可以帮助您。这里提供了打包和解包 Python 代码类型中的只读元组的例程。为了实现多年来 Python CodeType 变更的互操作性,我们提供了自己的 Code 类型版本以允许互操作性,并提供了一些减少编写字节码文件繁琐性的例程。
此包还广泛了解 Python 字节码魔术数字,包括 PyPy 等,以及如何将 sys.sys_info 的主要、次要和发布号转换为相应的魔术值。
因此,如果您想编写跨版本汇编器、字节码级分析器或优化器,此包也可能很有用。除了 dis 提供的指令分类之外,我们还有一些在字节码汇编器、优化器或反汇编器中可能有用的额外类别。
这里提供的程序接受从 Python 1.0 到 3.11 或左右的版本的字节码。该代码需要 Python 2.4 或更高版本,并在运行多个 Python 版本的 Python 上进行了测试。
在安装时,除了最新的 Python 版本外,请使用与该版本匹配的 Python egg 或 wheel,例如 xdis-6.0.2-py3.3.egg,xdis-6.0.2-py33-none-any.whl。当然,对于像 Python 2.6 这样的 wheel 之前的版本,您将不得不使用 eggs。
要使用 git 从源代码安装旧版本,请使用分支 python-2.4-to-2.7 以处理 2.4 到 2.7 的 Python 版本,python-3.1-to-3.2 以处理 3.1 到 3.2 的 Python 版本,python-3.3-to-3.5 以处理 3.3 到 3.5 的 Python 版本。主分支处理 3.6 及以后的 Python 版本。
安装
标准 Python 例程
$ pip install -e . $ pip install -r requirements-dev.txt
还提供了一个 GNU makefile,以便 make install(可能作为 root 或 sudo 执行)将执行上述步骤。
反汇编器示例
这里打包的跨版本反汇编器可以生成优于 Python dis 模块中通常找到的汇编列表。以下是一个示例:
pydisasm -S -F extended bytecode_3.8/pydisasm-example.pyc # pydisasm version 6.1.1.dev0 # Python bytecode 3.8.0 (3413) # Disassembled from Python 3.11.8 (main, Feb 14 2024, 04:47:01) [GCC 13.2.0] # Timestamp in code: 1693155156 (2023-08-27 12:52:36) # Source code size mod 2**32: 320 bytes # Method Name: <module> # Filename: simple_source/pydisasm-example.py # Argument count: 0 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 0 # Stack size: 3 # Flags: 0x00000040 (NOFREE) # First Line: 4 # Constants: # 0: 0 # 1: None # 2: ('version_info',) # 3: 1 # 4: (2, 4) # 5: 'Is small power of two' # Names: # 0: sys # 1: version_info # 2: print # 3: version # 4: len # 5: major # 6: power_of_two # import sys 4: 0 LOAD_CONST (0) ; TOS = 0 2 LOAD_CONST (None) ; TOS = None 4 IMPORT_NAME (sys) ; TOS = import_module(sys) 6 STORE_NAME (sys) ; sys = import_module(sys) # from sys import version_info 5: 8 LOAD_CONST (0) ; TOS = 0 10 LOAD_CONST (('version_info',)) ; TOS = ('version_info',) 12 IMPORT_NAME (sys) ; TOS = import_module(sys) 14 IMPORT_FROM (version_info) ; TOS = from sys import version_info 16 STORE_NAME (version_info) ; version_info = from sys import version_info 18 POP_TOP # print(sys.version) 7: 20 LOAD_NAME (print) ; TOS = print 22 LOAD_NAME (sys) ; TOS = sys 24 LOAD_ATTR (version) ; TOS = sys.version 26 CALL_FUNCTION (1 positional argument) ; TOS = print(sys.version) 28 POP_TOP # print(len(version_info)) 8: 30 LOAD_NAME (print) ; TOS = print 32 LOAD_NAME (len) ; TOS = len 34 LOAD_NAME (version_info) ; TOS = version_info 36 CALL_FUNCTION (1 positional argument) ; TOS = len(version_info) 38 CALL_FUNCTION (1 positional argument) ; TOS = print(len(version_info)) 40 POP_TOP # major = sys.version_info[0] 9: 42 LOAD_NAME (sys) ; TOS = sys 44 LOAD_ATTR (version_info) ; TOS = sys.version_info 46 LOAD_CONST (0) ; TOS = 0 48 BINARY_SUBSCR TOS = sys.version_info[0] 50 STORE_NAME (major) ; major = sys.version_info[0] # power_of_two = major & (major - 1) 10: 52 LOAD_NAME (major) ; TOS = major 54 LOAD_NAME (major) ; TOS = major 56 LOAD_CONST (1) ; TOS = 1 58 BINARY_SUBTRACT TOS = major - (1) 60 BINARY_AND TOS = major & (major - (1)) 62 STORE_NAME (power_of_two) ; power_of_two = major & (major - (1)) # if power_of_two in (2, 4): 11: 64 LOAD_NAME (power_of_two) ; TOS = power_of_two 66 LOAD_CONST ((2, 4)) ; TOS = (2, 4) 68 COMPARE_OP (in) ; TOS = power_of_two in ((2, 4)) 70 POP_JUMP_IF_FALSE (to 80) # print("Is small power of two") 12: 72 LOAD_NAME (print) ; TOS = print 74 LOAD_CONST ("Is small power of two") ; TOS = "Is small power of two" 76 CALL_FUNCTION (1 positional argument) ; TOS = print("Is small power of two") 78 POP_TOP >> 80 LOAD_CONST (None) ; TOS = None 82 RETURN_VALUE return None
在上面的示例中,请注意对堆栈中的项目执行了一些操作数解释。例如,在
24 LOAD_ATTR (version) | sys.version
从指令中可以看到 sys.version 是加载的解析属性。
同样在
68 COMPARE_OP (in) | power_of_two in (2, 4)
中,我们看到我们可以解析 in 操作的两个参数。最后,在某些 CALL_FUNCTIONS 中,我们可以确定函数的名称以及传递给它的参数。
测试
$ make check
添加了一个 GNU makefile,以简化设置运行正确命令,并按从快到慢的顺序运行测试。
如果您已安装 remake,您可以通过 remake --tasks 查看包括测试在内的所有任务列表。
用法
运行
$ ./bin/pydisasm -h
获取用法帮助。
作为 dis 的替代品
xdis 还提供了一些支持,作为 Python 库 dis 模块的替代品。当您想从较旧的 Python 版本中使用 Python 3.4 或更高版本的改进 API 时,这可能很有用。
例如
>>> # works in Python 2 and 3 >>> import xdis.std as dis >>> [x.opname for x in dis.Bytecode('a = 10')] ['LOAD_CONST', 'STORE_NAME', 'LOAD_CONST', 'RETURN_VALUE']
对于格式化反汇编或如何显示编译器标志,输出可能存在一些细微差异。但我们期望您会发现 xdis 的输出更具信息量。
另请参阅
https://pypi.ac.cn/project/uncompyle6/:Python 字节码解析
https://pypi.ac.cn/project/decompyle3/:Python 3.7 和 3.8 的字节码解析
https://pypi.ac.cn/project/xasm/:Python 字节码汇编器
https://pypi.ac.cn/project/x-python/ : 使用 Python 编写的 Python 字节码解释器
项目详情
下载文件
下载适用于您平台的应用文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源代码分发
构建分发
xdis-6.1.1.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 1cbeaf56b996ba1b1e744a3f66753692be5ef9855131b7332601aa0a124e5d13 |
|
MD5 | 72bb09aaac9c215ab3ae7731cd4713f4 |
|
BLAKE2b-256 | 64ae3a900836c9784d1999b0a7d6743dcd6e3a133f37d47fef2aa0f799fac179 |
xdis-6.1.1-py312-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 73365e0645429a3823ee612ae79a2a5a9ed83a0fbd51e1711bbe102884c485d9 |
|
MD5 | ec7a2b32cca9702cd64004852b57db75 |
|
BLAKE2b-256 | 8527e2af53debfcc56d75d7c9f7df4f66dc978ea2e9cffc0444e4c82afefbff7 |
xdis-6.1.1-py311-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 37ad24cd9fb72410f1973ea892ca46375b4a9b497bd3b3ed93f440182dfd0e15 |
|
MD5 | cee1d1f1307a09cb353b1233942e548c |
|
BLAKE2b-256 | 29273412477c1e249bb1cd983d4f09eae4f9e4cdfff97188c6ed4a26ad63f1bb |
xdis-6.1.1-py310-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 326bbeb04566eae9c9b679d4fca47262d920edd841fff93ed2efccaf9fec6237 |
|
MD5 | ddb1c49ca033ed1634e1d0a3c692f8ce |
|
BLAKE2b-256 | b47939207f6277bf7d1a2f31c8302dbd3c006ad4f5a8183ef90c83c34c40a2e7 |
xdis-6.1.1-py2-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 0f7bf67cd9c3a2fa3b14857f05ee159308e4aec97168bbf3cc8db902a14a0e24 |
|
MD5 | 69da2cfa584e1d24e6b20cd96ce04862 |
|
BLAKE2b-256 | aa2859714b850faaac29cfd86d5874a42f8fdbc7d3bffb29c0a1f7496c89b4e1 |