红联Linux门户
Linux帮助

理解boot.img与静态分析Android/linux内核

发布时间:2016-10-29 09:50:53来源:linux网站作者:0xJDchen
一些尝试和理解。
 
1>提取boot.img:
理解boot.img与静态分析Android/linux内核
其中,msm代表是高通的芯片,msm_sdcc.1是外接的SD卡挂载的目录,by-name指的是这个sd卡分区的名称。下面几行代表每个分区存储的东西。
理解boot.img与静态分析Android/linux内核
记得提前su,dd if=/dev/block/mmcblk0p8 of=/data/local/tmp/boot.img。将boot.img dump出来
理解boot.img与静态分析Android/linux内核
adb root获得root权限,将boot.img 移到pc上。
 
2>boot.img格式分析
如system/core/mkbootimg/bootimg.h
typedef struct boot_img_hdr boot_img_hdr;
#define BOOT_MAGIC "Android!"
#define BOOT_MAGIC_SIZE 8
#define BOOT_NAME_SIZE 16
#define BOOT_ARGS_SIZE 512
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 dt_size;      /* device tree in bytes */
unsigned unused;       /* 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 */
};
boot,img文件跳过2k的文件头之后,包括两个 gz包,一个是boot.img-kernel.gz:Linux内核,一个是boot.img-ramdisk.cpio.gz
大概的组成结构如下:
** +-----------------+ 
** | boot header     | 1 page
** +-----------------+
** | kernel          | n pages  
** +-----------------+
** | ramdisk         | m pages  
** +-----------------+
** | second stage    | o pages
** +-----------------+
** | device tree     | p pages
** +-----------------+
** n = (kernel_size + page_size - 1) / page_size
** m = (ramdisk_size + page_size - 1) / page_size
** o = (second_size + page_size - 1) / page_size
** p = (dt_size + page_size - 1) / page_size
总而言之,boot.img包括boot.img header、kernel以及ramdisk文件系统,其中kernel和ramdisk一般以zip的格式进行压缩(取决于厂商)。利用binwalk来提取分析一下,并利用dd来提取两个内核:
理解boot.img与静态分析Android/linux内核
 
3>先来分析kernel:
理解boot.img与静态分析Android/linux内核
拖入IDA,将处理器类型设置为ARM Little-endian,基地址改为c0008000。
理解boot.img与静态分析Android/linux内核
理解boot.img与静态分析Android/linux内核
此时,由于没有符号表,不方便阅读和理解。获取符号表
cat /proc/kallsyms > /data/local/tmp/syms.txt
同时,移到pc上。
adb pull/data/local/tmp/syms.txt syms.txt
得到这个
c0008000 T stext
c0008000 T _sinittext
c0008000 T _stext
c0008000 T __init_begin
c0008050 t __create_page_tables
c0008104 t __enable_mmu_loc
c0008110 t __vet_atags
c0008148 t __fixup_smp
c0008180 t __fixup_smp_on_up
...
将其转化为sym.idc,直接用python来转化,如下:
import re
address = []
sym = []
with open('syms.txt','rt') as fr:
for line in fr:
group = re.split(' ',line,3)
address.append(group[0])
sym.append(group[2])
with open('sym.idc','w+') as fw:
fw.write("#include <idc.idc>\n")
fw.write("static main()\n")
fw.write("{")
for i in range(0,len(address)):
fw.write("\n\tMakeNameEx(0x"+address[i]+",\""+sym[i][:len(sym[i])-1]+"\",0);")
fw.write("\n}")
print "OK!"
之后将sym.idc载入ida,可以根据linux源码来辅助阅读并修改内核。如下
理解boot.img与静态分析Android/linux内核
可以修改task_pid_nr_ns()的返回值来内核级绕过的tracepid的反调试。
 
4>再来看ramdisk
理解boot.img与静态分析Android/linux内核
理解boot.img与静态分析Android/linux内核
得到了randisk.img,通过binwalk来观察,看到了ramdisk的文件系统,以及里面的文件,如下:
理解boot.img与静态分析Android/linux内核
理解boot.img与静态分析Android/linux内核
Android手机获得Root权限,可以让/system和/data分区获得读写的权限.这两个分区的权限配置,一般在根分区的init.rc文件中,修改这个文件可永久获得root权限。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/25499.html