当前位置:首页 > 技术 > 正文内容

通过binfmt_misc优化CGI调试流程

访客 技术 2026年6月30日 1

通过binfmt_misc优化CGI调试流程

binfmt_misc 是 Linux 内核提供的一种机制,允许内核根据文件格式(如 ELF 头)将特定程序交由用户态解释器处理。例如,在启用 qemu-user 的情况下,ARM64 架构的 ELF 程序可以在 x86-64 Linux 系统上直接通过 execve() 调用成功运行。

可以通过命令 cat /proc/sys/fs/binfmt_misc/status 检查 binfmt_misc 是否已启用。通常情况下,默认是开启的,并且会自动注册与已安装的 qemu 相关的配置文件。

注册新的配置文件

可以使用以下格式注册新的配置文件:

echo ":name:type:offset:magic:mask:interpreter:flags" > /proc/sys/fs/binfmt_misc/register

参数说明

  • type: 可以是 EM 类型。
  • 如果为 E 类型,则可执行文件格式由文件扩展名识别,此时忽略 offsetmask 参数。
  • 如果为 M 类型,则通过文件中指定偏移位置的魔数(magic number)来识别。
  • flags: 控制解析器行为的标志位。
  • O: 当多个规则冲突时,优先匹配具有此标志的解析器。
  • E: 表示该解析器用于执行可执行文件。
  • F: 每次访问 register 文件时重新加载解析器配置。
  • C: 解析器配置仅在系统启动时加载一次。
  • B: 允许使用特权解析器执行文件。
  • M: 强制验证魔数。

注意:offset + size(magic) 必须小于 128,解释器字符串不得超过 127 个字符。

示例实验

即使目标文件 ./xxx 不是合法的可执行程序,只要创建适当的配置文件并指定 typeinterpreter,满足 interpreter ./xxx 是合法命令即可运行。

取消注册配置文件可通过以下命令实现:

echo -1 > /proc/sys/fs/binfmt_misc/xxx

也可以基于文件后缀进行匹配。

系统级调试

如果手中有真实设备,可以直接使用远程调试工具 gdbserver 进行调试。但有时可能会遇到断点无效的问题,常见的解决方法是对程序进行修补,插入一个无限循环 while(1)。然而这种方法较为繁琐,而通过 binfmt_misc 机制可以在第一次运行目标程序时,自动将其挂载到 gdbserver 上进行远程调试。

配置注册

首先注册一个新的规则:

echo ":cgi_test:E::cgi::/home/zikh/Desktop/ggs/binfmt_misc/debug:O" > /proc/sys/fs/binfmt_misc/register

自定义调试程序代码

以下是一个简单的调试脚本示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    char buf[100];
    char tmp_exec[200];
    const char *gdb_path = "/usr/bin/gdbserver";
    const char *target_config = "test2.cgi";

    // 分配内存用于存储新的参数列表
    char **new_argv = calloc(argc + 10, sizeof(char *));
    if (!new_argv) {
        perror("calloc failed");
        exit(EXIT_FAILURE);
    }

    // 提取目标程序名称
    const char *name = strrchr(argv[1], '/');
    if (name) {
        name++;
    } else {
        name = argv[1];
    }

    // 创建临时文件路径
    snprintf(tmp_exec, sizeof(tmp_exec), "/tmp/%s.tmp", name);
    snprintf(buf, sizeof(buf), "cp %s %s", argv[1], tmp_exec);
    system(buf);

    // 判断是否为目标 CGI 文件
    if (argc > 1 && strstr(argv[1], target_config)) {
        new_argv[0] = gdb_path;
        new_argv[1] = "0.0.0.0:1234"; // GDB Server 地址和端口
        new_argv[2] = tmp_exec;

        // 添加原始参数
        for (int i = 2; i < argc; i++) {
            new_argv[i + 1] = argv[i];
        }

        // 使用 GDB Server 启动目标程序
        execv(gdb_path, new_argv);
    } else {
        new_argv[0] = tmp_exec;

        // 直接运行目标程序
        for (int i = 2; i < argc; i++) {
            new_argv[i - 1] = argv[i];
        }

        execv(tmp_exec, new_argv);
    }

    perror("execv failed");
    free(new_argv);
    return EXIT_FAILURE;
}

qemu-user 模拟下的调试

尝试在 qemu-user 模拟环境下调试 CGI 程序时,发现链接到 busybox 的命令无法正常工作。问题可能出在 binfmt_misc 拦截 ARM ELF 文件后传递给调试程序时,参数构造不正确,导致动态链接的 ELF 文件启动失败。

错误信息如下:

测试发现,恢复 /proc/sys/fs/binfmt_misc/qemu-arm 的默认配置后可以正常工作。尝试调整 flags 参数也未解决问题。

修改后的规则示例:

echo ':qemu-arm:M:0:\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu_debug:CF' > /proc/sys/fs/binfmt_misc/register

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。