#!/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 = []

    image_info_list.append(
        (ramdisk_offset_base, info.vendor_ramdisk_size, 'vendor_ramdisk'))

    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'))

    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()
