3. 固件打包与重打包

固件打包与重打包 学习卡片

任务说明

本案例目标:解包一个固件,修改其文件系统中的特定文件内容,然后使用 firmware-mod-kit(FMK)重新打包,并验证新固件可正常启动。以典型的 OpenWrt 风格固件(包含内核与 SquashFS 根文件系统)为例,完成从解包到重打包的完整闭环。

环境准备

  • 操作系统:Ubuntu 20.04+ / Debian 11+(x86_64)
  • 安装依赖:apt-get install -y git build-essential zlib1g-dev liblzma-dev python3-magic
  • 获取 FMK:git clone https://github.com/rampageX/firmware-mod-kit.git,进入目录后执行 ./configure && make 完成编译

固件准备

由于真实固件体积较大且版权不一,本案例使用 FMK 自带的测试固件作为输入(位于 firmware-mod-kit/tests/ 目录下,文件名为 testfw.bin)。该固件为标准的 OpenWrt 格式:头部 + 内核 + SquashFS 文件系统,适合演示完整流程。若使用真实设备固件,操作步骤完全一致。

关键完整代码(Shell 脚本)

以下脚本实现完整闭环:解包 → 修改文件 → 重打包 → 验证。将脚本保存为 repack.sh 并置于 FMK 根目录下运行:

#!/bin/bash
# repack.sh - 固件解包/修改/重打包/验证闭环
set -euo pipefail

FMK_DIR="$(cd "$(dirname "$0")" && pwd)"
FIRMWARE="$FMK_DIR/tests/testfw.bin"
WORKDIR="$FMK_DIR/repack_work"
OUTPUT="$FMK_DIR/repacked.bin"

# 清理并创建工作目录
rm -rf "$WORKDIR"
mkdir -p "$WORKDIR"

# 1. 解包
cd "$FMK_DIR"
./unsquashfs_all.sh "$FIRMWARE" "$WORKDIR" 2>/dev/null || {
    echo "[ERROR] 解包失败"; exit 1; }
echo "[OK] 解包完成"

# 2. 定位文件系统目录(FMK 解包后根文件系统在 image/ 下)
FS_DIR="$WORKDIR/image"
if [ ! -d "$FS_DIR" ]; then
    echo "[ERROR] 未找到文件系统目录"; exit 1
fi

# 3. 修改文件:向 /etc/banner 追加一行标识
echo "Repacked by FMK $(date +%Y%m%d)" >> "$FS_DIR/etc/banner"
echo "[OK] 已修改 /etc/banner"

# 4. 重打包
./build_firmware.sh "$FIRMWARE" "$WORKDIR" "$OUTPUT" 2>/dev/null || {
    echo "[ERROR] 重打包失败"; exit 1; }
echo "[OK] 重打包完成: $OUTPUT"

# 5. 验证:检查输出文件是否存在且非空
if [ -s "$OUTPUT" ]; then
    echo "[PASS] 固件已生成,大小: $(stat -c%s "$OUTPUT") 字节"
else
    echo "[FAIL] 固件生成异常"
    exit 1
fi

# 6. 验证:重新解包输出固件,确认修改仍在
VERIFY_DIR="$WORKDIR/verify"
mkdir -p "$VERIFY_DIR"
./unsquashfs_all.sh "$OUTPUT" "$VERIFY_DIR" 2>/dev/null
if grep -q "Repacked by FMK" "$VERIFY_DIR/image/etc/banner"; then
    echo "[PASS] 修改内容已持久化到新固件"
else
    echo "[FAIL] 修改内容丢失"
    exit 1
fi

echo "[DONE] 全部验证通过"

运行方式

chmod +x repack.sh
./repack.sh

验证方法与判定标准

  • 脚本退出码为 0,且输出包含 [PASS] 与 [DONE] 行,表示整个流程成功。
  • 文件系统修改生效:脚本第 6 步重新解包输出固件,若在 verify/image/etc/banner 中能 grep 到追加的文本,说明修改已正确写入新固件。
  • 固件结构完整:生成的 repacked.bin 非空且能被 FMK 正常解包,说明头部、内核与文件系统的拼接正确,具备可启动的基本条件。

常见问题

  • 解包失败:确认固件格式为 FMK 支持的 OpenWrt 类型(SquashFS + TRX/日系头部)。若为其他格式(如 UBI、JFFS2),需使用 FMK 中对应的 unsquashfs_all.sh 或 ubifs_extract.sh 等专用工具。
  • 重打包后无法启动:通常因修改文件时破坏了文件系统权限或符号链接。建议仅修改普通文本文件内容,不删除/移动目录结构,不改变文件属主与权限位。
  • 真实设备固件:若固件包含 bootloader 分区或签名校验,重打包后需同时处理签名或校验和,否则设备会拒绝启动。本案例演示的是无签名保护的通用固件流程。