Cómo cifrar el código de Python
fondo
Python es un lenguaje interpretado. No hay un proceso de compilación. Al publicar un programa, es equivalente a revelar el código fuente. Esto también es una característica de él como lenguaje de código abierto. Pero en algunos escenarios, no queremos que otros vean nuestro código fuente, como el desarrollo de software comercial.
Cifrado
Enlace de referencia:
Cómo encriptar el código de Python
Ofuscación y encriptación del código fuente de Python
1, ofuscación de código
2, liberar el archivo .pyc
3, usar py2exe, pyinstaller para empaquetar como archivo exe
4, usar PyArmor para encriptar el script
5, usar pyconcrete para encriptar a pye archivo
6, use Cython para generar archivos py como archivos cifrados pyd
Proceso de compilación y descompilación
Este artículo adopta el sexto método, que consiste en utilizar Cython para generar archivos py en archivos cifrados pyd.
En circunstancias normales:
los archivos py se compilan en el proceso de archivos exe py—>(paquete pyinstaller)----> proceso de descompilación
de archivos exe archivo— >(paquete pyinstxttractor)—>archivo pyc—>(paquete uncompyle6)---->código fuente py
En el caso del cifrado,
el archivo py se compila en un proceso de archivo exe
py—>(Cypthon)—>archivo c y archivo pyd–>(paquete pyinstaller)---->
archivo exe.El archivo pyd generado en el medio es dificil de descompilar
Herramientas utilizadas en este artículo
python 3.8.5
pycharm
visual studio 2022 (requiere compilador C)
pyinstaller 5.1
Cython 0.29.30
pyinstxttractor.py https://sourceforge.net/projects/pyinstallerextractor/
python3 empaquetado como archivo exe
Aquí hay un archivo Hello.py.
El contenido del archivo Hello.py es el siguiente:
from tkinter import *
# 这是一段TK测试代码
class ChangeLabelDemo:
def __init__(self):
window = Tk()
window.title = "改变labeldemo" #窗口标题
frame1 = Frame(window)
frame1.pack()
self.lb1 = Label(frame1, text="Programming is fun")
self.lb1.pack()
frame2 = Frame(window)
frame2.pack()
label = Label(frame2, text="输入")
self.msg = StringVar()
entry = Entry(frame2, textvariable=self.msg)
btChangeText = Button(frame2, text="改变text", command=self.processButton)
self.v1 = StringVar()
rbRed = Radiobutton(frame2, text="Red", bg="red", variable=self.v1, value="R", command=self.processRadiobutton)
rbYellow = Radiobutton(frame2, text="Yellow", bg="yellow", variable=self.v1, value="Y",
command=self.processRadiobutton)
label.grid(row=1, column=1)
entry.grid(row=1, column=2)
btChangeText.grid(row=1, column=3)
rbRed.grid(row=1, column=4)
rbYellow.grid(row=1, column=5)
window.mainloop()
def processButton(self):
self.lb1["text"] = self.msg.get()
def processRadiobutton(self):
if self.v1.get() == "R":
self.lb1["fg"] = "red"
elif self.v1.get() == "Y":
self.lb1["fg"] = "yellow"
ChangeLabelDemo()
Paso 1: Instale el paquete pyinstaller
pip install pyinstaller
paso 2: ingrese la ruta del archivo actual en cmd
cd E:\研究生\pytorch\untitled\encypt
Paso 3: empaquete y genere el archivo exe, use el siguiente comando para empaquetarlo en un solo exe (elimine -F, no será un solo exe, -w no generará una ventana de ventana)
pyinstaller -F -w Hello.py
Se generan tres archivos build, dist y Hello.spec
El archivo exe está en la carpeta dist, haga doble clic para ejecutarlo
Python3 descompila archivos exe en código fuente
Herramienta de descompilación exe: pyinstxttractor.py descarga: https://sourceforge.net/projects/pyinstallerextractor/
Coloque pyinstxttractor.py en el mismo directorio que el archivo exe
y ejecute el siguiente comando cmd, primero ingrese a la carpeta dist
cd dist
A continuación, ejecute el siguiente comando en cmd
python pyinstxtractor.py Hello.exe
Descomprima correctamente (descompile) y hay más Hello.exe_extracted
carpetas
Ingrese Hello.exe_extracted
a la carpeta, hay un archivo Hello, este es el archivo pyc descomprimido, debe pasar
A continuación, intente Hello
descompilar el archivo
Primero instale el uncompyle6
paquete de descompilación
pip install uncompyle6
Luego ingrese a la carpeta donde se encuentra el exe
cd Hello.exe_extracted
Debe Hello
agregar un sufijo al archivo .pyc
, de lo contrario no se puede compilar. Ejecute el siguiente código para descompilar Hello.pyc
el archivo
uncompyle6 Hello.pyc
el resultado es un error
Unknown magic number 227 in Hello.pyc
Motivo del error :
el aviso es que Unknown magic number 227
esta falla se debe a que pyinstaller
cuando se empaqueta la herramienta, el archivo de código magic number
(versión de Python y tiempo de compilación) se borrará, por lo que al descompilar, debe magic numbe
agregar r nuevamente para reconocerlo. magic number
Podemos descomprimirlo en el directorio principal Extráigalo struct
del archivo (generalmente los primeros 16 bytes, que se pueden comparar con el archivo fuente antes de empaquetar), extraiga los struct
primeros 16 bytes en el cuerpo del archivo, agréguelo al archivo y luego realice uncompyle6
la descompilación.
Solución de error : Cómo descompilar EXE con Python3
Primero veamos struct
el contenido del archivo, preste atención a la primera línea, esta es la información que falta. La segunda línea comienza con E3.
A continuación, mire Hello
el contenido del archivo (no es un archivo pyc, por lo que debe eliminar el sufijo pyc y luego abrirlo con vs, pycharm y el bloc de notas lo abrirá con caracteres ilegibles), se puede ver E3
que struct
.
Lo siguiente que debe hacer es agregar los que faltan magic number
al archivo pyc
ejecuta el siguiente código en pycharm
# import py_compile
# import Hello
# Compile.compile('Hello.py')
# import Hello
# Hello()
struct_path = r"E:\研究生\pytorch\untitled\encypt\dist\Hello.exe_extracted/struct"
fn = open(struct_path, 'rb')
print(fn.seek(0)) # 切换指针位置到开头
magic_number = fn.read(16) # 读取文件的前16个字节,从0开始
print(magic_number)
point_number = fn.tell() # 获取当前指针位置
print(point_number) # 获取当前指针位置
print(fn.read(1)) # 再读取第17个字节,输出值是e3
add_magic_num_file_name = r"E:\研究生\pytorch\untitled\encypt\dist\Hello.exe_extracted/Hello.pyc"
MAGIC_NUMBER = b'U\r\r\n\x00\x00\x00\x00\xac\x95\x15_\x01\x01\x00\x00'
f = open(add_magic_num_file_name, 'rb')
new_content = f.read()
new_add_magic_number_file_name = r"E:\研究生\pytorch\untitled\encypt\dist\Hello.exe_extracted/Hello.pyc"
n_f = open(new_add_magic_number_file_name, "wb")
n_f.write(MAGIC_NUMBER + new_content)
f.close()
n_f.close()
output>>>
0
b'U\r\r\n\x00\x00\x00\x00\xac\x95\x15_\x01\x01\x00\x00'
16
b'\xe3'
En este momento, use vs para abrir Hello
el archivo nuevamente. Listo, ahora puedes usar uncompyle6
la descompilación
para ejecutar el siguiente código en cmd
uncompyle6 Hello.pyc
Se puede ver que el código fuente del exe está descompilado, por lo que si es un producto desarrollado por la empresa, se debe considerar su seguridad.
Nota:
1. Si el comentario existe en chino, se analizará en codificación Unicode, que se puede convertir con la herramienta correspondiente.
2. El archivo del programa principal se descompila . De hecho, todos los archivos pyc en la carpeta Hello
deben descompilarse . compilar 3. El número de bytes faltantes del archivo pyc de la biblioteca dependiente en el directorio PYZ-00.pyz_extracted es diferente al del programa principal. Tenga en cuenta que el número de bytes faltantes del archivo pyc de la biblioteca dependiente en el directorio PYZ El directorio -00.pyz_extracted es diferente al del programa principal. 4. Consulte aquí el tutorial de descompilación por lotes de los archivos pyc de la biblioteca dependientePYZ-00.pyz_extracted
uncompyle6
Compile archivos py a archivos pyd para evitar la descompilación
Compile el archivo py en una biblioteca de enlaces dinámicos, lo que aumentará en gran medida la dificultad de craqueo. Entre ellos, en python, el formato pyd es la biblioteca de enlaces dinámicos. Use cython para compilarlo en un archivo pyd.
Primero instale cpython
pip install Cython
Hello.py
Cree un nuevo archivo .py en el archivo y asígnele el nombre setup.py
, su contenido es:
# -*- coding: utf-8 -*-
"""
Created on Friday July 1 16:40:20 2022
@author: Li Zhengping
link:
https://www.jb51.net/article/178209.html
https://blog.csdn.net/ZhaDeNianQu/article/details/87717293
"""
from distutils.core import setup
from Cython.Build import cythonize
setup(name = 'any words.....', ext_modules = cythonize(["Hello.py",]))
Luego ejecute el siguiente comando en cmd
cd E:\研究生\pytorch\untitled\encypt
python setup.py build_ext --inplace
Nota: Se requiere el entorno de VC relevante para la compilación. Instalé la versión VS22 y no se puede compilar sin instalación.
El proceso en ejecución y los resultados generados se muestran en la siguiente figura, donde se compila el archivo pyd en el cuadro rojo. Debido a que tengo un sistema de 64 bits y python, se generará el sufijo amd64, por lo que podemos eliminarlo y cambiarle el nombre Hello.pyd
.
Nota: Cuando mylib.pyd y mylib.py existen al mismo tiempo, la prioridad de importación es pyd>py, por lo que no es necesario eliminar el archivo py y la importación predeterminada es pyd.
En este punto, eliminamos la carpeta de compilación
y la compilamos nuevamente en exe.
Ejecute el siguiente código en cmd
pyinstaller -F -w Hello.py
El archivo compilado
también almacena el archivo exe en la carpeta dist
Puede verificarlo: después de descompilar main.exe nuevamente,
primero ingrese la ruta dist
cd dist
Tenga en cuenta que el archivo pyinstxttractor.py debe colocarse en el archivo con la misma ruta que el exe
y luego ejecutar
python pyinstxtractor.py Hello.exe
El resultado sigue siendo el archivo Hello.pyc en lugar del archivo Hello.pyd, es decir, el archivo Hello.py se empaqueta en lugar del archivo Hello.pyd, por lo que la operación aún se puede descompilar.
A continuación, busqué cómo empaquetar archivos pyd y encontré el siguiente blog: Python .py genera archivos .pyd y empaqueta .exe Notas
Primero, debe crear un archivo main.py, que se utiliza como un programa de entrada para importar el archivo pyd. La prioridad predeterminada del archivo pyd es más alta que la del archivo py, por lo que Hello.py y Hello.pyd pueden existen al mismo tiempo, lo que significa que no es necesario eliminar Hello.py.
main.py
El contenido es el siguiente
from tkinter import *
import Hello
if __name__ == '__main__':
Hello.ChangeLabelDemo()
Nota:
1. __main__
Solo puede haber una entrada del programa. Si la entrada principal está definida en el archivo py de origen, debe comentarse y ajustarse la sangría del código. De lo contrario, el código después de llamar al archivo pyd a través de main if name == ‘main’
. py no se ejecutará.
2. Hello.py
Todas las bibliotecas de terceros importadas en el encabezado del archivo de origen deben copiarse en main.py
el encabezado del archivo; de lo contrario, la operación se bloqueará.
Luego ingrese en cmd
pyinstaller -F -w main.py
A continuación, verifiquémoslo con pyinstxtractor.py
el archivo desempaquetado e ingresemos la línea de comando a su vez (recuerde copiar primero pyinstxttractor.py a la carpeta actual):main.exe
cd dist
python pyinstxtractor.py main.exe
Se obtendrá una main.exe_extracted
carpeta y se encontrarán archivos debajo de la carpeta Hello.pyd
en lugar de Hello.py
archivos, lo que indica que el paquete se empaquetó correctamente al hacer referencia al archivo pyd. Los archivos pyd son difíciles de descompilar, por lo que el código fuente puede estar bien protegido.
Hecho
Link de referencia
Empaquetado como exe por pyinstaller:
1. Mejora de pyinstxttractor.py: una herramienta para descompilar pyinstaller para generar exe
2. pyinstaller empaqueta el proyecto escrito por pyqt5 en exe (ejecutable sin el entorno)
3. Descompile el archivo EXE generado por python para convertir
py El archivo se genera como un archivo pyd para la descompilación:
4. Cómo descompilar (descifrar el código fuente) y evitar la descompilación después de que PyInstaller empaqueta el archivo Python en un archivo exe
5. PyInstxttractor + Uncompale
empaqueta el archivo pyd en un archivo exe:
6 .Python .py genera archivos .pyd y empaqueta consideraciones .exe
Bienvenido a prestar atención a mi cuenta pública "Diagnóstico de fallas y aprendizaje de Python"