如何保护python脚本?
几年前,当我准备发布我的第一个python应用程序时,我不得不面对一个问题:如何混淆python脚本,以便没有清晰的代码显示给我的客户?现在我有了一个解决方案 构建模糊脚本 首先将Python脚本编译为代码对象如何保护python脚本?,python,Python,几年前,当我准备发布我的第一个python应用程序时,我不得不面对一个问题:如何混淆python脚本,以便没有清晰的代码显示给我的客户?现在我有了一个解决方案 构建模糊脚本 首先将Python脚本编译为代码对象 char *filename = "foo.py"; char *source = read_file( filename ); PyCodeObject *co = Py_CompileString( source, "<frozen foo>", Py_file_inpu
char *filename = "foo.py";
char *source = read_file( filename );
PyCodeObject *co = Py_CompileString( source, "<frozen foo>", Py_file_input );
更改了原始字节码:
Increase oparg of each absolute jump instruction by the size of wrap header
Obfuscate original byte code
...
换行页脚:
LOAD_GLOBALS N + 1 (__armor_exit__)
CALL_FUNCTION 0
POP_TOP
END_FINALLY
\uuuuuu armor\u enter
,\uuuuuu armor\u exit\uuuuuuuuu
附加到co\u consts
co_stacksize
增加2CO\u标志中设置CO\u模糊(0x8000000)标志
co_consts
中的所有代码对象char*string\u code=marshal.dumps(co);
char*obfuscated_code=模糊_算法(字符串_code);
最后生成模糊脚本
sprintf(buf,“\uuuu-pyarmor\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;
保存文件(“dist/foo.py”,buf);
模糊化脚本是一个普通的Python脚本,看起来像这样
__pyarmor__(__name__, __file__, b'\x01\x0a...')
运行模糊脚本
为了通过公共Python解释器运行模糊的脚本dist/foo.py
,
有3个功能需要添加到模块内置:\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,uuuuuuuuuuuuuuuuuuuuuuuuu
- 首先将调用
\uuuuuuuuuuuuuuuuuuuuuu
,它将从混淆的代码中导入原始模块
static PyObject*
__pyarmor(字符*名称,字符*路径名,无符号字符*模糊代码)
{
char*string\u code=恢复\u模糊化\u代码(模糊化\u代码);
PyCodeObject*co=marshal.loads(字符串\u代码);
返回PyImport\u ExecCodeModuleEx(名称、co、路径名);
}
- 执行代码对象后,将立即调用
\uuuuuuu\uuuu\uuuuu\uuuuu
static PyObject*
__装甲输入(PyObject*self,PyObject*args)
{
//获取代码对象
PyFrameObject*frame=PyEval_GetFrame();
PyCodeObject*f_code=frame->f_code;
//增加此代码对象的引用调用
//借用公司名称->作为呼叫计数器的ob\U refcnt
//一般来说,Python解释器不会增加它
PyObject*refcalls=f_code->co_name;
refcalls->ob_refcnt++;
//如果字节码被混淆,则还原它
如果(模糊化了(f_代码->co_标志)){
恢复字节码(f码->co码);
清除模糊标志(f代码);
}
Py_返回_无;
}
- 只要代码对象完成执行,就会调用
\uuuuuuuuu\uuuuuuuu\uuuuuuuuuu\uuuuuuuuuu
static PyObject*
__装甲\u退出\u(PyObject*self,PyObject*args)
{
//获取代码对象
PyFrameObject*frame=PyEval_GetFrame();
PyCodeObject*f_code=frame->f_code;
//减少此代码对象的引用调用
PyObject*refcalls=f_code->co_name;
refcalls->ob_refcnt--;
//仅当任何函数未使用此代码对象时,才模糊字节代码
//在多线程或递归调用中,可以引用一个代码对象
//由多个功能同时执行
if(refcalls->ob_refcnt==1){
混淆字节码(f码->co码);
设置模糊标志(f代码);
}
//清除此帧中的f_局部变量
清除\u帧\u局部变量(帧);
Py_返回_无;
}
有兴趣吗?访问其他问题的答案都很旧:因此这里需要更新。
__pyarmor__(__name__, __file__, b'\x01\x0a...')