说到Python文件后缀,不夸张的说你眼花缭乱,来看看你都遇到过哪些类型吧!
.py
如果你不知道这个,呵呵……那请你出去左转,你还是那种付钱的男孩,没有丝毫的改变。 我们去玩游戏吧...
.pyc
这个后缀应该算是Python的py代码之外最常遇到的文件类型了。
虽然Python通常被认为是一种解释性语言,但谁说它不能编译和执行呢?
Python通过编译生成的pyc文件,然后由Python虚拟机执行。 与py文件相比,编译成pyc本质上和py没有太大区别,只是这个模块的加载速度提高了,而代码并没有增强。 执行速度快,通常不需要主动编译pyc文件。
pyc文件存在的意义是什么?
除了稍微增强模块加载率之外,更多的是在一定意义上保护源代码不被泄露。
当然,为什么说它有一定的意义呢? 因为既然有编译,显然就有反编译,这个稍后再说……
如何将py文件编译成pyc文件? 有以下三种方法:
1.使用Python直接编译
python -m sample.py
2. py_编译
import py_compile
py_compile.compile('sample.py')
3. 编译全部
import compileall
compileall.compile_file('sample.py')
compileall.compile_dir(dirpath)
三种形式一目了然,区别在于compileall可以一次性递归编译文件夹下的所有py文件
.pyo
pyo是优化编译后的源文件,pyo文件的大小一般大于或等于pyc文件。
这个优化并没有多大作用,只是删除了断言。 原文如下:
当使用 -O 标志调用 Python 解释器时,会生成优化代码并将其存储在 .pyo 文件中。 优化器目前没有多大帮助; 它仅删除断言语句。 当使用-O时,所有字节码都会被优化; 。 pyc 文件将被忽略,.py 文件将被编译为优化的字节码。
指示:
python -O -m py_compile sample.py
.pyd
看完前几个,相信你也能猜出字母d了。 是Python的动态链接库; 动态链接库(DLL)文件是一个可执行文件,允许程序共享代码和执行特殊任务所需的其他文件。 资源。
您可以在Python安装目录的DLL文件夹中看到它们。
.pyz(w)
从Python 3.5开始,.pyz和.pyzw分别被定义为“Python Zip应用程序”和“Windows下的Python Zip应用程序”的扩展名。
添加了外部zipapp模块以方便管理,并且可以使用Zip将Python程序打包成可执行的.pyz文件。
使用起来也比较简单,但是它不能像pyinstaller等打包的exe工具那样独立于Python环境运行,而且此类文件往往需要使用文本编辑器来查看其源代码信息,一般来说没什么用处。
。EXE文件
为什么单独提到exe文件,因为Python有很多工具可以将Python源代码打包成exe,使其可以脱离Python环境独立运行。
python反编译
所谓道高一尺,魔高一尺。 无论是Python、JAVA还是C语言,只要有编译反编译pyc源码,就一定有反编译操作。
无论你怎么看待加密,都一定有人能够破解,只是成本不同,所以编译只能作为一种防君子小人的操作。
今天主要和大家聊聊pyc文件的反编译,有哪些小心的做法和陷阱。
首先,由于反编译是一种异常方法,Python自然不会原生自带这个模块。
我们需要先安装依赖项:
# 安装依赖
pip install uncompyle6
操作也比较简单,在命令行输入:
uncompyle6 sample.pyc(pyo) > sample.py
这就是结局? 阴谋和陷阱又如何呢? 哈哈,继续关注...
使用注释的技巧
我们创建一个名为 BreezePython.py 的文件,并对下面的代码进行编译和反编译,看看反编译内容与原始代码的区别
import platform
def test():
"""
这是一个测试方法,用来验证反编译
:return: None
"""
# 打印系统详情
print(platform.platform())
test()
编译:
python -m BreezePython.py
反编译:
uncompyle6 BreezePython.cpython-37.pyc > output.py
我们看一下反编译后的文件有什么不同:
# uncompyle6 version 3.6.4
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: C:UsersAdministratorDesktopuncompileBreezePython.py
# Size of source mod 2**32: 453 bytes
import platform
def test():
"""
这是一个测试方法,用来验证反编译
:return: None
"""
print(platform.platform())
test()
# okay decompiling BreezePython.cpython-37.pyc
与原来的代码相比有什么不同?
没错,注释...文档注释默认保留,但是用#所做的注释在编译+反编译过程中会丢失。
所以如果你是个心机小子,就用#来写代码注释吧。 即使代码被反编译了,没有注释,连我们自己都会被一大段没有注释的代码逼疯,哈哈。
反编译陷阱
反编译万无一失吗? 不...让我给你举个例子。 这段代码是随机的,只是为了让它在反编译时抛出错误:
class Demo:
def __init__(self, color):
self.color = color
def jduge(self):
if not self.color:
return "get None"
if not self.color == 'red':
mood = "disappointed"
return "I'm %s,I like white best" % mood
return "get None..."
if __name__ == '__main__':
Main = Demo("red")
print(Main.jduge())
通常此代码应返回: get None...
但是这段代码反编译后是什么样子呢?
# uncompyle6 version 3.6.4
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: C:UsersAdministratorDesktopuncompileBreezePython.py
# Size of source mod 2**32: 391 bytes
class Demo:
def __init__(self, color):
self.color = color
def jduge(self):
if not self.color:
return 'get None'
else:
mood = self.color == 'red' or 'disappointed'
return "I'm %s,I like white best" % mood
return 'get None...'
if __name__ == '__main__':
Main = Demo('red')
print(Main.jduge())
# okay decompiling __pycache__BreezePython.cpython-37.pyc
编译后的代码返回:我是真的,我最喜欢白色
我勒个去? 这都搞成什么乱七八糟的事情了。
根据多年的挖掘经验,当反编译代码遇到多个if not时,最后一个if not就会被所谓的缩写弄巧成拙,最终导致反编译错误。
这是个坑,你也能利用吗?
这就是今天文章的全部内容。 希望这篇文章能让你了解Python的文件类型以及编译和反编译操作。 如果您有所收获反编译pyc源码,期待您的支持和转发。
留言送书
今天捐赠一本书:《Java高并发与网络编程亿万流量实战》
PS:最近当当网有满100立减5的活动
发表评论