【问题标题】:How to create self-decompressing executables on linux when you cannot execve a pipe无法执行管道时如何在 linux 上创建自解压可执行文件
【发布时间】: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

【问题讨论】:

    标签: c linux pipe exec


    【解决方案1】:

    只有mmap 能够执行的文件才能执行。不幸的是,由于管道的顺序性和有限的缓冲区大小,管道不能以这种方式映射(它可能需要再次重新读取之前的代码,而这些代码在读取一次后就会消失)。

    您将有更多的运气,而不是使用管道在 ramfs 中创建文件,将其 mmap 到父内存空间的一个区域,将未压缩的代码复制到 mmap,然后最终让子执行ramfs 中的文件,最后在父级中取消链接 ramfs 中的文件,以便在子级退出时自动释放它。

    希望对你有帮助,如果有不清楚的地方请评论。

    【讨论】:

    • ramfs 是指 /tmp 吗?我一直认为 /tmp 是这样的
    • @blacklemon67 /tmp 有时是 ramfs,尽管在某些较旧的系统上它是磁盘上的真实文件系统,ramfs 是放置在 ram 中而不是磁盘上的文件系统,因此会尽快销毁当你完成它时。请参阅此处了解如何制作jamescoyle.net/how-to/943-create-a-ram-disk-in-linux
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多