rpmrebuild
1.工具简介:rpmrebuild
rpmrebuild 是一款经典的LinuxRPM包逆向与重构工具,与之对应的是 deb 官方的解包工具。
它的核心能力在于:在没有源代码( SRPM )或不想全量重新编译的情况下,直接对已有的二进制 .rpm 包进行拆包、编辑和重新打包。
在需要进行软件跨平台移植、内部组件二次适配、二进制文件Bug修复、修改默认配置文件、修改包内目录结构时,如果你手头只有一个打好的二进制包,利用它的 --edit-whole 或 --change-files 等功能,可以非常方便地进入沙箱修改文件并原地生成新包,而不需要全量编译然后出包,可谓非常之便利。
2.踩坑与报错排查
在最近处理一批由第三方跨平台工具打出来的 RPM 包时,发现官方原生版本的 rpmrebuild 存在两个严重的问题:
问题一:解包阶段直接崩溃,报错rpm2cpio:Nosuchfile
报错表现:
执行拆包命令时,工具直接报错退出:
rpm2cpio::Nosuchfileordirectory
(RpmUnpack)rpm2cpiofailed,tryingrpm2archive,thismighttakelongtime
原因分析:
使用 strace 抓取底层系统调用后发现,传给 rpm2cpio 的参数是个空字符串。翻阅官方 rpmrebuild.sh 源码发现这是一个低级的变量名Bug:原作者在重构解压模块的 RpmUnpack 函数时,误将存储包路径的全局变量 $RPMREBUILD_PAQUET 写成了未被赋值的 $PAQUET 。
处理方案:
在源码中将相关的 $PAQUET 变量彻底修正为正确的 $RPMREBUILD_PAQUET 。
问题二:跨架构(非标架构)打包报错setarch:未识别的架构
报错表现:
当处理一些带有 amd64 (Debian系惯用命名)或 aarch64 标签的跨平台包时,工具会报错:
setarch:amd64:未识别的架构
#或者在rpmbuild阶段报错:
错误:没有找到可供构建的兼容构架
原因分析:
rpmbuild 拥有极其严格的构建环境校验(会去查对 /usr/lib/rpm/rpmrc 字典),它默认不认识 amd64 这种非标称呼。而 rpmrebuild 脚本试图调用 setarch 去模拟环境,在真正的异构或非标命名面前直接失效报错。
处理方案:
对源码进行深度改造。彻底废弃了原脚本中脆弱的 setarch 逻辑,并在参数解析器中原生引入了 --force-arch 参数。其底层逻辑是:在动态生成 SPEC 文件后,使用 sed 强行删除 BuildArch 属性让 rpmbuild 失去校验基准,随后通过命令行参数将用户指定的 target 和宏变量强行注入,实现无视宿主机物理架构的“强制交叉重打包”。
3. 开箱即用的修复版获取
如果你也遇到了上述报错,或者需要处理复杂的跨架构 RPM 包重构,为了避免浪费时间去踩这些上古 bash 脚本的坑,可以直接使用我修复并增强后的版本。
增强版主要特性:
修复了空变量导致解压失败的致命 Bug 。
原生引入 --force-arch=<arch> 参数,完美绕过 rpmbuild 的严苛校验,实现 amd64 等非标架构或异构架构的直接重压包
获取方式(GitHub):
(由于是 Fork 仓库,GitHub 默认搜索不到,请直接点击链接或使用 fork:true 语法搜索)
使用方式
安装步骤
直接从源码编译安装即可:
git clone https://github.com/KongQBin/rpmrebuild.git
cd ./rpmrebuild/src
make
sudo make install
重新打包
当你拿到一个需要修改的 target-app.rpm 时,请按照以下顺序操作:
触发解包与拦截
在终端中执行以下命令唤起重打包流程:
rpmrebuild --package --edit-whole --force-arch=amd64 target-app.rpm
`--edit-whole`: 核心参数,拦截并允许全面编辑。
`--force-arch=<arch>`: 强行指定目标架构(如 `amd64`, `aarch64`, `loongarch64` ,`sw_64`等)。
注意:传入的架构名必须在目标系统的 `rpm` 兼容字典中存在(或硬件原生支持),否则压包虽然成功,但最终 `rpm -ivh` 安装时可能会因不认识架构而遭拒。
当然也可以不设置 --force-arch 以作为普通的 rpmrebuild 使用。
进入沙箱替换文件
命令执行后,终端会自动弹出一个 `vim` 界面(这是动态逆向生成的 `spec` 文件内容)。
此时先不要在这个 `vim` 里做任何操作,让进程挂起。
打开一个全新的终端窗口,进入以下目录:
cd ~/.tmp/rpmrebuild.*/work/root/
这里就是 `rpmrebuild` 提取出的包内安装文件沙箱,完整保留了原包的目录结构。
现在,就可以随心所欲地在沙箱内修改配置文件、替换二进制库、或者增删脚本了。
同步修改 SPEC 文件
沙箱内的文件修改完成后,回到刚才那个挂着 `vim` 的终端。
规则:
如果你在沙箱里只是修改或替换了原有文件,无需关心 `SPEC`,直接输入 `:wq` 保存退出即可。
如果你在沙箱里新增或删除了文件,必须在当前 `vim` 界面的 `%files` 段落中,手动补上或删掉对应的文件绝对路径,否则出包时会报错“文件未打包”或“找不到文件”。
修改完成后,输入 `:wq` 保存退出。
确认并生成新包
退出 `vim` 后,终端会提示:`Do you want to continue ? (y/N)。`
输入 `y` 并回车。
静待底层 `rpmbuild` 跑完流程,终端会打印出最新生成的 `RPM` 包的绝对路径(通常在 `~/rpmbuild/RPMS/` 目录下)。
最后大功告成!
浙公网安备 33010602011771号