#!/usr/bin/env python3
#
# Copyright 2018, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Unpacks the boot image.

Extracts the kernel, ramdisk, second bootloader, dtb and recovery dtbo images.
"""

from argparse import ArgumentParser, FileType, RawDescriptionHelpFormatter
from struct import unpack
import os
import shlex

BOOT_IMAGE_HEADER_V3_PAGESIZE = 4096
VENDOR_RAMDISK_NAME_SIZE = 32
VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE = 16


def create_out_dir(dir_path):
    """creates a directory 'dir_path' if it does not exist"""
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)


def extract_image(offset, size, bootimage, extracted_image_name):
    """extracts an image from the bootimage"""
    bootimage.seek(offset)
    with open(extracted_image_name, 'wb') as file_out:
        file_out.write(bootimage.read(size))


def get_number_of_pages(image_size, page_size):
    """calculates the number of pages required for the image"""
    return (image_size + page_size - 1) // page_size


def cstr(s):
    """Remove first NULL character and any character beyond."""
    return s.split('\0', 1)[0]


def format_os_version(os_version):
    if os_version == 0:
        return None
    a = os_version >> 14
    b = os_version >> 7 & ((1<<7) - 1)
    c = os_version & ((1<<7) - 1)
    return '{}.{}.{}'.format(a, b, c)


def format_os_patch_level(os_patch_level):
    if os_patch_level == 0:
        return None
    y = os_patch_level >> 4
    y += 2000
    m = os_patch_level & ((1<<4) - 1)
    return '{:04d}-{:02d}'.format(y, m)


def decode_os_version_patch_level(os_version_patch_level):
    """Returns a tuple of (os_version, os_patch_level)."""
    os_version = os_version_patch_level >> 11
    os_patch_level = os_version_patch_level & ((1<<11) - 1)
    return (format_os_version(os_version),
            format_os_patch_level(os_patch_level))


class BootImageInfoFormatter:
    """Formats the boot image info."""

    def format_pretty_text(self):
        lines = []
        lines.append(f'boot magic: {self.boot_magic}')

        if self.header_version < 3:
            lines.append(f'kernel_size: {self.kernel_size}')
            lines.append(
                f'kernel load address: {self.kernel_load_address:#010x}')
            lines.append(f'ramdisk size: {self.ramdisk_size}')
            lines.append(
                f'ramdisk load address: {self.ramdisk_load_address:#010x}')
            lines.append(f'second bootloader size: {self.second_size}')
            lines.append(
                f'second bootloader load address: '
                f'{self.second_load_address:#010x}')
            lines.append(
                f'kernel tags load address: {self.tags_load_address:#010x}')
            lines.append(f'page size: {self.page_size}')
        else:
            lines.append(f'kernel_size: {self.kernel_size}')
            lines.append(f'ramdisk size: {self.ramdisk_size}')

        lines.append(f'os version: {self.os_version}')
        lines.append(f'os patch level: {self.os_patch_level}')
        lines.append(f'boot image header version: {self.header_version}')

        if self.header_version < 3:
            lines.append(f'product name: {self.product_name}')

        lines.append(f'command line args: {self.cmdline}')

        if self.header_version < 3:
            lines.append(f'additional command line args: {self.extra_cmdline}')

        if self.header_version in {1, 2}:
            lines.append(f'recovery dtbo size: {self.recovery_dtbo_size}')
            lines.append(
                f'recovery dtbo offset: {self.recovery_dtbo_offset:#018x}')
            lines.append(f'boot header size: {self.boot_header_size}')

        if self.header_version == 2:
            lines.append(f'dtb size: {self.dtb_size}')
            lines.append(f'dtb address: {self.dtb_load_address:#018x}')

        if self.header_version >= 4:
            lines.append(
                f'boot.img signature size: {self.boot_signature_size}')

        return '\n'.join(lines)

    def format_mkbootimg_argument(self):
        args = []
        args.extend(['--header_version', str(self.header_version)])
        if self.os_version:
            args.extend(['--os_version', self.os_version])
        if self.os_patch_level:
            args.extend(['--os_patch_level', self.os_patch_level])

        args.extend(['--kernel', os.path.join(self.image_dir, 'kernel')])
        args.extend(['--ramdisk', os.path.join(self.image_dir, 'ramdisk')])

        if self.header_version >= 4 and self.boot_signature_size > 0:
            args.extend(['--boot_signature',
                         os.path.join(self.image_dir, 'boot_signature')])

        if self.header_version <= 2:
            if self.second_size > 0:
                args.extend(['--second',
                             os.path.join(self.image_dir, 'second')])
            if self.recovery_dtbo_size > 0:
                args.extend(['--recovery_dtbo',
                             os.path.join(self.image_dir, 'recovery_dtbo')])
            if self.dtb_size > 0:
                args.extend(['--dtb', os.path.join(self.image_dir, 'dtb')])

            args.extend(['--pagesize', f'{self.page_size:#010x}'])

            # Kernel load address is base + kernel_offset in mkbootimg.py.
            # However we don't know the value of 'base' when unpacking a boot
            # image in this script, so we set 'base' to zero and 'kernel_offset'
            # to the kernel load address, 'ramdisk_offset' to the ramdisk load
            # address, ... etc.
            args.extend(['--base', f'{0:#010x}'])
            args.extend(['--kernel_offset',
                         f'{self.kernel_load_address:#010x}'])
            args.extend(['--ramdisk_offset',
                         f'{self.ramdisk_load_address:#010x}'])
            args.extend(['--second_offset',
                         f'{self.second_load_address:#010x}'])
            args.extend(['--tags_offset', f'{self.tags_load_address:#010x}'])

            # dtb is added in boot image v2, and is absent in v1 or v0.
            if self.header_version == 2:
                # dtb_offset is uint64_t.
                args.extend(['--dtb_offset', f'{self.dtb_load_address:#018x}'])

            args.extend(['--board', self.product_name])
            args.extend(['--cmdline', self.cmdline + self.extra_cmdline])
        else:
            args.extend(['--cmdline', self.cmdline])

        return args


def unpack_boot_image(args):
    """extracts kernel, ramdisk, second bootloader and recovery dtbo"""
    info = BootImageInfoFormatter()
    info.boot_magic = unpack('8s', args.boot_img.read(8))[0].decode()

    kernel_ramdisk_second_info = unpack('9I', args.boot_img.read(9 * 4))
    # header_version is always at [8] regardless of the value of header_version.
    info.header_version = kernel_ramdisk_second_info[8]

    if info.header_version < 3:
        info.kernel_size = kernel_ramdisk_second_info[0]
        info.kernel_load_address = kernel_ramdisk_second_info[1]
        info.ramdisk_size = kernel_ramdisk_second_info[2]
        info.ramdisk_load_address = kernel_ramdisk_second_info[3]
        info.second_size = kernel_ramdisk_second_info[4]
        info.second_load_address = kernel_ramdisk_second_info[5]
        info.tags_load_address = kernel_ramdisk_second_info[6]
        info.page_size = kernel_ramdisk_second_info[7]
        os_version_patch_level = unpack('I', args.boot_img.read(1 * 4))[0]
    else:
        info.kernel_size = kernel_ramdisk_second_info[0]
        info.ramdisk_size = kernel_ramdisk_second_info[1]
        os_version_patch_level = kernel_ramdisk_second_info[2]
        info.second_size = 0
        info.page_size = BOOT_IMAGE_HEADER_V3_PAGESIZE

    info.os_version, info.os_patch_level = decode_os_version_patch_level(
        os_version_patch_level)

    if info.header_version < 3:
        info.product_name = cstr(unpack('16s',
                                        args.boot_img.read(16))[0].decode())
        info.cmdline = cstr(unpack('512s', args.boot_img.read(512))[0].decode())
        args.boot_img.read(32)  # ignore SHA
        info.extra_cmdline = cstr(unpack('1024s',
                                         args.boot_img.read(1024))[0].decode())
    else:
        info.cmdline = cstr(unpack('1536s',
                                   args.boot_img.read(1536))[0].decode())

    if info.header_version in {1, 2}:
        info.recovery_dtbo_size = unpack('I', args.boot_img.read(1 * 4))[0]
        info.recovery_dtbo_offset = unpack('Q', args.boot_img.read(8))[0]
        info.boot_header_size = unpack('I', args.boot_img.read(4))[0]
    else:
        info.recovery_dtbo_size = 0

    if info.header_version == 2:
        info.dtb_size = unpack('I', args.boot_img.read(4))[0]
        info.dtb_load_address = unpack('Q', args.boot_img.read(8))[0]
    else:
        info.dtb_size = 0
        info.dtb_load_address = 0

    if info.header_version >= 4:
        info.boot_signature_size = unpack('I', args.boot_img.read(4))[0]
    else:
        info.boot_signature_size = 0

    # The first page contains the boot header
    num_header_pages = 1

    # Convenient shorthand.
    page_size = info.page_size

    num_kernel_pages = get_number_of_pages(info.kernel_size, page_size)
    kernel_offset = page_size * num_header_pages  # header occupies a page
    image_info_list = [(kernel_offset, info.kernel_size, 'kernel')]

    num_ramdisk_pages = get_number_of_pages(info.ramdisk_size, page_size)
    ramdisk_offset = page_size * (num_header_pages + num_kernel_pages
                                 ) # header + kernel
    image_info_list.append((ramdisk_offset, info.ramdisk_size, 'ramdisk'))

    if info.second_size > 0:
        second_offset = page_size * (
            num_header_pages + num_kernel_pages + num_ramdisk_pages
            )  # header + kernel + ramdisk
        image_info_list.append((second_offset, info.second_size, 'second'))

    if info.recovery_dtbo_size > 0:
        image_info_list.append((info.recovery_dtbo_offset,
                                info.recovery_dtbo_size,
                                'recovery_dtbo'))
    if info.dtb_size > 0:
        num_second_pages = get_number_of_pages(info.second_size, page_size)
        num_recovery_dtbo_pages = get_number_of_pages(
            info.recovery_dtbo_size, page_size)
        dtb_offset = page_size * (
            num_header_pages + num_kernel_pages + num_ramdisk_pages +
            num_second_pages + num_recovery_dtbo_pages)

        image_info_list.append((dtb_offset, info.dtb_size, 'dtb'))

    if info.boot_signature_size > 0:
        # boot signature only exists in boot.img version >= v4.
        # There are only kernel and ramdisk pages before the signature.
        boot_signature_offset = page_size * (
            num_header_pages + num_kernel_pages + num_ramdisk_pages)

        image_info_list.append((boot_signature_offset, info.boot_signature_size,
                                'boot_signature'))

    create_out_dir(args.out)
    for offset, size, name in image_info_list:
        extract_image(offset, size, args.boot_img, os.path.join(args.out, name))
    info.image_dir = args.out

    return info


class VendorBootImageInfoFormatter:
    """Formats the vendor_boot image info."""

    def format_pretty_text(self):
        lines = []
        lines.append(f'boot magic: {self.boot_magic}')
        lines.append(f'vendor boot image header version: {self.header_version}')
        lines.append(f'page size: {self.page_size:#010x}')
        lines.append(f'kernel load address: {self.kernel_load_address:#010x}')
        lines.append(f'ramdisk load address: {self.ramdisk_load_address:#010x}')
        if self.header_version > 3:
            lines.append(
                f'vendor ramdisk total size: {self.vendor_ramdisk_size}')
        else:
            lines.append(f'vendor ramdisk size: {self.vendor_ramdisk_size}')
        lines.append(f'vendor command line args: {self.cmdline}')
        lines.append(
            f'kernel tags load address: {self.tags_load_address:#010x}')
        lines.append(f'product name: {self.product_name}')
        lines.append(f'vendor boot image header size: {self.header_size}')
        lines.append(f'dtb size: {self.dtb_size}')
        lines.append(f'dtb address: {self.dtb_load_address:#018x}')
        if self.header_version > 3:
            lines.append(
                f'vendor ramdisk table size: {self.vendor_ramdisk_table_size}')
            lines.append('vendor ramdisk table: [')
            indent = lambda level: ' ' * 4 * level
            for entry in self.vendor_ramdisk_table:
                (output_ramdisk_name, ramdisk_size, ramdisk_offset,
                 ramdisk_type, ramdisk_name, board_id) = entry
                lines.append(indent(1) + f'{output_ramdisk_name}: ''{')
                lines.append(indent(2) + f'size: {ramdisk_size}')
                lines.append(indent(2) + f'offset: {ramdisk_offset}')
                lines.append(indent(2) + f'type: {ramdisk_type:#x}')
                lines.append(indent(2) + f'name: {ramdisk_name}')
                lines.append(indent(2) + 'board_id: [')
                stride = 4
                for row_idx in range(0, len(board_id), stride):
                    row = board_id[row_idx:row_idx + stride]
                    lines.append(
                        indent(3) + ' '.join(f'{e:#010x},' for e in row))
                lines.append(indent(2) + ']')
                lines.append(indent(1) + '}')
            lines.append(']')
            lines.append(
                f'vendor bootconfig size: {self.vendor_bootconfig_size}')

        return '\n'.join(lines)

    def format_mkbootimg_argument(self):
        args = []
        args.extend(['--header_version', str(self.header_version)])
        args.extend(['--pagesize', f'{self.page_size:#010x}'])
        args.extend(['--base', f'{0:#010x}'])
        args.extend(['--kernel_offset', f'{self.kernel_load_address:#010x}'])
        args.extend(['--ramdisk_offset', f'{self.ramdisk_load_address:#010x}'])
        args.extend(['--tags_offset', f'{self.tags_load_address:#010x}'])
        args.extend(['--dtb_offset', f'{self.dtb_load_address:#018x}'])
        args.extend(['--vendor_cmdline', self.cmdline])
        args.extend(['--board', self.product_name])

        args.extend(['--dtb', os.path.join(self.image_dir, 'dtb')])

        if self.header_version > 3:
            args.extend(['--vendor_bootconfig',
                         os.path.join(self.image_dir, 'bootconfig')])

            for entry in self.vendor_ramdisk_table:
                (output_ramdisk_name, _, _, ramdisk_type,
                 ramdisk_name, board_id) = entry
                args.extend(['--ramdisk_type', str(ramdisk_type)])
                args.extend(['--ramdisk_name', ramdisk_name])
                for idx, e in enumerate(board_id):
                    if e:
                        args.extend([f'--board_id{idx}', f'{e:#010x}'])
                vendor_ramdisk_path = os.path.join(
                    self.image_dir, output_ramdisk_name)
                args.extend(['--vendor_ramdisk_fragment', vendor_ramdisk_path])
        else:
            args.extend(['--vendor_ramdisk',
                         os.path.join(self.image_dir, 'vendor_ramdisk')])

        return args


def unpack_vendor_boot_image(args):
    info = VendorBootImageInfoFormatter()
    info.boot_magic = unpack('8s', args.boot_img.read(8))[0].decode()
    info.header_version = unpack('I', args.boot_img.read(4))[0]
    info.page_size = unpack('I', args.boot_img.read(4))[0]
    info.kernel_load_address = unpack('I', args.boot_img.read(4))[0]
    info.ramdisk_load_address = unpack('I', args.boot_img.read(4))[0]
    info.vendor_ramdisk_size = unpack('I', args.boot_img.read(4))[0]
    info.cmdline = cstr(unpack('2048s', args.boot_img.read(2048))[0].decode())
    info.tags_load_address = unpack('I', args.boot_img.read(4))[0]
    info.product_name = cstr(unpack('16s', args.boot_img.read(16))[0].decode())
    info.header_size = unpack('I', args.boot_img.read(4))[0]
    info.dtb_size = unpack('I', args.boot_img.read(4))[0]
    info.dtb_load_address = unpack('Q', args.boot_img.read(8))[0]

    # Convenient shorthand.
    page_size = info.page_size
    # The first pages contain the boot header
    num_boot_header_pages = get_number_of_pages(info.header_size, page_size)
    num_boot_ramdisk_pages = get_number_of_pages(
        info.vendor_ramdisk_size, page_size)
    num_boot_dtb_pages = get_number_of_pages(info.dtb_size, page_size)

    ramdisk_offset_base = page_size * num_boot_header_pages
    image_info_list = []

    if info.header_version > 3:
        info.vendor_ramdisk_table_size = unpack('I', args.boot_img.read(4))[0]
        vendor_ramdisk_table_entry_num = unpack('I', args.boot_img.read(4))[0]
        vendor_ramdisk_table_entry_size = unpack('I', args.boot_img.read(4))[0]
        info.vendor_bootconfig_size = unpack('I', args.boot_img.read(4))[0]
        num_vendor_ramdisk_table_pages = get_number_of_pages(
            info.vendor_ramdisk_table_size, page_size)
        vendor_ramdisk_table_offset = page_size * (
            num_boot_header_pages + num_boot_ramdisk_pages + num_boot_dtb_pages)

        vendor_ramdisk_table = []
        vendor_ramdisk_symlinks = []
        for idx in range(vendor_ramdisk_table_entry_num):
            entry_offset = vendor_ramdisk_table_offset + (
                vendor_ramdisk_table_entry_size * idx)
            args.boot_img.seek(entry_offset)
            ramdisk_size = unpack('I', args.boot_img.read(4))[0]
            ramdisk_offset = unpack('I', args.boot_img.read(4))[0]
            ramdisk_type = unpack('I', args.boot_img.read(4))[0]
            ramdisk_name = cstr(unpack(
                f'{VENDOR_RAMDISK_NAME_SIZE}s',
                args.boot_img.read(VENDOR_RAMDISK_NAME_SIZE))[0].decode())
            board_id = unpack(
                f'{VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE}I',
                args.boot_img.read(
                    4 * VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE))
            output_ramdisk_name = f'vendor_ramdisk{idx:02}'

            image_info_list.append((ramdisk_offset_base + ramdisk_offset,
                                    ramdisk_size, output_ramdisk_name))
            vendor_ramdisk_symlinks.append((output_ramdisk_name, ramdisk_name))
            vendor_ramdisk_table.append(
                (output_ramdisk_name, ramdisk_size, ramdisk_offset,
                 ramdisk_type, ramdisk_name, board_id))

        info.vendor_ramdisk_table = vendor_ramdisk_table

        bootconfig_offset = page_size * (num_boot_header_pages
            + num_boot_ramdisk_pages + num_boot_dtb_pages
            + num_vendor_ramdisk_table_pages)
        image_info_list.append((bootconfig_offset, info.vendor_bootconfig_size,
            'bootconfig'))
    else:
        image_info_list.append(
            (ramdisk_offset_base, info.vendor_ramdisk_size, 'vendor_ramdisk'))

    dtb_offset = page_size * (num_boot_header_pages + num_boot_ramdisk_pages
                             ) # header + vendor_ramdisk
    image_info_list.append((dtb_offset, info.dtb_size, 'dtb'))

    create_out_dir(args.out)
    for offset, size, name in image_info_list:
        extract_image(offset, size, args.boot_img, os.path.join(args.out, name))
    info.image_dir = args.out

    if info.header_version > 3:
        vendor_ramdisk_by_name_dir = os.path.join(
            args.out, 'vendor-ramdisk-by-name')
        create_out_dir(vendor_ramdisk_by_name_dir)
        for src, dst in vendor_ramdisk_symlinks:
            src_pathname = os.path.join('..', src)
            dst_pathname = os.path.join(
                vendor_ramdisk_by_name_dir, f'ramdisk_{dst}')
            if os.path.lexists(dst_pathname):
                os.remove(dst_pathname)
            os.symlink(src_pathname, dst_pathname)

    return info


def unpack_image(args):
    boot_magic = unpack('8s', args.boot_img.read(8))[0].decode()
    args.boot_img.seek(0)
    if boot_magic == 'ANDROID!':
        info = unpack_boot_image(args)
    elif boot_magic == 'VNDRBOOT':
        info = unpack_vendor_boot_image(args)
    else:
        raise ValueError(f'Not an Android boot image, magic: {boot_magic}')

    if args.format == 'mkbootimg':
        mkbootimg_args = info.format_mkbootimg_argument()
        if args.null:
            print('\0'.join(mkbootimg_args) + '\0', end='')
        else:
            print(shlex.join(mkbootimg_args))
    else:
        print(info.format_pretty_text())


def get_unpack_usage():
    return """Output format:

  * info

    Pretty-printed info-rich text format suitable for human inspection.

  * mkbootimg

    Output shell-escaped (quoted) argument strings that can be used to
    reconstruct the boot image. For example:

    $ unpack_bootimg --boot_img vendor_boot.img --out out --format=mkbootimg |
        tee mkbootimg_args
    $ sh -c "mkbootimg $(cat mkbootimg_args) --vendor_boot repacked.img"

    vendor_boot.img and repacked.img would be equivalent.

    If the -0 option is specified, output unescaped null-terminated argument
    strings that are suitable to be parsed by a shell script (xargs -0 format):

    $ unpack_bootimg --boot_img vendor_boot.img --out out --format=mkbootimg \\
        -0 | tee mkbootimg_args
    $ declare -a MKBOOTIMG_ARGS=()
    $ while IFS= read -r -d '' ARG; do
        MKBOOTIMG_ARGS+=("${ARG}")
      done <mkbootimg_args
    $ mkbootimg "${MKBOOTIMG_ARGS[@]}" --vendor_boot repacked.img
"""


def parse_cmdline():
    """parse command line arguments"""
    parser = ArgumentParser(
        formatter_class=RawDescriptionHelpFormatter,
        description='Unpacks boot, recovery or vendor_boot image.',
        epilog=get_unpack_usage(),
    )
    parser.add_argument('--boot_img', type=FileType('rb'), required=True,
                        help='path to the boot, recovery or vendor_boot image')
    parser.add_argument('--out', default='out',
                        help='output directory of the unpacked images')
    parser.add_argument('--format', choices=['info', 'mkbootimg'],
                        default='info',
                        help='text output format (default: info)')
    parser.add_argument('-0', '--null', action='store_true',
                        help='output null-terminated argument strings')
    return parser.parse_args()


def main():
    """parse arguments and unpack boot image"""
    args = parse_cmdline()
    unpack_image(args)


if __name__ == '__main__':
    main()
