为了账号安全,请及时绑定邮箱和手机立即绑定

Python3代码工程化加密

标签:
Python


这几天公司的Python3需要加密,网上的文章要么提供思路不提供代码,要么加密之后自己都没法用了。。没办法只能自己写了

文章整体思路

   1、修改python源码opcode为随机值

   修改下载后的Python源码包中opcode值(opcode可以理解为python读取代码的坐标,比如一个变量的opcode是5,则cpython读取这个变量时是从第5个字符串开始读的),修改后会导致关键变量的opcode混乱,除了自己的环境外,其他人都执行和解密不了了

   2、在修改好opcode的python环境,把所有py文件编译成pyc,然后删除原始py文件

修改opcode的脚本:

#!/usr/bin/env python2.7 # encoding:utf-8 #FileName scramble-opcodes.py __author__ = 'mafei' import argparse import re import random import os python_version = 'Python-3.5.3' regex_for_opcode_h = r'^#define\s+(?P<name>[A-Z_]+)\s+(?P<code>\d+)(?P<extra>.*)' regex_for_opcode_py = r'^(?P<key>[a-z_]+)+\(\'+(?P<name>[A-Z_]+)+\'+\,\s+(?P<code>\d+)(?P<extra>.*)'   try:     from importlib.machinery import SourceFileLoader except ImportError:     import imp           class replace_opcode(object):          def __init__(self):         self.replace_dict = {}         self.not_have_argument_code_list = []         self.have_argument_code_list = []          def set_list(self, reg, file):         f1 = open(file, 'r+')         infos = f1.readlines()         f1.seek(0, 0)         for line in infos:             rex = re.compile(reg).match(line)             if rex:                 if rex.group('name') in ['CALL_FUNCTION', 'CALL_FUNCTION_KW', 'CALL_FUNCTION_EX', 'CALL_FUNCTION_VAR',                                          'CALL_FUNCTION_VAR_KW']:                     continue                 elif int(rex.group('code')) < 90:                     self.not_have_argument_code_list.append(int(rex.group('code')))                 else:                     self.have_argument_code_list.append(int(rex.group('code')))          def replace_file(self, reg, file, is_update=False):         if not is_update:             self.set_list(reg, file)         f1 = open(file, 'r+')         infos = f1.readlines()         f1.seek(0, 0)         for line in infos:             rex = re.compile(reg).match(line)             if rex:                 n = self.replace_code(rex, is_update)                 line = line.replace(rex.group('code'), str(n))             f1.write(line)         f1.close()              def replace_code(self, rex, is_update):         if is_update:             try:                 n = self.replace_dict[rex.group('name')]             except:                 n = rex.group('code')             return n         if rex.group('name') == "CALL_FUNCTION":             n = int(rex.group('code'))         elif rex.group('name') in ['CALL_FUNCTION_KW', 'CALL_FUNCTION_EX', 'CALL_FUNCTION_VAR',                                    'CALL_FUNCTION_VAR_KW']:             n = int(rex.group('code'))         else:             if int(rex.group('code')) < 90:                 n = random.choice(self.not_have_argument_code_list)                 self.not_have_argument_code_list.remove(n)             else:                 n = random.choice(self.have_argument_code_list)                 self.have_argument_code_list.remove(n)         self.replace_dict[rex.group('name')] = n         return n              def run(self, source_directory):         OPCODE_PY = 'Lib/opcode.py'         OPTARGETS_H = "Include/opcode.h"         print source_directory         print('start run......', os.path.join(source_directory, OPCODE_PY))         self.replace_file(reg=regex_for_opcode_py, file=os.path.join(source_directory, OPCODE_PY))         print('run {} end'.format(os.path.join(source_directory, OPCODE_PY)))         print('start run......', os.path.join(source_directory, OPCODE_PY))         self.replace_file(reg=regex_for_opcode_h, file=os.path.join(source_directory, OPTARGETS_H), is_update=True)         print('run {} end'.format(os.path.join(source_directory, OPTARGETS_H)))         self.write_opcode_targets_contents()         print('run {} end'.format(os.path.join(source_directory, OPTARGETS_H)))          def write_opcode_targets_contents(self, file='Python/opcode_targets.h'):         """Write C code contents to the target file object.         """         targets = ['_unknown_opcode'] * 256         for opname, op in sorted(self.replace_dict.items(), key=lambda nc: nc[1]):             targets[op] = "TARGET_%s" % opname         with open(os.path.join(source_directory, file), 'w') as f:             f.write("static void *opcode_targets[256] = {\n")             sep = ',%s' % os.linesep             f.write(sep.join(["    &&%s" % s for s in targets]))             f.write("\n};\n")                           if __name__ == '__main__':     parser = argparse.ArgumentParser(description='Scramble python opcodes table')     parser.add_argument('--python-source', dest='src', type=str,                         help='Python source code', required=True)     args = parser.parse_args()     source_directory = os.path.abspath(args.src)     # main(source_directory)     replace_opcode_class = replace_opcode()     replace_opcode_class.run(source_directory)

cd /opt/ 下载源码包 wget  解压   tar xJf Python-3.5.3.tar.xz

执行修改opcode操作

python scramble-opcodes.py --python-source=/opt/Python-3.5.3

#后面几步就是标准的python安装步骤啦

cd /opt/Python-3.5.3 

./configure --prefix=/opt/python-3.5.3 && make && make install

加入系统路径

export PATH=/opt/python-3.5.3/bin/:$PATH  这时候执行python3就可以进入python3.5.3的修改opcode后的环境了

加密Python代码(一定要在修改过opcode的Python环境执行,否则不生效的)

#!/usr/bin/env python2.7 # encoding:utf-8 __author__ = 'mafei' import os import subprocess import argparse import sys def compile_py3(source_dir):     g = os.walk(source_dir)     # compileall.compile_dir(source_dir, maxlevels=100)     subprocess.check_output('{} -m compileall -b {}'.format(sys.executable,source_dir),shell=True)     for path,d,filelist in g:         for filename in filelist:             #对所有py文件进行加密并删除原始文件             if os.path.splitext(filename)[-1] =='.py':                 os.remove(os.path.join(path, filename))                 print('compile {}'.format(os.path.join(path, filename))) if __name__ == '__main__':     parser = argparse.ArgumentParser(description='Scramble python opcodes table')     parser.add_argument('--python-source', dest='src', type=str,                         help='Python source code', required=True)     args = parser.parse_args()     source_directory = os.path.abspath(args.src)     compile_py3(source_directory)

©著作权归作者所有:来自51CTO博客作者马鹏飞的原创作品,如需转载,请注明出处,否则将追究法律责任


点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消