在共享库中打包可执行文件?

时间:2009-12-08 21:25:40

标签: linux

是否可以将可执行文件打包到共享库中并调用所述库中的函数:

  • 解压缩可执行文件
  • 通过fork
  • 使用可执行文件

我问的原因是因为我最近遇到的情况是我的共享库被加载到“沙盒”环境中(可能是基于chroot的)并且我真的希望能够为一个单独的进程生成一个单独的进程可执行(松散耦合)。

2 个答案:

答案 0 :(得分:2)

只要您有权写入未安装noexec的文件系统上的目录,那么您只需将可执行文件存储在unsigned char的大型数组中并将其写出来fwrite,然后使用fork / exec来运行它。

实际上,最好的解决方案就是在没有 fork()的情况下使用exec - 只需让孩子一方在fork()之后调用另一个函数(然后在完成该功能时退出_exit()

答案 1 :(得分:1)

完全合情合理。

static const char program[] = {
    0x7f, 0x45, 0x4c, 0x46, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x43, 0x05, 0x02, 0x00, 0x03, 0x00, 0x1a, 0x00, 0x43, 0x05,
    0x1a, 0x00, 0x43, 0x05, 0x04, 0x00, 0x00, 0x00, 0xb9, 0x31, 0x00, 0x43,
    0x05, 0xb2, 0x0d, 0xcd, 0x80, 0x25, 0x20, 0x00, 0x01, 0x00, 0x93, 0xcd,
    0x80, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c,
    0x64, 0x0a
};

void hello(void) {
    int fd;
    pid_t child;
    char name[1024];
    char *tmp = getenv("TEMP") ?: getenv("TMP") ?: "/tmp";
    if (strlen(tmp) > sizeof(name) - 8) return;
    sprintf(name, "%s/XXXXXX", tmp);
    fd = mkstemp(name);
    if (fd == -1) return;
    if (write(fd, program, sizeof(program)) < sizeof(program)) {
        close(fd);
        unlink(name);
        return;
    }
    fchmod(fd, 0700);
    close(fd);
    (child = fork()) ? waitpid(child, 0, 0) : execl(name, name);
    unlink(name);
}

在Linux x86或兼容版上运行时,此功能会在屏幕上显示“hello,world”。

但是,我绝对不会推荐这个。如果你想要一个单独的二进制文件,只需发布​​一个单独的二进制文件,并要求它与你的库一起安装在沙盒中。