mirror of
https://github.com/chenxiaolong/avbroot.git
synced 2026-06-02 06:23:34 +02:00
6387b8ae4d
* https://github.com/chenxiaolong/avbroot/commit/6f8de8b2c4cde899e30c8d1744f8c19b5a742f6d * https://github.com/chenxiaolong/avbroot/commit/fce0bfabab05ccea25a90fb9b014b0a4dd3b760b * https://github.com/chenxiaolong/avbroot/commit/f82db7aafcb3f8a0229df1ef86c91d8631b90e0b also noticed that I had missed https://github.com/chenxiaolong/avbroot/commit/d7439e15aedb77948e7079fc1e23c2f44e6636ec a while back. added that, too. Signed-off-by: Ivan <reddxae@proton.me>
613 lines
54 KiB
Markdown
613 lines
54 KiB
Markdown
# avbroot
|
||
|
||
avbroot – это утилита для воспроизводимой модификации OTA-образов Android A/B-формата и их переподписания пользовательскими ключами. Она также включает в себя [набор подкоманд](./README.extra.md) для упаковки и распаковки образов Android различных форматов.
|
||
|
||
Прежде чем использовать avbroot, рекомендуется иметь хорошее понимание того, как работают AVB и OTA в формате A/B. Как минимум, следует ознакомиться с [разделом предостережений,](#предостережения) чтобы избежать хардбрика устройства.
|
||
|
||
## Требования
|
||
|
||
* Поддерживаются только устройства, использующие современную A/B-разметку. Это большинство девайсов, выпускаемых с Android 10 и новее (за исключением устройств от Samsung). Чтобы проверить, использует ли ваше устройство необходимую схему разметки, откройте zip-архив OTA и проверьте:
|
||
|
||
* наличие файла `payload.bin` (обычно находится в корне архива)
|
||
* наличие файла `META-INF/com/android/metadata` (Android 10-11) или `META-INF/com/android/metadata.pb` (Android 12+)
|
||
|
||
* Устройство должно поддерживать установку пользовательского публичного ключа для подтверждения статуса доверия загрузчика. Обычно это производится с помощью команды `fastboot flash avb_custom_key`.
|
||
|
||
Список девайсов, на которых проверялась совместимость с указанным выше функционалом, находится здесь: [#299.](https://github.com/chenxiaolong/avbroot/issues/299)
|
||
|
||
## Патчи
|
||
|
||
avbroot модифицирует следующие образы:
|
||
|
||
* `boot` или `init_boot`, в зависимости от устройства, модифицируется для получения root-доступа, если это запрашивается.
|
||
|
||
* `boot`, `recovery` или `vendor_boot`, в зависимости от устройства, модифицируется для замены сертификата проверки подписи OTA на пользовательский. Это позволяет устанавливать будущие пропатченные OTA через режим Recovery уже после блокировки загрузчика, то есть в качестве обновления. Также это предотвращает случайную установку оригинального непропатченного OTA.
|
||
|
||
* `system` тоже модифицируется для замены сертификата проверки подписи OTA. Это не позволит системному приложению обновлений ОС установить оригинальный непропатченный OTA и дает возможность использовать сторонние приложения для установки пропатченных OTA.
|
||
|
||
## Предостережения
|
||
|
||
* **Всегда оставляйте опцию `Заводской разблокировки`** (или OEM unlocking в англ.) **включенной при наличии root-прав с заблокированным загрузчиком.** Это очень важно. Доступ к root-правам потенциально позволяет перезаписать загрузочный раздел из-под системы, будь то сделано случайно или намеренно, файлом, который не был подписан должным образом. В таком случае, система и режим Recovery больше не смогут загрузиться, а команда `fastboot flashing unlock` будет недоступна, потому что параметр Заводской разблокировки отключен. То есть, это приведет к **_хардбрику устройства_**.
|
||
|
||
Повторюсь: **_ВСЕГДА оставляйте `Заводскую разблокировку` включенной при наличии root-прав._**
|
||
|
||
* Любая операция, приводящая к прошивке некорректно подписанного загрузочного образа, приведет к тому, что устройство больше не сможет загрузиться в систему/режим Recovery, а для его восстановления потребуется повторная разблокировка загрузчика (и, следовательно, стирание всех пользовательских данных). К подобным операциям в том числе относятся:
|
||
|
||
* Метод `Прямой установки` для обновления Magisk. Magisk можно обновлять **только путем репатчинга OTA,** но не через его приложение.
|
||
|
||
* Функция `Удаление Magisk` в приложении Magisk. Если вам больше не нужен root-доступ, Magisk **должен быть удален путем репатчинга OTA** с использованием параметра `--rootless`, но не через его приложение.
|
||
|
||
Если в загрузочный раздел были внесены какие-либо изменения, **не перезагружайтесь**. Обратитесь за помощью, [открыв Issue,](https://github.com/chenxiaolong/avbroot/issues/new) и четко разъясните, какие конкретные действия привели к возникновению такой ситуации. Если Android всё еще работает и доступ к root-правам сохранился – вероятно, получится откатить изменения до исходного состояния, не стирая ваши данные.
|
||
|
||
## Использование
|
||
|
||
1. Убедитесь, что вы ознакомились и поняли указанные выше [предостережения.](#предостережения)
|
||
|
||
2. Скачайте последнюю версию со страницы [релизов.](https://github.com/chenxiaolong/avbroot/releases) Чтобы сверить цифровую подпись, см. раздел [проверки цифровых подписей.](#проверка-цифровых-подписей)
|
||
|
||
avbroot – это отдельный исполняемый файл. Он не требует установки и может быть запущен из любого места на диске.
|
||
|
||
3. [Сгенерируйте ключи подписи.](#генерация-ключей)
|
||
|
||
Пропустите этот шаг, если вы обновляете Android, Magisk или KernelSU уже после выполнения [первоначальной настройки](#первоначальная-настройка). Повторная генерация ключей подписи для [обновлений](#обновления) не требуется: для всех последующих обновлений должны использоваться те ключи, что были созданы при первоначальной настройке.
|
||
|
||
4. Пропатчите ОТА-архив с помощью команды:
|
||
|
||
```bash
|
||
avbroot ota patch \
|
||
--input /путь/к/ota.zip \
|
||
--key-avb /путь/к/avb.key \
|
||
--key-ota /путь/к/ota.key \
|
||
--cert-ota /путь/к/ota.crt \
|
||
```
|
||
|
||
Добавьте следующие аргументы в конец команды в зависимости от того, как вы хотите получить root-доступ.
|
||
|
||
* Для получения root-доступа с использованием Magisk:
|
||
|
||
```bash
|
||
--magisk /путь/к/magisk.apk \
|
||
--magisk-preinit-device <имя>
|
||
```
|
||
|
||
Если вы не знаете имени раздела предварительной инициализации Magisk, следуйте инструкции [в соответствующем разделе.](#предварительная-инициализация-устройства-для-magisk)
|
||
|
||
Если вы пропатчили загрузочный образ вручную через приложение Magisk (вместо автоматического идентичного патчинга через avbroot), используйте следующий аргумент:
|
||
|
||
```bash
|
||
--prepatched /путь/к/magisk_patched-xxxxx_yyyyy.img
|
||
```
|
||
|
||
* Для получения root-доступа с использованием KernelSU:
|
||
|
||
```bash
|
||
--prepatched /путь/к/kernelsu_boot.img
|
||
```
|
||
|
||
* Без root-доступа:
|
||
|
||
```bash
|
||
--rootless
|
||
```
|
||
|
||
Больше информации про существующие аргументы можно найти в разделе [расширенного использования.](#расширенное-использование)
|
||
|
||
Если название для `--output` не указывается, то готовый файл будет записан как `<название-ota-zip-в-input>.patched`.
|
||
|
||
5. Готово! Для прошивки пропатченного OTA следуйте инструкции в разделе [первоначальной настройки.](#первоначальная-настройка) Для последующих обновлений тоже есть соответствующий [раздел обновлений.](#обновления)
|
||
|
||
## Генерация ключей
|
||
|
||
Во время патчинга OTA, avbroot подписывает несколько компонентов:
|
||
|
||
* загрузочный образ (boot)
|
||
* образ vbmeta
|
||
* payload из OTA
|
||
* сам архив OTA
|
||
|
||
Первые два компонента подписываются ключом AVB, а последние два – ключом OTA. Можно использовать один и тот же ключ, однако в следующих шагах описано, как сгенерировать два отдельных.
|
||
|
||
Если вы патчите OTA сразу для нескольких устройств, настоятельно рекомендуется генерировать уникальные ключи для каждого девайса – так вы защитите себя от случайной прошивки неподходящего OTA.
|
||
|
||
1. Сгенерируйте ключи подписи для AVB и OTA.
|
||
|
||
```bash
|
||
avbroot key generate-key -o avb.key
|
||
avbroot key generate-key -o ota.key
|
||
```
|
||
|
||
2. Преобразуйте публичную часть ключа подписи AVB в формат метаданных публичного ключа AVB. Именно этот формат используется в загрузчике устройства для установки пользовательского ключа.
|
||
|
||
```bash
|
||
avbroot key encode-avb -k avb.key -o avb_pkmd.bin
|
||
```
|
||
|
||
3. Сгенерируйте самоподписанный сертификат для ключа подписи OTA. Он используется режимом Recovery для проверки подписи OTA при установке обновления.
|
||
|
||
```bash
|
||
avbroot key generate-cert -k ota.key -o ota.crt
|
||
```
|
||
|
||
avbroot совместим с любым стандартным 4096-битным приватным ключом RSA в кодировке PKCS#8 и сертификатом X509 в кодировке PEM, например с теми, которые генерируются openssl.
|
||
|
||
Если вы потеряете ключ(-и) подписи AVB или OTA, вы больше не сможете подписывать новые OTA-архивы. Придется генерировать новые ключи подписи и разблокировать загрузчик (что приведет к стиранию всех данных). В таком случае возвращайтесь к инструкции в разделе [использования.](#использование)
|
||
|
||
## Первоначальная настройка
|
||
|
||
1. Убедитесь, что вы используете утилиту fastboot версии 35 или новее. Предыдущие версии содержат баги, что не позволяют команде `fastboot flashall` (которая понадобится по ходу инструкции) работать правильно.
|
||
|
||
```bash
|
||
fastboot --version
|
||
```
|
||
|
||
2. Перезагрузитесь в режим fastboot и разблокируйте загрузчик, если не сделали этого ранее. Это приведет к стиранию всех пользовательских данных.
|
||
|
||
```bash
|
||
fastboot flashing unlock
|
||
```
|
||
|
||
3. Перед первой установкой, на устройстве уже должна быть установлена в оригинальном виде та прошивка, пропатченную версию которой вы собираетесь ставить. Если это не так, сначала установите оригинальную непропатченную OTA.
|
||
|
||
4. Извлекаем из пропатченного OTA модифицированные образы:
|
||
|
||
```bash
|
||
avbroot ota extract \
|
||
--input /путь/к/ota.zip.patched \
|
||
--directory extracted \
|
||
--fastboot
|
||
```
|
||
|
||
Если вы на всякий случай хотите прошить вообще все разделы из ОТА, извлечь их можно, указав аргумент `--all`.
|
||
|
||
5. Установите переменную окружения `ANDROID_PRODUCT_OUT`, указав директорию с извлеченными файлами.
|
||
|
||
Для sh/bash/zsh (Linux, macOS, WSL):
|
||
|
||
```bash
|
||
export ANDROID_PRODUCT_OUT=extracted
|
||
```
|
||
|
||
Для PowerShell (Windows):
|
||
|
||
```powershell
|
||
$env:ANDROID_PRODUCT_OUT = "extracted"
|
||
```
|
||
|
||
Для cmd (Командная строка или Терминал) (Windows):
|
||
|
||
```bat
|
||
set ANDROID_PRODUCT_OUT=extracted
|
||
```
|
||
|
||
6. Прошейте извлеченные образы разделов.
|
||
|
||
```bash
|
||
fastboot flashall --skip-reboot
|
||
```
|
||
|
||
Обратите внимание, что так прошиваются лишь те образы, что относятся к системе. Разделы загрузчика и модема же остаются нетронутыми из-за ограничений fastboot. Если они не обновлены до необходимой версии, или вы не уверены в этом, после прошивки перейдите к пункту [обновлений](#обновления) и установите пропатченный OTA в режиме Recovery. Прошивка полного OTA гарантирует, что абсолютно все разделы будут обновлены.
|
||
|
||
Для устройств Pixel есть ещё один вариант: запуск скрипта `flash-base.sh` из папки заводских образов (factory images) обновит загрузчик и модем.
|
||
|
||
7. После перезагрузки из fastbootd в загрузчик (bootloader), установите пользовательский публичный ключ AVB в загрузчик:
|
||
|
||
```bash
|
||
fastboot reboot-bootloader
|
||
fastboot erase avb_custom_key
|
||
fastboot flash avb_custom_key /путь/к/avb_pkmd.bin
|
||
```
|
||
|
||
8. **[Опционально]** Перед блокировкой загрузчика загрузитесь в систему, дабы убедиться, что все подписано правильно.
|
||
|
||
Установите приложение Magisk или KernelSU и выполните следующую команду:
|
||
|
||
```bash
|
||
adb shell su -c 'dmesg | grep libfs_avb'
|
||
```
|
||
|
||
Если AVB работает корректно, будет выведено следующее сообщение:
|
||
|
||
```bash
|
||
init: [libfs_avb]Returning avb_handle with status: Success
|
||
```
|
||
|
||
Как ещё один вариант, Android-версию avbroot также можно использовать для [проверки разделов на устройстве](./README.extra.md#verifying-avb-hashes-and-signatures-on-device).
|
||
|
||
9. Перезагрузитесь в fastboot и заблокируйте загрузчик. Это снова приведет к стиранию данных.
|
||
|
||
```bash
|
||
fastboot flashing lock
|
||
```
|
||
|
||
Подтвердите нажатием клавиш уменьшения громкости и включения, а после перезагрузитесь в систему.
|
||
|
||
Напоминаю: **не отключайте `Заводскую разблокировку`!**
|
||
|
||
**ПРЕДУПРЕЖДЕНИЕ**: Если вы прошили CalyxOS, мастер настройки [автоматически отключит опцию `Заводской разблокировки`.](https://github.com/CalyxOS/platform_packages_apps_SetupWizard/blob/7d2df25cedcbff83ddb608e628f9d97b38259c26/src/org/lineageos/setupwizard/SetupWizardApp.java#L135-L140) Не забудьте снова включить её вручную в настройках для разработчиков. Для перестраховки можете использовать [модуль `OEMUnlockOnBoot`,](https://github.com/chenxiaolong/OEMUnlockOnBoot) который автоматически включает пункт Заводской разблокировки при каждом запуске системы.
|
||
|
||
10. Готово! Установка последующих обновлений системы, Magisk или KernelSU, описывается в [следующем разделе.](#обновления)
|
||
|
||
## Обновления
|
||
|
||
Обновления Android, Magisk и KernelSU выполняются одинаково – исключительно путем обновления или репатчинга того же самого OTA.
|
||
|
||
1. Сгенерируйте новый пропатченный OTA согласно инструкции в разделе [использования.](#использование)
|
||
|
||
2. Если обновляется Magisk или KernelSU, сначала установите их новый `.apk`. Если вы случайно открыли приложение, убедитесь, что оно **не начало** прошивать загрузочный образ. Если в самом приложении появится предложение обновить загрузочный образ, отклоните его.
|
||
|
||
3. Перезагрузитесь в режим Recovery: `adb reboot recovery`. Если устройство повисло на сплеше с сообщением "No command", удерживайте кнопку питания, а затем один раз нажмите кнопку увеличения громкости.
|
||
|
||
4. Обновитесь (Apply update from adb → `adb sideload <ota.zip.patched>`).
|
||
|
||
5. Перезагрузите устройство. Обратите внимание, что при первом запуске после обновления ОС устройство может загружаться дольше обычного (иногда до нескольких минут).
|
||
|
||
**ПРЕДУПРЕЖДЕНИЕ**: В силу специфики работы виртуального A/B в Android, сразу после установки OTA и перезагрузки, в фоновом режиме незаметно запускается операция слияния снапшотов. Во время этого процесса невозможно установить другой OTA через режим Recovery. Пока продолжается слияние снапшотов, избегайте любых действий, которые могут привести к бутлупу (например, установка модулей), поскольку в случае сбоя восстановить устройство получится только повторно разблокировав загрузчик, стирая все данные.
|
||
|
||
Узнать текущий статус процесса можно, выполнив команду: `adb logcat -v color -s update_engine`. Дополнительно, если установлено [Custota](https://github.com/chenxiaolong/Custota) (даже если оно не настроено на использование пользовательского OTA-сервера), приложение будет отображать соответствующее уведомление до завершения операции слияния снапшота.
|
||
|
||
## Возврат на заводскую прошивку
|
||
|
||
Если вы хотите отказаться от использования avbroot и вернуться на стоковую прошивку:
|
||
|
||
1. Перезагрузитесь в режим fastboot и разблокируйте загрузчик. Это приведет к стиранию всех пользовательских данных.
|
||
|
||
2. Удалите пользовательский публичный ключ AVB.
|
||
|
||
```bash
|
||
fastboot erase avb_custom_key
|
||
```
|
||
|
||
3. Прошейте стоковую прошивку. Готово.
|
||
|
||
## OTA-обновления
|
||
|
||
avbroot заменяет `/system/etc/security/otacerts.zip` в разделах системы и Recovery на новый архив, содержащий пользовательский сертификат подписи OTA. Это предотвращает случайную установку непропатченных OTA как из-под загруженной системы, так и при прошивке через Recovery.
|
||
|
||
Рекомендуется отключить системное приложение для обновлений, чтобы оно не пыталось установить непропатченные OTA:
|
||
|
||
* Стоковая (заводская) прошивка: Отключите `Автоматические обновления системы` (Automatic system updates в англ.) в настройках для разработчиков.
|
||
* Кастомная прошивка: Отключите приложение обновлений системы (или запретите ему доступ к Интернету) через Настройки -> Приложения -> Все приложения -> (меню/три точки) -> Показать системные -> (найдите приложение обновлений, например Обновления системы/Updater).
|
||
|
||
Это особенно важно для некоторых кастомных прошивок, поскольку их фирменное приложение для обновления системы может уйти в бесконечный цикл, загружая OTA-обновление, а затем повторяя попытку загрузки и установки при неудачной проверке подписи.
|
||
|
||
Если вы хотите поднять собственный сервер для ОТА-обновлений, вам может быть интересно приложение [Custota.](https://github.com/chenxiaolong/Custota)
|
||
|
||
## Режим обслуживания
|
||
|
||
Некоторые устройства поставляются с режимом обслуживания, который загружает систему с чистым образом `userdata`, благодаря чему специалист по ремонту может проводить диагностику устройства, не имея доступа к пользовательским данным владельца.
|
||
|
||
Если на устройстве есть root-права, использовать этот режим небезопасно. Если у вас обычная сборка Magisk/KernelSU, не подписанная вашим собственным ключом, кто угодно может установить официальное приложение Magisk/KernelSU в режиме обслуживания и запросто получить root-права без какой-либо аутентификации.
|
||
|
||
Потому, чтобы безопасно использовать режим обслуживания:
|
||
|
||
1. Отключите root-доступ на устройстве, пропатчив OTA с аргументом `--rootless` (вместо `--magisk` или `--prepatched`) и прошив его.
|
||
|
||
2. Включите режим обслуживания.
|
||
|
||
3. Получив отремонтированное устройство обратно, выйдите из режима обслуживания.
|
||
|
||
4. Прошейте рутированный OTA в обычном режиме.
|
||
|
||
Поскольку удаление root-прав и повторное их получение выполняются путем перепрошивки OTA, данные устройства стёрты не будут.
|
||
|
||
## Предварительная инициализация устройства для Magisk
|
||
|
||
Magisk версии 25211 и новее требует наличие раздела, доступного для записи пользовательских правил SELinux, к которым необходимо обращаться на ранних этапах загрузки. Его можно определить только на реальном устройстве, поэтому avbroot требует указания точного названия с помощью аргумента `--magisk-preinit-device <имя>`. Чтобы получить имя раздела:
|
||
|
||
1. Извлеките загрузочный образ из оригинального, непропатченного OTA:
|
||
|
||
```bash
|
||
avbroot ota extract \
|
||
--input /path/to/ota.zip \
|
||
--directory . \
|
||
--boot-only
|
||
--partition <название раздела> # init_boot или boot, в зависимости от устройства
|
||
```
|
||
|
||
2. Теперь нужно пропатчить загрузочный образ с помощью приложения Magisk. Это **ДОЛЖНО** быть сделано именно на целевом устройстве или устройстве той же модели! Имя раздела будет неверным и не подойдет, если пропатчить образ на устройстве иной модели.
|
||
|
||
Приложение Magisk выведет в лог строку, подобную следующей:
|
||
|
||
```
|
||
- Pre-init storage partition device ID: <имя>
|
||
```
|
||
|
||
Также и avbroot может вывести информацию о разделе, обнаруженном Magisk, для этого выполните команду:
|
||
|
||
```bash
|
||
avbroot boot magisk-info \
|
||
--image magisk_patched-*.img
|
||
```
|
||
|
||
Имя раздела будет выведено как: `PREINITDEVICE=<имя>`.
|
||
|
||
Теперь, когда имя раздела известно, его нужно указать avbroot с помощью команды `--magisk-preinit-device <имя>`. Имя раздела стоит запомнить или сохранить где-нибудь на будущее, оно вряд ли изменится при обновлении Magisk.
|
||
|
||
Если запустить приложение Magisk на целевом устройстве невозможно (например, оно не загружается), пропатчите OTA с аргументом `--ignore-magisk-warnings` и прошейте его. Затем выполните указанные выше шаги и повторно пропатчите OTA, но уже с указанием аргумента `--magisk-preinit-device <имя>`.
|
||
|
||
## Проверка OTA
|
||
|
||
Чтобы проверить все подписи и хэши, связанные с установкой OTA и процессом загрузки AVB, выполните команду:
|
||
|
||
```bash
|
||
avbroot ota verify \
|
||
--input /путь/к/ota.zip \
|
||
--cert-ota /путь/к/ota.crt \
|
||
--public-key-avb /путь/к/avb_pkmd.bin
|
||
```
|
||
|
||
Эта команда работает для любого OTA, независимо от того, пропатчено оно или нет.
|
||
|
||
Если опции `--cert-ota` и `--public-key-avb` не указаны, то подписи проверяются только на корректность, не проверяя, совпадают ли они внутри всех файлов.
|
||
|
||
## Подсказки через Tab
|
||
|
||
Поскольку avbroot имеет множество опций, будет удобно настроить подсказки с автозаполнением для используемой оболочки. Конфигурации генерируются в самом avbroot.
|
||
|
||
#### bash
|
||
|
||
Добавьте в `~/.bashrc`:
|
||
|
||
```bash
|
||
eval "$(avbroot completion -s bash)"
|
||
```
|
||
|
||
#### zsh
|
||
|
||
Добавьте в `~/.zshrc`:
|
||
|
||
```bash
|
||
eval "$(avbroot completion -s zsh)"
|
||
```
|
||
|
||
#### fish
|
||
|
||
Добавьте в `~/.config/fish/config.fish`:
|
||
|
||
```bash
|
||
avbroot completion -s fish | source
|
||
```
|
||
|
||
#### PowerShell
|
||
|
||
Добавьте в загрузочный скрипт PowerShell (`profile.ps1`):
|
||
|
||
```powershell
|
||
Invoke-Expression (& avbroot completion -s powershell)
|
||
```
|
||
|
||
## Расширенное использование
|
||
|
||
### Использование заранее пропатченного boot.img
|
||
|
||
avbroot может подменить используемый загрузочный образ на заранее пропатченный (вместо того, чтобы самостоятельно применять патч). Это пригодится в случае, если у вас уже имеется пропатченный через приложение Magisk образ ядра или образ с поддержкой KernelSU. Для этого используйте аргумент `--prepatched <загрузочный образ>` вместо `--magisk <apk>`. То есть, указав `--prepatched`, avbroot пропустит применение патчинга Magisk'ом, но по-прежнему применит патч OTA-сертификата.
|
||
|
||
Обратите внимание, что avbroot проверяет совместимость предварительно пропатченного образа с оригинальным. Например, если поля заголовка образа не совпадают, или вовсе указан иной, незагрузочный образ, то процесс патча будет прерван. Эти проверки, конечно, ничего не гарантируют, но должны предостеречь от случайного использования некорректного образа. Чтобы обойти базовые проверки безопасности, укажите аргумент `--ignore-prepatched-compat`. Если вы хотите убрать вообще все проверки (чего делать крайне не рекомендуется), укажите его дважды.
|
||
|
||
### Пропуск патча для root-доступа
|
||
|
||
avbroot можно использовать для простого переподписания OTA, указав аргумент `--rootless` вместо `--magisk`/`--prepatched`. В таком случае пропатченный OTA не будет рутирован. Единственная модификация, которая будет применена – это замена сертификата проверки OTA, чтобы систему можно было обновлять с помощью будущих пропатченных OTA.
|
||
|
||
### Пропуск патчинга сертификата OTA
|
||
|
||
Вы можете пропустить изменение otacerts.zip, используя аргументы `--skip-system-ota-cert` и `--skip-recovery-ota-cert`. **Не используйте их без веской причины.**
|
||
|
||
При использовании `--skip-system-ota-cert`, сертификаты OTA в образе `system` изменены не будут. Это не позволит сторонним приложениям для OTA-обновлений устанавливать будущие пропатченные OTA из-под загруженной системы.
|
||
|
||
При использовании `--skip-recovery-ota-cert`, сертификаты OTA в образах `vendor_boot` или `recovery` изменены не будут. **Это не позволит устанавливать будущие пропатченные OTA в режиме Recovery.**
|
||
|
||
Если вы используете аргумент `--skip-recovery-ota-cert`, потому что уже добавили сертификат OTA в загрузочный образ вручную, рекомендуетcя [проверить пропатченный OTA](#проверка-ota), дабы удостовериться, что замена произведена корректно. Процесс верификации проверяет только копию сертификатов OTA в загрузочном образе, не проверяя копию в образе системы.
|
||
|
||
### Пропуск всех патчей
|
||
|
||
Чтобы внести самый минимум изменений, укажите аргументы:
|
||
|
||
* `--skip-system-ota-cert`
|
||
* `--skip-recovery-ota-cert`
|
||
* `--rootless`
|
||
* не используйте аргумент `--dsu`.
|
||
|
||
Так, пользовательскими ключами будут переподписаны лишь образ `vbmeta` и OTA, остальные разделы останутся нетронутыми.
|
||
|
||
**Это следует использовать только для устранения неполадок.** Без патчей сертификатов, поверх полученного OTA не получится установить никакие обновления.
|
||
|
||
### Подмена образов
|
||
|
||
avbroot поддерживает подмену целых образов в OTA, даже тех, что не являются загрузочными (например, `vendor_dlkm`). Образ можно заменить, используя аргумент `--replace <имя раздела> /путь/к/образу.img`.
|
||
|
||
Единственное, что меняется – это то, откуда считывается файл. При использовании `--replace` вместо образа раздела из оригинального `payload.bin` в OTA, он берется напрямую по указанному вами пути. Заменяющие образы разделов должны иметь правильные колонтитулы vbmeta, соответствующие оригинальным.
|
||
|
||
Это не влияет на ход применения пачтей. Например, при использовании Magisk, патч получения root-прав применяется к загрузочному образу одинаково, независимо от того, был ли он получен из оригинального `payload.bin` или это файл, указанный через `--replace`.
|
||
|
||
### Переподписание разделов
|
||
|
||
avbroot автоматически переподписывает все разделы в OTA, которые он изменяет. Однако и те разделы, что не были затронуты, также можно переподписать с помощью параметра `--re-sign <имя раздела>`. Это полезно, например, когда OTA содержит разделы, подписанные публичным тестовым ключом AOSP (test key).
|
||
|
||
### Загрузка подписанных GSI
|
||
|
||
Функция [динамических обновлений системы (DSU)](https://developer.android.com/topic/dsu?hl=ru) в Android использует корень доверия, отличный от используемого обычной системой. Вместо `avb_custom_key` в загрузчике, она получает доверенные ключи из файлов `first_stage_ramdisk/avb/*.avbpubkey` в ramdisk'е разделов `init_boot` или `vendor_boot`. Эти файлы закодированы в том же двоичном формате, что и файл `avb_pkmd.bin`.
|
||
|
||
avbroot может добавить пользовательский публичный ключ AVB в эту директорию с помощью параметра `--dsu` при патчинге OTA. Это позволяет запускать [общие образы системы (GSI)](https://developer.android.com/topic/generic-system-image?hl=ru), подписанные пользовательским ключом AVB.
|
||
|
||
### Очистка флагов vbmeta
|
||
|
||
Некоторые сборки Android-прошивок могут поставляться с образом `vbmeta`, в котором флаги установлены таким образом, что AVB фактически отключен. Если avbroot сталкивается с такими образом, процесс патчинга завершается ошибкой с сообщением следующего типа:
|
||
|
||
```
|
||
Verified boot is disabled by vbmeta's header flags: 0x3
|
||
```
|
||
|
||
Чтобы принудительно включить AVB (очистив флаги), укажите аргумент `--clear-vbmeta-flags`.
|
||
|
||
### Изменение алгоритма CoW сжатия для вирутального A/B
|
||
|
||
Алгоритм CoW (copy-on-write) сжатия для виртуального A/B можно изменить, используя аргумент `--vabc-algo <алгоритм>`, указав `gz` или `lz4`. Как правило, по умолчанию OTA использует алгоритм, который совместим с изначальной версией Android, на которой поставлялось устройство.
|
||
|
||
* Девайсы, поставляемые с Android 12, поддерживают `gz` и `brotli` (последний не поддерживается avbroot)
|
||
* Девайсы, поставляемые с Android 14, поддерживают `lz4`
|
||
* Девайсы, поставляемые с Android 15, поддерживают `zstd` (не поддерживается avbroot)
|
||
|
||
Выбор быстрого алгоритма, такого как lz4, может значительно ускорить установку OTA из-под системы (при использованием стороннего приложения для OTA-обновлений). Однако, при установке OTA в режиме Recovery, разницы в скорости не будет.
|
||
|
||
Обратите внимание, что текущая используемая версия Android должна поддерживать выбранный алгоритм сжатия. В противном случае установка завершится ошибкой. Например, попытка установить OTA-обновление с Android 14, использующее алгоритм lz4, приведет к ошибке, если установка производится из-под Android 13.
|
||
|
||
### Использование в неинтерактивном режиме
|
||
|
||
По умолчанию avbroot интерактивно запрашивает пароли к приватным ключам. Чтобы запустить avbroot в неинтерактивном режиме, можно:
|
||
|
||
* Предоставить пароли через файлы:
|
||
|
||
```bash
|
||
avbroot ota patch \
|
||
--pass-avb-file /путь/к/avb.passphrase \
|
||
--pass-ota-file /путь/к/ota.passphrase \
|
||
<...>
|
||
```
|
||
|
||
На Unix-подобных системах "файлы" могут быть каналами ("pipes"). В оболочках, поддерживающих подстановку процесса (bash, zsh и т. д.), пароль можно запросить с помощью команды (например, запрашивая у менеджера паролей).
|
||
|
||
```bash
|
||
avbroot ota patch \
|
||
--pass-avb-file <(команда для запроса пароля AVB) \
|
||
--pass-ota-file <(команда для запроса пароля OTA) \
|
||
<...>
|
||
```
|
||
|
||
* Предоставить пароли через переменные среды. Это менее безопасно, поскольку любой процесс, запущенный от имени того же пользователя, может видеть значения переменных среды.
|
||
|
||
```bash
|
||
export PASSPHRASE_AVB="пароль AVB"
|
||
export PASSPHRASE_OTA="пароль OTA"
|
||
|
||
avbroot ota patch \
|
||
--pass-avb-env-var PASSPHRASE_AVB \
|
||
--pass-ota-env-var PASSPHRASE_OTA \
|
||
<...>
|
||
```
|
||
|
||
* Использовать незашифрованные приватные ключи. Крайне не рекомендуется.
|
||
|
||
### Извлечение образов из OTA
|
||
|
||
Чтобы извлечь образы разделов, содержащихся в `payload.bin`, используйте команду:
|
||
|
||
```bash
|
||
avbroot ota extract \
|
||
--input /путь/к/ota.zip \
|
||
--directory extracted
|
||
```
|
||
|
||
По умолчанию извлекаются только те образы, которые потенциально могут быть пропатчены с помощью avbroot. Чтобы извлечь все образы, используйте опцию `--all`. Для извлечения конкретных образов используйте опцию `--partition <название раздела>`, которую можно указать несколько раз.
|
||
|
||
Эта команда также поддерживает извлечение встроенного сертификата OTA и публичного ключа AVB с помощью опций `--cert-ota` и `--public-key-avb`. Чтобы извлечь только эти компоненты, укажите аргумент `--none`, чтобы пропустить извлечение образов разделов.
|
||
|
||
### Режим записи ZIP
|
||
|
||
По умолчанию, avbroot использует потоковую запись для вывода OTA во время патчинга. Это означает, что он вычисляет дайджест sha256 для цифровой подписи одновременно с записью файла. Такой режим приводит к тому, что в ZIP-файле появляются описатели данных, что является частью стандарта ZIP и работает на подавляющем большинстве устройств. Однако некоторые устройства могут иметь некорректно работающие парсеры ZIP-файлов и не смогут правильно прочитать ZIP-файлы OTA, содержащие описатели данных. Если это так, используйте опцию `--zip-mode seekable` при патчинге.
|
||
|
||
Режим seekable записывает ZIP-файлы без описателей данных, но, как следует из названия, требует перемещения по файлу, вместо последовательной записи. Дайджест sha256 для цифровой подписи вычисляется после того, как ZIP-файл был полностью записан.
|
||
|
||
### Подписание с использованием внешней программы
|
||
|
||
avbroot поддерживает делегирование всех операций подписания RSA внешней программе с помощью опции `--signing-helper`. При использовании этой опции, для `--key-avb` и `--key-ota` должен быть указан публичный ключ вместо приватного.
|
||
|
||
Для каждой операции подписания, avbroot будет вызывать программу с параметрами:
|
||
|
||
```bash
|
||
<helper> <algorithm> <public key>
|
||
```
|
||
|
||
Алгоритм (`<algorithm>`) — это один из `SHA{256,512}_RSA{2048,4096}`, а публичный ключ (`<public key>`) — это тот, что был передан в avbroot. Внешняя программа может использовать публичный ключ для поиска соответствующего приватного ключа (например, на аппаратном модуле безопасности). avbroot запишет дайджест, отформатированный по PKCS#1 v1.5, в `stdin`, а внешняя программа должна выполнить операцию сырого подписания RSA и записать сырую подпись (октетная строка, соответствующая размеру ключа) в `stdout`.
|
||
|
||
По умолчанию, это поведение совместимо с опцией `--signing_helper` в avbtool от AOSP. Однако avbroot дополнительно расширяет аргументы для поддержки неинтерактивного использования. Если используются опции `--pass-{avb,ota}-file` или `--pass-{avb,ota}-env-var`, то внешняя программа будет вызвана с двумя дополнительными аргументами, указывающими на файл пароля или переменную окружения.
|
||
|
||
```bash
|
||
<helper> <algorithm> <public key> file <pass file>
|
||
# или
|
||
<helper> <algorithm> <public key> env <env file>
|
||
```
|
||
|
||
Обратите внимание, что avbroot проверит подпись, возвращенную внешней программой, на соответствие с публичным ключом. Это гарантирует, что процесс патчинга завершится ошибкой, если был использован неправильный приватный ключ.
|
||
|
||
### Размер страницы 16 КБ в настройках для разработчиков
|
||
|
||
На современных устройствах с Android 16 и выше, в настройках для разработчиков может появиться опция переключения на ядро с размером страницы 16 КБ. Однако, эта функция не будет работать в системе, пропатченной с помощью avbroot, поскольку переключение данной настройки осуществляется путём установки инкрементальной OTA:
|
||
|
||
* `/vendor/boot_otas/boot_ota_16k.zip` — используется для переключения на ядро с размером страницы 16 КБ (в разделе `boot` уже должно быть прошито ядро с размером страницы 4K)
|
||
* `/vendor/boot_otas/boot_ota_4k.zip` — используется для переключения на ядро с размером страницы 4 КБ (в разделе `boot` уже должно быть прошито ядро с размером страницы 16K)
|
||
|
||
Эти файлы (в `boot_otas`) невозможно прошить на системе, пропатченной avbroot, потому что `payload.bin` внутри них подписан ключом производителя. Кроме того, это неполноценные OTA-файлы: у них нет метаданных, характерных для OTA, а сам zip-файл не подписан. Это просто обычный архив, который содержит подписанный `payload.bin`.
|
||
|
||
Поддержка `boot_otas` не планируется. Это потребует реализации функционала для модификации ФС в инкрементальных OTA и их дальнейшей обработки, что сделать очень непросто.
|
||
|
||
Если вы всё же хотите завести эту функцию, можно попробовать вручную подписать файлы в `boot_otas` собственным ключом. Поскольку инкрементальные OTA не пересоздаются, раздел `boot` должен оставаться без изменений во время выполнения команды `avbroot ota patch`.
|
||
|
||
1. Распакуйте `vendor.img` с помощью avbroot и [afsr](https://github.com/chenxiaolong/afsr):
|
||
```bash
|
||
avbroot avb unpack -i vendor.img
|
||
afsr unpack -i raw.img
|
||
```
|
||
|
||
2. Извлеките `payload.bin` из `boot_otas/boot_ota_16k.zip`.
|
||
|
||
3. Переподпишите `payload.bin` вашим OTA-ключом:
|
||
```bash
|
||
avbroot payload repack \
|
||
-i payload.bin.orig \
|
||
-o payload.bin \
|
||
-k ota.key \
|
||
--output-properties payload_properties.txt
|
||
```
|
||
|
||
4. Создайте новый zip, включающий `payload.bin` и `payload_properties.txt`. Файлы должны быть добавлены без сжатия (например, с помощью `zip -0`).
|
||
|
||
5. Повторите эту процедуру для `boot_otas/boot_ota_4k.zip`.
|
||
|
||
6. Соберите `vendor.img` обратно и подпишите его вашим AVB-ключом:
|
||
```bash
|
||
afsr pack -o raw.img
|
||
avbroot avb pack -o vendor.img -k avb.key --recompute-size
|
||
```
|
||
|
||
7. Пропатчите обычный OTA-архив с прошивкой, подменив `vendor` на модифицированный образ:
|
||
```bash
|
||
avbroot ota patch \
|
||
--replace vendor <модифицированный vendor.img> \
|
||
<дальше указываются аргументы, как при обычном патчинге>
|
||
```
|
||
|
||
## Сборка из исходного кода
|
||
|
||
Убедитесь, что у вас установлен [набор инструментов Rust.](https://www.rust-lang.org/ru/) Затем выполните:
|
||
|
||
```bash
|
||
cargo build --release
|
||
```
|
||
|
||
Исполняемый файл будет записан в `target/release/avbroot`.
|
||
|
||
Дебаг-сборки тоже работают, но они будут работать значительно медленнее (в вычислениях sha256), потому что оптимизации компилятора отключены.
|
||
|
||
### Кросс-компиляция на Android
|
||
|
||
Чтобы использовать кросс-компиляцию на Android, установите [cargo-android](https://github.com/chenxiaolong/cargo-android) и воспользуйтесь оболочкой `cargo android`. Чтобы создать релизную сборку для aarch64, выполните:
|
||
|
||
```bash
|
||
cargo android build --release --target aarch64-linux-android
|
||
```
|
||
|
||
Возможно выполнение тестов, если хост работает под управлением Linux, установлен qemu-user-static, а исполняемый файл собран с `RUSTFLAGS=-C target-feature=+crt-static` и `--features static`.
|
||
|
||
## Проверка цифровых подписей
|
||
|
||
Чтобы проверить цифровые подписи, [следуйте этой инструкции.](https://github.com/chenxiaolong/chenxiaolong/blob/master/VERIFY_SSH_SIGNATURES.md)
|
||
|
||
## Вклад
|
||
|
||
Буду рад вашему вкладу в разработку! Однако я вряд ли приму изменения для поддержки устройств, которые ведут себя значительно иначе, чем устройства Pixel.
|
||
|
||
## Лицензия
|
||
|
||
avbroot распространяется по лицензии GPL-3.0-only. Полный текст лицензии см. в [`LICENSE`.](./LICENSE)
|
||
|