【Python源码保护】01 - pyobfuscate代码混淆

1.1 什么是代码混淆

代码混淆是指将代码进行加密、压缩、乱序等操作,使得代码难以被阅读和理解,从而达到保护代码的目的。代码混淆可以有效地防止代码被反编译和盗用,提高代码的安全性

严格意义上说,这一方法并不是加密,而是上代码的可读性变差。比如删除注释,添加毫无意义的注释,添加无效代码,对变量、函数、类进行重命名等。内容不可读,代码就受到了保护。代码混淆的工具很多,比如pyobfuscate。

1.2 pyobfuscate 安装使用

pyobfusate通过多种方式转换源代码。其中一些转换是可逆的,有些转换则是不可逆的。以下是pyobfuscate目前的作用列表:

  • 删除注释和文档字符串(不可逆)

  • 更改缩进(可逆)

  • 在标记之间添加空白(有些可逆)

  • 重命名函数、类和变量(不可逆)

  • 插入伪行而不是空行。

pyobfusate一次只对一个源文件进行操作,它没有混淆几个想文件之间的接口。

安装:

git clone https://github.com/astrand/pyobfuscate.git
cd pyobfuscate/
pip install .

执行代码混淆命令,将混淆后的结果重定向输出到指定文件:

python pyobfuscate.py [source.py] > [out.py]

pyobfuscate.py复制到python环境的Scripts,每次进行代码混淆,则进入该Scripts执行python pyobfuscate.py [source.py] > [out.py]

1.3 实践

代码混淆后会改变其中的函数名,引用到该代码的外部函数需要将其改为混淆之后的函数名。项目实践中,在变与不变之间构建一个桥梁,避免每次混淆代码后都要改变其引用的代码。

将函数名放到了字典中,该字典的key为字符串常量,不会被混淆,value存函数名,是会被混淆的。该字典在__init__.py包(package)中初始化,并由模块(module)中赋具体的函数名。执行代码混淆时,__init__.py混淆,而是混淆包内的模块,这样就能保证__init__.py中的字典记录的是字符串常量与最新函数名对应关系。

代码混淆前
请添加图片描述

目录结构如上所示,需要混淆的文件以包(package)的形式放到一个文件夹下。

main.py

if __name__ == '__main__':
    import my_package
    my_package.func_dict['hello']()
    my_package.func_dict['func_1']()
    my_package.func_dict['func_2']()

my_package/__init__.py

# 1. 先定义函数名字典func_dict
func_dict = {
    'hello': None,
    'func_1': None,
    'func_2': None,
}

# 2. 再通过 from import
# 将func_dict赋值为混淆后的函数名
from . import my_module_1
from . import my_module_2

my_package/my_module_1.py

from . import func_dict

def hello():
    print('hello')

def func_1():
    print('func_1')

func_dict['hello'] = hello
func_dict['func_1'] = func_1

my_package/my_module_2.py

from . import func_dict

def func_2():
    func_dict['hello']()
    print('func_2')

func_dict['func_2'] = func_2

代码混淆后

my_module_1.pymy_module_2.py混淆后置dist文件夹:

python pyobfuscate.py my_algorithm_1.py > dist\my_module_1.py
python pyobfuscate.py my_algorithm_2.py > dist\my_module_2.py

请添加图片描述

my_package/my_module_1.py

if 82 - 82: Iii1i
from . import func_dict
if 87 - 87: Ii % i1i1i1111I . Oo / OooOoo * I1Ii1I1 - I1I
if 81 - 81: i1 + ooOOO / oOo0O00 * i1iiIII111 * IiIIii11Ii
def OOoOoo000O00 ( ) :
 print ( 'hello' )
 if 55 - 55: o0Oo - ii1I1iII1I1I . i1I1IiIIiIi1 % oo0O000ooO * iIIiiIIiii1
 if 11 - 11: ooo0O0oO00
def o00o0OO00O ( ) :
 print ( 'func_1' )
 if 57 - 57: iiIi1 - ii % Ii * i1i1i1111I / Ii
 if 43 - 43: iIIiiIIiii1
func_dict [ 'hello' ] = OOoOoo000O00
func_dict [ 'func_1' ] = o00o0OO00O
# dd678faae9ac167bc83abf78e5cb2f3f0688d3a3

my_package/my_module_2.py

from . import func_dict
if 82 - 82: Iii1i
if 87 - 87: Ii % i1i1i1111I . Oo / OooOoo * I1Ii1I1 - I1I
def ooo0oOoooOOO0 ( ) :
 func_dict [ 'hello' ] ( )
 print ( 'func_2' )
 if 47 - 47: oO000o00o00o + II111i1I
 if 99 - 99: iIIii11
func_dict [ 'func_2' ] = ooo0oOoooOOO0
# dd678faae9ac167bc83abf78e5cb2f3f0688d3a3

总结:

使用代码混淆时,需要清楚哪些内容是可以混淆的(如变量名等),哪些是不会混淆的(字符串、import等),了解其中的变与不变能更好构建项目。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值