CAdapt 是面向 Linux 的 ELF 元数据修补工具,可调整已编译程序、动态库和内核模块的符号版本要求。适用于已确认 ABI 兼容、但版本元数据阻止运行或加载的场景。
- GLIBC:读取指定
libc.so.6的符号版本,适配单个 ELF 或目录;原版本可用时优先保留,保留符号隐藏标记。 - 动态链接器:修改 ELF 的
PT_INTERP解释器路径。等长或更短的新路径原地改写,剩余字节补零;更长的新路径会重写文件——新串追加到文件末尾,PT_INTERP与.interp节区改指向新位置,其余内容与全部偏移保持不动。写入前校验新解释器存在、可执行、为同架构ET_DYN且本身无PT_INTERP,写入后重读验证。可用-p只查看、--dry-run只试运行。 - RPATH:修改 ELF 的
DT_RPATH/DT_RUNPATH运行库搜索路径。等长或更短的新路径原地改写进.dynstr,剩余字节补零;更长路径会重写文件——新.dynstr追加到文件末尾的新 LOAD 段里,DT_STRTAB/DT_STRSZ与 RPATH 条目按新位置重算(patchelf 的做法);无 RPATH 的目标会新增一条DT_RUNPATH(.dynamic增长一个槽位)。同时存在两项时优先改DT_RUNPATH。可用--print-rpath只查看、--dry-run只试运行,空字符串表示清空。 - KMOD:修改
.ko的vermagic与传统__versions格式的符号 CRC。 - 32 位与多候选:支持 32 位与 64 位小端 ELF。
-c(libc)与-i(解释器)均可重复指定(如 32 位与 64 位各一个),每个目标按类别、字节序、机器架构挑选匹配的候选;目录可同时包含两种文件。指定的 libc/解释器与目标不匹配时警告并跳过该文件;大端 ELF 暂不支持,警告并跳过。32 位内核模块的__versions条目用 4 字节 CRC;目标模块架构与当前系统不一致、而符号 CRC 或vermagic又取自当前系统时,警告并拒绝修改。
需要 Linux、支持 GNU++11 的 C++ 编译器和 CMake 3.5+。测试额外需要 Python 3.7+ 与 cc。
cmake -S . -B build -DCADAPT_STRICT=ON
cmake --build build
ctest --test-dir build --output-on-failure语言标准固定为 GNU++11。CADAPT_STRICT=ON 将编译警告和语言扩展视为错误。仅构建工具可加 -DBUILD_TESTING=OFF,无需 Python。较旧 CMake 可进入构建目录执行 cmake .. 和 ctest。在旧系统运行时,请使用对应的 GLIBC/sysroot 构建。
./build/cadapt -h
# GLIBC
./build/cadapt -c /path/to/libc.so.6 -t /path/to/target_elf_or_directory
# KMOD
./build/cadapt -m ./my_driver.ko -s ./Module.symvers \
-v "4.18.0-193.el8.x86_64 SMP mod_unload"
# 动态链接器(解释器)
./build/cadapt -i /lib64/ld-linux-x86-64.so.2 -t ./my_program
./build/cadapt -p -t ./my_program
./build/cadapt -i /lib64/ld-linux-x86-64.so.2 -t ./my_program --dry-run
# 混合目录:32 位与 64 位目标各自匹配对应的 libc/解释器
./build/cadapt -c /lib/libc.so.6 -c /lib64/libc.so.6 -t ./mixed_dir
./build/cadapt -i /lib/ld-linux.so.2 -i /lib64/ld-linux-x86-64.so.2 -t ./mixed_dir- 提供
-s/--symvers时,CRC 仅取自该文件;缺失符号不会从当前内核静默兜底。 - 省略
-s或-v时,按需采集当前系统模块的 CRC 或vermagic。使用系统 CRC 时,显式指定的vermagic必须与该来源一致;适配其他内核请提供对应的Module.symvers和vermagic。 - KMOD 完整校验后才写入;校验失败时目标保持不变。同步写入失败会返回失败,但不保证回滚已写入内容。
- 目录扫描跳过符号链接。正常帮助返回
0,参数或适配失败返回非零退出码。
2026-10-12,项目借助 OpenAI Codex 完成了一轮代码审查、问题修复和回归验证。 修复记录可在提交历史中查阅,验证基线为 4af3cbc。
- 本地使用 GCC 9.5 和 GCC 15.2 完成 GNU++11 严格编译,八个 CTest 检查全部通过。
- 检查覆盖命令行、GLIBC 多版本与隐藏位、KMOD CRC/来源冲突、异常 ELF、扫描与同步失败、日志和资源所有权。
- 自动回归脚本位于 tests/,CI 配置位于 ci.yml;远程运行状态见页面顶部徽章。
上述说明记录的是 AI 辅助审查与实际测试结果,不代表 OpenAI 官方认证,也不保证任意文件或 ABI 的兼容性。
- 当前支持带节头表的 32 位与 64 位小端 ELF;不支持大端或扩展节区编号。
- 解释器适配:更长路径会重写文件(临时文件 + 原子替换),新文件换 inode,符号链接目标会被拒绝;
.interp节区的sh_addr仍指向旧位置(只改sh_offset/sh_size),以PT_INTERP为准。 - RPATH 适配:更长路径会重写文件(临时文件 + 原子替换),新文件换 inode,符号链接目标会被拒绝;新段的虚址取所有 LOAD 段最高虚址之上,程序头表无空闲槽位时会整个搬到新段里(ET_EXEC 且原来没有
PT_PHDR时补一个)。 - 扩展 KMOD 节区
__version_ext_names/__version_ext_crcs会明确拒绝修改。 - 工具原地修改文件,请先备份。仅修改元数据,无法检查或修复 ABI 差异;程序仍可能崩溃,错误的内核模块可能引发 Kernel Panic/Oops。
- 错误日志写入可执行文件目录下的
cadaptErrlog.txt;日志不可写时会输出到 stderr。