热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python防反编译_Python浅谈Python的编译与反编译

1-Python编译过程涉及的文件py源代码文件,由python.exe解释,可在控制台下运行,可用文本编辑器进行编辑;

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文件:

内置的py_compile模块可以把py文件编译为pyc或pyo文件;

内置的compileall模块可以把整个目录中的py文件编译为pyc或pyo文件;

生成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 compileall

compileall.compile_dir("py files dir")

生成pyc文件示例:

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ ls -l

total 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

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ cat sample.py

# -*- coding: utf-8 -*-

print("Hello Python !")

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ cat sample2.py

# -*- coding: utf-8 -*-

print("Hello World !")

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ python -m compileall ./

Listing './'...

Compiling './sample.py'...

Compiling './sample2.py'...

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ ls -l

total 6

drwxr-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

anliven@DESKTOP-68OFQFP 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.py

python -O -m py_compile /dir/{file1,file2}.py

python -O -m compileall /dir/

示例:python3.6生成pyo文件

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ python -O -m compileall ./

Listing './'...

Compiling './sample.py'...

Compiling './sample2.py'...

anliven@DESKTOP-68OFQFP 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文件

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ ls -l

total 6

drwxr-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

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ py -2 -O -m compileall ./

Listing ./ ...

Listing ./__pycache__ ...

Compiling ./sample.py ...

Compiling ./sample2.py ...

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ ls -l

total 8

drwxr-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文件

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ python sample.cpython-36.pyc

Hello Python !

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ python sample2.cpython-36.pyc

Hello World !

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ python sample.cpython-36.opt-1.pyc

Hello Python !

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ python sample2.cpython-36.opt-1.pyc

Hello World !

运行pyo文件

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ ls -l

total 8

drwxr-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

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ py -2 sample.pyo

Hello Python !

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ py -2 sample2.pyo

Hello World !

5 - 利用uncompyle6进行Python反编译

uncompyle6

安装uncompyle6

$ pip3 install --proxy="10.144.1.10:8080" uncompyle6

Collecting uncompyle6

Downloading uncompyle6-3.0.0-py36-none-any.whl (195kB)

100% |████████████████████████████████| 204kB 321kB/s

Requirement already satisfied: six in c:\python36\lib\site-packages (from uncompyle6)

Collecting spark-parser<1.9.0,>&#61;1.8.5 (from uncompyle6)

Downloading spark_parser-1.8.5-py36-none-any.whl

Collecting xdis<3.7.0,>&#61;3.6.9 (from uncompyle6)

Downloading xdis-3.6.11-py36-none-any.whl (74kB)

100% |████████████████████████████████| 81kB 153kB/s

Collecting click (from spark-parser<1.9.0,>&#61;1.8.5->uncompyle6)

Using cached click-6.7-py2.py3-none-any.whl

Installing collected packages: click, spark-parser, xdis, uncompyle6

Successfully installed click-6.7 spark-parser-1.8.5 uncompyle6-3.0.0 xdis-3.6.11

$ pip3 show uncompyle6

Name: uncompyle6

Version: 3.0.0

Summary: Python cross-version byte-code decompiler

Home-page: https://github.com/rocky/python-uncompyle6/

Author: Rocky Bernstein, Hartmut Goebel, John Aycock, and others

Author-email: rb&#64;dustyfeet.com

License: MIT

Location: c:\python36\lib\site-packages

Requires: xdis, spark-parser, six

示例&#xff1a;反编译pyc文件

anliven&#64;DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ ls -l

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

anliven&#64;DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$

anliven&#64;DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ uncompyle6 sample.cpython-36.pyc > s1.py

anliven&#64;DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ ls -l

total 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

anliven&#64;DESKTOP-68OFQFP 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 bytes

print(&#39;Hello Python !&#39;)

# okay decompiling sample.cpython-36.pyc

anliven&#64;DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$

示例&#xff1a;反编译pyo文件

anliven&#64;DESKTOP-68OFQFP 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

anliven&#64;DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$

anliven&#64;DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ uncompyle6 sample2.pyo > s2.py

anliven&#64;DESKTOP-68OFQFP 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 &#39;Hello World !&#39;

# okay decompiling sample2.pyo

anliven&#64;DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$

uncompyle6的帮助信息

$ uncompyle6 --help

Usage:

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 library

Options:

-o 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

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 attempts a disassembly after compiling

-d print timestamps

-p use 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 message

Debugging Options:

--asm -a include byte-code (disables --verify)

--grammar -g show matching grammar

--tree -t include syntax tree (disables --verify)

Extensions of generated files:

&#39;.pyc_dis&#39; &#39;.pyo_dis&#39; successfully decompiled (and verified if --verify)

&#43; &#39;_unverified&#39; successfully decompile but --verify failed

&#43; &#39;_failed&#39; decompile failed (contact author for enhancement)

6 - 其他Python反编译工具

Decompyle&#43;&#43;

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.


推荐阅读
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文介绍了一些Java开发项目管理工具及其配置教程,包括团队协同工具worktil,版本管理工具GitLab,自动化构建工具Jenkins,项目管理工具Maven和Maven私服Nexus,以及Mybatis的安装和代码自动生成工具。提供了相关链接供读者参考。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了StartingzookeeperFAILEDTOSTART相关的知识,希望对你有一定的参考价值。下载路径:https://ar ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • Java SE从入门到放弃(三)的逻辑运算符详解
    本文详细介绍了Java SE中的逻辑运算符,包括逻辑运算符的操作和运算结果,以及与运算符的不同之处。通过代码演示,展示了逻辑运算符的使用方法和注意事项。文章以Java SE从入门到放弃(三)为背景,对逻辑运算符进行了深入的解析。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • Postgresql备份和恢复的方法及命令行操作步骤
    本文介绍了使用Postgresql进行备份和恢复的方法及命令行操作步骤。通过使用pg_dump命令进行备份,pg_restore命令进行恢复,并设置-h localhost选项,可以完成数据的备份和恢复操作。此外,本文还提供了参考链接以获取更多详细信息。 ... [详细]
author-avatar
mofa007_903
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有