如何保护Python代码不被用户读取?

发布于 2024-07-08 04:22:57 字数 234 浏览 11 评论 0 原文

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

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

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

有没有好的方法来处理这个问题呢?

I am developing a piece of software in Python that will be distributed to my employer's customers. My employer wants to limit the usage of the software with a time-restricted license file.

If we distribute the .py files or even .pyc files it will be easy to (decompile and) remove the code that checks the license file.

Another aspect is that my employer does not want the code to be read by our customers, fearing that the code may be stolen or at least the "novel ideas".

Is there a good way to handle this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(28

何以心动 2024-07-15 04:22:58

Python 作为一种字节码编译的解释语言,很难锁定。 即使您使用像 py2exe 这样的 exe 打包程序,可执行文件的布局也是众所周知的,并且 Python 字节码很好理解。

通常在这种情况下,你必须做出权衡。 保护代码到底有多重要? 其中是否存在真正的秘密(例如银行转账对称加密的密钥),或者您只是偏执? 选择能让您最快开发出最佳产品的语言,并现实地认识到您的新颖想法的价值。

如果您决定确实需要安全地强制执行许可证检查,请将其编写为小型 C 扩展,以便许可证检查代码可以很难(但并非不可能!)进行逆向工程,并将大部分代码留在 Python 中。

Python, being a byte-code-compiled interpreted language, is very difficult to lock down. Even if you use a exe-packager like py2exe, the layout of the executable is well-known, and the Python byte-codes are well understood.

Usually in cases like this, you have to make a tradeoff. How important is it really to protect the code? Are there real secrets in there (such as a key for symmetric encryption of bank transfers), or are you just being paranoid? Choose the language that lets you develop the best product quickest, and be realistic about how valuable your novel ideas are.

If you decide you really need to enforce the license check securely, write it as a small C extension so that the license check code can be extra-hard (but not impossible!) to reverse engineer, and leave the bulk of your code in Python.

仙女山的月亮 2024-07-15 04:22:58

Python 不是您需要的工具

您必须使用正确的工具来做正确的事情,并且 Python 的设计初衷并不是为了混淆。 事实恰恰相反; 在 Python 中,一切都是开放的,或者很容易揭示或修改,因为这是该语言的哲学。

如果你想要一些看不透的东西,那就寻找其他工具。 这并不是一件坏事,重要的是存在几种不同的工具用于不同的用途。

混淆确实很难,

即使是已编译的程序也可以进行逆向工程,因此不要认为您可以完全保护任何代码。 你可以分析混淆的PHP、破解flash加密密钥等。较新版本的Windows每次都会被破解。

制定法律要求是一个好方法

您无法阻止某人滥用您的代码,但您可以轻松发现是否有人滥用您的代码。 因此,这只是一个偶然的法律问题。

代码保护被高估

如今,商业模式倾向于销售服务而不是产品。 您无法复制、盗版或窃取服务。 也许是时候考虑顺其自然了……

Python is not the tool you need

You must use the right tool to do the right thing, and Python was not designed to be obfuscated. It's the contrary; everything is open or easy to reveal or modify in Python because that's the language's philosophy.

If you want something you can't see through, look for another tool. This is not a bad thing, it is important that several different tools exist for different usages.

Obfuscation is really hard

Even compiled programs can be reverse-engineered so don't think that you can fully protect any code. You can analyze obfuscated PHP, break the flash encryption key, etc. Newer versions of Windows are cracked every time.

Having a legal requirement is a good way to go

You cannot prevent somebody from misusing your code, but you can easily discover if someone does. Therefore, it's just a casual legal issue.

Code protection is overrated

Nowadays, business models tend to go for selling services instead of products. You cannot copy a service, pirate nor steal it. Maybe it's time to consider to go with the flow...

じее 2024-07-15 04:22:58

编译 python 并分发二进制文件!

明智的想法:

使用CythonNuitkaShed Skin 或类似将 python 编译为 C 代码的东西,然后将您的应用程序分发为 python 二进制库 (pyd)。

这样,就不会留下任何 Python(字节)代码,并且我认为您已经完成了任何人(即您的雇主)可以从常规代码中期望的任何合理数量的模糊化。 (.NET 或 Java 比这种情况更不安全,因为字节码没有被混淆,并且可以相对容易地反编译成合理的源代码。)

Cython 与 CPython 越来越兼容,所以我认为它应该可以工作。 (我实际上正在为我们的产品考虑这一点。我们已经构建了一些第三方库作为 pyd/dll,因此将我们自己的 python 代码作为二进制文件发送对我们来说并不是一个太大的步骤。)

请参阅 这篇博文< /a> (不是我写的)有关如何操作的教程。 (thx @hithwen)

疯狂的想法:

您可能会让 Cython 为每个模块单独存储 C 文件,然后将它们全部连接起来并使用大量内联构建它们。 这样,你的 Python 模块就变得相当单一,很难用常用工具进行修改。

超越疯狂

如果您可以静态链接到(并优化)Python 运行时和所有库 (dll),您也许能够构建单个可执行文件。 这样,拦截对 python 以及您使用的任何框架库的调用肯定会很困难。 但如果您使用 LGPL 代码,则无法完成此操作。

Compile python and distribute binaries!

Sensible idea:

Use Cython, Nuitka, Shed Skin or something similar to compile python to C code, then distribute your app as python binary libraries (pyd) instead.

That way, no Python (byte) code is left and you've done any reasonable amount of obscurification anyone (i.e. your employer) could expect from regular Code, I think. (.NET or Java less safe than this case, as that bytecode is not obfuscated and can relatively easily be decompiled into reasonable source.)

Cython is getting more and more compatible with CPython, so I think it should work. (I'm actually considering this for our product.. We're already building some thirdparty libs as pyd/dlls, so shipping our own python code as binaries is not a overly big step for us.)

See This Blog Post (not by me) for a tutorial on how to do it. (thx @hithwen)

Crazy idea:

You could probably get Cython to store the C-files separately for each module, then just concatenate them all and build them with heavy inlining. That way, your Python module is pretty monolithic and difficult to chip at with common tools.

Beyond crazy:

You might be able to build a single executable if you can link to (and optimize with) the python runtime and all libraries (dlls) statically. That way, it'd sure be difficult to intercept calls to/from python and whatever framework libraries you use. This cannot be done if you're using LGPL code though.

失与倦" 2024-07-15 04:22:58

我理解您希望您的客户使用 python 的强大功能,但又不想暴露源代码。

以下是我的建议:

(a) 将代码的关键部分编写为 C 或 C++ 库,然后使用 SIPswig 将 C/C++ API 公开给 Python 命名空间。

(b) 使用 cython 代替 Python

(c) 在 (a) 和 (b) 中,应该可以使用 Python 接口将库作为许可的二进制文件分发。

I understand that you want your customers to use the power of python but do not want expose the source code.

Here are my suggestions:

(a) Write the critical pieces of the code as C or C++ libraries and then use SIP or swig to expose the C/C++ APIs to Python namespace.

(b) Use cython instead of Python

(c) In both (a) and (b), it should be possible to distribute the libraries as licensed binary with a Python interface.

悸初 2024-07-15 04:22:58

您看过 pyminifier 吗? 它可以缩小、混淆和压缩 Python 代码。 对于休闲逆向工程来说,示例代码看起来非常糟糕。

$ pyminifier --nonlatin --replacement-length=50 /tmp/tumult.py
#!/usr/bin/env python3
ﺭ异

Have you had a look at pyminifier? It does Minify, obfuscate, and compress Python code. The example code looks pretty nasty for casual reverse engineering.

$ pyminifier --nonlatin --replacement-length=50 /tmp/tumult.py
#!/usr/bin/env python3
ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲמּ=ImportError
ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ燱=print
ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ????=False
ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ澨=object
try:
 import demiurgic
except ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲמּ:
 ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ燱("Warning: You're not demiurgic. Actually, I think that's normal.")
try:
 import mystificate
except ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲמּ:
 ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ燱("Warning: Dark voodoo may be unreliable.")
ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲﺬ=ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ????
class ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ????(ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ澨):
 def __init__(self,*args,**kwargs):
  pass
 def ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ클(self,dactyl):
  ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ퐐=demiurgic.palpitation(dactyl)
  ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ????=mystificate.dark_voodoo(ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ퐐)
  return ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ????
 def ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ????(self,whatever):
  ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ燱(whatever)
if __name__=="__main__":
 ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ燱("Forming...")
 ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲﺃ=ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ????("epicaricacy","perseverate")
 ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲﺃ.ﺭ异????????ﭞﰣﺁں????????????뻛????????嬭ﱌ????????????Ꝫﴹ뙫????퉊ﳦﲣפּܟﺶ????ﶨࠔ????????????????????????????ﶻ????????????????????䉊ﰸﭳᣲ????("Codswallop")
# Created by pyminifier (https://github.com/liftoff/pyminifier)
横笛休吹塞上声 2024-07-15 04:22:58

使用 Cython。 它将您的模块编译为高性能 C 文件,然后可以将其编译为本机二进制库。 与 .pyc 字节码相比,这基本上是不可逆的!

我写了一篇关于如何为 Python 项目设置 Cython 的详细文章,请查看:

使用 Cython 保护 Python 源

Use Cython. It will compile your modules to high-performant C files, which can then be compiled to native binary libraries. This is basically un-reversable, compared to .pyc bytecode!

I've written a detailed article on how to set up Cython for a Python project, check it out:

Protecting Python Sources With Cython

不念旧人 2024-07-15 04:22:58

您的雇主是否意识到他可以“窃取”其他人从您的代码中获得的任何想法? 我的意思是,如果他们可以阅读你的作品,那么你也可以阅读他们的作品。 也许考虑如何从这种情况中受益会比担心可能损失多少带来更好的投资回报。

[编辑]对尼克评论的回答:

一无所获,也一无所失。 客户得到了他想要的东西(并且因为他自己进行了更改而付费)。 由于他没有发布更改,就好像其他人都没有发生一样。

现在,如果客户出售该软件,他们必须更改版权声明(这是非法的,因此您可以起诉并会获胜 - >简单的情况)。

如果他们不更改版权声明,第二级客户会注意到该软件来自您的原创,并想知道发生了什么。 他们很可能会联系您,这样您就会了解您的作品的转售情况。

同样,我们有两种情况: 原始客户只售出了几份。 这意味着他们无论如何也赚不到多少钱,所以何必费心呢。 或者他们批量销售。 这意味着您有更好的机会了解他们的工作并采取行动。

但最终,大多数公司都试图遵守法律(一旦声誉受损,开展业务就困难得多)。 所以他们不会窃取你的作品,而是与你一起改进它。 因此,如果您包含源代码(具有保护您免于简单转售的许可证),他们很可能会简单地推迟所做的更改,因为这将确保更改出现在下一个版本中,并且他们不必维护它。 这是双赢的:你得到了改变,如果他们真的、迫切需要改变,他们也可以自己做出改变,即使你不愿意将其包含在正式版本中。

Is your employer aware that he can "steal" back any ideas that other people get from your code? I mean, if they can read your work, so can you theirs. Maybe looking at how you can benefit from the situation would yield a better return of your investment than fearing how much you could lose.

[EDIT] Answer to Nick's comment:

Nothing gained and nothing lost. The customer has what he wants (and paid for it since he did the change himself). Since he doesn't release the change, it's as if it didn't happen for everyone else.

Now if the customer sells the software, they have to change the copyright notice (which is illegal, so you can sue and will win -> simple case).

If they don't change the copyright notice, the 2nd level customers will notice that the software comes from you original and wonder what is going on. Chances are that they will contact you and so you will learn about the reselling of your work.

Again we have two cases: The original customer sold only a few copies. That means they didn't make much money anyway, so why bother. Or they sold in volume. That means better chances for you to learn about what they do and do something about it.

But in the end, most companies try to comply to the law (once their reputation is ruined, it's much harder to do business). So they will not steal your work but work with you to improve it. So if you include the source (with a license that protects you from simple reselling), chances are that they will simply push back changes they made since that will make sure the change is in the next version and they don't have to maintain it. That's win-win: You get changes and they can make the change themselves if they really, desperately need it even if you're unwilling to include it in the official release.

孤城病女 2024-07-15 04:22:58

不要依赖混淆。 正如您所得出的正确结论,它提供的保护非常有限。
更新:这是一个论文链接,它进行了反向工程Dropbox 中的混淆 Python 代码。 操作码重新映射的方法是一个很好的障碍,但显然它可以被克服。

相反,正如许多海报所提到的那样:

  • 不值得花费逆向工程时间(你的软件非常好,付费是有意义的)
  • 让他们签署合同并在可行的情况下进行许可证审核。

或者,正如强大的 Python IDE WingIDE 所做的那样:赠送代码。 没错,放弃代码并让人们回来获取升级和支持。

Do not rely on obfuscation. As You have correctly concluded, it offers very limited protection.
UPDATE: Here is a link to paper which reverse engineered obfuscated python code in Dropbox. The approach - opcode remapping is a good barrier, but clearly it can be defeated.

Instead, as many posters have mentioned make it:

  • Not worth reverse engineering time (Your software is so good, it makes sense to pay)
  • Make them sign a contract and do a license audit if feasible.

Alternatively, as the kick-ass Python IDE WingIDE does: Give away the code. That's right, give the code away and have people come back for upgrades and support.

聽兲甴掵 2024-07-15 04:22:58

传送 .pyc 文件有其问题 - 它们与创建它们的 python 版本之外的任何其他 python 版本都不兼容,这意味着您必须知道产品将运行的系统上正在运行哪个 python 版本。 这是一个非常有限的因素。

Shipping .pyc files has its problems - they are not compatible with any other python version than the python version they were created with, which means you must know which python version is running on the systems the product will run on. That's a very limiting factor.

诺曦 2024-07-15 04:22:58

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

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

In some circumstances, it may be possible to move (all, or at least a key part) of the software into a web service that your organization hosts.

That way, the license checks can be performed in the safety of your own server room.

最美不过初阳 2024-07-15 04:22:58

我很惊讶在任何答案中都没有看到 pyconcrete 。 也许是因为它比问题更新?

它可能正是您所需要的。

它不会混淆代码,而是在加载时对其进行加密和解密。

来自 pypi 页面

保护python脚本工作流程

  • your_script.py 导入 pyconcrete
  • pyconcrete将挂钩导入模块
  • 当您的脚本导入MODULE时,
    pyconcrete import hook 将尝试先找到 MODULE.pye 然后
    通过 _pyconcrete.pyd 解密 MODULE.pye 并执行解密的数据(如
    .pyc 内容)
  • 加密和 解密_pyconcrete.pyd中的密钥记录
    (如 DLL 或 SO)密钥将隐藏在二进制代码中,不能
    直接在十六进制视图中查看

I was surprised in not seeing pyconcrete in any answer. Maybe because it's newer than the question?

It could be exactly what you need(ed).

Instead of obfuscating the code, it encrypts it and decrypts at load time.

From pypi page:

Protect python script work flow

  • your_script.py import pyconcrete
  • pyconcrete will hook import module
  • when your script do import MODULE,
    pyconcrete import hook will try to find MODULE.pye first and then
    decrypt MODULE.pye via _pyconcrete.pyd and execute decrypted data (as
    .pyc content)
  • encrypt & decrypt secret key record in _pyconcrete.pyd
    (like DLL or SO) the secret key would be hide in binary code, can’t
    see it directly in HEX view
花落人断肠 2024-07-15 04:22:58

尽管没有完美的解决方案,但可以执行以下操作:

  1. 将一些关键的启动代码片段移至本机库中。
  2. 在本机库中强制执行许可证检查。

如果要删除对本机代码的调用,则程序无论如何都不会启动。 如果不删除,则将强制执行许可证。

尽管这不是跨平台或纯 Python 解决方案,但它可以工作。

Though there's no perfect solution, the following can be done:

  1. Move some critical piece of startup code into a native library.
  2. Enforce the license check in the native library.

If the call to the native code were to be removed, the program wouldn't start anyway. If it's not removed then the license will be enforced.

Though this is not a cross-platform or a pure-Python solution, it will work.

同尘 2024-07-15 04:22:58

保护代码的唯一可靠方法是在您控制的服务器上运行它,并为您的客户端提供与该服务器交互的客户端。

The reliable only way to protect code is to run it on a server you control and provide your clients with a client which interfaces with that server.

玩世 2024-07-15 04:22:58

我认为还有一种方法可以保护你的 Python 代码; 混淆方法的一部分。 我相信有一个像《骑马与砍杀》这样的游戏或者其他游戏改变并重新编译了他们自己的Python解释器(我认为是开源的原始解释器),并且只是将OP代码表中的OP代码更改为与标准Python OP不同代码。

因此 python 源代码未修改,但 *.pyc 文件的文件扩展名不同,并且操作码与公共 python.exe 解释器不匹配。 如果您检查游戏数据文件,所有数据都是 Python 源格式。

通过这种方式,可以使用各种令人讨厌的伎俩来迷惑不成熟的黑客。 阻止一群没有经验的黑客很容易。 这是你不可能击败的职业黑客。 但我想,大多数公司不会长期保留专业黑客(可能是因为事情被黑客入侵了)。 但不成熟的黑客比比皆是(理解为好奇的 IT 人员)。

例如,您可以在修改后的解释器中允许它检查源中的某些注释或文档字符串。 您可以为此类代码行设置特殊的操作代码。 例如:

OP 234 代表源代码行“# Copyright I write this”
或者将该行编译成相当于“if False:”的操作码(如果缺少“# Copyright”)。 基本上出于某种隐晦的原因禁用整个代码块。

重新编译修改后的解释器可能可行的一种用例是您没有编写应用程序,该应用程序很大,但您需要付费来保护它,例如当您是金融应用程序的专用服务器管理员时。

我发现让源代码或操作码开放以供人们关注,但对网络流量使用 SSL 有点矛盾。 SSL 也不是 100% 安全。 但它被用来阻止大多数人阅读它。 一点点预防措施是明智的。

此外,如果有足够多的人认为 Python 源代码和操作码太明显,那么很可能有人最终会至少为其开发一个简单的保护工具。 因此,越多的人询问“如何保护 Python 应用程序”只会促进这种发展。

I think there is one more method to protect your Python code; part of the Obfuscation method. I believe there was a game like Mount and Blade or something that changed and recompiled their own python interpreter (the original interpreter which i believe is open source) and just changed the OP codes in the OP code table to be different then the standard python OP codes.

So the python source is unmodified but the file extensions of the *.pyc files are different and the op codes don't match to the public python.exe interpreter. If you checked the games data files all the data was in Python source format.

All sorts of nasty tricks can be done to mess with immature hackers this way. Stopping a bunch of inexperienced hackers is easy. It's the professional hackers that you will not likely beat. But most companies don't keep pro hackers on staff long I imagine (likely because things get hacked). But immature hackers are all over the place (read as curious IT staff).

You could for example, in a modified interpreter, allow it to check for certain comments or doc strings in your source. You could have special OP codes for such lines of code. For example:

OP 234 is for source line "# Copyright I wrote this"
or compile that line into op codes that are equivalent to "if False:" if "# Copyright" is missing. Basically disabling a whole block of code for what appears to be some obscure reason.

One use case where recompiling a modified interpreter may be feasible is where you didn't write the app, the app is big, but you are paid to protect it, such as when you're a dedicated server admin for a financial app.

I find it a little contradictory to leave the source or opcodes open for eyeballs, but use SSL for network traffic. SSL is not 100% safe either. But it's used to stop MOST eyes from reading it. A wee bit precaution is sensible.

Also, if enough people deem that Python source and opcodes are too visible, it's likely someone will eventually develop at least a simple protection tool for it. So the more people asking "how to protect Python app" only promotes that development.

北座城市 2024-07-15 04:22:58

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

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

将代码作为 .pyc 文件传送将防止您的保护被几个 # 所破坏,但这几乎不是有效的反盗版保护(好像有这样的技术一样) ,到最后,它不应该实现与公司达成的体面许可协议所能实现的任何目标。

专注于让你的代码尽可能好用——拥有满意的客户会给你的公司带来比防止某些理论上的盗版更多的钱。

Depending in who the client is, a simple protection mechanism, combined with a sensible license agreement will be far more effective than any complex licensing/encryption/obfuscation system.

The best solution would be selling the code as a service, say by hosting the service, or offering support - although that isn't always practical.

Shipping the code as .pyc files will prevent your protection being foiled by a few #s, but it's hardly effective anti-piracy protection (as if there is such a technology), and at the end of the day, it shouldn't achieve anything that a decent license agreement with the company will.

Concentrate on making your code as nice to use as possible - having happy customers will make your company far more money than preventing some theoretical piracy..

极度宠爱 2024-07-15 04:22:58

另一种使代码更难被窃取的尝试是使用 jython,然后使用 java obfuscator

这应该可以很好地工作,因为 jythonc 将 python 代码翻译为 java,然后将 java 编译为字节码。 因此,一旦您混淆了类,就很难理解反编译后发生的情况,更不用说恢复实际代码了。

jython 的唯一问题是你不能使用用 c 编写的 python 模块。

Another attempt to make your code harder to steal is to use jython and then use java obfuscator.

This should work pretty well as jythonc translate python code to java and then java is compiled to bytecode. So ounce you obfuscate the classes it will be really hard to understand what is going on after decompilation, not to mention recovering the actual code.

The only problem with jython is that you can't use python modules written in c.

許願樹丅啲祈禱 2024-07-15 04:22:58

您应该看看 getdropbox.com 的人员如何为他们的客户端软件(包括 Linux)做到这一点。 破解它非常棘手,需要一些非常有创意的拆卸才能突破保护机制。

You should take a look at how the guys at getdropbox.com do it for their client software, including Linux. It's quite tricky to crack and requires some quite creative disassembly to get past the protection mechanisms.

冷夜 2024-07-15 04:22:58

使用 Python 能做的最好的事情就是模糊事物。

  • 删除所有文档字符串
  • 仅分发 .pyc 编译文件。
  • 冻结它
  • 隐藏类/模块中的常量,以便 help(config) 不会显示所有内容

您可以通过加密其中的一部分并即时解密并将其传递给 eval() 来添加一些额外的隐藏内容。 但无论你做什么,都会有人打破它。

所有这些都无法阻止坚定的攻击者反汇编字节码或通过帮助、目录等挖掘您的 api。

The best you can do with Python is to obscure things.

  • Strip out all docstrings
  • Distribute only the .pyc compiled files.
  • freeze it
  • Obscure your constants inside a class/module so that help(config) doesn't show everything

You may be able to add some additional obscurity by encrypting part of it and decrypting it on the fly and passing it to eval(). But no matter what you do someone can break it.

None of this will stop a determined attacker from disassembling the bytecode or digging through your api with help, dir, etc.

我偏爱纯白色 2024-07-15 04:22:58

通过对重要文件进行散列和签名并使用公钥方法进行检查,使用标准加密方案对代码进行签名怎么样?

通过这种方式,您可以为每个客户颁发带有公钥的许可证文件。

另外,你可以使用像这个这样的python混淆器(刚刚用谷歌搜索过) 。

What about signing your code with standard encryption schemes by hashing and signing important files and checking it with public key methods?

In this way you can issue license file with a public key for each customer.

Additional you can use an python obfuscator like this one (just googled it).

我是男神闪亮亮 2024-07-15 04:22:58

拥有时间限制许可证并在本地安装的程序中检查它的想法是行不通的。 即使进行了完美的混淆,许可证检查也可以被删除。 但是,如果您检查远程系统上的许可证并在封闭的远程系统上运行程序的重要部分,您将能够保护您的 IP。

防止竞争对手将源代码用作自己的源代码或编写相同代码的受启发版本,一种保护方法是向您的程序逻辑添加签名(一些秘密,以便能够证明代码是从您那里窃取的)并混淆python 源代码因此很难阅读和使用。

良好的混淆为您的代码添加了与将其编译为可执行文件(并剥离二进制文件)基本相同的保护。 弄清楚混淆的复杂代码是如何工作的可能比实际编写自己的实现更困难。

这无助于防止你的程序被黑客攻击。 即使使用混淆代码许可证,内容也会被破解,并且程序可能会被修改为具有稍微不同的行为(就像将代码编译为二进制文件无助于保护本机程序一样)。

除了符号混淆之外,不重构代码可能是个好主意,如果调用图指向许多不同的地方,这会使一切变得更加混乱,即使实际上这些不同的地方最终做了同样的事情。

混淆代码内的逻辑签名(例如,您可以创建程序逻辑使用的值表,但也用作签名),可用于确定代码源自您。 如果有人决定使用您的混淆代码模块作为他们自己产品的一部分(即使在重新混淆它以使其看起来不同之后),您可以表明,该代码是通过您的秘密签名窃取的。

Idea of having time restricted license and check for it in locally installed program will not work. Even with perfect obfuscation, license check can be removed. However if you check license on remote system and run significant part of the program on your closed remote system, you will be able to protect your IP.

Preventing competitors from using the source code as their own or write their inspired version of the same code, one way to protect is to add signatures to your program logic (some secrets to be able to prove that code was stolen from you) and obfuscate the python source code so, it's hard to read and utilize.

Good obfuscation adds basically the same protection to your code, that compiling it to executable (and stripping binary) does. Figuring out how obfuscated complex code works might be even harder than actually writing your own implementation.

This will not help preventing hacking of your program. Even with obfuscation code license stuff will be cracked and program may be modified to have slightly different behaviour (in the same way that compiling code to binary does not help protection of native programs).

In addition to symbol obfuscation might be good idea to unrefactor the code, which makes everything even more confusing if e.g. call graphs points to many different places even if actually those different places does eventually the same thing.

Logical signature inside obfuscated code (e.g. you may create table of values which are used by program logic, but also used as signature), which can be used to determine that code is originated from you. If someone decides to use your obfuscated code module as part of their own product (even after reobfuscating it to make it seem different) you can show, that code is stolen with your secret signature.

淡写薰衣草的香 2024-07-15 04:22:58

CythonNuitka 都不是答案,因为当运行使用 NuitkaCython 编译的解决方案时生成.pyd.exe文件缓存目录,并将所有.pyc文件复制到缓存目录中,因此攻击者可以简单地反编译.pyc 文件并查看您的代码或更改它。

Neiher Cython nor Nuitka were not the answer, because when running the solution that is compiled with Nuitka or Cython into .pyd or .exe files a cache directory is generated and all .pyc files are copied into the cache directory, so an attacker simply can decompile .pyc files and see your code or change it.

最冷一天 2024-07-15 04:22:58

我已经研究了我自己项目的一般软件保护,总体理念是完全保护是不可能的。 您唯一希望实现的目标是将保护增加到一定程度,使您的客户绕过该级别的成本比购买另一个许可证的成本更高。

话虽如此,我只是在谷歌上检查 python 混淆,并没有发现很多东西。 在 .Net 解决方案中,混淆是在 Windows 平台上解决问题的首选方法,但我不确定是否有人在 Linux 上有与 Mono 一起使用的解决方案。

接下来的事情是用编译语言编写代码,或者如果您真的想一路走下去,那么就用汇编语言。 剥离的可执行文件比解释语言更难反编译。

这一切都归结为权衡。 一方面,你可以轻松地使用 Python 进行软件开发,同时也很难隐藏秘密。 另一方面,你有用汇编程序编写的软件,它更难编写,但更容易隐藏秘密。

你的老板必须在这个连续体中选择一个支持他的要求的点。 然后他必须给你工具和时间,这样你就可以构建他想要的东西。 然而我敢打赌,他会反对实际的开发成本和潜在的金钱损失。

I have looked at software protection in general for my own projects and the general philosophy is that complete protection is impossible. The only thing that you can hope to achieve is to add protection to a level that would cost your customer more to bypass than it would to purchase another license.

With that said I was just checking google for python obsfucation and not turning up a lot of anything. In a .Net solution, obsfucation would be a first approach to your problem on a windows platform, but I am not sure if anyone has solutions on Linux that work with Mono.

The next thing would be to write your code in a compiled language, or if you really want to go all the way, then in assembler. A stripped out executable would be a lot harder to decompile than an interpreted language.

It all comes down to tradeoffs. On one end you have ease of software development in python, in which it is also very hard to hide secrets. On the other end you have software written in assembler which is much harder to write, but is much easier to hide secrets.

Your boss has to choose a point somewhere along that continuum that supports his requirements. And then he has to give you the tools and time so you can build what he wants. However my bet is that he will object to real development costs versus potential monetary losses.

一场春暖 2024-07-15 04:22:58

可以将 py2exe 字节码放在加密资源中,以便 C 启动器在内存中加载并执行它。 此处此处

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

您还可以找到防止调试器的教程,使反汇编器失败,设置错误调试器断点并使用校验和保护您的代码。 搜索 [“加密代码”执行“内存中”] 以获取更多链接。

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

It is possible to have the py2exe byte-code in a crypted resource for a C launcher that loads and executes it in memory. Some ideas here and here.

Some have also thought of a self modifying program to make reverse engineering expensive.

You can also find tutorials for preventing debuggers, make the disassembler fail, set false debugger breakpoints and protect your code with checksums. Search for ["crypted code" execute "in memory"] for more links.

But as others already said, if your code is worth it, reverse engineers will succeed in the end.

榆西 2024-07-15 04:22:58

使用同样的方法来保护c/c++的二进制文件,即对可执行文件或库二进制文件中的每个函数体进行混淆,在每个函数入口处插入一条指令“jump”,跳转到特殊函数来恢复混淆后的代码。 字节码是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解释器使用,当这些代码对象第一次被调用时

  • 第一个操作是JUMP_ABSOLUTE,它将跳转到偏移量n

  • < p>在偏移量n处,指令是调用PyCFunction。 该函数将恢复偏移量3到n之间的混淆字节码,并将原始字节码放在偏移量0处。混淆后的代码可以通过以下代码得到

     char *obfucated_bytecode; 
          py_ssize_t 长度; 
          PyFrameObject* 框架 = PyEval_GetFrame(); 
          PyCodeObject *f_code = 帧->f_code; 
          PyObject *co_code = f_code->co_code;       
          PyBytes_AsStringAndSize(co_code, &obfucated_bytecode, &len) 
      
  • 该函数返回后,最后一条指令是跳转到
    偏移0。现在执行真正的字节码。

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

Use the same way to protect binary file of c/c++, that is, obfuscate each function body in executable or library binary file, insert an instruction "jump" at the begin of each function entry, jump to special function to restore obfuscated code. Byte-code is binary code of Python script, so

  • First compile python script to code object
  • Then iterate each code object, obfuscate co_code of each code object as the following
    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
  • Save obfuscated code object as .pyc or .pyo file

Those obfuscated file (.pyc or .pyo) can be used by normal python interpreter, when those code object is called first time

  • 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.

There is a tool Pyarmor to obfuscate python scripts by this way.

思慕 2024-07-15 04:22:58

关于隐藏 python 源代码有一个全面的答案,可以找到 此处

讨论的可能技术有:
- 使用编译的字节码 (python -mcompileall)
- 可执行文件创建者(或安装程序,例如 PyInstaller
- 软件即服务(我认为隐藏代码的最佳解决方案)
- python源代码混淆器

There is a comprehensive answer on concealing the python source code, which can be find here.

Possible techniques discussed are:
- use compiled bytecode (python -m compileall)
- executable creators (or installers like PyInstaller)
- software as an service (the best solution to conceal your code in my opinion)
- python source code obfuscators

耳根太软 2024-07-15 04:22:58

如果我们专注于软件许可,我建议您查看我在此处编写的另一个 Stack Overflow 答案,以获得一些灵感说明如何构建许可证密钥验证系统。

GitHub 上有一个开源库,可以帮助您进行许可证验证。

您可以通过pip install Licensing来安装它,然后添加以下代码:

pubKey = "<RSAKeyValue><Modulus>sGbvxwdlDbqFXOMlVUnAF5ew0t0WpPW7rFpI5jHQOFkht/326dvh7t74RYeMpjy357NljouhpTLA3a6idnn4j6c3jmPWBkjZndGsPL4Bqm+fwE48nKpGPjkj4q/yzT4tHXBTyvaBjA8bVoCTnu+LiC4XEaLZRThGzIn5KQXKCigg6tQRy0GXE13XYFVz/x1mjFbT9/7dS8p85n8BuwlY5JvuBIQkKhuCNFfrUxBWyu87CFnXWjIupCD2VO/GbxaCvzrRjLZjAngLCMtZbYBALksqGPgTUN7ZM24XbPWyLtKPaXF2i4XRR9u6eTj5BfnLbKAU5PIVfjIS+vNYYogteQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"

res = Key.activate(token="WyIyNTU1IiwiRjdZZTB4RmtuTVcrQlNqcSszbmFMMHB3aWFJTlBsWW1Mbm9raVFyRyJd",\
                   rsa_pub_key=pubKey,\
                   product_id=3349, key="ICVLD-VVSZR-ZTICT-YKGXL", machine_code=Helpers.GetMachineCode())

if res[0] == None not Helpers.IsOnRightMachine(res[0]):
    print("An error occured: {0}".format(res[1]))
else:
    print("Success")

您可以阅读更多有关RSA公钥等配置方式的信息此处

If we focus on software licensing, I would recommend to take a look at another Stack Overflow answer I wrote here to get some inspiration of how a license key verification system can be constructed.

There is an open-source library on GitHub that can help you with the license verification bit.

You can install it by pip install licensing and then add the following code:

pubKey = "<RSAKeyValue><Modulus>sGbvxwdlDbqFXOMlVUnAF5ew0t0WpPW7rFpI5jHQOFkht/326dvh7t74RYeMpjy357NljouhpTLA3a6idnn4j6c3jmPWBkjZndGsPL4Bqm+fwE48nKpGPjkj4q/yzT4tHXBTyvaBjA8bVoCTnu+LiC4XEaLZRThGzIn5KQXKCigg6tQRy0GXE13XYFVz/x1mjFbT9/7dS8p85n8BuwlY5JvuBIQkKhuCNFfrUxBWyu87CFnXWjIupCD2VO/GbxaCvzrRjLZjAngLCMtZbYBALksqGPgTUN7ZM24XbPWyLtKPaXF2i4XRR9u6eTj5BfnLbKAU5PIVfjIS+vNYYogteQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"

res = Key.activate(token="WyIyNTU1IiwiRjdZZTB4RmtuTVcrQlNqcSszbmFMMHB3aWFJTlBsWW1Mbm9raVFyRyJd",\
                   rsa_pub_key=pubKey,\
                   product_id=3349, key="ICVLD-VVSZR-ZTICT-YKGXL", machine_code=Helpers.GetMachineCode())

if res[0] == None not Helpers.IsOnRightMachine(res[0]):
    print("An error occured: {0}".format(res[1]))
else:
    print("Success")

You can read more about the way the RSA public key, etc are configured here.

弥枳 2024-07-15 04:22:58

首先,这里是有关混淆的公共 Github 存储库的列表。

在所有选择中,我最终使用 python-obfuscator ,然后使用 python-minifier 也可以减小脚本大小。 请小心,先混淆,然后缩小,以使脚本仍然可执行。

First, here is a list of public Github repositories regarding obfuscation.

Among all choices out there I ended up using python-obfuscator followed by python-minifier to decrease also the script size. Be careful though to obfuscate first and then minify in order for the script to be still executable.

清晨说晚安 2024-07-15 04:22:57

“有没有好的办法来解决这个问题呢?” 不可以。没有任何措施可以防止逆向工程。 甚至 DVD 机器上的固件也已被逆向工程,并且 AACS 加密密钥 被暴露。 尽管 DMCA 将其定为刑事犯罪,但情况仍然如此。

由于没有任何技术方法可以阻止您的客户阅读您的代码,因此您必须应用普通的商业方法。

  1. 许可证。 合同。 条款和条件。 即使人们可以阅读代码,这仍然有效。 请注意,某些基于 Python 的组件可能要求您在销售使用这些组件的软件之前支付费用。 此外,某些开源许可证禁止您隐藏该组件的来源或起源。

  2. 提供重要价值。 如果你的东西非常好——价格令人难以拒绝——那么就没有动力浪费时间和金钱对任何东西进行逆向工程。 逆向工程的成本很高。 让您的产品稍微便宜一些。

  3. 提供升级和增强功能,使任何逆向工程都成为一个坏主意。 当下一个版本破坏了他们的逆向工程时,就没有意义了。 这可能会走向荒谬的极端,但您应该提供新功能,使下一个版本比逆向工程更有价值。

  4. 以极具吸引力的价格提供定制服务,以至于他们宁愿付钱给您来构建和支持增强功能。

  5. 使用过期的许可证密钥。 这很残酷,会给你带来坏名声,但它肯定会让你的软件停止工作。

  6. 将其作为网络服务提供。 SaaS 不涉及客户下载。

"Is there a good way to handle this problem?" No. Nothing can be protected against reverse engineering. Even the firmware on DVD machines has been reverse engineered and the AACS Encryption key exposed. And that's in spite of the DMCA making that a criminal offense.

Since no technical method can stop your customers from reading your code, you have to apply ordinary commercial methods.

  1. Licenses. Contracts. Terms and Conditions. This still works even when people can read the code. Note that some of your Python-based components may require that you pay fees before you sell software using those components. Also, some open-source licenses prohibit you from concealing the source or origins of that component.

  2. Offer significant value. If your stuff is so good -- at a price that is hard to refuse -- there's no incentive to waste time and money reverse engineering anything. Reverse engineering is expensive. Make your product slightly less expensive.

  3. Offer upgrades and enhancements that make any reverse engineering a bad idea. When the next release breaks their reverse engineering, there's no point. This can be carried to absurd extremes, but you should offer new features that make the next release more valuable than reverse engineering.

  4. Offer customization at rates so attractive that they'd rather pay you to build and support the enhancements.

  5. Use a license key which expires. This is cruel, and will give you a bad reputation, but it certainly makes your software stop working.

  6. Offer it as a web service. SaaS involves no downloads to customers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文