理解boot.img與靜態分析Android/linux內核

  一些嘗試和理解。python

  1>提取boot.img:linux

    

    其中,msm表明是高通的芯片,msm_sdcc.1是外接的SD卡掛載的目錄,by-name指的是這個sd卡分區的名稱。下面幾行表明每一個分區存儲的東西。app

 

    

    記得提早su,dd if=/dev/block/mmcblk0p8 of=/data/local/tmp/boot.img。將boot.img dump出來spa

 

    

    adb root得到root權限,將boot.img 移到pc上。調試

  2>boot.img格式分析code

    如system/core/mkbootimg/bootimg.hblog

  

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來提取兩個內核:ip

    

   3>先來分析kernel:ci

    

    拖入IDA,將處理器類型設置爲ARM Little-endian,基地址改成c0008000。cmd

         

    此時,因爲沒有符號表,不方便閱讀和理解。獲取符號表

    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源碼來輔助閱讀並修改內核。以下

  

  能夠修改task_pid_nr_ns()的返回值來內核級繞過的tracepid的反調試。

  4>再來看ramdisk

    

    

    獲得了randisk.img,經過binwalk來觀察,看到了ramdisk的文件系統,以及裏面的文件,以下:

    

    

    Android手機得到Root權限,能夠讓/system和/data分區得到讀寫的權限.這兩個分區的權限配置,通常在根分區的init.rc文件中,修改這個文件可永久得到root權限。

相關文章
相關標籤/搜索