给定一个python.pyc文件,是否有一个工具可以让我查看字节码?
Python模块由CPython解释器自动编译成.pyc文件。包含字节码的.pyc文件是二进制格式(封送代码?)。是否有一个GUI(或命令行)工具可以让我查看字节码?有一个名为的可视化python反汇编程序给定一个python.pyc文件,是否有一个工具可以让我查看字节码?,python,bytecode,pyc,Python,Bytecode,Pyc,Python模块由CPython解释器自动编译成.pyc文件。包含字节码的.pyc文件是二进制格式(封送代码?)。是否有一个GUI(或命令行)工具可以让我查看字节码?有一个名为的可视化python反汇编程序 要以命令行方式执行此操作,您可以使用moduledis(,),OP已经发现了这一点。每个*.pyc文件都是包含以下内容的二进制文件: 一个四字节的幻数——它只是随着编组代码的每次更改而更改的字节数 四字节修改时间戳-是生成.pyc的源文件的Unix修改时间戳,以便在源更改时可以重新编译 由
要以命令行方式执行此操作,您可以使用module
dis
(,),OP已经发现了这一点。每个*.pyc文件都是包含以下内容的二进制文件:
- 一个四字节的幻数——它只是随着编组代码的每次更改而更改的字节数李>
- 四字节修改时间戳-是生成.pyc的源文件的Unix修改时间戳,以便在源更改时可以重新编译李>
- 由于Python3.3+版本,接下来的四个字节是将源文件的大小编码为long的字段李>
- 封送的代码对象
文件
view\u pyc\u file.py
import platform
import time
import sys
import binascii
import marshal
import dis
import struct
def view_pyc_file(path):
"""Read and display a content of the Python`s bytecode in a pyc-file."""
file = open(path, 'rb')
magic = file.read(4)
timestamp = file.read(4)
size = None
if sys.version_info.major == 3 and sys.version_info.minor >= 3:
size = file.read(4)
size = struct.unpack('I', size)[0]
code = marshal.load(file)
magic = binascii.hexlify(magic).decode('utf-8')
timestamp = time.asctime(time.localtime(struct.unpack('I', b'D\xa5\xc2X')[0]))
dis.disassemble(code)
print('-' * 80)
print(
'Python version: {}\nMagic code: {}\nTimestamp: {}\nSize: {}'
.format(platform.python_version(), magic, timestamp, size)
)
file.close()
if __name__ == '__main__':
view_pyc_file(sys.argv[1])
$ cat main.py
print("Never give up")
使用next CPython的版本进行测试:
- 2.7.9
- 3.4.2
- 3.5.2
示范 文件的内容
main.py
import platform
import time
import sys
import binascii
import marshal
import dis
import struct
def view_pyc_file(path):
"""Read and display a content of the Python`s bytecode in a pyc-file."""
file = open(path, 'rb')
magic = file.read(4)
timestamp = file.read(4)
size = None
if sys.version_info.major == 3 and sys.version_info.minor >= 3:
size = file.read(4)
size = struct.unpack('I', size)[0]
code = marshal.load(file)
magic = binascii.hexlify(magic).decode('utf-8')
timestamp = time.asctime(time.localtime(struct.unpack('I', b'D\xa5\xc2X')[0]))
dis.disassemble(code)
print('-' * 80)
print(
'Python version: {}\nMagic code: {}\nTimestamp: {}\nSize: {}'
.format(platform.python_version(), magic, timestamp, size)
)
file.close()
if __name__ == '__main__':
view_pyc_file(sys.argv[1])
$ cat main.py
print("Never give up")
通过python2.7创建和读取pyc文件
setivolkylany$~/Downloads/temp/temp$ python2.7 -m py_compile main.py
setivolkylany$~/Downloads/temp/temp$ python2.7 view_pyc_file.py ./main.pyc
1 0 LOAD_CONST 0 ('Never give up')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 1 (None)
8 RETURN_VALUE
--------------------------------------------------------------------------------
Python version: 2.7.9
Magic code: 03f30d0a
Timestamp: Fri Mar 10 15:08:20 2017
Size: None
通过python3.4创建和读取pyc文件
setivolkylany$~/Downloads/temp/temp$ python3.4 -m py_compile main.py
setivolkylany$~/Downloads/temp/temp$ python3.4 view_pyc_file.py __pycache__/main.cpython-34.pyc
1 0 LOAD_NAME 0 (print)
3 LOAD_CONST 0 ('Never give up')
6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
9 POP_TOP
10 LOAD_CONST 1 (None)
13 RETURN_VALUE
--------------------------------------------------------------------------------
Python version: 3.4.2
Magic code: ee0c0d0a
Timestamp: Fri Mar 10 15:08:20 2017
Size: 23
通过python3.5创建和读取pyc文件
setivolkylany$~/Downloads/temp/temp$ python3.5 -m py_compile main.py
setivolkylany$~/Downloads/temp/temp$ python3.5 view_pyc_file.py __pycache__/main.cpython-35.pyc
1 0 LOAD_NAME 0 (print)
3 LOAD_CONST 0 ('Never give up')
6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
9 POP_TOP
10 LOAD_CONST 1 (None)
13 RETURN_VALUE
--------------------------------------------------------------------------------
Python version: 3.5.2
Magic code: 160d0d0a
Timestamp: Fri Mar 10 15:08:20 2017
Size: 23
基于:
def view_pyc_file(path):
"""Read and display a content of the Python`s bytecode in a pyc-file."""
file = open(path, 'rb')
magic = file.read(4)
bit_field = None
timestamp = None
hashstr = None
size = None
if sys.version_info.major == 3 and sys.version_info.minor >=7:
bit_field = int.from_bytes(file.read(4), byteorder=sys.byteorder)
if 1 & bit_field == 1:
hashstr = file.read(8)
else:
timestamp = file.read(4)
size = file.read(4)
size = struct.unpack('I', size)[0]
elif sys.version_info.major == 3 and sys.version_info.minor >= 3:
timestamp = file.read(4)
size = file.read(4)
size = struct.unpack('I', size)[0]
else:
timestamp = file.read(4)
code = marshal.load(file)
magic = binascii.hexlify(magic).decode('utf-8')
timestamp = time.asctime(time.localtime(struct.unpack('I', b'D\xa5\xc2X')[0]))
dis.disassemble(code)
print('-' * 80)
print(
'Python version: {}\nMagic code: {}\nTimestamp: {}\nSize: {}\nHash: {}\nBitfield: {}'
.format(platform.python_version(), magic, timestamp, size, hashstr, bit_field)
)
file.close()
您可以导入模块吗?这当然会执行它。你能澄清一下“查看字节码”吗?你想把它反编译成python代码(
.py
)还是想了解每个字节的含义?我想看看并研究字节码。我特别想了解模块全局对象是如何表示的。我在谷歌上搜索了一下,发现Python附带了一个名为“dis”的模块,我可以用它来表示。“导入dis;导入mymodule;dis.dis(模块)”。仍然想知道是否有一个GUI工具用于此。现在需要根据(Python 3.7)进行更新。我无法在评论中添加所需的修改,因此我将其添加为一个新的答案,但是@PADYMKO请随意使用它编辑您的答案。此项目现在已经相当过时,因此我不希望它能够阅读(完美地)最新Python版本生成的字节码。