1

这主要是一个愚蠢的问题,因为 UPX(一种从可执行文件中提取额外字节的工具)比buildapp工具中的内置压缩节省了少量空间。

一个非常小的演示应用程序会创建一个 42 兆字节的文件。可以理解,因为 SBCL 环境并不小。

传递--compress-core选项将其buildapp缩小到 9.2MB。

我想我会尝试将 UPX 扔到生成的二进制文件中,而节省的只是更多的字节:9994288 -> 9871360

但是,生成的文件不再运行 - 它只是跳转到 SBCL REPL(没有错误,就好像我只是手动运行一样sbcl),并且在那里进行一些探索表明构成我的测试程序的函数不再存在。

UPX 对导致这种破坏的二进制文件做了什么?

4

1 回答 1

1

这可能不是答案,但它可以作为一个线索:我发现如果你添加任何东西,即使是一个字节,到使用 创建的 SBCL 可执行文件的末尾sb-ext:save-lisp-and-die,那么所有定义都会消失,就像你描述的那样.

也许 SBCL 通过将核心(包含您的定义)附加到 SBCL ELF(或 Windows 上的 PE)二进制文件的副本以及末尾的一些元数据来创建可执行文件,以便 SBCL 仍然可以找到核心的开头,即使它已附加到一个可执行文件。

如果您对使用 创建的可执行文件进行十六进制编辑save-lisp-and-die,您会发现它以字符串“LCBS”(SBCL 向后)结尾,这似乎支持我的理论。“LCBS”可能是一个神奇的数字,让 SBCL 知道是的,这个可执行文件包含自己的核心。

UPX 压缩可执行文件,最后可能包括那个幻数。当 SBCL 在磁盘上打开它的 UPX 压缩后的 self 时,它最后不会找到“LCBS”,因此它假定可执行文件没有附加核心。

如果是这种情况,我无法解释为什么标准库似乎仍然存在。在这种情况下,可能会加载 SBCL /usr/lib/sbcl/sbcl.core(或 Windows 上的等效项)。这可以通过将可执行文件移动到未安装 SBCL 的机器上进行测试,并查看它是否可以正常工作,如果可以,您是否还有carcdrlist等。

于 2016-07-31T06:50:39.850 回答