android打包解包boot.img,system.img

2024-09-08 06:58

本文主要是介绍android打包解包boot.img,system.img,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原帖地址:http://www.52pojie.cn/thread-488025-1-1.html

转载Mark一下,日后研究


最近工作需要对boot.img,system.img进行破解。顺便将心得分享一下。

我的工作环境是在linux下的。所以工具都是针对linux的。
boot.img破解相关工具:
1、split_boot    perl脚本
2、boot_info    perl脚本
3、repack_ramdisk   bash脚本
4、unpack_ramdisk  bash脚本
5、mkbootimg x86二进制程序
工作原理先不解释了,有兴趣的朋友可以就此帖聊聊。
首先通过split_boot来分解boot.img或recovery.img。
./split_boot boot.img
分解后有个base address 0x00800000(一下数据都是举例并非真实数据)和command line信息要记录下来。
不记也可以用boot_info查看一下就可以了。其实就只有command line有用。
解包目录:
boot/ramdisk
boot.img-kernel
boot.img-ramdisk.cpio.gz
修改主要是boot/ramdisk目录下的东西,修改完后用repack_ramdisk工具打包生成新的boot.img-ramdisk.cpio.gz覆盖旧的。
最后用mkbootimg --cmdline '上面信息获取的command line' --kernel boot/boot.img-kernel --ramdisk boot/boot.img-ramdisk.cpio.gz -o 输出目录 --base 上面信息获取的base address(如:0x00800000)

最关键的部分来了。很多朋友都说重新打包后的boot.img无法用odin刷进去。

寻找壳数据并补充:
关键部分在于新的boot.img缺少了一些标记数据,其实分析过源码bootimg.h的人也知道,既然能解开,重新打包后应该是没错的啊。
确实是这样的,任何数据,能正常解包,再重新打包都不会有错。我们可以想想,为什么要odin工具刷入?因为那是三星自己开发的刷机工具。所以它肯定有区别于android默认的fastboot工具。
不同手机厂家也一样的道理,对于这种二进制数据包,如果厂家是从bootimg.h数据结构上做手脚,那么肯定就不是bootimg.h的数据结构了,那么它就只有在boot.img生成后,再进行二次加工生成的
加壳数据包。我是这样理解的,只要是特定结构的数据包,用ue打开后都会看到一些空白段(也就是0000组成的无数据区),这些区域可以填充特定数据来改变原来的数据包结构(可以理解为签名),
三星的boot.img为发现它的数据包末尾多处一段数据,可以用ue查找ASCII一下"QCDT" 就可以发现这部分多处来的壳数据。首先要修复这个地方,把壳数据二进制复制并粘贴到新的boot.img末尾。

修改头数据:
看过bootimg.h以及mkbootimg源码就可以知道一些不能改动的值,下面我们看看一些关键头部数据。
struct boot_img_hdr
{
    unsigned char magic[BOOT_MAGIC_SIZE];

    unsigned kernel_size;  /* size in bytes */
    unsigned kernel_addr;  /* physical load addr */

    unsigned ramdisk_size; /* size in bytes */
    unsigned ramdisk_addr; /* physical load addr */

    unsigned second_size;  /* size in bytes */
    unsigned second_addr;  /* physical load addr */

    unsigned tags_addr;    /* physical addr for kernel tags */
    unsigned page_size;    /* flash page size we assume */
    unsigned unused[2];    /* future expansion: should be 0 */

    unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */
    
    unsigned char cmdline[BOOT_ARGS_SIZE];

    unsigned id[8]; /* timestamp / checksum / sha1 / etc */
};
因为我们只修改了ramdisk所以这里应该只改变了ramdisk_size,而其他的数据,就让它完好无损把。
所以呢,我们就要用旧的boot.img的头部数据,覆盖新的boot.img数据。在这之前要先复制新boot.img的ramdisk_size部分数据出来。
用ue打开新boot.img,拷贝第二行开始前4位如:00 4b 8a 90,新建一个空白文档切换到16进制编辑模式,把刚才的复制粘贴到这里保留起来。
用ue打开旧boot.img,拷贝从0h~250h行的数据到新boot.img覆盖,最后从新文档中保留的ramdisk_size地址复制粘贴回新boot.img的第二行前4位。
这样一来boot.img就搞定了,只要一个 tar cvf  boot.img.tar boot.img打包成tar文件就可以用odin刷进去了。

==========================================
修改三星的system.img比较麻烦,因为它并非bootimg.h结构,而是ext4文件结构,而且还是sparse img模式的ext4。
首先需要的工具如下:
make_ext4fs
mkuserimg.sh
simg2img
当我们拿到三星的system.img文件其实名字是这样system.img.ext4。通过file system.img.ext4我们可以发现它其实是data,也就是sparse img模式的ext4。
我们需要用simg2img来转换。
simg2img system.img.ext4 system.img
这时候再用file查看就是ext4结构数据来。
接下来需要挂载到系统来修改
sudo mount -t ext4 -o loop system.img ./system
ls 查看一下system.img镜像大小。
ls -l system.img
-rw-rw-r--  1 xxx:xxx 2499805184 .... system.img
因为我们打包需要设定镜像文件大小,这个大小是固定的,最好别乱改。
另外,之前我们解开boot.img的ramdisk里有一个file_contexts文件,也拷贝到当前目录,打包需要用到。
修改过后通过make_ext4fs来打包为sparse img模式的ext4,关键参数是 -s
sudo make_ext4fs -s -l 2499805184 -a system -S ./file_contexts ./system.img.ext4 ./system
打包完后继续上面的壳理论,因为这时候你哪怕tar打包后还是刷不进去的。
寻找壳或者签名.....
找到签名位置在 0x220h~0x428h,所以我们从旧system.img.ext4里拷贝一下这段数据,覆盖到新的system.img.ext4,然后再tar打包就可以刷了。

目前我自己也有烦恼,卡在了,如何把system.img内的framework进行二次修改。因为当前真机是user模式且odex化,所以我以及把所有的framework,app以及里面odex化的app只要我能找到的odex都全部
用一个自己写的脚本进行了转换。
odex -> baksmali -> smali -> dex -> zip -> zipalign -> jar -> dexopt-wrapper(这步是在真机内执行的,用的是本机的dexopt,以及确定可以重新打包odex成功)。
我把所有重新odex的文件都push回system.img了。重新打包后刷进手机,三清后重启,结果手机开机动画处停留了一段时间就重启。
因为看不到logcat所以臆测可能是odex签名校验问题,根据网上资料查找到了libdvm.so的函数dvmCheckOptHeaderAndDependencies返回值的问题。
IDA 修改返回值为true后,还是如此。ida修改没问题。确定不是对libdvm.so修改导致的错误。
如果有大神路过请留下解决思路。有什么办法可以在保留user模式情况下修改掉所有的odex或者是重新odex还有什么错误的地方?

这篇关于android打包解包boot.img,system.img的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1147433

相关文章

Spring Boot Maven 插件如何构建可执行 JAR 的核心配置

《SpringBootMaven插件如何构建可执行JAR的核心配置》SpringBoot核心Maven插件,用于生成可执行JAR/WAR,内置服务器简化部署,支持热部署、多环境配置及依赖管理... 目录前言一、插件的核心功能与目标1.1 插件的定位1.2 插件的 Goals(目标)1.3 插件定位1.4 核

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Spring Boot spring-boot-maven-plugin 参数配置详解(最新推荐)

《SpringBootspring-boot-maven-plugin参数配置详解(最新推荐)》文章介绍了SpringBootMaven插件的5个核心目标(repackage、run、start... 目录一 spring-boot-maven-plugin 插件的5个Goals二 应用场景1 重新打包应用

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP