Úprava systémových aplikácií v Androide

04.07.2020 | 15:00 | Mirecove dristy | Miroslav Bendík

V dnešnom článku budeme rezať do živého. Rozpitváme si pomocou dekompilátora jednu systémovú aplikáciu, urobíme pár úprav a nahradíme vstavanú systémovú aplikáciu opravenou verziou.

Čo budeme potrebovať

V prvom rade budeme potrebovať telefón s Androidom a root prístupom. Odporúčam mať nainštalovaný aj nejaký lepší recovery image (TWRP, alebo niečo podobné pre prípad, že niečo veľmi veľmi pokazíme). Ďalej budeme potrebovať nástroje adb, apktool, dex2jar a jd-gui.

Čo ideme zmeniť

Tu si musí každý čitateľ dosadiť vlastnú odpoveď. Ja som nedávno prešiel so svojou starou vykopávkou Xiaomi Redmi 4A na MIUI 11 (Android 9). Nepríjemne ma prekvapila napríklad skutočnosť, že MIUI 11 ukladá všetky screenshoty v JPEG a nie je v systéme možnosť to zmeniť.

Sťahujeme balíky z telefónu

Z telefónu budeme potrebovať požadovaný apk balíček + balíčky frameworku, na ktorých je závislý. Najskôr si vyhľadáme požadovaný balíček (v mojom prípade System UI). Prihlásime sa teda do telefónu cez adb shell a zistíme cestu k apk súboru. Príkaz pm list package vypíše nainštalované balíčky a príznak -f pridá do výpisu cestu k apk súboru.

$ pm list package -f|grep systemui
package:/vendor/overlay/SysuiDarkTheme/SysuiDarkThemeOverlay.apk=com.android.systemui.theme.dark
package:/vendor/overlay/DevicesAndroidOverlay.apk=com.miui.systemui.overlay.devices.android
package:/system/priv-app/MiuiSystemUI/MiuiSystemUI.apk=com.android.systemui

Balík stiahneme príkazom adb pull /system/priv-app/MiuiSystemUI/MiuiSystemUI.apk. Teraz môžme skúsiť dekompilovať balík. Použijeme na to príkaz apktool:

$ java -jar apktool_2.4.1.jar d MiuiSystemUI.apk
I: Using Apktool 2.4.1 on MiuiSystemUI.apk
I: Loading resource table...
I: Decoding Shared Library (miui), pkgId: 16
I: Decoding Shared Library (android.miui), pkgId: 17
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /home/mirec/.local/share/apktool/framework/1.apk
W: Could not decode attr value, using undecoded value instead: ns=android, name=theme, value=0x100d00c5
W: Could not decode attr value, using undecoded value instead: ns=android, name=theme, value=0x100d00c5
W: Could not decode attr value, using undecoded value instead: ns=android, name=theme, value=0x100d00c5
W: Could not decode attr value, using undecoded value instead: ns=android, name=theme, value=0x100d00c5
W: Could not decode attr value, using undecoded value instead: ns=android, name=theme, value=0x100d00c5
W: Could not decode attr value, using undecoded value instead: ns=android, name=theme, value=0x100d00c5
I: Regular manifest package...
I: Decoding file-resources...
W: Could not decode attr value, using undecoded value instead: ns=android, name=src, value=0x1002006e
W: Could not decode attr value, using undecoded value instead: ns=android, name=color, value=0x10010084
W: Could not decode attr value, using undecoded value instead: ns=android, name=src, value=0x10020080
W: Could not decode attr value, using undecoded value instead: ns=android, name=src, value=0x10020081
W: Could not decode attr value, using undecoded value instead: ns=android, name=color, value=0x10010084
W: Could not decode attr value, using undecoded value instead: ns=android, name=color, value=0x10010084
W: Could not decode attr value, using undecoded value instead: ns=android, name=color, value=0x10010084
I: Decoding values */* XMLs...
Can't find framework resources for package of id: 16. You must install proper framework files, see project website for more info.

Ako vidíme vo výpise príkazu apktool chýbajú 2 frameworky (miui a android.miui). Stiahneme teda príslušné frameworky (nájdené cez adb príkazom find).

adb pull /system/app/miui/miui.apk
adb pull /system/framework/framework-ext-res/framework-ext-res.apk

Teraz ich potrebujeme ešte nainštalovať do apktool, takže spustíme:

$ java -jar apktool_2.4.1.jar if miui.apk
I: Framework installed to: /home/mirec/.local/share/apktool/framework/16.apk
$ java -jar apktool_2.4.1.jar if framework-ext-res.apk
I: Decoding Shared Library (miui), pkgId: 16
I: Framework installed to: /home/mirec/.local/share/apktool/framework/17.apk

Dekompilácia tentoraz prebehne v poriadku:

$ java -jar apktool_2.4.1.jar d MiuiSystemUI.apk -f

I: Using Apktool 2.4.1 on MiuiSystemUI.apk
I: Loading resource table...
I: Decoding Shared Library (miui), pkgId: 16
I: Decoding Shared Library (android.miui), pkgId: 17
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /home/mirec/.local/share/apktool/framework/1.apk
I: Loading resource table from file: /home/mirec/.local/share/apktool/framework/16.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Loading resource table from file: /home/mirec/.local/share/apktool/framework/17.apk
I: Decoding Shared Library (miui), pkgId: 16
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...

Úprava binárky

Týmto krokom sme získali kód v nízkoúrovňovom jazyku smali (podobný assembleru). Lepšie by sa nám však vyznalo vo vysokoúrovňovom java kóde. Skúsime teda dekompilovať apk do java zdrojákov (len ako pomôcku, pri samotnej úprave to nepotrebujeme). Rozbalíme zo zip súboru MiuiSystemUI.apk (apk sú v skutočnosti zip) súbor classes.dex a konvertujeme ho na jar príkazom d2j-dex2jar.sh classes.dex z balíka dex-tools. Teraz sa môžme pohrabať v zdrojákoch pomocou jd-gui (java -jar jd-gui-1.6.6.jar classes-dex2jar.jar).

jd-gui
Obrázok 1: JD-GUI - hľadaná časť súboru

Teraz keď vieme, čo sa deje v aplikácii a vieme, stačí zmeniť výskyt jpg/jpeg za png v súboroch v adresári MiuiSystemUI/smali/com/android/systemui/screenshot.

Zdrojový kód smali
Obrázok 2: Zdrojový kód smali

Vytvorenie balíka

Po úprave zostavíme nový apk balíček.

java -jar apktool_2.4.1.jar b MiuiSystemUI -o MiuiSystemUI.apk
I: Using Apktool 2.4.1
I: Checking whether sources has changed...
I: Smaling smali folder into classes.dex...
I: Checking whether resources has changed...
I: Building resources...
W: warning: string 'battery_can_use_time' has no default translation.
W: warning: string 'battery_profiles' has no default translation.
W: warning: string 'dlg_cancel' has no default translation.
W: warning: string 'dlg_confirm' has no default translation.
W: warning: string 'dlg_summary_close_app' has no default translation.
W: warning: string 'dlg_summary_close_theme' has no default translation.
W: warning: string 'dlg_summary_close_wifi' has no default translation.
W: warning: string 'dlg_summary_nfc' has no default translation.
W: warning: string 'dlg_summary_title' has no default translation.
W: warning: string 'enable_extreme_power_save_mode' has no default translation.
W: warning: string 'enable_power_save_mode' has no default translation.
W: warning: string 'notification_low_battery_action_btn' has no default translation.
W: warning: string 'notification_low_battery_need_charge' has no default translation.
W: warning: string 'notification_low_battery_open_save_mode' has no default translation.
W: warning: string 'notification_low_battery_title' has no default translation.
W: warning: string 'oldman_airplane_mode_text' has no default translation.
W: warning: string 'oldman_incall_text' has no default translation.
W: warning: string 'open_extreme_power_save_mode_title' has no default translation.
W: warning: string 'save_mode_btn_ok' has no default translation.
I: Building apk file...
I: Copying unknown files/dir...
I: Built apk...

Aby sa dal balík použiť v androide musí byť digitálne podpísaný (pokojne self signed certifikátom). Vytvoríme teda najskôr privátny kľúč príkazom keytool -genkeypair -v -keystore android.keystore -alias android -keyalg RSA -keysize 2048 -validity 10000.

Teraz môžme balík pospísať príkazom jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore android.keystore MiuiSystemUI.apk android.

Nahradenie systémovéj aplikácie

Balík prenesieme do androidu príkazom adb push /sdcard/MiuiSystemUI.apk (priamo na systémovú partíciu nemôžme cez adb zapisovať). Následne v systéme pripojíme /system v režime na zápis príkazom mount -o remount,rw /system. Ak to nejde naštartujeme telefón do recovery a pripojíme /system s právami na zápis priamo v recovery (pokročilé recovery obrazy podporujú shell cez adb). Teraz prekopírujeme balík na správne miesto príkazom cp /sdcard/MiuiSystemUI.apk /system/priv-app/MiuiSystemUI/MiuiSystemUI.apk.

Android balíky po inštalácii automaticky kompiluje a ukladá na ART/Dalivk cache partíciu. Aj keď je balík nahradený stále sa môže načítavať skompilovaná a optimalizovaná verzia z cache. Tu by som chcel zdôrazniť nemažte ART / Dalvik cache. Ja som to urobil a potom som hodinu hľadal, ako ju znovu vytvoriť, pretože aj taká banalita ako spustenie nastavení trvala vyše 30s. Cache sa nemusí automaticky vytvoriť a fakt som sa zapotil keď som nevedel donútiť inak nezdokumentovaný daemon installd, aby rekompiloval cache. Keby niekto urobil náhodou tú istú chybu, tak opraviť sa dá príkazom pm compile -a -r first-boot. Kompilácia vybraného balíka sa dá vynútiť príkazom pm compile -m speed com.android.systemui.

Po reštarte telefónu by sa mal konečne použíť náš upravený balík namiesto pôvodného.

Ukladanie screenshotu do PNG
Video 1: Ukladanie screenshotu do PNG

Moje postrehy - nespokojnosť s Androidom

Prakticky každý aspekt Androidu vo mne zanechal nepríjemný pocit sklamania. Od komunity cez prístup googlu, výrobcu telefónu až po prístup výrobcu chipsetu. Jednoducho celé zle.

Používam starší, ale po hardvérovej stránke plne vyhovujúci telefón Xiaomi Redmi 4A. Pred pár rokmi som zaň zaplatil asi stovku a stále dokáže pracovať pomerne svižne a má pri mojom nenáročnom používaní vydrž tak 10 dní na nabitie. Jednoducho pohodový, ľahký a malý telefón.

Oficiálny softvér dodávaný výrobcom je Android 6 s nadstavbou MIUI. Tesne po vydaní 4A prišlo Xiaomi s identickým hardvérom - 5A, ktorá dostala update na Android 8. Aby som tu nepobehoval s totálne deravým Androidom som nedávno nainštaloval Android 9 s MIUI 11.

Inštalácia MIUI 11 na Redmi 4A
Video 2: Inštalácia MIUI 11 na Redmi 4A

Ďalší softvérový problém je s kvalitou fotoaparátu. Jednoducho fotografie z toho lezú spatlané denoise algoritmom, takže žiadne detaily v tmavších oblastiach nevykreslí. Pritom hardvér v pohode podporuje Camera2 API a pri fotografovaní do RAW viem vytiahnuť aj detaily v tieňoch (huba v prílohách). Lenže výrobca nepovolil Camera2 API, takže musím použiť neoficiálny ROM.

Potom tu máme problém s absenciou Vulkan API. To by malo byť podporované každým hardvérom, ktorý zvláda OpenGL ES 3.1. Malo … keby výrobca chipsetu dodal ovládače. Lenže qualcomm je schopný zarezať podporu ešte v dobe, kedy výrobné linky chrlia hardvér vo veľkom. Vulkan API teda nebude …

Ešte tu máme komunitu. Peknú, zdravú, milú komunitu zloženú z uplakancov, ktorí nič nevedia a prospechárov, ktorí nič zadarmo neurobia.

Prílohy



    • RE: Úprava systémových aplikácií v Androide 04.07.2020 | 20:17
      Avatar bedňa LegacyIce-antiX  Administrátor

      Pekný hacking.

      Moje postrehy - nespokojnosť s Androidom

      Toto je klasický prípad vývoja v podaní nadnárodných korporácií.

      Rovnako sa o to dnes snaží RedHat nasledovaný Canonicalom preniesť na Linux.

      Som tu za hejtera, keď upozorňujem na nebezpečenstvo zabitia celého Linux enviroment. systemd pohltil celý enviroment. Gnome odstraňuje funkčnosť a kurvý celý desktop enviroment. Wayland je aj po dvanástich rokoch vývoja a predrbaných miliónoch v nepoužiteľnom stave a schválne nikdy použiteľný ani nebude.

      Namiesto natívneho behu aplikácií, chcú všetko presunúť do kontajnerov, namiesto "nebezpečnej" inštalácie aplikácií zo zdrojov distribúcie sa inštalácia presúva do deravých "bezpečných" Flatpak a Snap.

      To je trend ktorý je podporovaný číslami užívateľov. Preto tvrdím, že každý kto používa tieto šmejďárny podporuje toto kriplenie.

      Tvrdil to aj RMS, ale toho už úspešne odstránili moderní a úspešní, teda takto to howorieval Wl.

      Táto správa neobsahuje vírus, pretože nepoužívam MS Windows. http://kernelultras.org
    • RE: Úprava systémových aplikácií v Androide 07.09.2020 | 14:35
      Avatar distefano wattOS, Xubuntu minimal,  Používateľ

      Mirec, ja mam tebou spominany Redmi 5A s Androidom 8 a MIUI 11, po aktualizacii na Android 8 som si ale vsimol badatelne spomalenie systemu. Pri A9 alebo 10 by sa to malo prejavit este viac. Este otazocku, bolo by mozne Redmi 5A prisposobit na podporu eSIM?

      • RE: Úprava systémových aplikácií v Androide 07.09.2020 | 14:57
        Avatar Livan Manjaro s XFCE, Q4OS s KDE  Používateľ

        Veci ohľadne eSIm sa dozvieš napr. tu. Ak telefon nemá čip na eSIM, nedá sa tam eSIM nahrať, musí ho teda hardvérovo podporovať, čo majú väčšinou drahšie modely.

      • RE: Úprava systémových aplikácií v Androide 20.09.2020 | 17:50
        Avatar Miroslav Bendík Gentoo  Administrátor

        Fuu ja so spomalením nemám problém, ale používam firmvér pre iný telefón, takže možno preto ;)