Google zaviedol obmedzenia v systéme Android 9, na ktorých môžu vývojári pristupovať k API. Tu je návod, ako obísť tieto skryté obmedzenia API.
V roku 2018 spoločnosť Google vydala Android Pie. Medzi zmenami používateľského rozhrania a novými funkciami došlo aj k niektorým zmenám na strane vývojárov. Tieto zmeny zahŕňali nové rozhrania API, opravy chýb pre existujúce rozhrania API a tiež obmedzenia prístupu k skrytým API.
Našťastie však existujú spôsoby, ako tieto obmedzenia obísť. Predtým, ako sa dostanem k tomu, ako obísť obmedzenia, mal by som trochu vysvetliť, čo sú skryté API, prečo boli na prvom mieste obmedzené a prečo by ste k nim možno chceli pristupovať.
Skryté API sú rozhrania API v systéme Android, ktoré vývojári aplikácií bežne nevidia. Ak sa pozriete na kód AOSP, uvidíte celý rad tried, premenných a metód, ktoré majú @hide
anotácia v bloku komentárov nad nimi.
Táto anotácia určuje, aký nástroj Google používa pri kompilácii súpravy SDK na vylúčenie položky pod ňou. Táto súprava SDK sa potom distribuuje vývojárom v rámci súprav SDK stiahnutých cez Android Studio. Ak nepoužijete upravenú súpravu SDK, Android Studio si bude myslieť, že niektorá z týchto skrytých položiek jednoducho neexistuje. Ak sa ho pokúsite použiť priamo, zobrazí sa červenou farbou a odmietne kompiláciu.
Existuje mnoho dôvodov, prečo môže byť rozhranie API skryté. Niektoré veci sú určené len na použitie internými alebo systémovými aplikáciami a nebudú fungovať, ak ich použije aplikácia tretej strany. Iné sú experimentálne alebo nestabilné a v budúcnosti môžu byť odstránené alebo zmenené. Niektoré sú dokonca len rozhrania API, ak Google jednoducho nechce použiť bežný cyklus ukončenia podpory, ak budú niekedy odstránené.
Zatiaľ čo štandardná súprava Android SDK má a veľa v ňom niekedy nestačí. Niekedy existuje niečo, čo chcete urobiť, čo už v systéme Android existuje, ale nie je verejne odhalené.
Napríklad veľa aplikácií, ktoré vytváram, vrátane SystemUI Tuner a Widgety uzamknutej obrazovky, využite množstvo rôznych skrytých API. SystemUI Tuner potrebuje prístup k niektorým, aby bolo možné správne sledovať, meniť a resetovať možnosti. Lockscreen Widgets niektoré používa okrem iného na zobrazenie tapety pod ňou.
Väčšina vývojárov nepotrebuje pristupovať k skrytým API, ale niekedy môžu byť veľmi užitočné.
S vydaním systému Android 9 (Pie) Google predstavil skrytý čierny zoznam API. Nie každé skryté API bolo zahrnuté a existovali rôzne úrovne zoznamov. K skrytým rozhraniam API na bielej listine môže pristupovať ktokoľvek. K skrytým rozhraniam API na svetlošedom zozname má prístup akákoľvek aplikácia, no v budúcich verziách Androidu môžu byť nedostupné. K čomukoľvek na tmavom šedom zozname mali prístup iba aplikácie zacielené na úrovne API pred Pie (t. j. pred úrovňou API 28). Aplikáciám zacieleným na Pie a novšie by bol zamietnutý prístup. Nakoniec, skryté rozhrania API na čiernej listine neboli prístupné žiadnej nesystémovej (alebo nepriradenej) aplikácii, bez ohľadu na cieľové rozhranie API.
Android 10 zmenil spôsob usporiadania zoznamov a mierne ich zjednodušil, ale myšlienka zostala rovnaká. K niektorým skrytým rozhraniam API mohli aplikácie pristupovať, zatiaľ čo iné boli zablokované. Android 11 posilnila detekciu prístupu do blokovať obchvat používa sa pre koláč a 10.
Vo všetkých verziách Androidu vždy, keď sa aplikácia tretej strany pokúsi o prístup k skrytému API na čiernej listine, Android zobrazí príslušnú chybu „nenájdené“.
V skutočnosti existuje niekoľko spôsobov, ako sa dostať cez skrytú čiernu listinu API. V závislosti od vašich potrieb si môžete vybrať tie, ktoré fungujú pre všetky verzie Androidu, tie, ktoré fungujú len pre Android 9 a 10, tie, ktoré používajú natívny kód C++, a tie, ktoré sú plne založené na jazyku Java. Existuje dokonca iba vývojové riešenie pomocou ADB.
ADB Alternatívne riešenie
Ak vaše zariadenie používa systém Android Pie, spustite nasledujúce dva príkazy ADB, aby ste povolili skrytý prístup k API.
adb shell settings put global hidden_api_policy_pre_p_apps 1
adb shell settings put global hidden_api_policy_p_apps 1
Ak vaše zariadenie používa systém Android 10 alebo novší, spustite nasledujúci príkaz ADB, aby ste povolili skrytý prístup k API.
adb shell settings put global hidden_api_policy 1
Ak sa chcete vrátiť k predvolenému správaniu, stačí nahradiť put
s delete
a odstráňte 1
.
Je zrejmé, že tieto príkazy nie sú práve užitočné pre produkčnú aplikáciu. Môžem vám povedať z prvej ruky, že správne poučiť používateľov o tom, ako používať ADB, je neuveriteľne ťažké. Môžu však byť užitočné, ak potrebujete aktualizovať starú aplikáciu, aby vyhovovala novým obmedzeniam.
Natívne/JNI riešenie
Existujú dva spôsoby, ako môžete obísť skrytý zoznam zakázaných rozhraní API pomocou JNI v aplikácii pre Android. Jeden funguje pre Android 9 a 10 a druhý funguje pre Android 9 a novší.
Android 9 a 10
Ak už máte natívnu časť svojej aplikácie, implementácia bude jednoduchá. Stačí použiť JNI_OnLoad()
funkciu.
static art:: Runtime* runtime = nullptr;
extern "C"jint JNI_OnLoad(JavaVM *vm, void *reserved){
...
runtime = reinterpret_cast<: javavmext>(vm)->GetRuntime();
runtime->SetHiddenApiEnforcementPolicy(art:: hiddenapi:: EnforcementPolicy:: kNoChecks);
...
}
Uvedomte si, že táto metóda funguje iba v systéme Android 9 a 10.
Android 9 a novší
Pre akúkoľvek verziu Androidu máte na výber z dvoch knižníc na obídenie skrytého obmedzenia API: FreeReflection a RestrictionBypass.
Oba sa dajú ľahko implementovať a používať.
Na implementáciu FreeReflection, pridajte závislosť do svojho build.gradle na úrovni modulu.
implementation 'me.weishu: free_reflection: 3.0.1'
Potom prepíšte attachBaseContext()
vo svojej triede aplikácií.
@Override
protectedvoidattachBaseContext(Context base){
super.attachBaseContext(base);
Reflection.unseal(base);
}
Ak nemáte triedu aplikácií, môžete si ju pridať celkom jednoducho. Vytvorte novú triedu, ktorá sa rozšíri Application
a potom naň ukážte v súbore AndroidManifest.xml.
Príklad:
publicclassAppextendsApplication{
...
@Override
protectedvoidattachBaseContext(Context base){
super.attachBaseContext(base);
Reflection.unseal(base);
}
}
<manifest>
...
...
name=".App">
...
application>
manifest>
Na implementáciu RestrictionBypass, pridajte úložisko JitPack do svojho build.gradle na úrovni projektu.
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
Potom pridajte závislosť do svojho build.gradle na úrovni modulu.
implementation 'com.github.ChickenHook: RestrictionBypass: 2.2'
A to je všetko. Táto knižnica automaticky odstraňuje obmedzenia čiernej listiny.
Riešenie Java
Aj keď sú riešenia JNI efektívne, môžu sa stať, že nebudete chcieť použiť natívny kód. Ak ešte nerobíte veci v C++, môže to vašej aplikácii pridať zbytočnú veľkosť spolu s obmedzeniami platformy. Našťastie existujú spôsoby, ako obísť skrytý čierny zoznam API iba pomocou Java.
Android 9 a 10
V systéme Android 9 a 10 môžete použiť to, čo sa dá nazvať dvojitým odrazom alebo metaodrazom, aby ste obišli skrytý čierny zoznam API. Pretože systém kontroluje iba to, čo volajú aplikácie tretích strán, dvojitá reflexia ho oklame, aby si myslel, že systém uskutočňuje skryté volania API.
Tento trik možno použiť na zavolanie metódy, ktorá vašej aplikácii poskytne skryté výnimky z rozhrania API, ktoré sú vhodne pomenované setHiddenApiExemptions()
. Jednoducho pridajte nasledujúci kód niekde na začiatku životného cyklu vašej aplikácie (ako je napríklad cyklus aplikácie onCreate()
metóda) a zvládne obídenie čiernej listiny.
Method forName = Class.class.getDeclaredMethod("forName", String.class);
Method getDeclaredMethod = Class.class.getDeclaredMethod("getDeclaredMethod", String.class, Class[].class);Class vmRuntimeClass = (Class) forName.invoke(null, "dalvik.system.VMRuntime");
Method getRuntime = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "getRuntime", null);
Method setHiddenApiExemptions = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "setHiddenApiExemptions", newClass[] { String[].class} );
Object vmRuntime = getRuntime.invoke(null);
setHiddenApiExemptions.invoke(vmRuntime, newString[][] { newString[] { "L" } });
Ak je vaša aplikácia kompatibilná s verziami Androidu nižšími ako 9, nezabudnite to zabaliť do kontroly verzie.
Android 9 a novší
Ak chcete obísť skrytú čiernu listinu API v systéme Android 9 a akejkoľvek novšej verzii, môžete použiť knižnicu LSPosed. Táto knižnica používa Unsafe API Java, takže je nepravdepodobné, že by sa niekedy zlomila.
Ak ju chcete implementovať, jednoducho pridajte závislosť do svojho build.gradle na úrovni modulu.
implementation 'org.lsposed.hiddenapibypass: hiddenapibypass: 2.0'
Potom ho použite na obídenie čiernej listiny.
HiddenApiBypass.addHiddenApiExemptions("L");
Ak je vaša aplikácia kompatibilná s verziami Androidu nižšími ako 9, nezabudnite to zabaliť do kontroly verzie.
Záver a ďalšie informácie
Existuje veľa možností, ako obísť skrytú čiernu listinu API v systéme Android, bez ohľadu na to, na ktorú verziu platformy zacieľujete alebo používate. Ak máte záujem dozvedieť sa viac o tom, ako tieto metódy a knižnice fungujú, určite si pozrite nasledujúce odkazy.
- Otázky a odpovede o pretečení môjho zásobníka.
- Knižnica Hidden API Bypass LSposed na GitHub.
- Knižnica ChickenHook's RestrictionBypass na GitHub.
- tiann's FreeReflection knižnica na GitHub.
- Dokumentácia Google na skrytom zozname zakázaných rozhraní API.