理解boot.img与逆向分析Android/linux内核

怀抱观古今,寝食展戏谑。这篇文章主要讲述理解boot.img与逆向分析Android/linux内核相关的知识,希望能为你提供帮助。
一些尝试和理解。
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
【理解boot.img与逆向分析Android/linux内核】
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 512struct 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 readdress = [] 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权限。
 

    推荐阅读