购买提示

购买卡卷,然后点击右上角的头像->我的余额->金币兑换(或者点击金币兑换跳转),输入兑换码后点击立即兑换

简介

懂的都懂,Python源代码很容易泄漏;目前主流加密方式:

  • 编译成pyc文件
  • 通过PyInstall或者Nuitka编译成exe文件
  • 使用三方库混淆源代码
  • 使用Cython编译为pyd

上述方式如何进行加密,以及对应破解难易程度不在本文的讨论范围之内,如感兴趣可自行搜索,本文主要是介绍如何定义Python解释器来达到加密源代码的目的;

平台

  1. 全平台
  2. 解压密码:

版本

v1版 – 时间富裕版

  • 两端AES加密算法,且通过联调
  • 加密工程
隐藏内容
本内容需评论后查看

v2版 – 节省时间版

  • 包含v1版
  • Python 3.11.9源码修改,你就不需要再按照教程一步一步做了,我都已经给你做完了,只需要你更改一下aes的密钥就能直接编译
隐藏内容
本内容需权限查看
  • 普通用户: 149.9金币
  • VIP会员: 89.94金币6折
  • 永久会员: 免费
已有25人解锁查看

定制解释器

1、修改opcode操作码

下载Python源代码,本文以3.11.9版本为例子,其它版本类似,请模仿跟随;

https://www.python.org/ftp/python/3.11.9/Python-3.11.9.tgz

opcode中定义了每个操作码的对应操作,如破解pyc文件就可以根据操作码一个一个的翻译;

修改规则:交换code值,但小于90的只能和小于90的互换,90以上的只能和90以上的交换;例如0x01是POP_TOP,那就将0x01换成UNARY_NOT;

继续修改与opcode相关的两个文件,其中Lib -> opcode.h文件中值的交换、Python -> opcode_targets.h文件中位置的交换;

./configure --prefix=/user/jncoder/kk(修改为自己的路径) --enable-optimizations --disable-shared --with-ensurepip=yes
sudo make -j $(sysctl -n hw.ncpu)
sudo make install

现在修改optcode部分已经结束了,我们看看效果先,新建一个python文件;

for i in range(1,10):
print(i)

结果为:

接下来用我们自己编译的Python环境将main.py编译为main.pyc

python3 -m py_compile main.py

执行完成后,会在__pycache__目录生成main.pyc文件,运行后会显示上图一样的结果,这里我就不展示图片了;
但当我们使用正常的Python环境中去执行main.pyc,将会得到一个错误:

RuntimeError: Bad Magic number in .pyc file

这就代表着正常的Python环境已经不认识我们编译出来的pyc文件了,这就是修改opcode操作码后的效果,但这并不是最终效果,因为这种太容易破解了,只要拿到Python环境就能破解;

2、使用AES算法加密pyc代码

2.1、定义新的文件类型

我们先看一下pyc文件的结构,其中PyObject_VAR_HEAD占16个字节,只起到表明文件类型(MagicNumber就包含在其中)、编译时间以及一些校验,对实际的代码运行影响不大;

PYC文件结构体

在实际运行中这部分只是为了确认是不是一个合法的pyc,所以修改MagicNumber值,定义新的文件类型;将后面的所有字节加密,我采用的是变形的aes加密。最后将加密后的字节存入一个新的文件;pya;

文件:Lib -> importLib -> _bootstrap_external.py

2.2、添加新文件类型的解释函数

添加对pya文件解释函数,让其正确加载并解释运行;
1. maybe_pyc_file判断如果是pyc文件,执行下面的run_pyc_file来运行pyc文件。所以我们直接复制maybe_pyc_file,在下面新加一个maybe_pya_file;

文件:Python -> pythonrun.c -> maybe_pya_file

再在run_pyc_file下面加一个run_pya_file,函数的参数和返回值类型保持不变;(文件:Python -> pythonrun.c -> run_pya_file)

文件:Python -> pythonrun.c -> run_pya_file

在PyMarshal_ReadLastObjectFromFile下面加一个PyMarshal_ReadLastObjectFromPYAFile,这个函数才是解密函数;

文件:Python -> marshal.c -> PyMarshal_ReadLastObjectFromPYAFile

现在解密过程都已经添加完成,我们回到pythonrun.c文件函数_PyRun_SimpleFileObject中,增加对pya文件的判断;

文件:Python -> pythonrun.c -> _PyRun_SimpleFileObject

2.2、添加import时的解释函数

如果工程有多个py文件要相互import,那么就会直接报错,无法找到相应的模块,这是因为python解释器在import时还不能import pya文件;所以,还需要继续修改Import逻辑,增加到pya文件的解释;

文件:Lib -> importLib -> _bootstrap_externa.py -> SourcelessFileLoader

新增_classify_pya函数,这其实是仿照_classify_pyc写的,主要是在Import时验证pya文件的合法性;

文件:Lib -> importLib -> _bootstrap_external.py

到这里Python环境已经修改完毕,那就编译一个版本吧;

./configure --prefix=/user/jncoder/kk(修改为自己的路径) --enable-optimizations --disable-shared --with-ensurepip=yes
sudo make -j $(sysctl -n hw.ncpu)
sudo make install

创建加密工程

将Python编译出来的pyc文件通过AES算法加密,使其只能在我们修改过的Python环境中运行;

加密单个pyc文件

一般工程都会有多个py文件,所以这里还需要一个递归,使其将所有pyc文件都加密为pya文件;

递归整个项目

结束语

通过AES加密源代码、以及定制Python解释器,到这里就已经结束了;
如果仔细看文章的小伙伴应该知道,关于Python端AES加密、以及C语言端AES解密的代码我并没有贴出来,主要是篇幅太长的原因;

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。