python程序商业化,代码安全最终方案,pyinstaller与cython打包python执行程序

news2024/11/24 6:50:19

其实一般的程序安全上只需要两步就行,没必要再加密改解释器等,已经不可能反编译到原有python了,因为动态链接库就是汇编了,中间经历了python转c,c在转动态库,代码已经没有可读性了。但是一些密码等重要字符还是要处理好,如分割存储密码,多次转换等。

(1)cython 编译为动态链接库(linux为so,windows为pyd)即可。

(2)然后再用pyinstaller与打包为exe,可以压缩一下,参考https://liuhuiyao.blog.csdn.net/article/details/81236642

过程

目录结构

main中import aaa, aaa中import bbb,bbb中 import n.ccc

先获取所有模块名,及模块路径

(也可以考虑合并为一个文件,但代码会作为一个字符串,汇编后不知会不会容易泄露)

获取所有依赖模块名可参考:https://liuhuiyao.blog.csdn.net/article/details/132920782

然后在引用上述代码,编写如下:

if __name__ == '__main__':
    mw=ModuleWriterGenerator()
    mw.generate_for_file("main.py")
    mnames = list()
    mpaths=list()
    mpaths2=list()
    pydRootPath="D:/hahah/test/"#生成的pyd文件根路径
    for name in mw._modules:
        mnames.append(name)
        path=mw._modules[name][0]
        if path:
            mpaths.append((pydRootPath+path.replace(".py",".cp311-win_amd64.pyd"),"."))
            mpaths2.append(path)
    print (mnames)#模块名,用于pyinstaller 打包exe中main.spec文件中的binaries属性
    print(mpaths) #pyd文件路径,用于pyinstaller 打包exe中main.spec文件中的hiddenimports属性
    print(mpaths2)#模块文件路径,可用于Cython转pyd

输出

['json', 'aaa', 'bbb', 'n', 'n.ccc']
[('D:/hahah/test/aaa.cp311-win_amd64.pyd', '.'), ('D:/hahah/test/bbb.cp311-win_amd64.pyd', '.'), ('D:/hahah/test/n/__init__.cp311-win_amd64.pyd', '.'), ('D:/hahah/test/n/ccc.cp311-win_amd64.pyd', '.')]
['aaa.py', 'bbb.py', 'n/__init__.py', 'n/ccc.py']

cython转为pyd

import Cython.Build
import distutils.core
def py_to_pyd(files:list):
    cpy = Cython.Build.cythonize(files)  # 返回distutils.extension.Extension对象列表

    distutils.core.setup(
        name='pyd的编译',  # 包名称
        version="1.0",  # 包版本号
        ext_modules=cpy,  # 扩展模块
        author="",  # 作者
        author_email=""  # 作者邮箱
    )
if __name__ == '__main__':
    files = ['aaa.py', 'bbb.py', 'n/__init__.py', 'n/ccc.py']  # 需要编译的文件
    py_to_pyd(files)

pyinstaller打包exe

打包前,先把py,pyc文件,删除或移动到其他目录,防止误打包进去暴漏代码。

pyinstaller -F main.py
执行上述,生成的程序可能无法运行,缺少各种模块或者动态库,需要编辑main.spec描述文件.

pyinstaller可以通过py文件import的方式引入pyd文件,但pyd文件中引入的其他包不会被打包到exe,需要手动指定把哪些pyd打包进去。

​​​​​​​改动main.spec文件

先执行完pyinstaller -F main.py命令,会生成一个main.spec文件,修改其中的两个属性如下:

动态库拷贝添加到下面数组中,第一个参数是源文件路径,第二个参数目标路径

binaries=[('D:/hahah/test/aaa.cp311-win_amd64.pyd', '.'), ('D:/hahah/test/bbb.cp311-win_amd64.pyd', '.'), ('D:/hahah/test/n/__init__.cp311-win_amd64.pyd', '.'), ('D:/hahah/test/n/ccc.cp311-win_amd64.pyd', '.')],


缺少的python模块添加到以下数组中,缺哪个补哪个(可以全写上,但把py,pyc文件先删除,防止打包进去暴漏代码)

hiddenimports=['json', 'aaa', 'bbb', 'n', 'n.ccc'],

修改完如下:只改了其中两行

# -*- mode: python ; coding: utf-8 -*-


block_cipher = None


a = Analysis(
    ['main.py'],
    pathex=[],
    binaries=[('D:/hahah/test/aaa.cp311-win_amd64.pyd', '.'), ('D:/hahah/test/bbb.cp311-win_amd64.pyd', '.'), ('D:/hahah/test/n/__init__.cp311-win_amd64.pyd', '.'), ('D:/hahah/test/n/ccc.cp311-win_amd64.pyd', '.')],
    datas=[],
    hiddenimports=['json', 'aaa', 'bbb', 'n', 'n.ccc'],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='main',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)


编辑完毕后执行如下命令生成程序

pyinstaller main.spec


运行main.exe ,确认没有问题

自己文章参考

https://blog.csdn.net/u013378306/article/details/132908028

https://liuhuiyao.blog.csdn.net/article/details/132920782

https://liuhuiyao.blog.csdn.net/article/details/132907302

https://liuhuiyao.blog.csdn.net/article/details/81236642

别人文章参考: 

Cython+Pyinstaller Python编译与打包-踩坑 - 知乎

pyinstaller与cython打包python执行程序_cython pyinstaller_telllong的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1015529.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

构建无限画布,协作数字绘图 | 开源日报 0915

tldraw/tldraw Stars: 16.4k License: Apache-2.0 tldraw 是一个协作数字白板项目,可在 tldraw.com 上使用。它的编辑器、用户界面和其他底层库都是开源的,并且可以通过 npm 进行分发。您可以使用 tldraw 为产品创建一个即插即用的白板,或者…

Smart Community(1)之设计规范

通过前面大数据开发相关知识的学习,准备做一个项目进行练习---我给他起了一个响亮的名字:基于HadoopHA的智慧社区服务平台 设计规范: 做一个项目之前肯定要先规定一些开发过程中的设计规范 (一)数据埋点规范&#xf…

Python中异常处理4-4

在Python中的异常处理4-1_棉猴的博客-CSDN博客中提到,在try块中的代码运行时如果出现异常,会自动抛出这个异常。可以通过raise语句手动抛出异常。 1 raise语句手动抛出异常 raise后面跟要抛出的异常类或者异常类的实例,表示手动抛出该异常&…

位图+布隆过滤器+海量数据并查集(它们都是哈希的应用)

一)位图: 首先计算一下存储一下10亿个整形数据,需要多大内存呢,多少个G呢? 2^3010亿,10亿个字节 byte kb mb gb 100000000个字节/1024/1024/10241G 所以10亿个字节就是1G,所以40亿个字节就是4G,也就是10个整…

电脑重装系统之后设置

edge一直处于正在同步设置关闭系统自动更新更改默认安装路径 edge一直处于正在同步设置 解决办法:卸载重新安装 用电脑管家16可以卸载 电脑管家16 链接:https://pan.baidu.com/s/1f5T4uXrumL8Fne9hyvTHcg?pwd0122 提取码:0122 edge 链接&am…

Go Moonbeam:Ai智能写作助手

【产品介绍】 • 名称 Go Moonbeam • 具体描述 Moonbeam是一个人工智能驱动的长篇写作助手。你可以用它创建散文,故事,文章,博客,和其他长形式的内容,可以轻松的将混乱的笔记转换为大纲。同时它…

对象创建和内存分配

对象创建和内存分配 Java中类创建是在平常不过的操作了,但是一个类的创建到底经历 了哪些过程呢? 对象创建 创建方法 使用关键字new一个对象 使用反射机制 User user (User)Class.forName("xxx.xxx.User").newInstance(); User user Us…

Linux开发工具之编译器gcc/g++

gcc/g是编译代码的,gcc/g都可以编译c语言的代码,但是c的代码只能用g来编译 在linux中,只要我们对源文件用gcc/g进行编译,就会生成一个可执行程序a.out,然后我们执行该程序就可得到结果了,下面来细看一下gcc…

深入了解==和equals的区别

1. 浅说和equals的区别 (1)比较的类型 不一样 可以比较基础数据类型和引用类型,比较基础数据类型的数据时比较的是值,比较引用对象时比较的是引用的地址。 equals比较引用类型,默认比较的是两个引用对象的引用地址&a…

Acwing 3302. 表达式求值

Acwing 3302. 表达式求值 题目描述思路讲解代码展示 题目描述 思路讲解 代码展示 #include <iostream> #include <cstring> #include <algorithm> #include <stack> #include <unordered_map>using namespace std;stack<int> num; stack…

redis链接阻塞,导致程序没有响应

目录 一、场景二、原因三、排查1、使用 info client 命令查看redis链接统计情况2、使用 client list 命令查看redis链接信息3、关闭程序&#xff0c;看阻塞的链接是否有所减少4、排查使用 blpop 命令的相关代码 四、解决 一、场景 1、程序在运行一段时间后&#xff0c;会出现没…

【分布式】分布式ID

目录 前言一、雪花算法snowflake1. 组成2. 优缺点3. 时钟回拨怎么解决a. 时钟回拨b. 解决方案 4. 项目中如何使用 二、基于Redis三、基于Zookeeper四、号段模式五、指定步长的自增ID六、UUID参考 六、扩展总结 前言 分布式场景下&#xff0c;一张表可能分散到多个数据结点上。因…

【数据结构】C++实现二叉搜索树

二叉搜索树的概念 二叉搜索树又称为二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树&#xff1a; 若它的左子树不为空&#xff0c;则左子树上所有结点的值都小于根结点的值。若它的右子树不为空&#xff0c;则右子树上所有结点的值都大于根结…

问道管理:注册制对涨幅的限制?

注册制作为中国证券商场变革的重中之重&#xff0c;其本质是将发行商场转移到审阅商场&#xff0c;实现商场准入的有效管控。与此同时&#xff0c;注册制关于股票商场的涨幅也有必定的约束。 首先&#xff0c;注册制能够经过严厉的审阅来制约公司发行股票的数量和节奏。传统IP…

Linux 多线程( 进程VS线程 | 线程控制 )

文章目录 Linux进程 VS 线程进程的多个线程共享 进程和线程的关系线程创建 pthread_create获取线程ID pthread_self线程等待 pthread_join终止线程进程分离线程ID及进程地址空间布局 Linux进程 VS 线程 进程是资源分配的基本单位。线程是OS调度的基本单位。 线程共享进程数据…

Michael.W基于Foundry精读Openzeppelin第34期——MerkleProof.sol

Michael.W基于Foundry精读Openzeppelin第34期——MerkleProof.sol 0. 版本0.1 MerkleProof.sol 1. 目标合约2. 代码精读2.1 processProof(bytes32[] memory proof, bytes32 leaf) && processProofCalldata(bytes32[] calldata proof, bytes32 leaf)2.2 verify(bytes32[…

图像处理之频域滤波DFT

摘要&#xff1a;傅里叶变换可以将任何满足相应数学条件的信号转换为不同系数的简单正弦和余弦函数的和。图像信号也是一种信号&#xff0c;只不过是二维离散信号&#xff0c;通过傅里叶变换对图像进行变换可以图像存空域转换为频域进行更多的处理。本文主要简要描述傅里叶变换…

Heap及其应用

目录 堆的相关知识 什么是堆&#xff1f; 堆的性质&#xff1a; 堆的实现&#xff1a; 堆的结构&#xff1a; &#xff08;一&#xff09;堆的插入 向上调整法&#xff1a; 寻找父节点 循环结束条件 代码&#xff1a; &#xff08;二&#xff09;堆的删除 删除根节点…

Huggingface:免费开源AI人工智能API工具平台

| 【产品介绍】 • 名称 Huggingface • 成立/上线时间 2016年 • 具体描述 HuggingFace是一个开源的自然语言处理AI工具平台&#xff0c;它为NLP的开发者和研究者提供了一个简单、快速、高效、可靠的解决方案&#xff0c;让NLP变得更加简…

R绘制箱线图

代码大部分来自boxplot()函数的帮助文件&#xff0c;可以通过阅读帮助文件&#xff0c;调整代码中相应参数看下效果&#xff0c;进而可以理解相应的作用&#xff0c;帮助快速掌握barplot()函数的用法。 语法 Usage(来自帮助文件) barplot(height, ...)## Default S3 method: …