China-Handy – Teil 3
Posted on So 14 Februar 2021 in Computer & Electronics
Wie ihr im letzen Post lesen konntet, hatte ich es erfolgreich geschafft, mein neues Xiaomi Redmi Note 9 Pro zu bricken. Inzwischen hat es einen kleinen touristischen Ausflug nach Flensburg hinter sich (zu Ingram Micro, die in Deutschland die Reparaturen für Xiaomi machen). Nun geht es wieder, allerdings natürlich mit der Stock-Firmware, die neu geflasht wurde. Also habe ich alle Schritte aus dem letzten Post erneut absolviert (also bis auf Bootloader Sperren natürlich) und habe nun ein laufendes Xiaomi.eu System.
Im Großen und Ganzen gefällt mir das OS ganz gut, aber es enthält noch immer einige Dinge, die ich nicht haben will. Z.B. diese komische App-Vault App, die sich auf dem -1 Screen eingenistet hat und mich mit vielen chinesischen Schriftzeichen begrüßt. Und natürlich sind auch alle Standard Apps, wie Kontakte, Phone, Kalender, File-Browser etc. in der MI-Version installiert und jede davon begrüßt mich beim ersten Öffnen mit den Datenschutzbedingungen, in die ich erstmal einwilligen soll. Das finde ich natürlich suboptimal. Am liebsten wäre mir eigentlich ein völlig unverändertes Android-System, ohne "Verbesserungen" vom Hersteller. Entsprechende Projekte gibt es natürlich, aber die haben aktuell noch keine als stable oder official gekennzeichneten ROMs für mein Modell released. Also vorerst Xiaomi.eu.
Entschlackungskur
Nun ist es nicht so, dass man da nichts unternehmen könnte, um das System ein wenig zu fine-tunen. Mit anderen Worten: heute wollen wir mal Apps löschen.
Nun ist es so, dass sich gerade die mitgelieferten System-Apps nicht einfach so
deinstallieren lassen. Manche kann man zumindest deaktivieren, viele aber auch
nicht. Aber dagegen ist ein Kraut gewachsen und das heißt adb
. Auch
störrische Apps lassen sich per USB-Debugging deaktivieren oder deinstallieren
und entgegen der landläufigen Meinung muss das Telefon dazu nicht gerootet
werden. Und das geht so:
- Sicherstellen, dass USB debugging und install via USB aktiviert sind (siehe letzter Post).
- Telefon via USB mit dem Computer verbinden
- Ggf. am Telefon den USB-Debugging-Zugriff bestätigen
Nun können wir uns auf dem Telefon einen shell-Zugang holen.
adb shell
Und schon befinden wir uns in einer LINUX-Shell in der wir arbeiten können.
Der Paket-Manger von Android hat den schönen Namen pm
. Und mit dem können wir
uns alle installierten Apps anzeigen lassen
joyeuse:/ $ pm list packages
package:com.android.cts.priv.ctsshim
package:com.qualcomm.qti.qms.service.telemetry
package:com.qualcomm.qti.qcolor
package:com.android.internal.display.cutout.emulation.corner
package:com.google.android.ext.services
[...]
package:com.termux
[...]
... Apps deaktivieren
pm disable-user com.termux
... wieder aktivieren
pm enable com.termux
... oder deinstallieren.
# uninstall and wipe data
pm uninstall --user 0 com.termux
# uninstall but keep data
pm uninstall -k --user 0 com.termux
Das --user 0
spezifiziert, dass die Deinstallation für User 0 ausgeführt
werden soll. Das ist der Hauptbenutzer des Handies.
Und schon sind wir mitten im Android Paket-Namens-Chaos. Für jede App gibt es nämlich drei verschiedene Namen/Bezeichnungen, die hier eine Rolle spielen:
- Anzeigename – also der Name unter dem die App unter
Settings > Apps
aufgeführt wird. Dieser Name steht gewöhnlich auch unter dem Icon. z.B. "Kalender" - Package Name – also das womit das
pm
Kommando arbeitet. z.B.com.google.android.calendar
- APK-Dateiname – also der Name der Installationsdatei.
Und wie kriege ich nun raus, welche dieser, teils kryptisch benannten, Pakete ich loswerden will? Dazu gibt es mehre Hilfsmittel. Nehmen wir mal an, wir wollen die Xiaomi Fitness-App Mi fit loswerden und haben keine Ahnung, wie das dazugehörige Package heißt.
Diese App gibt's im Google Play Store und der einfachste Weg führt über diesen. Geht mit dem Browser Eures Vertrauens nach https://play.google.com, sucht dort nach der App und geht auf die gefundene App-Seite:
Wie Ihr seht, steht der gesuchte Package-Name in der URL: com.xiaomi.hm.health
.
Aber was, wenn eine App nicht aus dem Play Store kommt, sondern mit dem System
kam? In dem Fall könnt Ihr die Paketliste von pm
durchsuchen. Versuchen wir
mal die Kalender-App zu finden:
joyeuse:/ $ pm list packages -f calendar
package:/system/priv-app/CalendarProvider/CalendarProvider.apk=com.android.providers.calendar
package:/data/app/com.google.android.calendar-YG-s2KnUClyb-YTvQBqlPg==/base.apk=com.google.android.calendar
package:/product/app/GoogleCalendarSyncAdapter/GoogleCalendarSyncAdapter.apk=com.google.android.syncadapters.calendar
oder
joyeuse:/ $ pm list packages | grep calendar
package:com.android.providers.calendar
package:com.google.android.calendar
package:com.google.android.syncadapters.calendar
Hochmut
Auf diese Weise habe ich nun diverse Pakete identifiziert, die mir äußerst
überflüssig vorkamen und ich habe angefangen, das eine oder andere zu löschen.
Bei manchen Pakten war unklar, ob man die braucht, oder ob sie weg können und
da hilft Google. Natürlich stößt man dabei unweigerlich auf die zahlreichen
Xiaomi/Samsung/LG/... bloatware list-Seiten bei github, XDA-Developers und
diverse Foren. Und dann wird man mutiger und fordert das Schicksal erneut
heraus. Kurz – ich habe die Namen aller Pakete die mich überflüssig dünkten in
ein Text-File kopiert (crap.txt
) und dann alles schön automatisiert gelöscht.
Nimm das, Du chinesisches Spionagewerkzeug!
xargs -L 1 adb shell pm uninstall --user 0 < crap.txt
Oder für Freunde der for-Schleife:
for i in `cat crap.txt` ; do adb shell pm uninstall --user 0 $i; done
Das funktioniert super! Und es ist sehr bequem – einfach alles rein kopieren,
das man selber identifiziert hat, noch ein paar aus den obigen Listen dazu und
man kann sogar Zeilen auskommentieren (wie gewohnt, ein #
davor), dann
scheitert die entsprechende Deinstallation, weil aus Sicht des pm
Befehls ja
kein Package angegeben wurde.
Sehr gut! (...lautes Siegesgebrüll...)
... kommt vor dem Fall.
Das fühlte sich richtig super an! Also jedenfalls bis das Handy anfing, sich
komisch zu verhalten. Irgendwie ist der System-Launcher permanent abgeschmiert
und offenbar hatte ich auch die Telefon-App gelöscht, denn sie war
unauffindbar. Aber wer will schon telefonieren? Das mit dem Launcher konnte
ich retten, indem ich schnell den Nova-launcher installiert haben, den ich eh
schöner finde. Zwar kam ich nicht mehr an die App-Icons auf den normalen Screens
ran, aber ich habe ein APK zum Download gefunden, dass ich dann via ADB und
pm
installieren konnte. In's Setup kam ich noch und konnte so den default
Launcher wählen.
Offenbar waren nicht alle Apps, die ich gelöscht hatte so überflüssig, wie ich dachte. Grumpf!
Apps wieder installieren
Das mit der Phone App war leicht zu lösen – die gibt's im Playstore, wie Sand
am Meer. Desgleichen, habe ich die Google Variante von Kalender, Kontakte etc.
installiert und so insgesamt gefällt mir das nun alles schon ganz gut.
Allerdings sind auch ein paar andere Kleinigkeiten auf der Strecke geblieben. Z.B.
kann ich aktuell keine Klingeltöne mehr einstellen, weil das dann abstürzt.
Offenbar hab ich da eine wichtige Komponente gelöscht (com.android.thememanager
).
Das Problem dabei ist, dass es sich dabei zum Teil um System-Apps handelt, die man nicht einfach aus dem Play Store holen kann. Nun könnte ich natürlich das ROM einfach neu flashen und alles wäre wieder da, aber das habe ich im Laufe der letzten Blog-Post nun so oft gemacht, dass es mir inzwischen echt auf den Zeiger geht, danach jedes mal wieder alles neu einzurichten. Und überhaupt – das muss doch auch komplizierter gehen!?!
Aber woher nehmen, wenn nicht stehlen? Eine Möglichkeit besteht darin, mal den
Paketnamen in die Suchmaschine Meines Vertrauens einzugeben und zu schauen, ob
man das apk nicht zufällig auf APKmirror, oder
anderswo finden kann. Dazu ist es hilfreich, diesen Paketnamen auch zu kennen und so
war ich froh, meine crap.txt
Liste zu haben.
Aber es geht meist noch simpler: Der uninstall Befehl hatte zwar das jeweilige Paket deinstalliert, aber nicht das apk-File gelöscht. Und das können wir nun erneut installieren. Z.B. für die Wallpaper-Verwaltung:
cmd package install-existing com.miui.miwallpaper
Das ist doch schön. Funktioniert aber nicht immer, denn einige APK-Files mussten scheinbar doch dran glauben:
joyeuse:/ $ cmd package install-existing com.miui.miwallpaper.earth
android.content.pm.PackageManager$NameNotFoundException: Package com.miui.miwallpaper.earth doesn't exist
Bei einem Bild der Erde ist das zu verschmerzen, aber in anderen Fällen mag es problematischer sein.
Die App im Heuhaufen
Aber Moment mal – die fehlenden Pakete waren auf dem ROM drauf, das ich installiert habe. Das muss man doch irgendwie auspacken können! Also mal genauer ansehen. Mein ROM (xiaomi.eu_multi_HMNote9ProEU_V12.0.1.0.QJZMIXM_v12-10.zip) ist ein Zipfile – auspacken:
❯ unzip xiaomi.eu_multi_HMNote9ProEU_V12.0.1.0.QJZMIXM_v12-10.zip
❯ ll
-rw------- 1 phil phil 15458304 2008-02-29 02:33 boot.img
-rw------- 1 phil phil 185524870 2008-02-29 02:33 cust.new.dat.br
-rw------- 1 phil phil 0 2008-02-29 02:33 cust.patch.dat
-rw------- 1 phil phil 2118 2008-02-29 02:33 cust.transfer.list
-rw------- 1 phil phil 684 2008-02-29 02:33 dynamic_partitions_op_list
drwx------ 2 phil phil 4096 2008-02-29 02:33 firmware-update
drwx------ 3 phil phil 4096 2008-02-29 02:33 META-INF
-rw------- 1 phil phil 378467683 2008-02-29 02:33 product.new.dat.br
-rw------- 1 phil phil 0 2008-02-29 02:33 product.patch.dat
-rw------- 1 phil phil 8595 2008-02-29 02:33 product.transfer.list
-rw------- 1 phil phil 1291611334 2008-02-29 02:33 system.new.dat.br
-rw------- 1 phil phil 0 2008-02-29 02:33 system.patch.dat
-rw------- 1 phil phil 22475 2008-02-29 02:33 system.transfer.list
-rw------- 1 phil phil 503193350 2008-02-29 02:33 vendor.new.dat.br
-rw------- 1 phil phil 0 2008-02-29 02:33 vendor.patch.dat
-rw------- 1 phil phil 11370 2008-02-29 02:33 vendor.transfer.list
Keine Ahnung, warum die alle ein Datum in 2008 haben. Aber egal. Dieses system.new.dat.br
File dürfte das Filesystem enthalten, dass wir brauchen. Nur was für ein Format ist das?
❯ file system.new.dat.br
system.new.dat.br: data
Hm. Wenig hilfreich. Eine Google-Suche später bin ich schlauer. Offenbar ist das ein eigenes Kompressionsformat mit dem selten dämlichen Namen brotli, das hier definiert wird: https://www.ietf.org/rfc/rfc7932.txt
Und es gibt ein Tool zum Ein- und Auspacken. Her damit und ausgepackt:
apt install brotli
brotli -d system.new.dat.br
Und schon haben wir ein File system.new.dat
. Mal beschnuppern:
❯ file system.new.dat
system.new.dat: data
Na toll – und was ist das nun wieder? Auch da hilft eine kurze Recherche
weiter. Wir haben ein sogenanntes sparse Android data image vor uns, das nun
in ein richtiges Filesystem-Image verwandelt werden muss. Das tool dazu heißt
sdat2img.py
und ist auf github zu
bekommen.
sdat2img.py system.transfer.list system.new.dat
Nun sprudelt eine gefühlte Million Meldungen in diesem Stil an uns vorbei:
Copying 143 blocks into position 295569...
Copying 512 blocks into position 298784...
Copying 512 blocks into position 294034...
Copying 512 blocks into position 8334...
Copying 512 blocks into position 293522...
Copying 512 blocks into position 473823...
Copying 512 blocks into position 21134...
Copying 512 blocks into position 293010...
Copying 512 blocks into position 292498...
Copying 512 blocks into position 552645...
Copying 512 blocks into position 108445...
Copying 512 blocks into position 108957...
Copying 512 blocks into position 380166...
Copying 512 blocks into position 102301...
Und am Ende haben wir eine Datei namens system.img
, die nun endlich was handfestes ist:
❯ file system.img
system.img: Linux rev 1.0 ext2 filesystem data, UUID=4729639d-b5f2-5cc1-a120-9ac5f788683c (extents) (large files) (huge files)
Die können wir nun mounten:
❯ sudo mount system.img /mnt
mount: /mnt: wrong fs type, bad option, bad superblock on /dev/loop14, missing codepage or helper program, or other error.
... oder auch nicht. Was zum Geier ist jetzt schon wieder los???
❯ sudo dmesg
[...]
[29155.324896] EXT4-fs (loop14): couldn't mount RDWR because of unsupported optional features (4000)
[...]
Also wieder Google. Irgendein Problem mit nicht unterstützten Optionen, die mir relativ egal waren, als ich den entscheidenden Tip fand das read only zu mounten:
sudo mount -o ro system.img /mnt
Und siehe da – wir haben ein schönes gemountetes Filesystem. Also auf zur apk-Suche:
❯ find ./ -name *.apk
./system/priv-app/CallLogBackup/CallLogBackup.apk
./system/priv-app/VpnDialogs/VpnDialogs.apk
./system/priv-app/SharedStorageBackup/SharedStorageBackup.apk
./system/priv-app/Shell/Shell.apk
[...]
./system/app/EasterEgg/EasterEgg.apk
./system/app/HTMLViewer/HTMLViewer.apk
./system/app/mi_connect_service/mi_connect_service.apk
./system/app/SecureElement/SecureElement.apk
[...]
OK – besser. Nun bleibt noch herauszufinden, welche davon wir genau benötigen. Und leider haben die apk Files natürlich wieder andere Namen, als die Packages, die sie enthalten. Und dazu brauchen wir wieder mal eine weiteres Tool:
sudo apt install aapt
Damit kann man ein apk entsprechend befragen. Z.B.:
❯ aapt dump badging Calculator.apk | grep "package: name="
package: name='com.miui.calculator' versionCode='20120303' versionName='12.3.3' platformBuildVersionName=''
Und etwas systematischer:
find ./ -name *.apk -exec aapt dump badging {} \; | grep "package: name\|application-label:"
Damit kann man arbeiten. D.h. ich werde mich nun mal durch die Liste arbeiten
und sie mit meiner crap.txt
Datei vergleichen.
Soviel für heute.