【发布时间】:2015-01-06 14:53:12
【问题描述】:
我一直在做一个小技巧来减小可执行文件的文件大小。我知道存在可以正确压缩可执行文件的工具,但这更多是为了我自己的乐趣,而不是任何严肃的事情。
我的想法是使用 gzip 压缩可执行文件,然后将其作为数组嵌入到另一个名为启动器的 c 程序中。当启动器运行时,它会建立一个管道系统,如下所示:
parent launcher -> fork 1 of launcher -> fork 2 of launcher
fork 1 将自身转换为 gzip,因此它会解压缩父级提供的任何内容,并将解压缩后的版本吐出到 fork 2。
这就是破解的开始。Fork 2 尝试执行文件“/dev/fd/n”,其中 n 是从 fork 1 到 fork 2 的管道的文件号。本质上,这意味着 fork 2将尝试执行 gzip 输出的任何二进制文件。
但是,这不起作用(令人惊讶。)我尝试跟踪我的示例实现,并且在“/dev/fd/n”上执行 execv 的行返回 -1 EACCES(权限被拒绝)。但是,如果我打开一个终端并运行ls -l /dev/fd/,我会得到类似:
lrwx------ 1 blackle users 64 Nov 10 05:14 0 -> /dev/pts/0
lrwx------ 1 blackle users 64 Nov 10 05:14 1 -> /dev/pts/0
lrwx------ 1 blackle users 64 Nov 10 05:14 2 -> /dev/pts/0
lr-x------ 1 blackle users 64 Nov 10 05:14 3 -> /proc/17138/fd
他们都拥有用户(我)的权限+x。这意味着它应该是可执行的,不是吗?或者这只是一个非常奇怪的内核边缘情况,说它没有获得权限,但实际上它无法执行,因为它不是一个真实的文件。
近 7 年后更新
随着 linux“memfd”的出现,现在可以在 linux 上创建不接触文件系统的自解压可执行文件。见:https://gitlab.com/PoroCYon/vondehi
【问题讨论】: