如何保护Python代码?

痞子三分冷 提交于 2020-01-12 04:10:37

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

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

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

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

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


#1楼

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

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

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

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

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

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

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

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


#2楼

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

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

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

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


#3楼

Python是字节码编译的解释语言,很难锁定。 即使您使用py2exe之类的exe打包程序,该可执行文件的布局也是众所周知的,并且Python字节码也很容易理解。

通常在这种情况下,您必须进行权衡。 保护代码真的有多重要? 那里是否有真正的秘密(例如对银行转账进行对称加密的密钥),或者您只是偏执? 选择一种语言,使您能够最快地开发出最好的产品,并要对您的新颖创意的价值抱有现实的态度。

如果您确定确实需要安全地执行许可证检查,则将其编写为一个小的C扩展,以便可以对许可证检查代码进行额外的难度(但并非不可能!)以进行反向工程,并将大部分代码保留在Python中。


#4楼

您应该看看getdropbox.com上的家伙如何为他们的客户端软件(包括Linux)做到这一点。 破解起来非常棘手,并且需要一些创造性的拆卸才能通过保护机制。


#5楼

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

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

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

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

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

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

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


#6楼

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

话虽这么说,我只是检查google的python混淆,没有发现很多东西。 在.Net解决方案中,混淆是在Windows平台上解决问题的第一种方法,但是我不确定是否有人在Linux上具有可与Mono配合使用的解决方案。

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

一切都取决于权衡。 一方面,您可以轻松地使用python进行软件开发,但在其中隐藏秘密也是非常困难的。 另一方面,您有用汇编器编写的软件,它很难编写,但是更容易隐藏秘密。

您的老板必须在该连续体中的某个位置选择一个可以满足其要求的点。 然后他必须给您工具和时间,以便您可以构建他想要的东西。 但是我敢打赌,他将反对实际的开发成本与潜在的金钱损失。


#7楼

“有没有解决这个问题的好方法?” 不可以。没有任何东西可以防止逆向工程。 DVD机器上的固件甚至都经过了反向工程,并且暴露了AACS加密密钥 。 尽管DMCA将该行为定为刑事犯罪,但这仍然存在。

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

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

  2. 提供重大价值。 如果您的产品非常好-以难以拒绝的价格出售-则没有动力浪费时间和金钱进行任何逆向工程。 逆向工程很昂贵。 使您的产品便宜一些。

  3. 提供升级和增强功能,使任何逆向工程成为一个坏主意。 当下一个版本中断其逆向工程时,没有任何意义。 这可能荒唐至极,但是您应该提供新功能,这些新功能使下一个版本比逆向工程更有价值。

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

  5. 使用过期的许可证密钥。 这是残酷的,会给您带来不好的声誉,但是肯定会使您的软件停止工作。

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


#8楼

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

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


#9楼

根据客户端是谁,一个简单的保护机制,以合理的许可协议相结合,将远远超过任何复杂的许可/加密/模糊系统更有效。

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

将代码作为.pyc文件发送会阻止您的保护被#挫败,但是它几乎不是有效的反盗版保护(就好像有这种技术一样),总之,它不应该实现与公司达成良好的许可协议所能做的一切。

专注于使您的代码尽可能地好用-使满意的客户比防止理论上的盗版给您的公司带来更多的收益。


#10楼

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

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

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


#11楼

Python不是您需要的工具

您必须使用正确的工具来完成正确的事情,并且Python并非旨在被混淆。 恰恰相反 一切都是开放的,或者很容易在Python中显示或修改,因为这是该语言的理念。

如果您想要看不见的东西,请寻找其他工具。 这不是一件坏事,重要的是要存在几种不同的工具以用于不同的用途。

混淆真的很难

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

有法律要求是一个好方法

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

代码保护被高估

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


#12楼

使用Python最好的办法就是使事物变得晦涩难懂。

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

您可能可以通过加密一部分并将其动态解密并将其传递给eval()来添加一些其他模糊性。 但是,无论您做什么,都可以打破它。

所有这些都不会阻止坚定的攻击者拆卸字节码或使用帮助,目录等在您的api中进行挖掘。


#13楼

不要依靠混淆。 正如您已经正确得出的结论,它提供的保护非常有限。 更新:这是指向论文链接,该论文在Dropbox中反向工程了经过混淆的python代码。 这种方法-操作码重映射是一个很好的障碍,但显然可以克服。

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

  • 不值得进行反向工程的时间(您的软件是如此出色,值得付出)
  • 让他们签署合同,并在可行时进行许可证审核。

或者,就像踢屁股的Python IDE WingIDE那样: 放弃代码 。 没错,请放弃代码,让人们回来进行升级和支持。


#14楼

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


#15楼

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

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

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

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


#16楼

我了解您希望客户使用python的功能,但不希望公开源代码。

这是我的建议:

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

(b)使用cython代替Python

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


#17楼

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

为了防止竞争对手将源代码用作自己的源代码或编写受启发的同一代码版本,一种保护的方法是在程序逻辑中添加签名(某些秘密能够证明代码已从您身上被盗)并混淆了python源代码,因此很难阅读和利用。

良好的混淆功能为您的代码增加了基本上相同的保护,与将其编译为可执行文件(和剥离二进制文件)的保护相同。 弄清楚混淆后的复杂代码的工作原理可能比实际编写自己的实现还要困难。

这无助于防止程序被黑客入侵。 即使使用混淆代码,许可证内容也会被破解,并且程序可能会被修改为具有稍微不同的行为(以将代码编译为二进制无助于保护本机程序的相同方式)。

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

混淆代码内部的逻辑签名(例如,您可以创建由程序逻辑使用但也用作签名的值表),可以用来确定代码是否源自您。 如果有人决定将混淆代码模块作为自己产品的一部分使用(即使在对其进行混淆以使其看起来有所不同之后),您也可以证明,该代码已被您的秘密签名窃取。


#18楼

你看过催眠药吗? 它会缩小,混淆和压缩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)

#19楼

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

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

用Cython保护Python源


#20楼

使用相同的方法来保护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)可以在常规代码解释器首次使用时使用

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

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

    \n     char * obfucated_bytecode;\n     Py_ssize_t len;\n     PyFrameObject *框架= PyEval_GetFrame();\n     PyCodeObject * f_code = frame-> f_code;\n     PyObject * co_code = f_code-> co_code;      \n     PyBytes_AsStringAndSize(co_code,&obfucated_bytecode,&len)\n
  • 此函数返回后,最后一条指令将跳转到偏移量0。现在将执行实际的字节码。

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


#21楼

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

这可能正是您所需要的。

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

pypi页面

保护python脚本工作流程

  • your_script.py import pyconcrete
  • pyconcrete将挂钩导入模块
  • 当你的脚本做进口MODULE ,pyconcrete进口吊钩将试图找到MODULE.pye先解密MODULE.pye通过_pyconcrete.pyd和执行解密的数据(如.pyc文件内容)
  • 加密和解密_pyconcrete.pyd秘密密钥记录(例如DLL或SO),秘密密钥将隐藏在二进制代码中,无法在十六进制视图中直接看到

#22楼

长话短说:

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

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

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


#23楼

如果我们专注于软件许可,我建议您看一下我在这里写的另一个Stack Overflow答案以期获得如何构建许可密钥验证系统的灵感。

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

您可以通过pip install licensing进行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公钥等的配置方式。


#24楼

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


#25楼

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

明智的主意:

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

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

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

有关如何执行此操作的教程,请参阅此博客文章 (不是我本人)。 (thx @hithwen)

疯狂的主意:

您可能可以让Cython为每个模块分别存储C文件,然后将它们全部串联起来并使用大量的内联代码进行构建。 这样,您的Python模块是非常单一的,并且很难用通用工具来实现。

超越疯狂:

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


#26楼

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

当jythonc将python代码转换为java,然后将java编译为字节码时,这应该可以很好地工作。 因此,如果您对类进​​行了混淆,那么在反编译之后将很难理解其内容,更不用说恢复实际的代码了。

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


#27楼

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

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

它在ubuntu存储库中可用

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!