有没有办法从管道执行本机二进制文件?

Ale*_*x B 14 shell executable stdout

echo 'main(){}' | gcc -xc - -o /dev/stdout | ???
Run Code Online (Sandbox Code Playgroud)

有没有办法在类 Unix 系统上运行输出二进制文件?

编辑:我需要它在沙盒环境中运行 g++ 的输出,在那里我不能写任何文件(我保证没有恶意)。

Con*_*lls 10

我不相信这是可能的。在EXEC(2)系统调用总是需要的文件名或绝对路径(文件名是总是一个char*)。 posix_spawn对文件名也有类似的要求。

您可以做的最接近的事情是将输出通过管道传输到命名管道并尝试从管道执行。这可能有效,尽管 shell 可能拒绝执行任何没有--x--x--x设置位的文件。创建管道,mkfifo(1)看看你是否可以让它工作。

另一种方法是编写一些读取标准输入的内容,将文件写入临时区域,在其上设置 --x 位,分叉和执行然后删除文件。inode 和内容将一直保留到程序完成执行,但无法通过文件系统访问。当进程终止时,inode 将被释放并且存储将返回到空闲列表。

编辑:正如 Mat 指出的那样,第一种方法将不起作用,因为加载程序将尝试在可执行文件中请求页面,这将在文件上生成随机搜索流量,而这在管道上是不可能的。这留下了类似于第二种方法的某种方法。

  • 如果管道技巧有效,我会感到非常惊讶 - 你不能在管道上进行随机搜索,也不能映射它们 - 我很确定这会惹恼运行时加载器/链接器:) 你的第二个建议看起来不错但是,没有临时文件就无法想出任何东西。 (3认同)

kan*_*kan 7

使用 memfd 系统调用的解决方案:https : //github.com/abbat/elfexec

它在内存中创建一个命名文件描述符,可以在exec. 一个伪代码:

#include <linux/memfd.h>
...
int memfd = syscall(SYS_memfd_create, "someName", 0);
...
write(memfd,... elf-content...);
...
fexecve(memfd, argv, environ);
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以尝试tcc,它将一步编译和执行程序,而无需编写任何中间文件。它不是 gcc,这对您来说可能是个问题,但它的速度非常快,因此就您的目的而言,它甚至可能比 gcc 更好。