#!/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):
    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):
    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)])
        args.extend(['--os_version', self.os_version])
        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 <= 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()
