Python代码由于是解释性语言,常规的操作很容易被恢复出来原始的python代码。所以我们要通过解释器实际执行代码时候的操作,从C语言、IR、汇编的层面去对python代码进行防逆向保护。
环境:
OS :Windows 10 1709
Python:Python 3.8.6
Cython:Cython version 0.29.22
Visual Studio: VS2019
理论来说,肯定保护所有的程序代码是可行的,不过我们往往只希望保护一些比较核心的代码算法,例如一些比较私密核心的算法。本示例将展示将一个py文件先转换为c,在转换为pyd文件的过程。(pyd可以理解为是Windows当中的dll,在其他的python文件当中直接import就可以使用其中的函数。)
首先编写一个示例py文件
# cython: language_level=3
import hashlib
import numpy as np
def func(a):
if isinstance(a, np.ndarray):
b = a[0]
return hashlib.new('md5', str(b).encode()).hexdigest()
return "0"*32
注意这里的第一行注释,是为了让cython生成的c文件是针对python3的,没有这个会默认生成python2的代码,就会导致报错。
测试之后功能完好。
安装cython
pip install cython
编写操作cython的脚本,命名为compile.py。注意指定的代码文件的文件名不能有下划线!
import setuptools
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [
Extension("introducer", ["introducer.py"]),
]
setup(
name = 'MyProgram',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
注:如果出现error: Unable to find vcvarsall.bat错误,是因为
setup.py
第1行缺失语句import setuptools
运行之后就可以将py先变成c,再调用Visual Studio中的x64 cl.exe, link.exe进行编译链接,生成pyd文件。
python .\compile.py build_ext --inplace
之后就可以正常调用pyd了
基于上面的工作,我们已经可以实现较好的代码保护情况,不过有些时候,我们还想对pyd当中的代码进一步混淆加固,我们可以采用LLVM来对Visual Studio的编译程序进行替换。通过引入O-LLVM技术能够将代码控制流平坦化,使得代码抗逆向难度大大提升。
o-llvm实际上只是一个llvm的pass,对llvm-IR进行操作。o-llvm可选的特性:
-mllvm -fla:控制流扁平化
-mllvm -sub:指令替换
-mllvm -bcf:虚假控制流程
有人又进行了移植,如果你用的移植版本,还有字符串加密:
-mllvm -sobf
具体可以参考这个:
Windows(VisualStudio)使用LLVM(ollvm) 编译混淆加固保护项目 - 简书
之后再重新运行compile.py即可。