Common lisp 为什么UPX会破坏已编译的SBCL应用程序?

Common lisp 为什么UPX会破坏已编译的SBCL应用程序?,common-lisp,sbcl,upx,Common Lisp,Sbcl,Upx,这基本上是一个愚蠢的问题,因为UPX(一种从可执行文件中挤出额外字节的工具)在该工具内置的压缩上节省了少量空间 一个非常小的演示应用程序创建一个42兆字节的文件。可以理解,因为SBCL环境并不小 将--compress core选项传递到buildapp将压缩到9.2MB 我想我应该试着在生成的二进制文件上抛出UPX,节省的字节数只多了几个:9994288->9871360 然而,生成的文件不再运行——它只是跳入SBCL REPL(没有错误,就好像我只是手动运行了SBCL),一些人在那里摸索发现

这基本上是一个愚蠢的问题,因为UPX(一种从可执行文件中挤出额外字节的工具)在该工具内置的压缩上节省了少量空间

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

--compress core
选项传递到
buildapp
将压缩到9.2MB

我想我应该试着在生成的二进制文件上抛出UPX,节省的字节数只多了几个:
9994288->9871360

然而,生成的文件不再运行——它只是跳入SBCL REPL(没有错误,就好像我只是手动运行了
SBCL
),一些人在那里摸索发现组成我的测试程序的函数不再存在


UPX对导致这种破坏的二进制文件做了什么?这可能不是答案,但它可以作为一个线索:我发现,如果在使用
sb ext:save lisp and die
创建的SBCL可执行文件的末尾添加任何内容,即使是一个字节,那么所有的定义都会消失,正如您所描述的

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

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

UPX压缩可执行文件,可能在末尾包含那个神奇的数字。当SBCL打开其UPX压缩的self-on磁盘时,它在最后找不到“LCB”,因此它假定没有附加到可执行文件的核心


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

这可能不是答案,但它可以作为一个线索:我发现,如果添加任何内容,即使是一个字节,在使用
sbext:save lisp and die
创建的SBCL可执行文件的末尾,所有定义都将消失,正如您所描述的那样

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

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

UPX压缩可执行文件,可能在末尾包含那个神奇的数字。当SBCL打开其UPX压缩的self-on磁盘时,它在最后找不到“LCB”,因此它假定没有附加到可执行文件的核心

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