标签归档:obfuscation

如何保护Python代码?

问题:如何保护Python代码?

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

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

另一个方面是,我的雇主不希望我们的客户阅读该代码,因为担心该代码可能被盗或至少是“新颖的主意”。

有解决这个问题的好方法吗?最好使用现成的解决方案。

该软件将在Linux系统上运行(因此,我认为py2exe不会成功)。

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? Preferably with an off-the-shelf solution.

The software will run on Linux systems (so I don’t think py2exe will do the trick).


回答 0

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.


回答 1

“有没有解决这个问题的好方法?” 不可以。没有任何东西可以防止逆向工程。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 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 do 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.


回答 2

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…


回答 3

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

明智的主意:

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

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

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

有关如何执行此操作的教程,请参阅此博客文章(不是我本人)。(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.


回答 4

我了解您希望客户使用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.


回答 5

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

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

一无所有,一无所有。客户拥有自己想要的东西(并且自从进行更改以来就为此付费)。由于他没有发布更改,因此好像其他所有人都没有发生过。

现在,如果客户出售软件,则他们必须更改版权声明(这是非法的,因此您可以提起诉讼,将胜诉->简单案例)。

如果他们不更改版权声明,那么第二级客户将注意到该软件来自您原来的产品,并想知道这是怎么回事。他们很可能会与您联系,因此您将了解有关转售作品的信息。

同样,我们有两种情况:原始客户仅售出了几份。那意味着他们无论如何也赚不了多少钱,那为什么还要打扰呢。或者他们批量销售。这意味着您有更多的机会了解他们的工作并为此做些事情。

但是最后,大多数公司都试图遵守法律(一旦声誉受损,开展业务就会困难得多)。因此,他们不会窃取您的工作,而是会与您一起进行改进。因此,如果您包含源代码(具有可以防止您简单转售的许可证),则它们很可能会简单地推回所做的更改,因为这样可以确保更改在下一版本中进行,而不必维护。这是双赢的:您获得更改,并且即使您不愿意将其真正包含在正式版本中,他们也可以根据自己的需要进行更改,即使他们确实需要它。

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.


回答 6

你看过催眠药吗?它会缩小,混淆和压缩Python代码。对于偶然的逆向工程,示例代码看起来很讨厌。

$ 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)

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)

回答 7

不要依靠混淆。正如您已经正确得出的结论,它提供的保护非常有限。更新:这是指向论文链接,该论文在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.


回答 8

使用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


回答 9

运送.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.


回答 10

在某些情况下,有可能将软件(全部或至少关键部分)移入组织托管的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.


回答 11

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

  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.


回答 12

我认为还有另一种方法可以保护您的Python代码;混淆方法的一部分。我相信曾经有一款类似Mount and Blade的游戏,或者是某些东西进行了更改并重新编译了自己的python解释器(我认为它是开源的原始解释器),只是将OP代码表中的OP代码更改为与标准python OP不同代码。

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

各种各样的恶作剧都可以通过这种方式与未成熟的黑客打成一片。阻止一堆没有经验的黑客很容易。这是您不可能击败的专业黑客。但是我想象大多数公司不会让专业黑客长期待命(可能是因为事情被黑客入侵了)。但是到处都是不成熟的黑客(以好奇的IT员工的身份阅读)。

例如,您可以在经过修改的解释器中,允许其检查源中的某些注释或文档字符串。对于此类代码行,您可能具有特殊的OP代码。例如:

OP 234用于源代码行“#我写的版权”,或者将该行编译为等效于“如果为False:”的操作代码,如果缺少“#版权所有”。出于某些晦涩的原因,基本上禁用了整个代码块。

重新编译经过修改的解释器可能可行的一个用例是,您没有编写该应用程序,但该应用程序很大,但是却得到了保护它的报酬,例如当您是金融应用程序的专用服务器管理员时。

我发现让源代码或操作码开放供人们注意有点矛盾,但是使用SSL进行网络流量。SSL也不是100%安全的。但这是用来阻止MOST的眼睛阅读它的。采取一点预防措施是明智的。

另外,如果足够多的人认为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.


回答 13

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

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.


回答 14

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

它可能正是您所需要的。

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

pypi页面

保护python脚本工作流程

  • your_script.py import pyconcrete
  • pyconcrete将挂钩导入模块
  • 当脚本导入时 MODULE,pyconcrete导入钩子将尝试先查找MODULE.pye然后MODULE.pye通过解密_pyconcrete.pyd并执行解密的数据(如.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

回答 15

根据客户的身份,将简单的保护机制与明智的许可协议相结合将是远远的。超过任何复杂的许可/加密/模糊系统更有效。

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

将代码作为.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..


回答 16

使代码更难于窃取的另一种尝试是使用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.


回答 17

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

这样,您可以为每个客户颁发带有公钥的许可证文件。

另外,您可以使用像这样的python混淆器(只需在Google上对其进行搜索)。

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


回答 18

您应该看看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.


回答 19

使用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.


回答 20

具有时间限制的许可证并在本地安装的程序中进行检查的想法将不起作用。即使进行了完美的混淆,也可以删除许可证检查。但是,如果您在远程系统上检查许可证并在封闭的远程系统上运行程序的重要部分,则可以保护您的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.


回答 21

我已经为自己的项目研究了软件保护,并且总体上认为完全保护是不可能的。您唯一希望达到的目的是将保护级别提高到一个比购买另一个许可证要花更多的钱的客户。

话虽这么说,我只是检查google的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.


回答 22

长话短说:

  1. 加密您的源代码
  2. 编写自己的python模块加载器,以在导入时解密代码
  3. 在C / C ++中实现模块加载器
  4. 您可以向模块加载器添加更多功能,例如反调试器,许可证控制,硬件指纹绑定等。

有关更多详细信息,请查看此答案

如果您对该主题感兴趣,该项目将为您提供-pyprotect

Long story short:

  1. Encrypt your source code
  2. Write your own python module loader to decrypt your code when importing
  3. Implement the module loader in C/C++
  4. You can add more features to the module loader, for example anti-debugger, license control, hardware fingerprint binding, etc.

For more detail, look this answer.

If you are interested in the topic, this project will help you – pyprotect.


回答 23

对于在内存中加载并执行C启动器的加密资源,可能有py2exe字节码。这里这里的一些想法。

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

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

但是正如其他人已经说过的那样,如果您的代码值得,那么逆向工程师将最终获得成功。

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.


回答 24

如果我们专注于软件许可,我建议您看一下我在这里写的另一个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.


回答 25

使用相同的方法来保护c / c ++的二进制文件,即在可执行文件或库二进制文件中混淆每个函数主体,在每个函数条目的开头插入一条指令“ jump”,跳转到特殊函数以恢复混淆的代码。字节码是Python脚本的二进制代码,因此

  • 首先将python脚本编译为代码对象
  • 然后迭代每个代码对象,如下混淆每个代码对象的co_code
    0 JUMP_ABSOLUTE n = 3 + len(字节码)

    3
    ...
    ...这是混淆的字节码
    ...

    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

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

        char * obfucated_bytecode;
        Py_ssize_t len;
        PyFrameObject *框架= PyEval_GetFrame();
        PyCodeObject * f_code = frame-> 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.


回答 26

使用cxfreeze(对于Linux为py2exe)将完成此工作。

http://cx-freeze.sourceforge.net/

它在ubuntu存储库中可用

using cxfreeze ( py2exe for linux ) will do the job.

http://cx-freeze.sourceforge.net/

it is available in ubuntu repositories


回答 27

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

讨论的可能技术是:
-使用编译的字节码(python -m compileall
-可执行文件的创建者(或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