├── README.md ├── auxiliary_tools ├── SymExtractor │ ├── README.md │ └── SymExtractor.py ├── ImgExtractor │ ├── README.md │ └── ImgExtractor.py └── extract_bootloader.py └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | # ANDROID_EXPTOOLKIT 2 | 3 | ## A toolkit for Android Exp 4 | 5 | status : updating 6 | -------------------------------------------------------------------------------- /auxiliary_tools/SymExtractor/README.md: -------------------------------------------------------------------------------- 1 | # SymExtractor 2 | 3 | A python script to extract symbols from kernel image 4 | -------------------------------------------------------------------------------- /auxiliary_tools/ImgExtractor/README.md: -------------------------------------------------------------------------------- 1 | # ImgExtractor 2 | 3 | ## image extract script 4 | 5 | auto handle image|zimage|image.gz 6 | 7 | 8 | usage: ImgExtractor boot.img outputdir 9 | 10 | 11 | output: 12 | 13 | image --> image|ramdisk.img 14 | zimage --> zimage|zimage_gz|image|ramdisk.img 15 | image.gz --> image_gz|image|ramdisk.img 16 | 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # folder 35 | /SymExtractor/.idea/ 36 | .idea/ 37 | -------------------------------------------------------------------------------- /auxiliary_tools/extract_bootloader.py: -------------------------------------------------------------------------------- 1 | import sys, struct, os 2 | 3 | def main(): 4 | 5 | #Reading the commandline arguments 6 | if len(sys.argv) != 3: 7 | print "USAGE: %s bootloader.img output_path" % __file__ 8 | return 9 | bootloader_path = sys.argv[1] 10 | output_path = sys.argv[2] 11 | 12 | #Verifying the magic 13 | bootloader_file = open(bootloader_path, 'rb') 14 | data = bootloader_file.read() 15 | bootloader_file.close() 16 | magic = data[0:8] 17 | print hex(struct.unpack(">I",magic[0:4])[0]) 18 | if struct.unpack(">I",magic[0:4])[0] == 0x3cd61ace: 19 | extract_2(data,output_path) 20 | return 21 | 22 | elif struct.unpack(">I",magic[4:8])[0] == 0x70617274: 23 | extract_3(data,output_path) 24 | return 25 | 26 | elif magic == "BOOTLDR!": 27 | extract_1(data,output_path) 28 | return 29 | else: 30 | print "Can not handle ,check releasetools.py in AOSP" 31 | 32 | 33 | 34 | 35 | 36 | 37 | def extract_1(data,output_path): 38 | #Reading in the metadata block 39 | point = 8 40 | image_num,start_addr,size = struct.unpack("= len(img): 23 | print "can not find end of addresses list" 24 | return 25 | addresses = struct.unpack_from(" 0xffffffc000000000: 35 | offset = offset + 1 36 | if loc + offset * 8 >= len(img): 37 | print "can not find end of addresses list" 38 | return 39 | addresses = struct.unpack_from("= len(img): 45 | print "can not find end of addresses list" 46 | return 47 | addresses = struct.unpack_from("= len(img): 71 | print "out of range when try to find all sym_name" 72 | return 73 | addresses = struct.unpack_from("B", img, loc + offset ) 74 | offset = 0 75 | for i in range(sym_num): 76 | symlen = struct.unpack_from("B", img, loc + offset ) 77 | offset = offset + symlen[0] + 1 78 | if loc + offset >= len(img): 79 | print "out of range when try to find all sym_name" 80 | return 81 | 82 | sym_name_end = offset+loc-1 83 | 84 | #skip zero 85 | 86 | loc = sym_name_end 87 | offset = 1 88 | 89 | addresses = struct.unpack_from("B", img, loc + offset ) 90 | while addresses[0] == 0: 91 | offset = offset + 1 92 | if loc + offset >= len(img): 93 | print "out of range when try to find markers start" 94 | return 95 | addresses = struct.unpack_from("B", img, loc + offset) 96 | 97 | 98 | #alignment markers always start with 0 99 | markers_offset = (loc+offset)-0x8 100 | loc = markers_offset 101 | offset=1 102 | addresses = struct.unpack_from("= len(img): 106 | print "out of range when try to find all markers" 107 | return 108 | addresses = struct.unpack_from("= len(img): 113 | print "out of range when try to find sym_token_table" 114 | return 115 | addresses = struct.unpack_from("B", img, loc + offset*8) 116 | 117 | sym_token_table_offset = loc+offset*8 118 | 119 | loc = sym_token_table_offset 120 | offset = 1 121 | addresses = struct.unpack_from("= len(img): 125 | print "out of range when try to find end of sym token table" 126 | return 127 | addresses = struct.unpack_from("= len(img): 132 | print "out of range when try to find sym_token_index" 133 | return 134 | addresses = struct.unpack_from(" <32|64>" 187 | 188 | 189 | if __name__ == '__main__': 190 | argn = len(sys.argv) 191 | if argn < 3: 192 | usage() 193 | exit() 194 | elif argn >= 3: 195 | if sys.argv[2] == 64: 196 | main(sys.argv[1], 0xffffffc000080000) 197 | else: 198 | main(sys.argv[1], 0xc0008000) 199 | -------------------------------------------------------------------------------- /auxiliary_tools/ImgExtractor/ImgExtractor.py: -------------------------------------------------------------------------------- 1 | # /system/core/mkbootimg/mkbootimg pack script in Android sourch code 2 | # /system/core/mkbootimg/bootimg.h boot.img struct 3 | 4 | ''' 5 | #define BOOT_MAGIC "ANDROID!" 6 | #define BOOT_MAGIC_SIZE 8 7 | #define BOOT_NAME_SIZE 16 8 | #define BOOT_ARGS_SIZE 512 9 | #define BOOT_EXTRA_ARGS_SIZE 1024 10 | 11 | struct boot_img_hdr 12 | { 13 | uint8_t magic[BOOT_MAGIC_SIZE]; 14 | 15 | uint32_t kernel_size; /* size in bytes */ 16 | uint32_t kernel_addr; /* physical load addr */ 17 | 18 | uint32_t ramdisk_size; /* size in bytes */ 19 | uint32_t ramdisk_addr; /* physical load addr */ 20 | 21 | uint32_t second_size; /* size in bytes */ 22 | uint32_t second_addr; /* physical load addr */ 23 | 24 | uint32_t tags_addr; /* physical addr for kernel tags */ 25 | uint32_t page_size; /* flash page size we assume */ 26 | uint32_t unused; /* reserved for future expansion: MUST be 0 */ 27 | 28 | /* operating system version and security patch level; for 29 | * version "A.B.C" and patch level "Y-M-D": 30 | * ver = A << 14 | B << 7 | C (7 bits for each of A, B, C) 31 | * lvl = ((Y - 2000) & 127) << 4 | M (7 bits for Y, 4 bits for M) 32 | * os_version = ver << 11 | lvl */ 33 | uint32_t os_version; 34 | 35 | uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */ 36 | 37 | uint8_t cmdline[BOOT_ARGS_SIZE]; 38 | 39 | uint32_t id[8]; /* timestamp / checksum / sha1 / etc */ 40 | 41 | /* Supplemental command line data; kept here to maintain 42 | * binary compatibility with older versions of mkbootimg */ 43 | uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE]; 44 | } __attribute__((packed)); 45 | 46 | /* 47 | ** +-----------------+ 48 | ** | boot header | 1 page 49 | ** +-----------------+ 50 | ** | kernel | n pages 51 | ** +-----------------+ 52 | ** | ramdisk | m pages 53 | ** +-----------------+ 54 | ** | second stage | o pages 55 | ** +-----------------+ 56 | ** 57 | ** n = (kernel_size + page_size - 1) / page_size 58 | ** m = (ramdisk_size + page_size - 1) / page_size 59 | ** o = (second_size + page_size - 1) / page_size 60 | ** 61 | ** 0. all entities are page_size aligned in flash 62 | ** 1. kernel and ramdisk are required (size != 0) 63 | ** 2. second is optional (second_size == 0 -> no second) 64 | ** 3. load each element (kernel, ramdisk, second) at 65 | ** the specified physical address (kernel_addr, etc) 66 | ** 4. prepare tags at tag_addr. kernel_args[] is 67 | ** appended to the kernel commandline in the tags. 68 | ** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr 69 | ** 6. if second_size != 0: jump to second_addr 70 | ** else: jump to kernel_addr 71 | */ 72 | 73 | 74 | 75 | 76 | ''' 77 | 78 | 79 | 80 | import os 81 | import sys 82 | import struct 83 | import math 84 | import gzip 85 | import shutil 86 | 87 | 88 | def adjustpage(offset): 89 | if (offset) % 4096: 90 | adjustoffset = (((offset) / 4096) + 1) * 4096 91 | else: 92 | adjustoffset = (((offset) / 4096) + 1) * 4096 93 | 94 | 95 | 96 | 97 | class Boothead(): 98 | def __init__(self): 99 | self.MAGICNUM = '' 100 | self.kernel_size = 0 101 | self.kernel_addr = 0 102 | self.ramdisk_size = 0 103 | self.ramdisk_addr = 0 104 | self.second_size = 0 105 | self.second_addr = 0 106 | self.tags_addr = 0 107 | self.page_size = 0 108 | self.unused = 0 109 | self.os_version = 0 110 | self.name = '' 111 | self.cmdline = '' 112 | self.id = 0 113 | self.extra_cmdline = '' 114 | 115 | 116 | class ImgExtractor(): 117 | def __init__(self, imgpath,output_dir): 118 | self.imgpath = imgpath 119 | self.outputdir = output_dir 120 | self.imgdata = open(self.imgpath, 'rb').read() 121 | self.imghead = Boothead() 122 | self.pageshift = 12 123 | 124 | def getimghead(self): 125 | self.imghead.MAGICNUM = self.imgdata[0:8] 126 | self.imghead.kernel_size,\ 127 | self.imghead.kernel_addr,\ 128 | self.imghead.ramdisk_size,\ 129 | self.imghead.ramdisk_addr,\ 130 | self.imghead.second_size,\ 131 | self.imghead.ramdisk_addr,\ 132 | self.imghead.tags_addr,\ 133 | self.imghead.page_size,\ 134 | self.imghead.unused,\ 135 | self.imghead.os_version = struct.unpack_from('10I', self.imgdata, 8) 136 | self.imghead.name,self.imghead.cmdline = struct.unpack_from('16s512s',self.imgdata,48) 137 | self.imghead.id = struct.unpack_from("32s",self.imgdata,576)[0].encode('hex')[:40] 138 | self.imghead.extra_cmdline = struct.unpack_from('1024s',self.imgdata,608) 139 | 140 | 141 | def Extractkernel(self): 142 | self.getimghead() 143 | if self.imghead.MAGICNUM != "ANDROID!": 144 | print "not a bootimg" 145 | return 146 | 147 | 148 | kernelend = self.imghead.page_size+self.imghead.kernel_size 149 | kernel = self.imgdata[self.imghead.page_size:kernelend] 150 | 151 | #1.maybe the kernel is compressed and contain self decompress code 152 | #2.kernel maybe pad with dtb file 153 | 154 | #compressed kernel (AKA Image.gz ) 155 | 156 | if struct.unpack_from(">I",kernel,0)[0] == 0x1f8b0800: 157 | f = open(os.path.join(self.outputdir,'Image_gz'),'wb') 158 | f.write(kernel) 159 | f.close 160 | shutil.copy(os.path.join(self.outputdir,'Image_gz'),os.path.join(self.outputdir,'Image.gz')) 161 | os.system('gzip -d -f %s' % os.path.join(self.outputdir,'Image.gz')) 162 | #g = gzip.GzipFile('rb', fileobj=open(os.path.join(self.outputdir,'Image'), 'rb')) 163 | #g.read() 164 | #open(os.path.join(self.outputdir,'Imagetest'),'wb').write(g.read()) 165 | 166 | # self-decompress kernel (AKA zImage) 167 | elif kernel.startswith("0000A0E10000A0E10000A0E10000A0E10000A0E10000A0E10000A0E10000A0E1".decode('hex')): 168 | print 'get compress' 169 | f = open(os.path.join(self.outputdir, 'zImage'), 'wb') 170 | f.write(kernel) 171 | f.close 172 | kerneloff = kernel.find("1F8B0800".decode('hex')) 173 | 174 | f = open(os.path.join(self.outputdir, 'Image_gz'), 'wb') 175 | f.write(kernel[kerneloff:]) 176 | f.close 177 | 178 | shutil.copy(os.path.join(self.outputdir, 'Image_gz'), os.path.join(self.outputdir, 'Image.gz')) 179 | os.system('gzip -d -f -q %s' % os.path.join(self.outputdir, 'Image.gz')) 180 | # orignal kernel (Image) 181 | else: 182 | f = open(os.path.join(self.outputdir, 'Image'), 'wb') 183 | f.write(kernel) 184 | f.close 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | self.pageshift=int(math.log(self.imghead.page_size,2)) 199 | 200 | 201 | #adjust offset 202 | ramdiskstart = ((kernelend>>self.pageshift)<>self.pageshift)<