^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) #!/usr/bin/env python
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) # Copyright 2018, The Android Open Source Project
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) # Licensed under the Apache License, Version 2.0 (the "License");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) # you may not use this file except in compliance with the License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) # You may obtain a copy of the License at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) # http://www.apache.org/licenses/LICENSE-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) # Unless required by applicable law or agreed to in writing, software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) # distributed under the License is distributed on an "AS IS" BASIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) # See the License for the specific language governing permissions and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) # limitations under the License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) """unpacks the bootimage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) Extracts the kernel, ramdisk, second bootloader, dtb and recovery dtbo images.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) from __future__ import print_function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) from argparse import ArgumentParser, FileType
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) from struct import unpack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) import os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) BOOT_IMAGE_HEADER_V3_PAGESIZE = 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) VENDOR_BOOT_IMAGE_HEADER_V3_SIZE = 2112
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) def create_out_dir(dir_path):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) """creates a directory 'dir_path' if it does not exist"""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) if not os.path.exists(dir_path):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) os.makedirs(dir_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) def extract_image(offset, size, bootimage, extracted_image_name):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) """extracts an image from the bootimage"""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) bootimage.seek(offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) with open(extracted_image_name, 'wb') as file_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) file_out.write(bootimage.read(size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) def get_number_of_pages(image_size, page_size):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) """calculates the number of pages required for the image"""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return (image_size + page_size - 1) // page_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) def cstr(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) """Remove first NULL character and any character beyond."""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return s.split('\0', 1)[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) def format_os_version(os_version):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) a = os_version >> 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) b = os_version >> 7 & ((1<<7) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) c = os_version & ((1<<7) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return '{}.{}.{}'.format(a, b, c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) def format_os_patch_level(os_patch_level):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) y = os_patch_level >> 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) y += 2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) m = os_patch_level & ((1<<4) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return '{:04d}-{:02d}'.format(y, m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) def print_os_version_patch_level(value):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) os_version = value >> 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) os_patch_level = value & ((1<<11) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) print('os version: %s' % format_os_version(os_version))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) print('os patch level: %s' % format_os_patch_level(os_patch_level))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) def unpack_bootimage(args):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) """extracts kernel, ramdisk, second bootloader and recovery dtbo"""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) kernel_ramdisk_second_info = unpack('9I', args.boot_img.read(9 * 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) version = kernel_ramdisk_second_info[8]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if version < 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) print('kernel_size: %s' % kernel_ramdisk_second_info[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) print('kernel load address: %#x' % kernel_ramdisk_second_info[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) print('ramdisk size: %s' % kernel_ramdisk_second_info[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) print('ramdisk load address: %#x' % kernel_ramdisk_second_info[3])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) print('second bootloader size: %s' % kernel_ramdisk_second_info[4])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) print('second bootloader load address: %#x' % kernel_ramdisk_second_info[5])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) print('kernel tags load address: %#x' % kernel_ramdisk_second_info[6])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) print('page size: %s' % kernel_ramdisk_second_info[7])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) print_os_version_patch_level(unpack('I', args.boot_img.read(1 * 4))[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) print('kernel_size: %s' % kernel_ramdisk_second_info[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) print('ramdisk size: %s' % kernel_ramdisk_second_info[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) print_os_version_patch_level(kernel_ramdisk_second_info[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) print('boot image header version: %s' % version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if version < 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) product_name = cstr(unpack('16s', args.boot_img.read(16))[0].decode())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) print('product name: %s' % product_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) cmdline = cstr(unpack('512s', args.boot_img.read(512))[0].decode())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) print('command line args: %s' % cmdline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) cmdline = cstr(unpack('1536s', args.boot_img.read(1536))[0].decode())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) print('command line args: %s' % cmdline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if version < 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) args.boot_img.read(32) # ignore SHA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if version < 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) extra_cmdline = cstr(unpack('1024s',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) args.boot_img.read(1024))[0].decode())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) print('additional command line args: %s' % extra_cmdline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if version < 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) kernel_size = kernel_ramdisk_second_info[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ramdisk_size = kernel_ramdisk_second_info[2]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) second_size = kernel_ramdisk_second_info[4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) page_size = kernel_ramdisk_second_info[7]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) kernel_size = kernel_ramdisk_second_info[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ramdisk_size = kernel_ramdisk_second_info[1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) second_size = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) page_size = BOOT_IMAGE_HEADER_V3_PAGESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if 0 < version < 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) recovery_dtbo_size = unpack('I', args.boot_img.read(1 * 4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) print('recovery dtbo size: %s' % recovery_dtbo_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) recovery_dtbo_offset = unpack('Q', args.boot_img.read(8))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) print('recovery dtbo offset: %#x' % recovery_dtbo_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) boot_header_size = unpack('I', args.boot_img.read(4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) print('boot header size: %s' % boot_header_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) recovery_dtbo_size = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if 1 < version < 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) dtb_size = unpack('I', args.boot_img.read(4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) print('dtb size: %s' % dtb_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) dtb_load_address = unpack('Q', args.boot_img.read(8))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) print('dtb address: %#x' % dtb_load_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) dtb_size = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) # The first page contains the boot header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) num_header_pages = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) num_kernel_pages = get_number_of_pages(kernel_size, page_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) kernel_offset = page_size * num_header_pages # header occupies a page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) image_info_list = [(kernel_offset, kernel_size, 'kernel')]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) num_ramdisk_pages = get_number_of_pages(ramdisk_size, page_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ramdisk_offset = page_size * (num_header_pages + num_kernel_pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ) # header + kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) image_info_list.append((ramdisk_offset, ramdisk_size, 'ramdisk'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if second_size > 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) second_offset = page_size * (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) num_header_pages + num_kernel_pages + num_ramdisk_pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ) # header + kernel + ramdisk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) image_info_list.append((second_offset, second_size, 'second'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if recovery_dtbo_size > 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) image_info_list.append((recovery_dtbo_offset, recovery_dtbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 'recovery_dtbo'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if dtb_size > 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) num_second_pages = get_number_of_pages(second_size, page_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) num_recovery_dtbo_pages = get_number_of_pages(recovery_dtbo_size, page_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) dtb_offset = page_size * (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) num_header_pages + num_kernel_pages + num_ramdisk_pages + num_second_pages +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) num_recovery_dtbo_pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) image_info_list.append((dtb_offset, dtb_size, 'dtb'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) for image_info in image_info_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) extract_image(image_info[0], image_info[1], args.boot_img,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) os.path.join(args.out, image_info[2]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) def unpack_vendor_bootimage(args):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) kernel_ramdisk_info = unpack('5I', args.boot_img.read(5 * 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) print('vendor boot image header version: %s' % kernel_ramdisk_info[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) print('kernel load address: %#x' % kernel_ramdisk_info[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) print('ramdisk load address: %#x' % kernel_ramdisk_info[3])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) print('vendor ramdisk size: %s' % kernel_ramdisk_info[4])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) cmdline = cstr(unpack('2048s', args.boot_img.read(2048))[0].decode())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) print('vendor command line args: %s' % cmdline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) tags_load_address = unpack('I', args.boot_img.read(1 * 4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) print('kernel tags load address: %#x' % tags_load_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) product_name = cstr(unpack('16s', args.boot_img.read(16))[0].decode())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) print('product name: %s' % product_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) dtb_size = unpack('2I', args.boot_img.read(2 * 4))[1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) print('dtb size: %s' % dtb_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) dtb_load_address = unpack('Q', args.boot_img.read(8))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) print('dtb address: %#x' % dtb_load_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ramdisk_size = kernel_ramdisk_info[4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) page_size = kernel_ramdisk_info[1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) # The first pages contain the boot header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) num_boot_header_pages = get_number_of_pages(VENDOR_BOOT_IMAGE_HEADER_V3_SIZE, page_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) num_boot_ramdisk_pages = get_number_of_pages(ramdisk_size, page_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ramdisk_offset = page_size * num_boot_header_pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) image_info_list = [(ramdisk_offset, ramdisk_size, 'vendor_ramdisk')]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) dtb_offset = page_size * (num_boot_header_pages + num_boot_ramdisk_pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ) # header + vendor_ramdisk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) image_info_list.append((dtb_offset, dtb_size, 'dtb'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) for image_info in image_info_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) extract_image(image_info[0], image_info[1], args.boot_img,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) os.path.join(args.out, image_info[2]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) def unpack_image(args):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) boot_magic = unpack('8s', args.boot_img.read(8))[0].decode()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) print('boot_magic: %s' % boot_magic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if boot_magic == "ANDROID!":
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) unpack_bootimage(args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) elif boot_magic == "VNDRBOOT":
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) unpack_vendor_bootimage(args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) def parse_cmdline():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) """parse command line arguments"""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) parser = ArgumentParser(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) description='Unpacks boot.img/recovery.img, extracts the kernel,'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 'ramdisk, second bootloader, recovery dtbo and dtb')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) parser.add_argument(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) '--boot_img',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) help='path to boot image',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) type=FileType('rb'),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) required=True)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) parser.add_argument('--out', help='path to out binaries', default='out')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return parser.parse_args()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) def main():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) """parse arguments and unpack boot image"""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) args = parse_cmdline()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) create_out_dir(args.out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) unpack_image(args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if __name__ == '__main__':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) main()