zoukankan      html  css  js  c++  java
  • 理解boot.img与静态分析Android/linux内核

      一些尝试和理解。

      1>提取boot.img:

        

        其中,msm代表是高通的芯片,msm_sdcc.1是外接的SD卡挂载的目录,by-name指的是这个sd卡分区的名称。下面几行代表每个分区存储的东西。

        

        记得提前su,dd if=/dev/block/mmcblk0p8 of=/data/local/tmp/boot.img。将boot.img dump出来

        

        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来提取两个内核:

        

       3>先来分析kernel:

        

        拖入IDA,将处理器类型设置为ARM Little-endian,基地址改为c0008000。

             

        此时,由于没有符号表,不方便阅读和理解。获取符号表

        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>
    ")
        fw.write("static main()
    ")
        fw.write("{")
        for i in range(0,len(address)):
            fw.write("
    	MakeNameEx(0x"+address[i]+",""+sym[i][:len(sym[i])-1]+"",0);")
        fw.write("
    }")
    print "OK!"

      之后将sym.idc载入ida,可以根据linux源码来辅助阅读并修改内核。如下

      

      可以修改task_pid_nr_ns()的返回值来内核级绕过的tracepid的反调试。

      4>再来看ramdisk

        

        

        得到了randisk.img,通过binwalk来观察,看到了ramdisk的文件系统,以及里面的文件,如下:

        

        

        Android手机获得Root权限,可以让/system和/data分区获得读写的权限.这两个分区的权限配置,一般在根分区的init.rc文件中,修改这个文件可永久获得root权限。

  • 相关阅读:
    git 初始化与使用
    java解析webservice服务返回的xml
    计算时间天数
    XML和Java bean转换
    微信公众号-企业
    docker安装openldap
    webservice使用
    idea解决冲突插件
    Java--JSON嵌套JSON中带''字符的解决方式
    微信公众号开发
  • 原文地址:https://www.cnblogs.com/0xJDchen/p/6007938.html
Copyright © 2011-2022 走看看