Android 11 Recovery 集成 BusyBox 实战:从 PRODUCT_COPY_FILES 到 Root 权限验证

📅 2026/8/27 12:04:54
Android 11 Recovery 集成 BusyBox 实战:从 PRODUCT_COPY_FILES 到 Root 权限验证
一、先说结论在 Android Recovery 中使用 BusyBox通常需要确认三个问题BusyBox 是否被复制进 Recovery 文件系统BusyBox 是否具有可执行权限Recovery 当前 shell 是否具备执行这些命令所需的权限。本项目最终验证结果是BusyBox 已成功集成到 RecoveryRecovery 串口控制台默认就是rootadb root后可以获得 root shellBusyBox 功能可以正常使用因此没有必要额外集成su或改名后的rco。这次排查的关键并不是“如何强行增加一个提权命令”而是先确认当前系统是否已经具备 root 能力。注意以下所有涉及路径部分皆为作者本人实际开发中的路径参考部分内容因安全起见可能涉及脱敏。但大体架构思路各系统之间大同小异各位在应用时自行结合接触的项目源码架构情况进行参考比对即可。二、BusyBox 如何进入 Recovery本项目通过PRODUCT_COPY_FILES将预编译 BusyBox 复制到 RecoveryPRODUCT_COPY_FILES \ $(LOCAL_PATH)/init.recovery.rk30board.rc:recovery/root/init.recovery.rk30board.rc \ vendor/rockchip/common/bin/$(TARGET_ARCH)/busybox:recovery/root/sbin/busybox其中格式为源文件路径:镜像内目标路径BusyBox 的源文件是vendor/rockchip/common/bin/$(TARGET_ARCH)/busybox目标路径是recovery/root/sbin/busybox构建完成后它在 Recovery 中对应/sbin/busybox这里要注意PRODUCT_COPY_FILES只是复制文件不会编译源代码。因此它适合复制预编译 BusyBox配置文件init 脚本固件其他已经存在于源码树中的文件。如果目标是su.cpp这样的 C 源码不能直接使用PRODUCT_COPY_FILES必须先通过 Android 构建系统生成可执行文件。三、如何构建 Recovery 镜像source build/envsetup.sh lunch rk3566_kk-userdebug m recoveryimage -j16构建完成后重点检查两个位置out/target/product/rk3566_kk/recovery/root/sbin/busybox out/target/product/rk3566_kk/recovery.img第一个路径用于确认 BusyBox 是否进入 Recovery 文件树第二个路径是最终生成的 Recovery 镜像。可以在 Windows 下检查Get-Item out/target/product/rk3566_kk/recovery/root/sbin/busybox Get-Item out/target/product/rk3566_kk/recovery.img如果recovery/root/sbin/busybox不存在说明问题还在构建或复制阶段如果文件存在但板端无法执行则继续检查权限和运行环境。四、BusyBox 集成后不要只检查文件是否存在一个二进制文件进入镜像并不代表它一定能够运行还需要检查- 文件是否存在 - 文件是否具有执行权限 - 当前用户是否有权限执行 - 动态链接库是否完整 - SELinux 是否允许执行进入 Recovery 后可以执行ls -l /sbin/busybox id echo $PATH典型检查结果应类似-rwxr-xr-x root root /sbin/busybox uid0(root) gid0(root) PATH/sbin:/system/bin执行 BusyBox/sbin/busybox ls /也可以查看 BusyBox 支持的 applet/sbin/busybox --list需要区分两种使用方式/sbin/busybox ls这是直接调用 BusyBox再把ls作为参数传入。而下面这种方式ls只有在系统中存在ls软链接或者ls本身由其他工具提供时才可以使用。BusyBox 集成并不等于所有命令都会自动出现在任意目录下。五、Recovery 中的$是否代表 shell 用户不能仅凭提示符判断用户身份。有些 shell 即使运行在 root 用户下也可能显示$反过来提示符显示#也不能代替真正的身份检查。应始终使用id确认权限。重点查看uid0(root) gid0(root)如果是uid2000(shell)才说明当前确实是 shell 用户。因此本项目最终发现Recovery 串口控制台虽然最初看起来像普通 shell但实际执行id后确认其默认身份已经是 root。这也是为什么最终不需要通过rco再做一次提权。六、su和rco是什么关系Android 源码中原本存在一个su实现路径为system/extras/su/su.cpp它的主要逻辑是uid_t uid 0; gid_t gid 0; setgid(gid); setuid(uid); execvp(/system/bin/sh, exec_args);也就是说它默认尝试切换到 UID 0切换到 GID 0启动一个 root shell。本项目中Android.mk已经把模块名改成了LOCAL_MODULE : rco普通 system 构建中rco会安装到/system/bin/rco并且工程中还配置了system/bin/rco 的文件权限 SELinux 的 su_exec 类型 shell 执行 rco 时的域转换规则因此rco本质上就是一个改名后的 Androidsu。但是需要注意普通 system 中存在 rco 不代表 Recovery 中也存在 rcoRecovery 是独立镜像必须单独将对应模块构建并打包进去。七、为什么本项目最终没有集成 rco最初的设想是Recovery 是 shell 用户 - 需要 rco - rco 将 shell 切换为 root实际验证后运行环境变成了Recovery 串口控制台 - 默认 uid0(root) - 可直接执行 BusyBoxADB 侧则可以使用adb root adb shell进入设备后验证id如果输出uid0(root)说明 ADB shell 已经具备 root 权限。因此当前已有两条满足需求的路径串口 Recovery 控制台默认 root ADB Recovery adb root - root shell再增加一个rco只是重复已有能力还会引入额外的Recovery 模块构建setuid 或 capabilities 配置SELinux 文件上下文权限安全维护后续版本兼容问题。所以评审结论是暂不专门集成rco。八、遇到类似问题时的排查顺序以后排查“工具是否集成到 Recovery”时可以按照下面的顺序1. 查找源码或预编译文件rg --files | rg busybox|su|rco2. 查找构建入口重点搜索Android.mk Android.bp PRODUCT_PACKAGES PRODUCT_COPY_FILES TARGET_RECOVERY_ROOT_OUT3. 检查 Recovery 文件树out/target/product/product/recovery/root/确认目标文件是否真实存在。4. 检查文件属性ls -l file ls -Z file file file5. 检查当前用户id id -Z6. 检查环境变量echo $PATH echo $LD_LIBRARY_PATH7. 最后再判断是否需要新增提权工具如果当前已经是uid0(root)那么问题通常不是“缺少 su/rco”而应该转向检查文件权限路径动态链接库SELinux命令调用方式。九、总结Android Recovery 中集成 BusyBox核心链路是预编译 BusyBox - PRODUCT_COPY_FILES - recovery/root/sbin/busybox - recovery.img - 烧录 - 板端检查权限和执行结果而su/rco的作用是shell 用户 - setuid(0) - 启动 root shell但是否需要rco不能根据需求名称直接决定而应先执行id确认 Recovery 和 ADB 的实际身份。本项目最终结论是BusyBox 已成功集成 Recovery 串口默认 root adb root 可以获取 root 不需要额外集成 rco。最值得记住的经验是判断 Android 功能是否缺失不能只看源码配置也不能只看命令提示符。必须同时检查构建产物、镜像文件、文件权限、SELinux 状态和板端实际运行身份。