当前位置: 首页 > news >正文

Python3代码工程化加密

这几天公司的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)

转载自http://blog.51cto.com/mapengfei/1976189













本文转自Grodd51CTO博客,原文链接:http://blog.51cto.com/juispan/2065568,如需转载请自行联系原作者

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Java基础 - 标识符
  • docker 创建容器 时的 注意事项
  • Color Challenge 隐私政策
  • rpm-yum-make
  • iOS对象属性详解
  • 匹配分词
  • NSNotificationCenter传值
  • [ NOI 2001 ] 食物链
  • tomcat8 安装部署--一键版本
  • 【SSH网上商城项目实战25】使用java email给用户发送邮件
  • extjs 之columntree 自定义分页工具条
  • javascript基础修炼(9)——MVVM中双向数据绑定的基本原理
  • python lambda的详细介绍
  • 字典变成有序字典
  • Vbs脚本编程简明教程之六
  • 【技术性】Search知识
  • CAP理论的例子讲解
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • LeetCode18.四数之和 JavaScript
  • maven工程打包jar以及java jar命令的classpath使用
  • PHP那些事儿
  • text-decoration与color属性
  • Transformer-XL: Unleashing the Potential of Attention Models
  • 关于字符编码你应该知道的事情
  • 解决iview多表头动态更改列元素发生的错误
  • 力扣(LeetCode)22
  • 漂亮刷新控件-iOS
  • 前端_面试
  • 前端攻城师
  • 试着探索高并发下的系统架构面貌
  • 我看到的前端
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 怎么将电脑中的声音录制成WAV格式
  • puppet连载22:define用法
  • ​linux启动进程的方式
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • ​必胜客礼品卡回收多少钱,回收平台哪家好
  • #vue3 实现前端下载excel文件模板功能
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (C++17) optional的使用
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (poj1.2.1)1970(筛选法模拟)
  • (Windows环境)FFMPEG编译,包含编译x264以及x265
  • (二十三)Flask之高频面试点
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (生成器)yield与(迭代器)generator
  • (一)Java算法:二分查找
  • (转)Linq学习笔记
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .NET MAUI Sqlite程序应用-数据库配置(一)