Добавить в корзинуПозвонить
Найти в Дзене
mamaich

Как я обхожу vbmeta (Android Verified Boot)

В новых версиях Андроид нельзя просто взять и внести изменения в разделы system или vendor - Android Verified Boot не даст такому устройству загрузиться. Опишу, как я поступаю. Как обычно, дисклеймер: я не гарантирую, что описанные ниже команды выполняют то, что заявлено в статье. Не беру ответственность за какие-либо последствия ваших экспериментов. Сперва требуется получить доступ к консоли Андроид. Это может быть ADB либо UART консоль устройства. Через консоль получаем строку параметров ядра командой "bugreport": Строка параметров ядра, которую выводит на экран Андроид при загрузке, обрезана по длине, и часть параметров мы не видим. Посмотреть /proc/cmdline нам не дает selinux - поэтому используем bugreport. Приведу пример строки: Command line: init=/init console=ttyS0,115200 earlyprintk=aml-uart,0xff803000 no_console_suspend ramoops.pstore_en=1 ramoops.record_size=0x8000 ramoops.console_size=0x4000 ro rootwait skip_initramfs otg_device=1 reboot_mode_android=normal logo=osd0,loaded

В новых версиях Андроид нельзя просто взять и внести изменения в разделы system или vendor - Android Verified Boot не даст такому устройству загрузиться. Опишу, как я поступаю.

Как обычно, дисклеймер: я не гарантирую, что описанные ниже команды выполняют то, что заявлено в статье. Не беру ответственность за какие-либо последствия ваших экспериментов.

Сперва требуется получить доступ к консоли Андроид. Это может быть ADB либо UART консоль устройства. Через консоль получаем строку параметров ядра командой "bugreport":

Строка параметров ядра, которую выводит на экран Андроид при загрузке, обрезана по длине, и часть параметров мы не видим. Посмотреть /proc/cmdline нам не дает selinux - поэтому используем bugreport.

Приведу пример строки:

Command line: init=/init console=ttyS0,115200 earlyprintk=aml-uart,0xff803000 no_console_suspend ramoops.pstore_en=1 ramoops.record_size=0x8000 ramoops.console_size=0x4000 ro rootwait skip_initramfs otg_device=1 reboot_mode_android=normal logo=osd0,loaded,0x3d800000 vout=2160p60hz,enable panel_type=lcd_1 hdmitx=,420,8bit hdmimode=2160p60hz hdmichecksum=0xd4220000 dolby_vision_on=0 frac_rate_policy=1 hdmi_read_edid=1 cvbsmode=480cvbs osd_reverse=0 video_reverse=0 irq_check_en=0 androidboot.selinux=enforcing androidboot.firstboot=0 jtag=disable androidboot.hardware=amlogic androidboot.serialno=серийник androidboot.deviceid=серийник androidboot.pcbid=ид_платы androidboot.rh_unlock=0 androidboot.qc_mode=0 dm="1 vroot none ro 1,0 3184624 verity 1 /dev/mmcblk0p18 /dev/mmcblk0p18 4096 4096 398078 398078 sha1 d8a738400eb3245fd9778c2b03f9b237438d7d8a d5ff6f6c1552cea27ee7f6d2cd621dd5bc97fb25b30158cdb9a5fc607392b71b 10 restart_on_corruption ignore_zero_blocks use_fec_from_device /dev/mmcblk0p18 fec_roots 2 fec_blocks 401214 fec_start 401214" root=/dev/dm-0 androidboot.vbmeta.device=/dev/block/vbmeta androidboot.vbmeta.avb_version=1.1 androidboot.vbmeta.device_state=locked androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=3136 androidboot.vbmeta.digest=00e5d3f4c9d8f2040ad49398e36995b0a30700f8f0253813de04f450f6cfb839 androidboot.vbmeta.invalidate_on_error=yes androidboot.veritymode=enforcing androidboot.verifiedbootstate=green androidboot.dtbo_idx=0 buildvariant=user

На разных устройствах командная строка будет разной.
Жирным выделены строки, относящиеся к AVB, их надо удалить, а root=/dev/dm-0 заменить на реальный раздел system, в моем примере это будет root=/dev/mmcblk0p18.

Далее проваливаемся в интерактивный режим u-boot и оттуда запускаем ядро Андроид вручную командами (либо эти команды можно обернуть в скрипт):

setenv bootargs "init=/init console=ttyS0,115200 earlyprintk=aml-uart,0xff803000 no_console_suspend ramoops.pstore_en=1 ramoops.record_size=0x8000 ramoops.console_size=0x4000 ro rootwait skip_initramfs otg_device=1 reboot_mode_android=normal logo=osd0,loaded,0x3d800000 vout=2160p60hz,enable panel_type=lcd_1 hdmitx=,420,8bit hdmimode=2160p60hz hdmichecksum=0xd4220000 dolby_vision_on=0 frac_rate_policy=1 hdmi_read_edid=1 cvbsmode=480cvbs osd_reverse=0 video_reverse=0"

setenv bootargs ${bootargs} " irq_check_en=0 androidboot.selinux=enforcing androidboot.firstboot=0 jtag=disable androidboot.hardware=amlogic androidboot.serialno=серийник androidboot.deviceid=серийник androidboot.pcbid=ид_платы androidboot.rh_unlock=0 androidboot.qc_mode=0 root=/dev/mmcblk0p18 androidboot.dtbo_idx=0 buildvariant=user -- "

imgread kernel ${boot_part} ${loadaddr}

bootm ${loadaddr}

Строка setenv bootargs разбита на две части потому что у u-boot есть ограничение на ее длину при вставке в UART.

Команды загрузки ядра и передачи ему управления следует взять из скриптов u-boot устройства.
imgread и bootenv в примере взяты с устройства на процессоре Amlogic, а на устройствах c процессором Allwinner команды уже другие, например такие: sunxi_flash read 45000000 boot; boota 45000000 boot.

Обратите внимание на два дефиса (--) и пробел перед кавычками в конце второй setenv. U-boot принудительно дописывает в конец переменной bootargs параметры AVB, которые ранее я выделял жирным. Установка двух дефисов означает, что всё что будет написано после них игнорируется ядром и передается как параметры в процесс init, а процесс init эти ключи никак не использует. Таким образом ядро Андроид не будет знать, что ему надо инициализировать dm-verity и не будет проверять хеши/подпись разделов.

-2

Profit. Можно вносить изменения в раздел system, например, править файл политик selinux или добавлять свои сертификаты.