简体   繁体   English

无法执行管道时如何在 linux 上创建自解压可执行文件

[英]How to create self-decompressing executables on linux when you cannot execve a pipe

I've been working on a small hack to get the filesize of an executable down.我一直在研究一个小技巧来减小可执行文件的文件大小。 I'm aware there exist tools that do executable compressing properly, but this is more for my own enjoyment than anything serious.我知道存在可以正确执行可执行压缩的工具,但这更多是为了我自己的享受而不是任何严肃的事情。

My idea is to compress the executable with gzip, then embed it in another c program, called the launcher, as an array.我的想法是用 gzip 压缩可执行文件,然后将其作为数组嵌入到另一个称为启动器的 c 程序中。 When the launcher runs, it sets up a piping system like so:当启动器运行时,它会设置一个管道系统,如下所示:

parent launcher -> fork 1 of launcher -> fork 2 of launcher

fork 1 turns itself into gzip, so it decompresses whatever the parent feeds it, and spits out the decompressed version to fork 2. fork 1 将自己变成 gzip,因此它会解压缩父级提供给它的任何内容,并将解压后的版本吐出到 fork 2。

Here's where the hack kicks in. Fork 2 tries to exec the file "/dev/fd/n", where n is the file number of the pipe that goes from fork 1 to fork 2. In essence this means fork 2 will try to execute whatever binary gzip spits out.这就是 hack 开始的地方。 Fork 2 尝试执行文件“/dev/fd/n”,其中 n 是从 fork 1 到 fork 2 的管道的文件号。本质上,这意味着 fork 2 将尝试执行执行任何二进制 gzip 吐出的内容。

However, this doesn't work (surprise surprise.) I tried stracing my sample implementation and the line that does the execv on "/dev/fd/n" returns -1 EACCES (Permission denied).但是,这不起作用(惊喜)。我尝试跟踪我的示例实现,并且在“/dev/fd/n”上执行 execv 的行返回 -1 EACCES(权限被拒绝)。 However, if I open up a terminal and run ls -l /dev/fd/ I get something like:但是,如果我打开一个终端并运行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

All of them have permissions +x for the user (me.) This means it should be executable, no?他们所有人都拥有用户(我)的权限 +x。这意味着它应该是可执行的,不是吗? Or is this just a very strange kernel edge case that says it hasn't got the permissions, but really it can't execute because it's not a real file.或者是说,它已没有得到许可,但实际上它不能执行,因为它不是一个真正的文件,这只是一个非常奇怪的内核边缘情况。

UPDATE after nearly 7 years近 7 年后更新

With the advent of linux "memfd"s, it's now possible to create self-decompressing executables on linux that don't touch the filesystem.随着 linux "memfd" 的出现,现在可以在 linux 上创建不接触文件系统的自解压可执行文件。 See: https://gitlab.com/PoroCYon/vondehi见: https : //gitlab.com/PoroCYon/vondehi

Only files which are mmap able are possible to execute.只有可以执行mmap文件才能执行。 A pipe is unfortunately not mmapable in this way due to its sequential nature and limited buffer size (it may need to re-read earlier code again which would now be gone after reading it once).不幸的是,管道由于其顺序性质和有限的缓冲区大小而无法以这种方式进行 mmapable(它可能需要再次重新读取之前的代码,而这些代码现在在读取一次后就会消失)。

You would have much more luck instead of using a pipe to create a file in a ramfs, mmap it to an area of the memory space of the parent the copy the uncompressed code into the mmap, then finally have the child exec the file in the ramfs, finally unlink the file in ramfs in the parent so it is automatically freed when the child exits.您将有更多的运气,而不是使用管道在 ramfs 中创建文件,将其映射到父级内存空间的一个区域,将未压缩的代码复制到 mmap 中,然后最终让子级在ramfs,最后在父级的 ramfs 中取消链接文件,以便在子级退出时自动释放它。

Hope this helps, if anything is unclear please comment.希望这会有所帮助,如果有什么不清楚的请评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM