首页
社区
课程
招聘
[原创]android手机内核提取及逆向分析
发表于: 2014-11-24 16:25 29429

[原创]android手机内核提取及逆向分析

2014-11-24 16:25
29429
技术背景:
Android手机获得Root权限,可以让/system和/data分区获得读写的权限.这两个分区的权限配置,一般在根分区的init.rc文件中,修改这个文件可永久获得root权限.
众所周知,市面上绝大部分的Android手机文件系统有三个分区,分别是/,/system,/data.根分区(/)是打包为ramdisk.img后,再与kernel的zImage打包为boot.img. boot.img在EMMC/NAND中以RAW DATA的形式存在,且除使用烧写工具外,无法读写.正因如此,根分区(/)在每次开机时都会从存储器中加载到RAM, 所以根分区(/)是难以不被刷机破解的.

那么如何破解?
获得boot.img,解压boot.img得到ramdisk.img, 再由ramdisk.img解压得到root目录(/),修改其中的init.rc文件,再打包,最终得到新的boot.img.最后利用烧写工具将boot.img烧写到手机即可.(具体可参考AOSP/mkbootimg)

浅析boot分区结构


具体分析:
一.        提取kernel文件
(1)boot在哪里?通过下载官方的rom包,解压缩后可以看到里面的boot.img文件然后分解
关于rom包,简单介绍下里面的文件:
boot.img  Linux内核和基本文件系统的内核包
system.img  系统的/system目录
recovery.img 系统恢复程序所用的镜像
userdata.img  系统的/data目录

/data/app  用户应用程序
/system/app 系统应用
/system/fonts  字体
/system/media  开关机动画
/system/media/audio 其他音频,闹铃,提示音等
META-INF 刷机脚本信息和签名
/system/etc 系统配置文件夹,恢复出厂设置后都从这里和build.prop调用配置来覆盖出错的配置,里面init.d文件夹可以放入脚本,脚本名字前加数字表示优先级
build.prop 手机信息

(2.1)boot在哪里?真机中提取(这里以Samsung Galaxy S4 为例)
adb shell 进入真机, ls -l /dev/block/platform/msm_sdcc.1/by-name
msm 代表高通的芯片
这个msm_sdcc.1是外接的SD卡挂载的目录,by-name指的是这个sd卡分区的名称

现在可以通过dd命令将boot.img提取出来
dd if=/dev/block/mmcblk0p20 of=/sdcard/boot.img




(2.2)boot在哪里?真机中提取(这里以Lenovo A300t为例) 另一种查找boot.img的方法

首先介绍下手机分区信息:
主要有mtd分区和emmc分区

一般刷机包签名文件夹里的刷机脚本那里有updater-script文件.
例如:
format("ext4", "EMMC", "/dev/block/platform/xxxx", "0", "/system")是EMMC分区的,
format("yaffs2", "MTD","/dev/block/platform/xxxx", "0", "/system")是MTD分区的

MTD是用于访问memory设备(ROM、flash)的Linux的子系统.MTD的主要目的是为了使新的memory设备的驱动更加简单

EMMC 结构由一个嵌入式存储解决方案组成,带有MMC (多媒体卡)接口、快闪存储器设备及主控制器—— 所有都在一个小型的BGA 封装.接口速度高达每秒52MB,EMMC具有快速、可升级的性能

cat /proc/mtd

可以通过同样的方式,使用dd命令,将boot.img文件提取出来.

之后我们可以通过adb pull的方式把从真机中提取的boot.img文件提取到本地.之后用split_boogimg.pl 将提取的boot.img分解出来,可以得到boot.img-kernel


二.        逆向分析kernel文件:
一般来说,这个kernel内核文件都是一个gzip的压缩格式,偶尔也会有其他的压缩算法.比如三星S5内核文件的压缩算法是lzop

为什么是这样的情况呢?简要说下:
Kernel被载入内存后是以压缩的状态存放在磁盘之上的,他头上的一段代码就是为了初始化并且解压缩的一段代码.这段代码把自身压缩的一部分代码解压出来.放到真正内核所在的位置上.所以他所用的压缩算法要从他头上那段来指定的.所以如果今后厂商使用一些自己的压缩算法,那么需要更多逆向分析的.

这样我们可以通过一个解压缩的脚本,解压出真正的内核文件.一个二进制文件zImage.

#!/bin/bash
pos=`grep -P -a -b -m 1 --only-matching '\x1F\x8B\x08' zImage | cut -f 1 -d :`
echo "Extracting gzip'd kernel image from file: zImage (start = $pos)"

if [ ! -z $pos ]; then
echo "Dumping compressed image"
dd if=zImage of=zImage_unpacked.gz bs=1 skip=$pos 2>/dev/null >/dev/null
echo "Unzipping compressed image"
gunzip -qf zImage_unpacked.gz
fi


现在可以将它导入到IDA中分析,但是导入IDA后发现效果很不理想

这是因为我们需要符号表.但是android的linux内核是一个平面结构,它没有符号表.如果大家编译过linux内核可以发现编译好的zImage被打包到boot.img文件中去,下面有个巨大的vmlinux,它放到gdb里面去调试可以看到完整的符号表和调试信息.刷入手机的版本是没有的.
但是在/proc/kallsyms可以提供所有的kernel symbol

cat /proc/kallsyms 会发现地址都是0

为什么地址都是0呢?

因为有一个patch 在/proc/sys/kernel/kptr_restrict默认为1,就隐藏了symbol
只要我们将其置0就可以正常打印

如果我们之前在刷机的过程中放进去一个su授权文件,那么我们就可以
echo 0 > /proc/sys/kernel/kptr_restrict
cat /proc/kallsyms > /data/local/tmp/syms.txt

但是我们目的是为了root,这里如果没有su文件呢?

我们还有其他的方法.kallsyms既然可以打印symbol,那么说明symbol肯定在内核之中的.它就在__ksymtab里面.我们肯定可以知道一些常见的内核函数,比如kallsyms_lookup_name.我们可以在这个内核的二进制文件中找它的字符串.找到它的相对位置后,然后拿它的地址去搜索

我们可以搜到一个结构

从0xC0008000开始暴力搜索连续若干个具有上面的特征的内存,就可以找到内核的导出符号表

有了符号地址后,手动在ida中添加

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 3
支持
分享
最新回复 (20)
雪    币: 233
活跃值: (285)
能力值: ( LV12,RANK:270 )
在线值:
发帖
回帖
粉丝
2
Android手机获得Root权限,其实就是让/system和/data分区获得读写的权限。


我还是觉得这句话有问题。后者只是前者的一个用处而已。
2014-11-24 16:52
0
雪    币: 219
活跃值: (52)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
兄弟说的没错,但是android手机root大部分是为了这个~
2014-11-24 16:54
0
雪    币: 233
活跃值: (285)
能力值: ( LV12,RANK:270 )
在线值:
发帖
回帖
粉丝
4
那你至做外挂和破解的人于何地?
2014-11-24 16:58
0
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
root跟做这事完全是两码事。

何况大不大部分你哪里来统计数据? 你把因果搞错了。会误导后来人
2014-11-24 17:14
0
雪    币: 219
活跃值: (52)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
可能我的意思没有完全表达好,我想说的仅仅是android手机用户root就是为了处理system目录读写.至于root本身,当然还有各种用途
2014-11-24 17:18
0
雪    币: 463
活跃值: (283)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
表打击敢于分享技术的骚年!
2014-11-24 17:39
0
雪    币: 188
活跃值: (167)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
支持楼主
2014-11-24 18:15
0
雪    币: 219
活跃值: (52)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
9
感谢支持~~
2014-11-24 20:34
0
雪    币: 29
活跃值: (499)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
10
支持支持!
2014-11-24 20:54
0
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
多谢分享
2014-11-24 21:15
0
雪    币: 260
活跃值: (249)
能力值: ( LV12,RANK:350 )
在线值:
发帖
回帖
粉丝
12
看不懂,顶!
2014-11-24 21:44
0
雪    币: 131
活跃值: (98)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
13
其他的用处不也是有了权限才可以的么?
2014-11-24 21:54
0
雪    币: 693
活跃值: (108)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
14
骚年又冒泡了,还是土豪有真机可以玩呀
2014-11-24 22:04
0
雪    币: 233
活跃值: (285)
能力值: ( LV12,RANK:270 )
在线值:
发帖
回帖
粉丝
15
所以说"其实就是让/system和/data分区获得读写的权限"只是"获得Root权限"的一个用处而已。
/system和/data可写并不能获取root权限
有root权限,可以让/system和/data可写
2014-11-24 22:23
0
雪    币: 219
活跃值: (52)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
16
大哥说笑了~借用而已
2014-11-24 22:48
0
雪    币: 118
活跃值: (72)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
17
到底什么是安卓root呢,我是小白
2014-11-24 23:49
0
雪    币: 46
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
boot对应的block也可以用binwalk来分析

但是有个问题,不是所有设备都可以用by-name下面的boot找到启动块
2014-11-26 09:31
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
最终还是绕不过这个,谢谢分享
2016-8-24 14:02
0
雪    币: 433
活跃值: (2380)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
20
__ksymtab好哥哥这个文件怎么搞出来啊
2019-10-18 17:28
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
有没有办法不root从系统搞出boot.img。从网上找的固件包太困难,解包更困难,有的连zImage都是加密的。有知道的加我微信cherry20207788
最后于 2019-12-10 11:09 被wx_雪莱编辑 ,原因:
2019-12-10 11:00
0
游客
登录 | 注册 方可回帖
返回
//