一些嘗試和理解。
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>\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權限。