Python - 浅谈Python的编译与反编译,浅谈python,1 - Python
Python - 浅谈Python的编译与反编译,浅谈python,1 - Python
1 - Python编译过程涉及的文件
py
源代码文件,由python.exe解释,可在控制台下运行,可用文本编辑器进行编辑;
pyc
源代码文件经过编译后生成的二进制文件,无法用文本编辑器进行编辑;执行一个.py文件后,并不会自动生成对应的.pyc文件,需要指定触发Python来创建pyc文件;- pyc是由py文件经过编译后生成的二进制字节码(byte code)文件;- pyc文件的加载速度比py文件快;- pyc文件是一种跨平台的字节码,由python的虚拟机来执行;- pyc文件的内容跟python版本相关,不同的python版本编译生成不同的pyc文件,只能在相同版本环境下执行;
pyo
源代码文件经过优化编译后生成的文件,无法用文本编辑器进行编辑;Python3.5之后,不再使用.pyo文件名,而是使用类似“xxx.opt-n.pyc的文件名;
pyd
是python的动态链接库;动态链接库(DLL)文件是一种可执行文件,允许程序共享执行特殊任务所必需的代码和其他资源;pyd文件虽然是作为python的动态模块,但实质上还是DLL文件,只是后缀改为pyd;一般是用C、C++、D语言按照一定的格式编写;参考信息:https://docs.python.org/3/faq/windows.html?highlight=pyd#is-a-pyd-file-the-same-as-a-dll
pyz
从Python 3.5开始,定义了.pyz和.pyzw分别作为“Python Zip应用”和“Windows下Python Zip应用”的扩展名。新增了内置zipapp模块来进行简单的管理,可以用Zip打包Python程序到一个可执行.pyz文件。- zipapp — Manage executable python zip archives- https://docs.python.org/3/library/zipapp.html详细内容请见PEP441(https://www.python.org/dev/peps/pep-0441/)
2 - 生成pyc文件
执行一个.py文件后,并不会自动生成对应的.pyc文件,需要指定触发Python来创建pyc文件。
可以利用Python的import机制创建pyc文件:
生成pyc文件的过程:
Python在执行import语句时(例如“import abc”),将会到已设定的path中寻找abc.pyc或abc.dll文件。如果只是发现了abc.py,那么Python会首先将abc.py编译成相应的PyCodeObject中间结果,然后创建abc.pyc文件,并将中间结果写入该文件。然后,Python会import这个abc.pyc文件,实际上也就是将abc.pyc文件中的PyCodeObject重新在内存中复制出来。
生成pyc文件的方法:
命令形式:
python -m py_compile file.py # 生成单个pyc文件python -m py_compile /dir/{file1,file2}.py # 生成多个pyc文件python -m compileall /dir/ # 生成目录下所有py文件对应的pyc文件
脚本形式:compile模块的compile函数
import py_compile # 相当于命令行中的“-m py_compile”py_compile.compile(‘py file path‘)
脚本形式:compileall模块的compile_dir函数
import compileallcompileall.compile_dir("py files dir")
生成pyc文件示例:
[email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ ls -ltotal 2-rw-r--r-- 1 anliven 197121 50 3月 7 22:55 sample.py-rw-r--r-- 1 anliven 197121 49 3月 7 23:40 sample2.py[email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ cat sample.py# -*- coding: utf-8 -*-print("Hello Python !")[email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ cat sample2.py# -*- coding: utf-8 -*-print("Hello World !")[email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ python -m compileall ./Listing ‘./‘...Compiling ‘./sample.py‘...Compiling ‘./sample2.py‘...[email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ ls -ltotal 6drwxr-xr-x 1 anliven 197121 0 3月 7 23:42 __pycache__/-rw-r--r-- 1 anliven 197121 50 3月 7 22:55 sample.py-rw-r--r-- 1 anliven 197121 49 3月 7 23:40 sample2.py[email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ ls -l __pycache__/total 2-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample.cpython-36.pyc-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample2.cpython-36.pyc
3 - 生成pyo文件
与生成pyc文件类似,但要额外使用-O和-OO选项来生成pyo文件。
但在Python3.5之后,不再使用.pyo文件名,而是生成文件名类似“xxx.opt-n.pyc的文件。
命令示例:
python -O -m py_compile file.pypython -O -m py_compile /dir/{file1,file2}.pypython -O -m compileall /dir/
示例:python3.6生成pyo文件
[email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ python -O -m compileall ./Listing ‘./‘...Compiling ‘./sample.py‘...Compiling ‘./sample2.py‘...[email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ ls -l __pycache__/total 4-rw-r--r-- 1 anliven 197121 122 3月 7 23:42 sample.cpython-36.opt-1.pyc-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample.cpython-36.pyc-rw-r--r-- 1 anliven 197121 122 3月 7 23:42 sample2.cpython-36.opt-1.pyc-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample2.cpython-36.pyc
示例:python2.7生成pyo文件
[email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ ls -ltotal 6drwxr-xr-x 1 anliven 197121 0 3月 7 23:42 __pycache__/-rw-r--r-- 1 anliven 197121 50 3月 7 22:55 sample.py-rw-r--r-- 1 anliven 197121 49 3月 7 23:40 sample2.py[email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ py -2 -O -m compileall ./Listing ./ ...Listing ./__pycache__ ...Compiling ./sample.py ...Compiling ./sample2.py ...[email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ ls -ltotal 8drwxr-xr-x 1 anliven 197121 0 3月 7 23:42 __pycache__/-rw-r--r-- 1 anliven 197121 50 3月 7 22:55 sample.py-rw-r--r-- 1 anliven 197121 122 3月 7 23:45 sample.pyo-rw-r--r-- 1 anliven 197121 49 3月 7 23:40 sample2.py-rw-r--r-- 1 anliven 197121 122 3月 7 23:45 sample2.pyo
4 - 运行pyc或pyo文件
运行pyc文件
[email protected] MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__$ python sample.cpython-36.pycHello Python ![email protected] MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__$ python sample2.cpython-36.pycHello World ![email protected] MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__$ python sample.cpython-36.opt-1.pycHello Python ![email protected] MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__$ python sample2.cpython-36.opt-1.pycHello World !
运行pyo文件
[email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ ls -ltotal 8drwxr-xr-x 1 anliven 197121 0 3月 7 23:42 __pycache__/-rw-r--r-- 1 anliven 197121 50 3月 7 22:55 sample.py-rw-r--r-- 1 anliven 197121 122 3月 7 23:45 sample.pyo-rw-r--r-- 1 anliven 197121 49 3月 7 23:40 sample2.py-rw-r--r-- 1 anliven 197121 122 3月 7 23:45 sample2.pyo[email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ py -2 sample.pyoHello Python ![email protected] MINGW64 /d/Anliven/Anliven-Code/Test$ py -2 sample2.pyoHello World !
5 - 利用uncompyle6进行Python反编译
uncompyle6
Python cross-version byte-code decompilerPyPI:https://pypi.python.org/pypi/uncompyle6GitHub:https://github.com/rocky/python-uncompyle6安装uncompyle6
$ pip3 install --proxy="10.144.1.10:8080" uncompyle6Collecting uncompyle6 Downloading uncompyle6-3.0.0-py36-none-any.whl (195kB) 100% |████████████████████████████████| 204kB 321kB/sRequirement already satisfied: six in c:\python36\lib\site-packages (from uncompyle6)Collecting spark-parser<1.9.0,>=1.8.5 (from uncompyle6) Downloading spark_parser-1.8.5-py36-none-any.whlCollecting xdis<3.7.0,>=3.6.9 (from uncompyle6) Downloading xdis-3.6.11-py36-none-any.whl (74kB) 100% |████████████████████████████████| 81kB 153kB/sCollecting click (from spark-parser<1.9.0,>=1.8.5->uncompyle6) Using cached click-6.7-py2.py3-none-any.whlInstalling collected packages: click, spark-parser, xdis, uncompyle6Successfully installed click-6.7 spark-parser-1.8.5 uncompyle6-3.0.0 xdis-3.6.11$ pip3 show uncompyle6Name: uncompyle6Version: 3.0.0Summary: Python cross-version byte-code decompilerHome-page: https://github.com/rocky/python-uncompyle6/Author: Rocky Bernstein, Hartmut Goebel, John Aycock, and othersAuthor-email: [email protected]License: MITLocation: c:\python36\lib\site-packagesRequires: xdis, spark-parser, six
示例:反编译pyc文件
[email protected] MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__$ ls -ltotal 4-rw-r--r-- 1 anliven 197121 122 3月 7 23:42 sample.cpython-36.opt-1.pyc-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample.cpython-36.pyc-rw-r--r-- 1 anliven 197121 122 3月 7 23:42 sample2.cpython-36.opt-1.pyc-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample2.cpython-36.pyc[email protected] MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__$[email protected] MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__$ uncompyle6 sample.cpython-36.pyc > s1.py[email protected] MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__$ ls -ltotal 5-rw-r--r-- 1 anliven 197121 335 3月 8 00:01 s1.py-rw-r--r-- 1 anliven 197121 122 3月 7 23:42 sample.cpython-36.opt-1.pyc-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample.cpython-36.pyc-rw-r--r-- 1 anliven 197121 122 3月 7 23:42 sample2.cpython-36.opt-1.pyc-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample2.cpython-36.pyc[email protected] MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__$ cat s1.py# uncompyle6 version 3.0.1# Python bytecode 3.6 (3379)# Decompiled from: Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)]# Embedded file name: ./sample.py# Compiled at: 2018-03-07 22:55:30# Size of source mod 2**32: 50 bytesprint(‘Hello Python !‘)# okay decompiling sample.cpython-36.pyc[email protected] MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__$
示例:反编译pyo文件
[email protected] MINGW64 /d/Anliven/Anliven-Code/Test $ ls -l total 8 drwxr-xr-x 1 anliven 197121 0 3月 8 00:01 __pycache__/ -rw-r--r-- 1 anliven 197121 50 3月 7 22:55 sample.py -rw-r--r-- 1 anliven 197121 122 3月 7 23:45 sample.pyo -rw-r--r-- 1 anliven 197121 49 3月 7 23:40 sample2.py -rw-r--r-- 1 anliven 197121 122 3月 7 23:45 sample2.pyo [email protected] MINGW64 /d/Anliven/Anliven-Code/Test $ [email protected] MINGW64 /d/Anliven/Anliven-Code/Test $ uncompyle6 sample2.pyo > s2.py [email protected] MINGW64 /d/Anliven/Anliven-Code/Test $ cat s2.py # uncompyle6 version 3.0.1 # Python bytecode 2.7 (62211) # Decompiled from: Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)] # Embedded file name: ./sample2.py # Compiled at: 2018-03-07 23:40:22 print ‘Hello World !‘ # okay decompiling sample2.pyo [email protected] MINGW64 /d/Anliven/Anliven-Code/Test $
uncompyle6的帮助信息
$ uncompyle6 --helpUsage: uncompyle6 [OPTIONS]... [ FILE | DIR]... uncompyle6 [--help | -h | --V | --version]Examples: uncompyle6 foo.pyc bar.pyc # decompile foo.pyc, bar.pyc to stdout uncompyle6 -o . foo.pyc bar.pyc # decompile to ./foo.pyc_dis and ./bar.pyc_dis uncompyle6 -o /tmp /usr/lib/python1.5 # decompile whole libraryOptions: -o <path> output decompiled files to this path: if multiple input files are decompiled, the common prefix is stripped from these names and the remainder appended to <path> uncompyle6 -o /tmp bla/fasel.pyc bla/foo.pyc -> /tmp/fasel.pyc_dis, /tmp/foo.pyc_dis uncompyle6 -o /tmp bla/fasel.pyc bar/foo.pyc -> /tmp/bla/fasel.pyc_dis, /tmp/bar/foo.pyc_dis uncompyle6 -o /tmp /usr/lib/python1.5 -> /tmp/smtplib.pyc_dis ... /tmp/lib-tk/FixTk.pyc_dis -c <file> attempts a disassembly after compiling <file> -d print timestamps -p <integer> use <integer> number of processes -r recurse directories looking for .pyc and .pyo files --fragments use fragments deparser --verify compare generated source with input byte-code --verify-run compile generated source, run it and check exit code --weak-verify compile generated source --linemaps generated line number correspondencies between byte-code and generated source output --help show this messageDebugging Options: --asm -a include byte-code (disables --verify) --grammar -g show matching grammar --tree -t include syntax tree (disables --verify)Extensions of generated files: ‘.pyc_dis‘ ‘.pyo_dis‘ successfully decompiled (and verified if --verify) + ‘_unverified‘ successfully decompile but --verify failed + ‘_failed‘ decompile failed (contact author for enhancement)
6 - 其他Python反编译工具
Decompyle++
A Python Byte-code Disassembler/Decompiler
https://github.com/zrax/pycdc
Easy Python Decompiler
https://sourceforge.net/projects/easypythondecompiler/
Easy Python Decompiler is python bytecode decompiler, decompiles pyc & pyo files.
Python - 浅谈Python的编译与反编译
相关内容
- python之路--内置常用模块,python之路--,1. 简单的了解模
- 浅谈Python2获取中文文件名的编码问题,浅谈python2
- Python2和Python3中print的用法示例总结,python2python3
- 详谈python read readline readlines的区别,pythonreadlines
- CentOS 6.5下安装Python 3.5.2(与Python2并存),centospython2
- WINDOWS 同时安装 python2 python3 后 pip 错误的解决方法,
- Python 2与Python 3版本和编码的对比,python对比
- Python2.x版本中基本的中文编码问题解决,
- Windows下实现Python2和Python3两个版共存的方法,python2py
- 让python同时兼容python2和python3的8个技巧分享,python2py
评论关闭