我正在用Python开发一款软件,它将分发给我雇主的客户。我的雇主想用一个有时间限制的许可证文件来限制软件的使用。

如果我们分发.py文件甚至.pyc文件,将很容易(反编译和)删除检查许可证文件的代码。

另一个方面是,我的雇主不希望我们的客户读到代码,担心代码可能被窃取,或者至少是“新颖的想法”。

有什么好办法来解决这个问题吗?


当前回答

在某些情况下,可以将软件(全部或至少关键部分)移动到组织托管的web服务中。

这样,许可证检查就可以在您自己的服务器机房的安全环境中执行。

其他回答

可以将py2exe字节码放在C启动器的加密资源中,在内存中加载并执行它。这里和这里有一些想法。

有些人还想到了一种自我修改程序,使逆向工程变得昂贵。

您还可以找到防止调试器、使反汇编程序失败、设置错误调试器断点和使用校验和保护代码的教程。搜索[" crypded code" execute "in memory"]以获得更多链接。

但正如其他人所说,如果你的代码值得,逆向工程师最终会成功。

取决于客户是谁,一个简单的保护机制,结合合理的许可协议将比任何复杂的许可/加密/混淆系统更有效。

最好的解决方案是将代码作为服务出售,比如托管服务,或者提供支持——尽管这并不总是可行的。

以.pyc文件的形式发布代码可以防止你的保护被一些#所破坏,但这几乎不是有效的反盗版保护(就像有这样的技术一样),而且归根结底,它不应该达到任何与公司签订像样的许可协议所能达到的效果。

专注于让你的代码尽可能好用——拥有满意的客户会让你的公司赚更多的钱,而不是防止一些理论上的盗版。

在某些情况下,可以将软件(全部或至少关键部分)移动到组织托管的web服务中。

这样,许可证检查就可以在您自己的服务器机房的安全环境中执行。

在我自己的项目中,我对软件保护进行了一般的研究,总的观点是完全的保护是不可能的。您唯一希望实现的事情是将保护添加到一个级别,使您的客户绕过该级别的成本高于购买另一个许可证的成本。

话虽如此,我只是检查谷歌的python混淆,没有发现很多东西。在. net解决方案中,混淆将是在windows平台上解决问题的第一种方法,但我不确定是否有人在Linux上有与Mono一起工作的解决方案。

接下来要做的就是用编译语言写代码,如果你真的想这么做,那就用汇编语言。一个被剥离的可执行文件将比解释语言更难反编译。

这一切都归结于权衡。一方面,你可以用python轻松地进行软件开发,在python中也很难隐藏秘密。另一方面,你用汇编程序编写的软件更难编写,但更容易隐藏秘密。

你的老板必须在这个连续统一体中选择一个点来支持他的要求。然后他必须给你工具和时间,这样你才能建造他想要的东西。然而,我敢打赌,他会反对实际开发成本与潜在货币损失之间的对立。

用同样的方法保护c/c++的二进制文件,即对可执行文件或库二进制文件中的每个函数体进行混淆,在每个函数项的开头插入指令“跳转”,跳转到特定的函数来恢复混淆的代码。字节码是Python脚本的二进制代码,所以

首先编译python脚本代码对象 然后迭代每个代码对象,将每个代码对象的co_code混淆如下所示

    0   JUMP_ABSOLUTE            n = 3 + len(bytecode)

    3
    ...
    ... Here it's obfuscated bytecode
    ...

    n   LOAD_GLOBAL              ? (__pyarmor__)
    n+3 CALL_FUNCTION            0
    n+6 POP_TOP
    n+7 JUMP_ABSOLUTE            0

将混淆的代码对象保存为.pyc或.pyo文件

那些模糊的文件(。Pyc或.pyo)可以被普通的python解释器使用,当这些代码对象第一次被调用时

First op is JUMP_ABSOLUTE, it will jump to offset n At offset n, the instruction is to call a PyCFunction. This function will restore those obfuscated bytecode between offset 3 and n, and put the original byte-code at offset 0. The obfuscated code can be got by the following code char *obfucated_bytecode; Py_ssize_t len; PyFrameObject* frame = PyEval_GetFrame(); PyCodeObject *f_code = frame->f_code; PyObject *co_code = f_code->co_code; PyBytes_AsStringAndSize(co_code, &obfucated_bytecode, &len) After this function returns, the last instruction is to jump to offset 0. The really byte-code now is executed.

有一个工具Pyarmor可以通过这种方式混淆python脚本。