如何将Linux shell脚本编译成独立的可执行二进制文件(即不仅是chmod 755)?

59
我正在寻找一个免费的开源工具集,可以将各种“经典”的脚本语言(例如 Korn Shell、ksh、csh、bash 等)编译成一个可执行文件,如果脚本调用其他程序或可执行文件,则它们应被包含在单个可执行文件中。
原因:
1. 为了向客户交付代码而对代码进行混淆,以保护我们的知识产权 - 交付到客户自己的机器/系统上,我无法控制有关访问权限设置方面的任何内容。因此,程序文件必须是二进制的,通过查看文本编辑器或 hexdump 查看时无法轻易地查看其运行方式。 2. 为客户制作一个单一且简单的部署程序,不需要或只需最少的外部依赖。
我希望能够使用简单的方法,无需使用软件包管理器,因为:
1. 我不能指望客户的知识来执行(解压)打包说明 2. 我不能指望他们的计算机安装软件包的政策(也包括第三方)。
最简单的方法是能够将代码编译成一个单独的可执行文件,该文件不需要任何依赖项即可直接运行。
7个回答

50

1
我以前从未听说过这个,但它似乎可以做到OP所要求的。请注意,它可能与某些bash或ksh功能不兼容,但这对于OP的目的可能并不重要。它还具有一个功能,可以为编译后的二进制文件设置到期日期。 - ConcernedOfTunbridgeWells
1
这是明确的答案。我一直在使用SHC编译我的shell脚本,它已经存在了很长时间,如果我没记错的话,应该是从2002年开始。SHC是由Francisco Javier Rosales García制作的。虽然它有点老旧,但仍然可以使用。 - Louie Miranda
3
shc不是有效的混淆工具 -- 在运行时轻易地读取脚本内容。使用 stracesysdig,或者仅对 /proc 进行适当扫描即可提取原始脚本。 - Charles Duffy
“shc”并不是有效的混淆技术,这一点我毫不争辩。但在这里,“shc”并非用于混淆,而是将shell脚本以C代码的形式提供,然后编译成机器码二进制可执行文件,从而实现了一般意义上的混淆。 - therobyouknow
3
我意识到这是六年前发布的,但是运行由 shc 编译的程序仍然需要安装 shell 和所有被调用的实用程序。唯一它有用的地方就是(弱)混淆。 - Fox
显示剩余3条评论

9
你可以使用这个工具: http://megastep.org/makeself/
该工具可以生成一个Shell脚本自动解压缩捆绑的tar.gz归档文件到临时目录,然后在解压缩时可以运行任意命令。
使用此工具,您只需向客户端提供一个Shell脚本。
该脚本将会将你的ofbsh混淆脚本和二进制文件解压缩到/tmp目录,并在解压缩时透明地运行它们。

接受的答案是使用SHC,如下所示:https://dev59.com/8Ww15IYBdhLWcg3wv-RM#6438272 - therobyouknow
@therobyouknow,关于SHC的被接受答案并不支持将其他可执行文件捆绑在一起,而你的问题中提到了这是一个要求。 - Charles Duffy
SHC不支持在其他可执行文件中捆绑。我相信你的话,但它不需要捆绑在其他可执行文件中——如果SHC的输出是纯C代码,那么这个C代码可以使用标准工具进行编译、链接和构建,这些工具支持捆绑。 - therobyouknow
可执行文件、捆绑文件...这听起来很像SFX包(在7zip、winrar中)。我使用了shc,效果很好,甚至创建了一个obfsh脚本的可执行二进制文件来尝试将它们结合起来。 - m3nda

5
你可以使用类似于ofbsh的工具来混淆shell脚本。但是在Unix中,将其他程序捆绑到单个可执行文件中并不容易。通常的安装方法是为您所使用平台的软件包管理器(例如rpm, deb, pkg)构建一个软件包或提供一个tarball以在适当的目录中解压缩。
如果您需要一个可执行文件来解压缩内容,则可以尝试使用shell归档。查看shar(1)的文档,看看是否可以满足您的需求。
如果你确实需要一个脚本能力来将多个C程序粘合在一起,那么看看Tcl语言吧。它有一个API,旨在轻松包装期望看到argv[]样式参数的C程序。你甚至可以将C代码块嵌入到自定义的Tcl解释器中,并用各种Tcl脚本将其粘合在一起。
如果你真的需要让它不透明,你可以加密tcl脚本,并将整个东西包装在一个解密tcl脚本的缓冲区并在其中运行Tcl解释器的东西中。Tcl可以接受来自文件或char*缓冲区的脚本,因此未加密的脚本从未必须命中文件系统。

我更喜欢不需要软件包管理器的简单解决方案。首先,我不能确保客户具备执行此类操作的知识;其次,我不能依赖管控他们机器安装软件包的政策(甚至来自第三方)。最简单的解决方案是编译成适当的机器码并生成一个单一的可执行文件,该文件可以直接运行而无需任何依赖项。 - therobyouknow
对于ofbsh而言,这可能在某些情况下很有用。虽然代码看起来难以阅读可能会损害客户的感知,但是也许可以向客户解释代码被故意混淆了以便他们无法理解——除非我们试图向第三方付费客户隐藏事情,否则这并不一定有助于建立基于信任的关系。 - therobyouknow
最好一开始就提供可执行文件,这样可以消除任何隐藏方面的顾虑,这也可能是客户期望的,并且不会透露软件的实现方式。如果提供普通的可执行文件,没有人会觉得有什么被隐瞒的东西。 - therobyouknow

4

shc

我已修改原始源代码并升级到一个包含一些新功能和错误修复的新版本。 它可以在这里找到。

示例用法:

shc -f script.sh -o binary_name

script.sh将被编译成一个名为binary_name的二进制文件。

请注意,您仍需要在系统中安装所需的shell才能运行此可执行文件。


这在Ubuntu 18.04中似乎无法正常工作,是否有更新? - qodeninja
@qodeninja:请在项目的问题页面提供详细信息。你可能做错了什么。 - Jahid
谢谢您的回复。您介意我给您发电子邮件吗?我对您的项目非常感兴趣,但是无法弄清楚如何使其工作。 - qodeninja

2

arx 是一款出色的打包工具,您可以将混淆器整合到它的工作流程中。


1

您可用的选项:

  • 在您的代码中编写逻辑,当首次在一个框上运行代码时,它将检查所有必需包是否存在。如果不存在,代码将自动获取包并安装它们......无需要求用户做任何事情。唯一需要询问用户的问题是“是否继续安装上述软件包?(Y/N)”。除此之外的任何东西都太多了。

  • 完成以上代码后(是的,我知道你可能很难编写它,或者可能很简单,我不知道你的编码能力),将已完成的代码复制并粘贴到类似 kinglazy.com 的网站上,然后将生成一个实际的可执行文件。

这种特定选项有许多好处:

  • 是的,您将能够运行加密版本的脚本,而不会暴露任何专有信息。
  • 没有人可以尝试“查看”您的脚本,因为如果他们这样做,他们将看到一堆无法理解的加密术语。
  • 没有人可以尝试修改您的脚本,因为如果他们这样做,脚本将立即变得无法操作。
  • 没有人可以在您的脚本上运行调试器以查看其工作原理。如果他们这样做,脚本将中止。
  • 此外,没有人可以在同一服务器上创建您脚本的副本。如果他们这样做,它将中止并且无法工作。它只允许用户创建符号链接到您想要脚本所在的原始位置。

我可能漏掉了一些您要求的内容,但我相信以上内容已经满足了您的大部分要求。

不确定是否适用于其他脚本,但肯定适用于shell脚本。


-1

1
很遗憾,该域名已经失效。 - luca76
那个链接只是重定向到网站的主页。 - O5 Command Stands With Ukraine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接