TouYinger Q13W: как мы получили root через Magisk и заменили штатный экран на Projectivy
Перед копированием команд
Ниже полный разбор эксперимента и его ограничений. Встроенные блоки команд служат пояснениями к шагам. Не копируйте их для запуска: редактор Пикабу меняет часть пробелов и отступов. Для выполнения скачайте мои исходные TXT и копируйте команды из них.
Полный разбор с командами, backup и предупреждениями: https://t.me/the220iq/17?single
Проверка структуры boot, полный код и ограничения: https://t.me/the220iq/18?single
Особенно важны два ASCII-пробела между хешем и именем файла в строке формирования SHA256SUMS. В TXT они сохранены. Предупреждения о совместимости, собственном backup и проверенном аварийном восстановлении ниже обязательны.
Хотелось поставить нормальный домашний экран на проектор. В процессе выяснилось, что root там уже лежит с завода, но пользоваться им могут не все. Потом нашёлся второй лаунчер, который запускался поверх выбранного HOME. А в финале всё упёрлось в один невидимый символ из Windows.
Ниже наш реальный путь: заводской su → резервные копии → патч собственного boot.img в Magisk 30.7 → проверка записи → root для приложений. Отдельно покажу замену лаунчера и грабли, чтобы следующий человек собирал кинотеатр, а не коллекцию ошибок.
Фото моего Q13W: меню настроек Projectivy на проекционном экране.
Фото моего Q13W: меню Projectivy с пунктами «Настройки Projectivy» и «Настройки Android».
Фото моего Q13W: категории приложений на главном экране Projectivy.
1. Сначала границы применимости
Это журнал успешной работы на одном TouYinger Q13W, а не универсальная прошивка для всех «Туянгеров». Одинаковая надпись на корпусе не гарантирует одинаковые плату, загрузчик и разметку.
В наших текстовых логах:
- модель: Q13W;
- persist.zvt.boardname: ZJ_V660_KLS518R00;
- ro.build.display.id: tv_hi3751v660 HuanglongV100R002C01SPC004B010;
- платформа в свойствах разделов: huanglong/tv_hi3751v660/tv;
- boot/system/vendor fingerprint: huanglong/tv_hi3751v660/tv:12/SP1A.210812.016/eng_00211291647:userdebug/dev-keys;
- ro.build.description: tv_hi3751v660-userdebug 12 SP1A.210812.016 eng.eng_00.20251129.164805 dev-keys;
- boot: /dev/block/by-name/boot → /dev/block/mmcblk0p22, размер 62 914 560 байт;
- отдельные разделы ramdisk, recovery и recoverybak; слот ro.boot.slot_suffix пустой;
- Magisk после установки: 30.7:MAGISK:R;
- Projectivy в финале: 4.71, versionCode=95.
У прошивки есть странности: общий ro.build.fingerprint указывает на MStar и Android 4.4.4, а fingerprints разделов на Huanglong и Android 12. Поэтому по одной красивой строке «версия Android» совместимость не определяем. Имя платы подтверждено сохранённым диагностическим файлом проекта. Физическую маркировку и ревизию платы по фотографии мы не проверяли.
Особенно важно: до записи boot у меня уже была аварийная флешка с заводской прошивкой, и я ранее лично восстанавливал с неё этот проектор. Но точные файлы, их контрольные суммы и вся процедура восстановления в нашем журнале не сохранены. Я не стану придумывать их задним числом.
Если у вас нет подходящей именно вашему экземпляру заводской прошивки и понятного рабочего восстановления без загрузки Android, остановитесь до записи boot. Наличие backup на компьютере само по себе не означает, что его получится вернуть в не загружающийся проектор.
Все команды ниже для PowerShell в папке официальных Android SDK Platform-Tools. IP заменён переменной; префиксы PS C:\..., значки приглашения и вывод команд копировать не нужно. Команды очищены от артефактов выгрузки и адаптированы для PowerShell: адрес и имя patched вынесены в переменные, некоторые диагностические команды объединены. Дополнительные проверки и непроверенный откат отмечены отдельно.
2. Подключаемся и фиксируем исходное состояние
Platform-Tools берём у Google:
https://developer.android.com/tools/releases/platform-tools
У нас заработал сетевой ADB после включения отладки в инженерном меню. Универсальную комбинацию входа я не обещаю: ранние экраны остались во вложениях, а расположение пунктов может зависеть от прошивки. Не меняйте настройки панели и заводские параметры ради поиска ADB.
USB-A ↔ USB-A в нашем опыте подключения не дал. Обычный кабель между двумя host-портами здесь не предлагаю: назначение порта и правильная разводка должны быть подтверждены производителем.
На компьютере задаём адрес своего проектора:
$Target = "IP_ПРОЕКТОРА:5555"
.\adb connect $Target
.\adb devices -l
.\adb -s $Target shell id
Нужен именно ваш проектор со статусом device. При offline, unauthorized, другом адресе или нескольких непонятных устройствах дальше не идём.
Сетевой ADB на порту 5555 используйте только в доверенной локальной сети, без проброса в интернет. Это не защищённое pairing-подключение современных Android.
Дополнительная предосторожность перед сохранением: если в этих каталогах уже лежат образы предыдущего прохода, не запускайте backup поверх них. Сохраните исходный stock boot отдельно и используйте новые пути для нового снимка. Повторный снимок после установки Magisk уже не будет исходным boot.
Сохраняем сведения. Версию ADB, модель и fingerprints добавляю как явную проверку перед повторением:
New-Item -ItemType Directory -Force .\q13w_backup | Out-Null
.\adb version
.\adb -s $Target shell getprop ro.product.model
.\adb -s $Target shell getprop persist.zvt.boardname
.\adb -s $Target shell getprop ro.build.display.id
.\adb -s $Target shell getprop ro.build.description
.\adb -s $Target shell getprop ro.bootimage.build.fingerprint
.\adb -s $Target shell getprop ro.system.build.fingerprint
.\adb -s $Target shell getprop ro.build.version.sdk
.\adb -s $Target shell getprop > .\q13w_backup\q13w_getprop.txt
.\adb -s $Target shell pm list packages -f > .\q13w_backup\q13w_packages.txt
.\adb -s $Target shell cmd package resolve-activity --brief -a android.intent.action.MAIN -c android.intent.category.HOME
Последний ответ запишите: это исходный HOME для вашего устройства. У нас на этом этапе оказался уже установленный Monet, com.klevico.monet/.HomeActivity, а не Projectivy.
3. Root был, но с нюансом
Проверили наличие su и SELinux:
.\adb -s $Target shell "which su; ls -lZ /system/bin/su /system/xbin/su /vendor/bin/su 2>/dev/null; getenforce"
В ответе был /system/xbin/su с правами -rwsr-x---, владельцем root, группой shell и контекстом su_exec. SELinux был Permissive. Мы его таким не делали.
В ранней переписке разбирались отказ adb root и ошибка setgid при попытке заводского su сменить группу на root. Исходные ответы были на скриншотах, поэтому не привожу их как заново проверенный текстовый лог. Зато результат следующей команды сохранился непосредственно в тексте. Рабочей оказалась форма, которая оставляет группу shell:
.\adb -s $Target shell su 0,2000 id
Наш вывод, сокращённо:
uid=0(root) gid=2000(shell) euid=0(root) ... context=u:r:su:s0
Это ключ к дальнейшей работе на нашем экземпляре. Если ваша команда такого результата не даёт, нижеследующая цепочка для вас ещё не работает. Не заменяйте её на случайные способы root.
И это ещё не Magisk. Более того, диагностика показала ограниченные capabilities у заводского su: uid=0 здесь не означал «разрешено вообще всё». Поэтому часть диагностических команд получала Permission denied, хотя чтение разделов и последующая запись boot работали.
4. Резервные копии до модификации загрузки
Сначала читаем свою разметку:
.\adb -s $Target shell "su 0,2000 ls -l /dev/block/by-name"
.\adb -s $Target shell "su 0,2000 cat /proc/partitions"
.\adb -s $Target shell "su 0,2000 cat /proc/cmdline"
.\adb -s $Target shell getprop ro.boot.slot_suffix
Не подставляйте mmcblk0p22 в чужой проектор по памяти. Для команд использован проверенный на этом экземпляре путь by-name/boot. Само наличие раздела с именем fastboot не доказывает поддержку привычного fastboot flash.
Первая попытка снять backup в /sdcard провалилась: заводской root не смог писать через этот путь. Сработал /data/local/tmp. Команды в этом разделе читают разделы и пишут обычные файлы; if и of менять местами нельзя.
.\adb -s $Target shell df -h /data/local/tmp
.\adb -s $Target shell "mkdir -p /data/local/tmp/q13w_raw_critical"
.\adb -s $Target shell "su 0,2000 dd if=/dev/block/by-name/fastboot of=/data/local/tmp/q13w_raw_critical/fastboot.img bs=1048576"
.\adb -s $Target pull /data/local/tmp/q13w_raw_critical/fastboot.img .\q13w_backup\
У нас тест дал 1 048 576 байт и успешный pull. Только после этого пошёл набор критических разделов. Следующий список относится именно к нашей карте; при отсутствующем или иначе устроенном разделе не продолжайте вслепую.
$parts = @(
"fastboot","bootargs","bootargsbak",
"sbl","sblbak","batt_nv","ddrparam",
"dtbo","dtbobak","hrf","sensorhub","dmcu",
"slaveboot","slavebootbak","reserved1",
"atf","atfbak","hhee","hheebak",
"trustedcore","trustedcorebak",
"boot","ramdisk","recovery","recoverybak",
"reserved2","deviceinfo","misc","versioninfo",
"logo","bootmusic","bootmusicsec",
"panel","panelbak","demura","baseparam",
"reserved3","vbmeta_system","vbmeta_vendor",
"securestore","dfx","eng","reserved4","metadata"
)
$remote = "/data/local/tmp/q13w_raw_critical"
foreach ($p in $parts) {
Write-Host "BACKUP: $p"
.\adb -s $Target shell "su 0,2000 dd if=/dev/block/by-name/$p of=$remote/$p.img bs=1048576"
if ($LASTEXITCODE -ne 0) {
Write-Host "ERROR: $p"
break
}
}
Если цикл остановился с ERROR, сначала разбираемся с этим разделом. Успех следующих команд не исправляет неполный backup.
.\adb -s $Target shell "su 0,2000 dd if=/dev/block/mmcblk0boot0 of=/data/local/tmp/q13w_raw_critical/mmcblk0boot0.img bs=1048576"
.\adb -s $Target shell "su 0,2000 dd if=/dev/block/mmcblk0boot1 of=/data/local/tmp/q13w_raw_critical/mmcblk0boot1.img bs=1048576"
.\adb -s $Target shell "su 0,2000 sh -c 'cd /data/local/tmp/q13w_raw_critical && sha256sum *.img'" | Out-File -Encoding ascii .\q13w_backup\SHA256SUMS_device.txt
.\adb -s $Target pull /data/local/tmp/q13w_raw_critical .\q13w_backup\
Результат у нас: 46 образов, суммарно 709 885 952 байта. Это контроль нашей конфигурации, а не норматив для всех Q13W.
Проверка копий на ПК. Первые две проверки числа и общего размера файлов добавлены для повторения; далее идёт расчёт и сравнение хешей из журнала:
$dir = ".\q13w_backup\q13w_raw_critical"
(Get-ChildItem $dir -Filter *.img).Count
(Get-ChildItem $dir -Filter *.img | Measure-Object Length -Sum).Sum
Get-ChildItem $dir -Filter *.img | Sort-Object Name | ForEach-Object {
$h = (Get-FileHash $_.FullName -Algorithm SHA256).Hash.ToLower()
"$h $($_.Name)"
} | Set-Content -Encoding ascii .\q13w_backup\SHA256SUMS_pc.txt
Compare-Object (Get-Content .\q13w_backup\SHA256SUMS_device.txt | Sort-Object) (Get-Content .\q13w_backup\SHA256SUMS_pc.txt | Sort-Object)
Пустой Compare-Object имеет смысл только после проверки, что оба списка содержат ожидаемые имена всех 46 файлов и по 46 настоящих записей SHA-256, а не пустые строки или ошибки. Он подтверждает совпадение вычисленных хешей файлов на устройстве и на ПК, но не является проверкой восстановления.
Дополнительно у нас были скопированы odm, product и super. Ниже те же успешные команды, по одному образу. Перед pull и после него сравнивайте SHA-256; временные копии до проверки не удаляйте.
.\adb -s $Target shell "su 0,2000 dd if=/dev/block/by-name/odm of=/data/local/tmp/odm.img bs=1048576"
.\adb -s $Target shell "su 0,2000 sha256sum /data/local/tmp/odm.img"
.\adb -s $Target pull /data/local/tmp/odm.img .\q13w_backup\
Get-FileHash .\q13w_backup\odm.img -Algorithm SHA256
.\adb -s $Target shell "su 0,2000 dd if=/dev/block/by-name/product of=/data/local/tmp/product.img bs=1048576"
.\adb -s $Target shell "su 0,2000 sha256sum /data/local/tmp/product.img"
.\adb -s $Target pull /data/local/tmp/product.img .\q13w_backup\
Get-FileHash .\q13w_backup\product.img -Algorithm SHA256
.\adb -s $Target shell "su 0,2000 dd if=/dev/block/by-name/super of=/data/local/tmp/super.img bs=1048576"
.\adb -s $Target shell "su 0,2000 sha256sum /data/local/tmp/super.img"
.\adb -s $Target pull /data/local/tmp/super.img .\q13w_backup\
Get-FileHash .\q13w_backup\super.img -Algorithm SHA256
Размеры у нас: odm 56 623 104, product 419 430 400, super 3 816 816 640 байт. Для сохранения всех временных образов одновременно нужно свободное место с запасом, более 5 ГБ. Это дополнительное условие для приведённого здесь варианта без промежуточного удаления.
Не запускайте исходный backup повторно в ту же папку после патча: так можно затереть единственный stock boot уже модифицированным образом. Исходный набор держите отдельно, а для новых снимков создавайте другие каталоги.
Это не полный образ eMMC: userdata и cache мы не снимали. Индивидуальные разделы вроде securestore и deviceinfo нельзя выкладывать вместе с постом. Вторую копию backup стоит держать на отдельном носителе.
5. Патчим свой boot в Magisk
У нашего boot была Android-заголовочная сигнатура ANDROID!, размер 60 MiB. Перед записью изучались заголовок, ramdisk и хвост образа. Поиск AVB/verity не дал основания объявить устройство «без защиты»: часть диагностики упиралась в ограниченные права.
Мы не разблокировали загрузчик через fastboot, не прошивали чужой vbmeta и не отключали проверки готовой командой из чужой инструкции. Это важно: ниже описан уже подтверждённый на нашем экземпляре путь через доступный заводской su, а не замена общей инструкции Magisk для других устройств.
Magisk берём только у разработчика:
https://github.com/topjohnwu/Magisk/releases
Официальная инструкция и ограничения:
https://topjohnwu.github.io/Magisk/install.html
У нас использовался Magisk 30.7. Сам APK ещё не даёт root. Сначала на самом целевом проекторе патчится собственный исходный образ, не скачанный «готовый root для такой же модели».
Передали stock boot из нашего backup:
.\adb -s $Target push .\q13w_backup\q13w_raw_critical\boot.img /sdcard/Download/Q13W_stock_boot.img
.\adb -s $Target shell "sha256sum /sdcard/Download/Q13W_stock_boot.img"
Get-FileHash .\q13w_backup\q13w_raw_critical\boot.img -Algorithm SHA256
Обе суммы должны совпадать между собой. У нас исходный образ имел размер 62 914 560 байт и SHA-256:
2779dd3981266aa6bb051659fdc0733f962555c9f613f3af9286be44d7ed2fe4
Это идентификатор нашего файла, не предложение найти в интернете любой файл с похожим названием.
На проекторе в приложении Magisk: «Установка» в блоке Magisk → «Выбрать и исправить файл» → Download/Q13W_stock_boot.img. Дождались завершения патча и появления файла в Download.
Наш файл назывался magisk_patched-30700_IYiMI.img. У вас окончание будет другим; дальше переменная должна содержать точное имя вашего результата:
$PatchedName = "magisk_patched-30700_ВАШЕ_ИМЯ.img"
.\adb -s $Target shell "ls -lh /sdcard/Download/$PatchedName"
.\adb -s $Target shell "sha256sum /sdcard/Download/$PatchedName"
.\adb -s $Target pull /sdcard/Download/$PatchedName .\q13w_backup\
(Get-Item ".\q13w_backup\$PatchedName").Length
Get-FileHash ".\q13w_backup\$PatchedName" -Algorithm SHA256
У нас размер остался 62 914 560 байт, SHA-256 получился:
7dcff684c777430d69ff09be5fe6e9295fc070c82c613233f4572ee0dc6290a7
Чужой патч с нашим хешем вам не нужен. Нужны согласованные размеры и суммы собственного stock, собственного patched и копий файлов. Неожиданный размер, ошибка патча или непонятная структура образа являются причиной остановиться.
Дополнительно сравнили структуру двух файлов локальным Inspect-Boot. В сохранённом пользовательском выводе:
- ANDROID!, HeaderVersion=0, PageSize=16384 у обоих;
- KernelSize=45054464 у обоих, это совпадение размера, не доказательство идентичности ядра;
- RamdiskSize вырос с 1369094 до 1443114 байт;
- ramdisk остался gzip, а PayloadEnd сдвинулся с 46448640 до 46530560.
Полный read-only код вынесен в приложение «Q13W: проверка структуры boot». Он рассчитан на нашу структуру v0, не является универсальным валидатором и не разрешает прошивку сам по себе. Отдельное сравнение хешей ядра обсуждалось, но его исходный скриншот сейчас недоступен, поэтому независимо подтверждённое совпадение всего ядра здесь не заявляю.
6. Запись boot: здесь заканчивается безобидная диагностика
Следующая команда dd меняет загрузочный раздел. Неверный файл, путь, сборка или прерывание питания могут оставить проектор без загрузки. До неё должны быть проверены совместимость, собственный backup, аварийное восстановление, результат патча и устойчивое питание. Несовпадение любого условия означает остановку, а не попытку «всё равно попробовать».
Сначала только перенос файла и контроль:
.\adb -s $Target push ".\q13w_backup\$PatchedName" /data/local/tmp/Q13W_magisk_boot.img
.\adb -s $Target shell "sha256sum /data/local/tmp/Q13W_magisk_boot.img"
.\adb -s $Target shell "su 0,2000 sha256sum /dev/block/by-name/boot"
У нас хеш временного patched совпал с копией на ПК, а хеш ещё не изменённого раздела boot с сохранённым stock. Если у вас второе сравнение не сходится, не записывайте образ: исходное состояние уже другое.
Вот именно та запись, которая была выполнена у нас:
.\adb -s $Target shell "su 0,2000 dd if=/data/local/tmp/Q13W_magisk_boot.img of=/dev/block/by-name/boot bs=1048576"
Получено:
60+0 records in
60+0 records out
62914560 bytes (60 M) copied
После записи, ещё до перезагрузки:
.\adb -s $Target shell "su 0,2000 sync"
.\adb -s $Target shell "su 0,2000 sha256sum /dev/block/by-name/boot"
Раздел дал тот же 7dcff684…6290a7, что и наш patched. Мы сравнивали полную строку, не только начало и конец.
При ошибке dd или несовпадении хеша не делайте обычную перезагрузку «посмотреть, заведётся ли». Остановитесь и разбирайтесь с записью и своим подготовленным восстановлением. Проверенного сценария отката повреждённой записи наш журнал не содержит.
Только после успешной сверки:
.\adb -s $Target reboot
После полной загрузки:
.\adb connect $Target
.\adb -s $Target shell "su -c id"
.\adb -s $Target shell "su -c 'magisk -v'"
.\adb -s $Target shell "su -c 'sha256sum /dev/block/by-name/boot'"
Результат:
uid=0(root) gid=0(root) groups=0(root) context=u:r:magisk:s0
30.7:MAGISK:R
Хеш boot после загрузки тоже сохранился. Вот это уже работающий Magisk, а не просто установленная иконка приложения.
7. Почему root в ADB работал, а в приложении нет
Activity Launcher всё ещё отвечал:
Cannot run program "su": error=13, Permission denied
Для повторной проверки соберём использованные диагностические команды в одну:
.\adb -s $Target shell "su -c 'ls -ldZ /system/xbin; ls -lZ /system/xbin/su /system/xbin/magisk; cat /proc/mounts | grep system/xbin'"
su уже был ссылкой ./magisk, но каталог /system/xbin имел права 0750, root:shell. Обычное приложение не могло пройти через каталог к исполняемому файлу. В нашем случае /system/xbin был именно Magisk tmpfs, а не просто произвольным каталогом физического system.
Следующее исправление относится только к этой подтверждённой комбинации: Magisk работает, su ведёт на Magisk, /system/xbin является его tmpfs, права 0750 мешают приложениям. Если у вас другая картина, не меняйте права наугад и не ставьте этот скрипт «для профилактики».
Изначально этот mount был read-only. В переписке порядок был таким: сначала перемонтирование только подтверждённого Magisk tmpfs /system/xbin, затем проверка состояния, затем chmod. Сам вызов remount не повторён в пользовательской вставке, но выводы до и после показывают переход ro → rw:
.\adb -s $Target shell "su -c 'mount -o remount,rw /system/xbin'"
.\adb -s $Target shell "su -c 'cat /proc/self/mountinfo'" | Select-String -SimpleMatch "/system/xbin"
Продолжаем только если строка самого /system/xbin показывает rw и это по-прежнему tmpfs magisk. При ошибке или другой схеме остановитесь. Весь system перемонтировать не нужно. Далее:
.\adb -s $Target shell "su -c 'chmod 0755 /system/xbin'"
.\adb -s $Target shell "su -c 'ls -ldZ /system/xbin'"
Получили drwxr-xr-x. После этого в Activity Launcher появился запрос Magisk на предоставление root, и запуск заработал.
Но после reboot права вернулись к 0750. Поэтому на нашем устройстве понадобилось повторять исправление при старте через Magisk service.d.
Сначала проверили, что каталог существует. Ниже сокращённая диагностическая команда из исходной проверки:
.\adb -s $Target shell "su -c 'ls -ld /data/adb/service.d'"
Здесь создаётся постоянный загрузочный скрипт. Не перезаписывайте одноимённый существующий файл без проверки его назначения. Ниже исправленный вариант, который у нас прошёл проверку. Именно WriteAllText с явными LF, а не первая неудачная версия через Set-Content:
$content = "#!/system/bin/sh`nmount -o remount,rw /system/xbin`nchmod 0755 /system/xbin`nmount -o remount,ro /system/xbin`n"
[System.IO.File]::WriteAllText("$PWD\99-q13w-su-access.sh", $content, [System.Text.Encoding]::ASCII)
.\adb -s $Target push .\99-q13w-su-access.sh /data/local/tmp/99-q13w-su-access.sh
.\adb -s $Target shell "su -c 'cp /data/local/tmp/99-q13w-su-access.sh /data/adb/service.d/99-q13w-su-access.sh; chown root:root /data/adb/service.d/99-q13w-su-access.sh; chmod 0755 /data/adb/service.d/99-q13w-su-access.sh; od -An -tx1 /data/adb/service.d/99-q13w-su-access.sh'"
При любой ошибке push, cp, chown или chmod остановитесь. Команды установки разделены точками с запятой, поэтому успешный od в конце не доказывает успех предыдущих операций. Дополнительно сверяем содержимое, владельца root:root и права 0755:
.\adb -s $Target shell "su -c 'ls -l /data/adb/service.d/99-q13w-su-access.sh; cat /data/adb/service.d/99-q13w-su-access.sh'"
В полном дампе файла не должно быть 0d. Перевод строки LF выглядит как 0a. Проверяем весь файл: у нас ошибка пряталась после первых 64 байт.
Ручная проверка перед reboot:
.\adb -s $Target shell "su -c '/data/adb/service.d/99-q13w-su-access.sh'"
.\adb -s $Target shell "su -c 'ls -ldZ /system/xbin; cat /proc/mounts | grep system/xbin'"
Успех у нас выглядел так: каталог drwxr-xr-x, а строка mount для /system/xbin снова tmpfs ro. Скрипт открывает на запись только этот Magisk-mount, выставляет 0755 и возвращает его в read-only.
Если есть ошибка mount, неправильные права или mount остался rw, до обычной перезагрузки сначала исправьте причину. Успешный вывод chmod сам по себе ещё не подтверждает выполнение всей цепочки.
После успешной ручной проверки перезагрузили проектор и, ничего не исправляя через ADB, снова попробовали root-запуск из приложения. Он заработал. Это и было проверкой сохранения результата после загрузки.
Откат этого workaround в журнале не проверялся. Логика отката при сохранённом Magisk-доступе: убрать только этот скрипт из автозапуска, затем проверить поведение после reboot. Не удалять весь /data/adb и не считать это удалением Magisk.
8. Projectivy вместо штатного экрана
Хронологически это получилось ещё до установки Magisk. Поэтому для одной замены лаунчера проделывать весь root-квест может вообще не понадобиться.
Projectivy был заранее установлен на проектор. Программа разработчика:
https://github.com/spocky/miproja1
Релизы:
https://github.com/spocky/miproja1/releases
Точная первоначальная установка APK в доступном тексте не показана, поэтому отдельную команду adb install за «исторически проверенную» не выдаю. Перед изменением HOME установленный Projectivy нужно открыть вручную и проверить управление пультом.
У нас его HOME-компонент:
com.spocky.projengmenu/.ui.home.MainActivity
Добавим проверку пути пакета через pm path; затем проверим HOME-компонент и назначим его только после успешного ручного запуска:
.\adb -s $Target shell pm path com.spocky.projengmenu
.\adb -s $Target shell cmd package query-activities --brief -a android.intent.action.MAIN -c android.intent.category.HOME -p com.spocky.projengmenu
.\adb -s $Target shell cmd package set-home-activity --user 0 com.spocky.projengmenu/.ui.home.MainActivity
.\adb -s $Target shell cmd package resolve-activity --brief -a android.intent.action.MAIN -c android.intent.category.HOME
Ожидаем Projectivy. Нажимаем HOME на пульте. Если он не открывается, штатные пакеты пока не отключаем.
Первая попытка убрать штатный экран была через пакет TyyLauncher. Перед отключением предлагалось сохранить APK и сведения командами ниже. Отдельного текстового подтверждения их успешного выполнения в журнале нет, поэтому проверку наличия полученных файлов при повторении пропускать нельзя:
.\adb -s $Target pull /system/app/TyyLauncher/TyyLauncher.apk .\q13w_backup\
.\adb -s $Target shell dumpsys package com.chijimlee.tyylauncher > .\q13w_backup\TyyLauncher_dumpsys.txt
Только при совпадении пакета с нашей конфигурацией и рабочей замене:
.\adb -s $Target shell pm disable-user --user 0 com.chijimlee.tyylauncher
.\adb -s $Target shell pm list packages -d
Но после reboot старый экран всё равно появлялся. HOME открывал Projectivy, а автоматический старт жил отдельно.
Здесь помогло не гадание по названию APK, а проверка реально открытой Activity. Сразу после загрузки, до нажатия HOME:
.\adb -s $Target shell dumpsys activity activities | Select-String -Pattern "mResumedActivity|topResumedActivity"
.\adb -s $Target shell dumpsys window | Select-String -Pattern "mCurrentFocus|mFocusedApp"
Select-String здесь редакционная замена фильтра findstr из журнала; команды Android те же.
Виновник оказался другим:
com.zeasn.whale.saas/com.zeasn.whale.open.launcher.technical.ui.MainActivity
Важно: хотя в разговоре мы называли это «отключить активити», фактически применялась команда отключения всего пакета Whale, не одной Activity. Это может затронуть другие функции пакета.
Перед отключением Whale также предлагалось сохранить сведения. Здесь тоже нет отдельного текстового подтверждения выполненного сохранения:
.\adb -s $Target shell pm path com.zeasn.whale.saas
.\adb -s $Target shell dumpsys package com.zeasn.whale.saas > .\q13w_backup\WhaleLauncher_dumpsys.txt
И только после совпадения диагностического результата отключили именно его:
.\adb -s $Target shell pm disable-user --user 0 com.zeasn.whale.saas
.\adb -s $Target shell am force-stop com.zeasn.whale.saas
.\adb -s $Target shell pm list packages -d
Экран переключился на Projectivy сразу. После перезагрузки он открылся автоматически. Monet на этапе эксперимента оставался запасным HOME.
Для возврата доступности этих двух пакетов в истории предлагался pm enable. Ниже к нему редакционно добавлен явный --user 0. Выполнение как отдельный тест отката не зафиксировано:
.\adb -s $Target shell pm enable --user 0 com.chijimlee.tyylauncher
.\adb -s $Target shell pm enable --user 0 com.zeasn.whale.saas
enable возвращает доступность, но не обязательно первоначальное manifest-default состояние и не назначает прежний HOME. Исходный HOME возвращается отдельным set-home-activity с записанным вами компонентом, не с чужим именем из поста.
Ничего из этого не означает физическое удаление APK из системного образа. Даже встречавшееся позже pm uninstall -k --user 0 означает удаление установки для пользователя 0 с сохранением данных, а не гарантированное стирание системного APK. Массовый список «удалить всё китайское» здесь намеренно не привожу.
9. Грабли, коротко и по делу
- В разборе ранних скриншотов adb root не сработал; наличие userdebug в свойствах не гарантировало root у adbd. Заводской su оказался отдельным рабочим путём.
- Там же обсуждалось setgid failed при попытке su сменить группу на root. На нашем бинарнике сработало su 0,2000, но это не универсальный синтаксис для всех su.
- su не сделал все диагностические операции доступными. Были ошибки lpdump/dmctl и ограничения capabilities; отсутствие прочитанной информации нельзя превращать в вывод «проверок загрузки нет».
- Backup в /sdcard не записывался. Через /data/local/tmp получилось, после чего проверяли размеры и хеши.
- pm однажды был введён прямо в PowerShell. Это команда Android: ей нужен adb shell. Строки PS C:\... и Markdown-разметку также не копируем.
- Вложенные кавычки, пайпы и переменные PowerShell ломали Android-команды. Для фильтра путей надёжнее оказался Select-String -SimpleMatch, а длинные скрипты проще передавать файлом.
- set-home-activity изменил HOME, но не убрал OEM-автостарт. TyyLauncher отключили, а реально стартовал Whale. Выяснили через dumpsys.
- disabled-user не гарантировал исчезновение всех уже работающих или persistent-процессов. Ещё и опечатка tylauncher вместо tyylauncher однажды дала ложный «пустой» поиск.
- После Magisk root в ADB ещё не означал root для приложений: мешали права 0750 на /system/xbin.
- Одноразовый chmod пережил только текущую загрузку. Исправление перенесли в service.d.
- Первый скрипт имел CRLF только в последней строке. Проверка первых 64 байт ошибочно объявила файл чистым; полный od нашёл 0d 0a. После явного LF скрипт отработал правильно.
- При анализе образа переменная $input столкнулась с автоматической переменной PowerShell и дала пустой файл; помогло другое имя потока. В сtar случайно попала кириллическая буква. Эти опечатки и неудачные варианты в рабочую последовательность не включены.
- В поздней диагностике были неудачные эксперименты с thermal-командой. К root и Projectivy они отношения не имеют. Разгон, отключение термозащиты и изменение вентиляторов здесь не нужны.
10. Что в итоге действительно проверили
После перезагрузок подтвердились:
- root через Magisk и запрос прав из приложения;
- Projectivy автоматически открывается после загрузки;
- кнопка HOME возвращает Projectivy;
- автофокус работает;
- автоматическая коррекция трапеции работает;
- TorrServe запускается автоматически.
Фирменные сервисы фокуса, геометрии, пульта и входов нельзя удалять только потому, что имя пакета непонятное. Перед повторением нужен собственный контроль: настройки проектора, HOME, холодный старт, сон/пробуждение, HDMI, звук и пульт. Полная проверка всех этих режимов в доступном журнале не зафиксирована, поэтому не буду приписывать её нашему эксперименту.
После работы выключите сетевую отладку на проекторе и проверьте, что подключение больше не доступно. adb disconnect или adb kill-server выключают не слушающий сервис на проекторе, а соединение/сервер на ПК. Они не закрывают вопрос безопасности устройства.
Получился свой удобный экран и управляемый root, а не кастомная прошивка с нуля. Самой сложной частью оказался не Magisk, а необходимость каждый раз проверять, что реально произошло. В одном месте между «почти работает» и «работает после reboot» стоял ровно один невидимый CR.
Материал подготовлен с помощью ИИ по моему журналу команд и результатам эксперимента. Где нет проверенного шага или результата, это указано отдельно.
Q13W: историческая проверка структуры stock и patched boot
Это приложение к полному разбору, а не самостоятельная инструкция прошивки.
Код ниже читает локальные файлы на ПК и выводит поля заголовка и несколько участков образа. Он не подключается к проектору и не записывает его разделы. Код взят из рабочего этапа переписки; последующий пользовательский вывод подтверждает его выполнение на нашей паре образов. Здесь заново на образах он не запускался: сами файлы boot в этой выгрузке отсутствуют.
Ограничения:
- Это узкий диагностический скрипт для нашей структуры Android boot image v0, не универсальный parser/validator любых boot/init_boot/recovery.
- Перед применением подтвердите формат и версию заголовка. При другом формате, отсутствии файлов или неожиданном выводе остановитесь, а не используйте результаты для разрешения прошивки.
- Сравниваются поля размера, сигнатуры и выбранные участки, не весь kernel. Равенство KernelSize не доказывает равенство содержимого ядра.
- Хвост проверяется в нескольких местах. Нулевые показанные участки не означают, что весь хвост нулевой.
- Скрипт не устанавливает совместимость с аппаратной ревизией и не проверяет возможность восстановления.
- Замените имя magisk_patched-30700_IYiMI.img на имя собственного результата Magisk. Не используйте чужой patched image.
- Выполнять в PowerShell из папки, содержащей q13w_backup. Не копировать приглашения консоли или текст пояснений.
В нашем сохранённом пользовательском выводе:
- Length: 62914560 у обоих файлов.
- Magic: ANDROID! у обоих.
- HeaderVersion: 0 у обоих.
- PageSize: 16384 у обоих.
- KernelSize: 45054464 у обоих. Это только размер.
- RamdiskSize: 1369094 → 1443114.
- SecondSize: 0 у обоих.
- RamdiskOffset: 45072384 у обоих.
- PayloadEnd: 46448640 → 46530560.
- RamdiskMagic начинается с 1f 8b: gzip у обоих.
- TailStart64 у stock заполнен FF, у patched нулями.
- After208K64 и Last64 показаны нулевыми у обоих.
КОД:
function Align-Up([long]$Value, [long]$Alignment) {
return [long]([Math]::Ceiling($Value / [double]$Alignment) * $Alignment)
}
function Inspect-Boot([string]$Path) {
$fs = [System.IO.File]::OpenRead($Path)
try {
$hdr = New-Object byte[] 64
$null = $fs.Read($hdr, 0, 64)
$magic = [System.Text.Encoding]::ASCII.GetString($hdr,0,8)
$kernelSize = [BitConverter]::ToUInt32($hdr,8)
$ramdiskSize= [BitConverter]::ToUInt32($hdr,16)
$secondSize = [BitConverter]::ToUInt32($hdr,24)
$pageSize = [BitConverter]::ToUInt32($hdr,36)
$headerVer = [BitConverter]::ToUInt32($hdr,40)
$kernelOffset = $pageSize
$ramdiskOffset = $pageSize + (Align-Up $kernelSize $pageSize)
$secondOffset = $ramdiskOffset + (Align-Up $ramdiskSize $pageSize)
$payloadEnd = $secondOffset + (Align-Up $secondSize $pageSize)
$null = $fs.Seek($ramdiskOffset,[System.IO.SeekOrigin]::Begin)
$rmagic = New-Object byte[] 8
$null = $fs.Read($rmagic,0,8)
$null = $fs.Seek($payloadEnd,[System.IO.SeekOrigin]::Begin)
$tail1 = New-Object byte[] 64
$null = $fs.Read($tail1,0,64)
$after208 = $payloadEnd + 212992
$null = $fs.Seek($after208,[System.IO.SeekOrigin]::Begin)
$tail2 = New-Object byte[] 64
$null = $fs.Read($tail2,0,64)
$null = $fs.Seek(-64,[System.IO.SeekOrigin]::End)
$last = New-Object byte[] 64
$null = $fs.Read($last,0,64)
[PSCustomObject]@{
File = [System.IO.Path]::GetFileName($Path)
Length = $fs.Length
Magic = $magic
KernelSize = $kernelSize
RamdiskSize = $ramdiskSize
SecondSize = $secondSize
PageSize = $pageSize
HeaderVersion = $headerVer
RamdiskOffset = $ramdiskOffset
PayloadEnd = $payloadEnd
RamdiskMagic = (($rmagic | ForEach-Object { $_.ToString("x2") }) -join " ")
TailStart64 = (($tail1 | ForEach-Object { $_.ToString("x2") }) -join " ")
After208K64 = (($tail2 | ForEach-Object { $_.ToString("x2") }) -join " ")
Last64 = (($last | ForEach-Object { $_.ToString("x2") }) -join " ")
}
}
finally {
$fs.Close()
}
}
$stock = ".\q13w_backup\q13w_raw_critical\boot.img"
$patched = ".\q13w_backup\magisk_patched-30700_IYiMI.img"
Inspect-Boot $stock | Format-List
Inspect-Boot $patched | Format-List
Авторские материалы 220 IQ
Мой канал: https://t.me/the220iq
Полный разбор с точными командами, backup и предупреждениями: https://t.me/the220iq/17?single
Проверка структуры boot, полный код и ограничения: https://t.me/the220iq/18?single
Oneplus 13 нужна помощь!
Всем привет! Нужна помощь! На телефоне после обновления пропала мобильная сеть, wifi есть, имей есть, симку видит. Телефон с Китая на глобал шил не я! Загрузчик открыт, рут прав нет. Объясние пожалуйста как тупому, что делать? Магиск скачал, фикс патч v3.1 скачал.
Критическая уязвимость в Linux позволяет получить root почти на любой системе
Критическая уязвимость в Linux позволяет получить root почти на любой системе
Недавно раскрыта одна из самых простых и опасных уязвимостей в Linux за последние годы. CVE-2026-31431 позволяет любому обычному пользователю (без прав root) получить полный root-доступ практически на любой системе Linux, выпущенной с 2017 года.
- Уязвимость находится в крипто-подсистеме ядра (algif_aead + интерфейс AF_ALG + splice()).
- Для эксплуатации достаточно запустить 732-байтный Python-скрипт.
- Эксплойт работает полностью в памяти: он перезаписывает page cache setuid-бинарников (например, /usr/bin/su) и превращает их в свой код — без изменений на диске и почти без следов.
- Работает на большинстве дистрибутивов: Ubuntu, Debian, RHEL, Amazon Linux, SUSE, Fedora и других.
Баг появился в 2017 году из-за «оптимизации» (commit 72548b093ee3) и спокойно пролежал почти 9 лет.
CVSS 7.8 (High), но по факту — крайне опасен для любого сервера, где есть хотя бы одна учётная запись обычного пользователя (VPS, shared-хостинги, облака, контейнеры).
Что делать прямо сейчас:
- Обновить ядро Linux до последней версии (Патч уже включен в основные ветки ядра Linux (fix в 7.0, 6.19.12, 6.18.22 и новее)).
- Временная мера: отключить модуль algif_aead:
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
rmmod algif_aead 2>/dev/null || true
Публичный PoC уже гуляет по сети, поэтому обновляться нужно максимально быстро.
Это реально один из тех эксплойтов, от которых у админов волосы встают дыбом.
#Linux #CVE202631431 #CopyFail #Безопасность #Root #LinuxKernel
ROOTWIN_PROJECT
Ответ на пост «Почему выходцы из поколения 90х смеются над зумерами?»76
Боже, это настолько тупой наброс на вентилятор, просто ужас.
Да и, судя по всему, сгенерирован нихера не человеком.
Я, в своё время, роутеры настраивал без инструкций, методом "тут нажал и оно заработало". Смогут ли нынешние пиздюки так? Вопрос риторический.
А смогут ли нынешние молодые "типа спецы" зарутировать телефон? 😄 Полагаю, они даже не знают, что такое вообще существует.
Или карб у жиги перебрать? Понятно, что там нет ничего сложного, но это для нас, бывалых. Молодняк, даже пытаться не станет...
И ещё вот: была у меня PS2. По китайскому видно с ютуба, смог впаять в неё чип, чтобы играть в пиратки, и перепрошить, чтобы вся эта хуюмбула работала. А там, чтоб вы понимали, нихера не просто, нужно было раскинуть пины по всей плате, один даже находился на обратной стороне. Процедура называлась "чипование" (нынче звучит как-то не привычно).
А нынешним, что? Подавай видео инструкции и пальчиком покажи откуда и куда.
Так что нехуй сравнивать поколение админов и поколение юзеров. Из вас админов растить, можно заебаться, и не факт, что получится.
Root-доступ при помощи текстового редактора. Легкий способ для андроид-эмуляторов BlueStacks 4
Способ работает только для старых андроид-эмуляторов из серии BlueStacks 4!
Это все нужно, чтобы вы могли использовать такие приложения Shizuku.Carrier Vanity Name, Magisk и т.д, которые нужны для root, смены региона, запуска приложений и сервисов которые отказываются работать в вашем регионе и т.д.
Но перед этим, нужно получить root-доступ.!
Инструкция на тему - Как быстро и легко получить Root-доступ для андроид-эмуляторов BlueStacks 4.
Переходим в каталог:
C:\ProgramData\BlueStacks_nxt
Там находим файл "bluestacks.conf", и открываем его при помощи программы "Блокнот".
Вызываем меню найти, нажав на Ctrl+F.
В меню поиска вводим слово: root.
Во всех строках, где присутствует слово Root, число 0 заменяем на 1.
Затем нажимаем на "Сохранить" в меню "Файл".
Затем, в свойствах файла BlueStacks_nxt (щелкаем по файлу правой кнопкой мыши и выбираем "Свойства"), ставим галочку-атрибут, только для чтения.
Затем запускаем эмулятор BlueStacks 4, в нем запускаем приложение-утилиту "Root checker", чтобы убедиться, что root-права действительно получены.
ОЧЕНЬ ВАЖНЫЙ НЮАНС с Google-аккаунтом!
Скачивание и пользование такими "недоступными и проблемными" приложениями , сервисами играми, требует заведения нового google-аккаунта, к которому вы никогда не привязывали никакие банковские карты страны, которая попала под санкциями.
Иначе, пока вы пользуетесь таким Google-аккаунтом, даже смена региона после root не поможет вам обойти ограничения.
Причина.
Обычно когда вы вбиваете в приложение Google Pay и т.д данные банковской карты для бесконтактного расчета и интернет-платежей, данные о регионе, ФИО и т.д вносятся в Google-аккаунт.
Этот Google-аккаунт и выдает потом ваши данные сервису, приложению, игре, когда вы пытаетесь обойти их ограничению.
Как получить root-права для андроид-эмулятора BlueStacks 4. + Меняем регион для скачивания и пользования недоступными приложениями
Как получить root-права для андроид-эмулятора BlueStacks 4. + Меняем регион для скачивания и пользования недоступными приложениями
Если вы не хотите рисковать смартфоном, боясь что они превратиться в кирпич, то может получение root-прав и нужные действия, совершать на эмуляторе, который легко удалить и установить по новой, в случае если эмулятор вдруг перестанет работать.
Заодно не придется возиться с приложениями типа Shizuku.Carrier Vanity Name, Magisk и т.д.
ВНИМАНИЕ!
С эмулятором BlueStacks 4 (c версией Андроида Nougat 64 bit) работает только BlueStacksTweaker5.
Если у вас другая версия эмулятором BlueStacks, например 5-я, то нужна программа BlueStacksTweaker6.
Как получить Root-права для Эмулятора BlueStacks 4.
Скачиваем и запускаем программу BlueStacksTweaker5.
Открываем вкладку Root.
Сначала нажимаем кнопку Unclock(не запуская эмулятор).
Затем запускаем сам эмулятор BlueStacks 4(c версией Андроида Nougat 64 bit).
Снова переключаемся на программу BlueStacksTweaker5, и в той же вкладке ROOT, нажимаем кнопку PATCH.
Затем переключаемся на эмулятор BlueStacks 4.
И в нем устанавливаем и запускаем программу-утилиту "Root Checker"
Нажимаем на кнопку "Проверить статус ROOT"
Если все прошло успешно, то зеленым цветом отобразиться сообщение о том что устройство имеет root-права.
Если все прошло успешно, то зеленым цветом отобразиться сообщение о том что устройство имеет root-права.
Если что-то не получилось, и красными буквами вышло сообщение что у устройства root-прав, то тогда перейдите в BlueStacksTweaker5.
И на вкладке ROOT, нажмите "Unpatch", а затем снова снова нажмите "patch".
Далее зайдите в эмулятор BlueStacks 4, и снова при помощи приложения "Root Checker", проверьте наличие root-прав.
Если не получилось, то делайте вышеуказанное несколько раз, как получилось в моем случае.
Можно перезапускать эмулятор в процессе попыток.
КАК СМЕНИТЬ РЕГИОН НА АНДРОИД-ЭМУЛЯТОРЕ BlueStacks 4.
Запустите программу BlueStacksTweaker5, и откройте вкладку настройки.
Найдите заголовок "Устройство", и нажмите на кнопку "ПРИМЕНИТЬ", которая рядом.
Теперь ваш эмулятор отправляет играм и программам ненастоящие данные.
Но и не забывайте менять ip-адрес при помощи VPN-приложений и сервисов.
Это нужно, чтобы полностью обмануть игры и программы, которые отказываются работать на вашем смартфоне из-за того что вы находить в регионе, который попал под ограничения и запрет в плане пользования и скачивания приложений.
Так-же есть нюанс, который уже рассматривался в статье:
Внесение банковской карты в смартфон через Google Pay, не дает скачивать приложение и игры, недоступные для региона в Google Play
Внесение банковской карты в смартфон через Google Pay, не дает скачивать приложение и игры, недоступные для региона в Google Play
Так-же скачивание и пользование такими приложениями и играми требует заведения нового google-аккаунта, к которому вы никогда не привязывали никакие банковские карты страны, которая попала под санкциями.
Обычно когда вы вбиваете в приложение Google Psy и т.д данные банковской карты для бесконтактного расчета и интернет-платежей, данные о регионе, фио и т.д вносятся в Google -аккаунт.
И пока вы пользуетесь таким Google-аккаунтом, остальные хитрости часто не будут работать из-за того что такой Google-аккаунт будет выдавать вас
Как обойти региональные ограничения в Гугл Плей без VPN на скачивание игр и приложений. Дрессируем Google Play через баг рекомендаций)
Как обойти региональные ограничения в Гугл Плей без VPN на скачивание игр и приложений. Дрессируем Google Play через баг рекомендаций)
Баг в Google Play предлагает скачать, и даже обновить, недоступные приложения для региона: Баг в Google Play предлагает скачать, и даже обновить, недоступные приложения для региона, без помощи VPN и прочих фокусов














