Skip to content

Latest commit

 

History

History
512 lines (312 loc) · 41.7 KB

README.ru.md

File metadata and controls

512 lines (312 loc) · 41.7 KB

avbroot

avbroot – это программа для модификации OTA-образов Android A/B-формата с целью получения root-прав при сохранении прохождения AVB (Android Verified Boot) с использованием кастомных (пользовательских) ключей подписи. Она совместима как с Magisk, так и с KernelSU. При необходимости можно просто переподписать OTA, без получения root-доступа.

Прежде чем использовать avbroot, рекомендуется иметь хорошее понимание того, как работают AVB и OTA в формате A/B. Как минимум, следует ознакомиться с разделом предостережений, чтобы избежать хардбрика устройства.

ПРИМЕЧАНИЕ: avbroot 2.0 была переписана на Rust и больше не имеет в основе никакого кода AOSP, а CLI полностью обратно совместим. Тем не менее, старую реализацию на Python можно найти в одноименной ветке python.

Требования

  • Поддерживаются только устройства, использующие современную 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.

Патчи

avbroot модифицирует следующие образы:

  • boot или init_boot, в зависимости от устройства, модифицируется для получения root-доступа. В случае с Magisk, патч будет эквивалентен тому, что производится в самом приложении Magisk.

  • 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, и четко разъясните, какие конкретные действия привели к возникновению такой ситуации. Если Android всё еще работает и доступ к root-правам сохранился – вероятно, получится откатить изменения до исходного состояния, не стирая ваши данные.

Использование

  1. Убедитесь, что вы ознакомились и поняли указанные выше предостережения.

  2. Скачайте последнюю версию со страницы релизов. Чтобы сверить цифровую подпись, см. раздел проверки цифровых подписей.

    avbroot – это отдельный исполняемый файл. Он не требует установки и может быть запущен из любого места на диске.

  3. Сгенерируйте ключи подписи.

  4. Пропатчите ОТА-архив с помощью команды:

    avbroot ota patch \
        --input /путь/к/ota.zip \
        --key-avb /путь/к/avb.key \
        --key-ota /путь/к/ota.key \
        --cert-ota /путь/к/ota.crt \

    Добавьте следующие аргументы в конец команды в зависимости от того, как вы хотите получить root-доступ.

    • Для получения root-доступа с использованием Magisk:

      --magisk /путь/к/magisk.apk \
      --magisk-preinit-device <имя>

      Если вы не знаете имени раздела предварительной инициализации Magisk, следуйте инструкции в соответствующем разделе.

      Если вы пропатчили загрузочный образ вручную через приложение Magisk (вместо автоматического идентичного патчинга через avbroot), используйте следующий аргумент:

      --prepatched /путь/к/magisk_patched-xxxxx_yyyyy.img
    • Для получения root-доступа с использованием KernelSU:

      --prepatched /путь/к/kernelsu_boot.img
    • Без root-доступа:

      --rootless

    Больше информации про существующие аргументы можно найти в разделе расширенного использования.

    Если название для --output не указывается, то готовый файл будет записан как <название-ota-zip-в-input>.patched.

  5. Готово! Для прошивки пропатченного OTA следуйте инструкции в разделе первоначальной настройки. Для последующих обновлений тоже есть соответствующий раздел обновлений.

Генерация ключей

Во время патчинга OTA, avbroot подписывает несколько компонентов:

  • загрузочный образ (boot)
  • образ vbmeta
  • payload из OTA
  • сам архив OTA

Первые два компонента подписываются ключом AVB, а последние два – ключом OTA. Можно использовать один и тот же ключ, однако в следующих шагах описано, как сгенерировать два отдельных.

Если вы патчите OTA сразу для нескольких устройств, настоятельно рекомендуется генерировать уникальные ключи для каждого девайса – так вы защитите себя от случайной прошивки неподходящего OTA для другого телефона.

  1. Сгенерируйте ключи подписи для AVB и OTA.

    avbroot key generate-key -o avb.key
    avbroot key generate-key -o ota.key
  2. Преобразуйте публичную часть ключа подписи AVB в формат метаданных публичного ключа AVB. Именно этот формат используется в загрузчике устройства для установки пользовательского ключа.

    avbroot key extract-avb -k avb.key -o avb_pkmd.bin
  3. Сгенерируйте самоподписанный сертификат для ключа подписи OTA. Он используется режимом Recovery для проверки подписи OTA при сайдлоадинге обновления.

    avbroot key generate-cert -k ota.key -o ota.crt

avbroot совместим с любым стандартным 4096-битным приватным ключом RSA в кодировке PKCS#8 и сертификатом X509 в кодировке PEM, например с теми, которые генерируются openssl.

Если вы потеряете ключ(-и) подписи AVB или OTA, вы больше не сможете подписывать новые OTA-архивы. Придется генерировать новые ключи подписи и разблокировать загрузчик (что приведет к стиранию всех данных). В таком случае возвращайтесь к инструкции в разделе использования.

Первоначальная настройка

  1. Убедитесь, что вы используете утилиту fastboot версии 34 или новее. Предыдущие версии содержат баги, что не позволяют команде fastboot flashall (которая понадобится по ходу инструкции) работать правильно.

    fastboot --version
  2. Перезагрузитесь в режим fastboot и разблокируйте загрузчик, если не сделали этого ранее. Это приведет к стиранию всех пользовательских данных.

    fastboot flashing unlock
  3. Перед первой установкой, на устройстве уже должна быть установлена в оригинальном виде та прошивка, пропатченную версию которой вы собираетесь ставить. Если это не так, сначала установите оригинальную непропатченную OTA.

  4. Извлекаем из пропатченного OTA модифицированные образы:

    avbroot ota extract \
        --input /путь/к/ota.zip.patched \
        --directory extracted \
        --fastboot

    Если вы на всякий случай хотите прошить вообще все разделы из ОТА, извлечь их можно, указав аргумент --all.

  5. Установите переменную окружения ANDROID_PRODUCT_OUT, указав директорию с извлеченными файлами.

    Для sh/bash/zsh (Linux, macOS, WSL):

    export ANDROID_PRODUCT_OUT=extracted

    Для PowerShell (Windows):

    $env:ANDROID_PRODUCT_OUT = "extracted"

    Для cmd (Командная строка или Терминал) (Windows):

    set ANDROID_PRODUCT_OUT=extracted
  6. Прошейте извлеченные образы разделов.

    fastboot flashall --skip-reboot

    Обратите внимание, что так прошиваются лишь те образы, что относятся к системе. Разделы загрузчика и модема же остаются нетронутыми из-за ограничений fastboot. Если они не обновлены до необходимой версии, или вы не уверены в этом, после прошивки перейдите к пункту обновлений и установите пропатченный OTA-архив сайдлоадом в режиме Recovery. Прошивка полного OTA гарантирует, что абсолютно все разделы будут обновлены.

    Для устройств Pixel есть ещё один вариант: запуск скрипта flash-base.sh из папки заводских образов (factory images) обновит загрузчик и модем.

  7. После перезагрузки из fastbootd в загрузчик (bootloader), установите пользовательский публичный ключ AVB в загрузчик:

    fastboot reboot-bootloader
    fastboot erase avb_custom_key
    fastboot flash avb_custom_key /путь/к/avb_pkmd.bin
  8. [Опционально] Перед блокировкой загрузчика загрузитесь в систему, дабы убедиться, что все подписано правильно.

    Установите приложение Magisk или KernelSU и выполните следующую команду:

    adb shell su -c 'dmesg | grep libfs_avb'

    Если AVB работает корректно, будет выведено следующее сообщение:

    init: [libfs_avb]Returning avb_handle with status: Success
  9. Перезагрузитесь в fastboot и заблокируйте загрузчик. Это снова приведет к стиранию данных.

    fastboot flashing lock

    Подтвердите нажатием клавиш уменьшения громкости и включения, а после перезагрузитесь в систему.

    Напоминаю: не отключайте Заводскую разблокировку!

    ПРЕДУПРЕЖДЕНИЕ: Если вы прошили CalyxOS, мастер настройки автоматически отключит опцию Заводской разблокировки. Не забудьте снова включить её вручную в настройках для разработчиков. Для перестраховки можете использовать модуль OEMUnlockOnBoot, который автоматически включает пункт Заводской разблокировки при каждом запуске системы.

  10. Готово! Установка последующих обновлений системы, Magisk или KernelSU, описывается в следующем разделе.

Обновления

Обновления Android, Magisk и KernelSU выполняются одинаково – исключительно путем обновления или репатчинга того же самого OTA.

  1. Если Magisk или KernelSU обновились, сначала установите их новый .apk. Если вы случайно открыли приложение после обновления, убедитесь, что оно не начало прошивать загрузочный образ. Если появится предложение обновить сам загрузочный образ – отклоните его.

  2. Следуйте инструкции в разделе использования, чтобы пропатчить OTA уже с новым .apk Magisk'а/предварительно пропатченным образом с Magisk или KernelSU.

  3. Перезагрузитесь в режим Recovery. Если устройство повисло на сплеше с сообщением "No command", удерживайте кнопку питания, а затем нажмите кнопку увеличения громкости один раз.

  4. Обновитесь (Apply update from adb → adb sideload <ota.zip.patched>).

  5. Готово!

Возврат на заводскую прошивку

Если вы хотите отказаться от использования avbroot и вернуться на стоковую прошивку:

  1. Перезагрузитесь в режим fastboot и разблокируйте загрузчик. Это приведет к стиранию всех пользовательских данных.

  2. Удалите пользовательский публичный ключ AVB.

    fastboot erase avb_custom_key
  3. Прошейте стоковую прошивку. Готово.

OTA-обновления

avbroot заменяет /system/etc/security/otacerts.zip в разделах системы и Recovery на новый архив, содержащий пользовательский сертификат подписи OTA. Это предотвращает случайную установку непропатченных OTA как при загрузке в Android, так и при сайдлоадинге через Recovery.

Рекомендуется отключить приложение обновлений системы, чтобы оно не пыталось установить непропатченные OTA:

  • Стоковая прошивка: Отключите Автоматические обновления системы (Automatic system updates в англ.) в настройках для разработчиков.
  • Кастомная прошивка: Отключите приложение обновлений системы (или запретите ему доступ к Интернету) через Настройки -> Приложения -> Все приложения -> (меню/три точки) -> Показать системные -> (найдите приложение обновлений, например Обновления системы/Updater).

Это особенно важно для некоторых кастомных прошивок, поскольку их фирменное приложение для обновления системы может уйти в бесконечный цикл, загружая OTA-обновление, а затем повторяя попытку загрузки и установки при неудачной проверке подписи.

Если вы хотите поднять собственный сервер для ОТА-обновлений, вам может быть интересно приложение 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:

    avbroot ota extract \
        --input /path/to/ota.zip \
        --directory . \
        --boot-only
  2. Теперь нужно пропатчить загрузочный образ с помощью приложения Magisk. Это ДОЛЖНО быть сделано именно на целевом устройстве или устройстве той же модели! Имя раздела будет неверным и не подойдет, если пропатчить образ на устройстве иной модели.

    Приложение Magisk выведет в лог строку, подобную следующей:

    - Pre-init storage partition device ID: <имя>

    Также и avbroot может вывести информацию о разделе, обнаруженном Magisk, для этого выполните команду:

    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, выполните команду:

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:

eval "$(avbroot completion -s bash)"

zsh

Добавьте в ~/.zshrc:

eval "$(avbroot completion -s zsh)"

fish

Добавьте в ~/.config/fish/config.fish:

avbroot completion -s fish | source

PowerShell

Добавьте в загрузочный скрипт PowerShell (profile.ps1):

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.

Подмена разделов

avbroot поддерживает подмену целых образов в OTA, даже тех, что не являются загрузочными (например, vendor_dlkm). Образ можно заменить, указав аргумент --replace <имя раздела> /путь/к/образу.img.

Единственное, что меняется – это то, откуда считывается раздел. При использовании --replace вместо использования образа раздела из оригинального payload.bin в OTA, он берется напрямую по указанному вами пути. Таким образом, заменяющие образы разделов должны иметь правильные колонтитулы vbmeta, соответствующие оригинальным.

Это не влияет на ход применения пачтей. Например, при использовании Magisk, патч получения root-прав применяется к загрузочному образу одинаково, независимо от того, был ли он получен из оригинального payload.bin или это файл, указанный через --replace.

Очистка флагов vbmeta

Некоторые сборки Android-прошивок могут поставляться с образом vbmeta, в котором флаги установлены таким образом, что AVB фактически отключен. Если avbroot сталкивается с такими образом, процесс патчинга завершается ошибкой с сообщением следующего типа:

Verified boot is disabled by vbmeta's header flags: 0x3

Чтобы принудительно включить AVB (очистив флаги), укажите аргумент --clear-vbmeta-flags.

Использование в неинтерактивном режиме

По умолчанию avbroot интерактивно запрашивает пароли к приватным ключам. Чтобы запустить avbroot в неинтерактивном режиме, можно:

  • Предоставить пароли через файлы:

    avbroot ota patch \
        --pass-avb-file /путь/к/avb.passphrase \
        --pass-ota-file /путь/к/ota.passphrase \
        <...>

    На Unix-подобных системах "файлы" могут быть каналами ("pipes"). В оболочках, поддерживающих подстановку процесса (bash, zsh и т. д.), пароль можно запросить с помощью команды (например, запрашивая у менеджера паролей).

    avbroot ota patch \
        --pass-avb-file <(команда для запроса пароля AVB) \
        --pass-ota-file <(команда для запроса пароля OTA) \
        <...>
  • Предоставить пароли через переменные среды. Это менее безопасно, поскольку любой процесс, запущенный от имени того же пользователя, может видеть значения переменных среды.

    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, используйте команду:

avbroot ota extract \
    --input /путь/к/ota.zip \
    --directory extracted \
    --all

Режим записи 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 будет вызывать программу с параметрами:

<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, то внешняя программа будет вызвана с двумя дополнительными аргументами, указывающими на файл пароля или переменную окружения.

<helper> <algorithm> <public key> file <pass file>
# или
<helper> <algorithm> <public key> env <env file>

Обратите внимание, что avbroot проверит подпись, возвращенную внешней программой, на соответствие с публичным ключом. Это гарантирует, что процесс патчинга завершится ошибкой, если был использован неправильный приватный ключ.

Сборка из исходного кода

Убедитесь, что у вас установлен набор инструментов Rust. Затем выполните:

cargo build --release

Исполняемый файл будет записан в target/release/avbroot.

Дебаг-сборки тоже работают, но они будут работать значительно медленнее (в вычислениях sha256), потому что оптимизации компилятора отключены.

По умолчанию исполняемый файл ссылается на системные библиотеки bzip2 и liblzma, от которых зависит avbroot. Чтобы скомпилировать и статически связать эти две библиотеки, укажите аргумент --features static.

Кросс-компиляция на Android

Чтобы использовать кросс-компиляцию на Android, установите cargo-android и воспользуйтесь оболочкой cargo android. Чтобы создать релизную сборку для aarch64, выполните:

cargo android build --release --target aarch64-linux-android

Возможно выполнение тестов, если хост работает под управлением Linux, установлен qemu-user-static, а исполняемый файл собран с RUSTFLAGS=-C target-feature=+crt-static и --features static.

Проверка цифровых подписей

Чтобы проверить цифровые подписи, следуйте этой инструкции.

Вклад

Буду рад вашему вкладу в разработку! Однако я вряд ли приму изменения для поддержки устройств, которые ведут себя значительно иначе, чем устройства Pixel.

Лицензия

avbroot распространяется по лицензии GPLv3. Полный текст лицензии см. в LICENSE.