You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将char缓冲区作为可执行代码传入exec系列函数调用?

可行实现方案

以下方案均针对你硬编码的ELF格式二进制适用:

方案1:内存临时文件执行(最通用,完全匹配exec语义)

这是安全性最高、实现成本最低的方案,全程无磁盘文件落盘,不会产生残留风险:

  • 利用Linux系统的memfd_create系统调用,直接在内存中创建匿名文件描述符,不需要挂载特殊文件系统
  • 操作流程:
    1. 调用memfd_create("tmp_exec_bin", MFD_CLOEXEC)创建内存文件描述符
    2. 将硬编码的code数组完整写入该文件描述符
    3. 直接调用fexecve传入该文件描述符、argv参数数组、环境变量数组即可完成执行,完全符合你要的类exec调用效果
    4. 若运行环境glibc版本较低不支持fexecve,可以拼接路径/proc/self/fd/[你的fd编号],将该路径传给普通的execve函数即可
  • 参考实现代码:
#include <linux/memfd.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>

// 你的硬编码二进制数组和长度
extern const unsigned char code[];
extern const size_t code_len;

int exec_hardcode_bin(char *const argv[], char *const envp[]) {
    int fd = syscall(SYS_memfd_create, "exec_bin", MFD_CLOEXEC);
    if (fd < 0) {
        perror("memfd_create 调用失败");
        return -1;
    }
    if (write(fd, code, code_len) != code_len) {
        perror("二进制写入内存文件失败");
        close(fd);
        return -1;
    }
    // 优先用fexecve直接执行
    int ret = fexecve(fd, argv, envp);
    // 失败兜底用proc路径执行
    if (ret < 0) {
        char proc_path[64];
        snprintf(proc_path, sizeof(proc_path), "/proc/self/fd/%d", fd);
        ret = execve(proc_path, argv, envp);
    }
    close(fd);
    return ret;
}
  • 优势:完全遵循exec的原生语义,执行后原进程映像会被完全替换,不需要手动处理ELF加载、段映射等底层逻辑,安全性满足要求。

方案2:手动ELF加载执行(适配特殊无memfd环境)

如果运行环境不支持memfd_create和proc文件系统,可以自己实现轻量ELF加载器:

  • 手动解析硬编码的ELF头、程序头,将可执行段、数据段映射到进程虚拟地址的对应位置
  • 手动构造栈结构,写入argc、argv、环境变量、辅助向量等执行必要信息
  • 最后跳转至ELF入口地址执行
  • 注意:该方案不会自动替换原进程的完整映像,原进程打开的文件描述符、信号处理规则等资源会被保留,如果需要完全等价exec的语义需要手动清理这些资源,实现复杂度较高。

注意事项

  • 如果硬编码的是静态链接ELF,上述两种方案都可以正常运行;如果是动态链接ELF,需要运行环境存在对应的动态链接器和依赖库才能正常执行
  • 硬编码的二进制数组要注意字节对齐,数组长度必须和实际二进制大小完全一致,避免写入内容不完整导致执行崩溃

内容的提问来源于stack exchange,提问作者psionic12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 09:24:04