Kako zaobići skrivenu crnu listu API-ja na Androidu 9+

click fraud protection

Google je u Androidu 9 uveo ograničenja o tome kojim API-jima programeri mogu pristupiti. Evo kako zaobići ta skrivena API ograničenja.

Davne 2018. Google je objavio Android Pie. Među promjenama korisničkog sučelja i novim značajkama, bilo je i nekih promjena na strani programera. Te su promjene uključivale nove API-je, ispravke pogrešaka za postojeće API-je, a također ograničenja pristupa skrivenim API-jima.

No, srećom, postoje načini da se zaobiđu ta ograničenja. Prije nego što počnem govoriti o tome kako zaobići ograničenja, trebao bih objasniti što su skriveni API-ji, zašto su uopće bili ograničeni i zašto biste im mogli pristupiti.

Skriveni API-ji su API-ji u Androidu koje programeri aplikacija obično ne mogu vidjeti. Ako pogledate AOSP-ov kod, vidjet ćete čitavu hrpu klasa, varijabli i metoda koje imaju @hide komentar unutar bloka komentara iznad njih.

Ova napomena upućuje na alat koji Google koristi prilikom kompajliranja SDK-a da izuzme stavku ispod njega. Taj se SDK zatim distribuira programerima unutar SDK-ova preuzetih putem Android Studija. Osim ako ne koristite modificirani SDK, Android Studio će misliti da bilo koja od tih skrivenih stavki jednostavno ne postoji. Ako pokušate upotrijebiti jedan izravno, pokazat će ga crvenom bojom i odbiti će se prevesti.

Mnogo je razloga zašto API može biti skriven. Neke stvari namijenjene su samo internim ili sistemskim aplikacijama i neće raditi ako ih koristi aplikacija treće strane. Drugi su eksperimentalni ili nestabilni i mogu se ukloniti ili promijeniti u budućnosti. Neki su čak samo API-ji, ali Google ne želi primijeniti uobičajeni ciklus zastare ako se ikad uklone.

Dok standardni Android SDK ima mnogo u njemu ponekad nije dovoljno. Ponekad postoji nešto što želite učiniti, a već postoji u Androidu, ali jednostavno nije javno izloženo.

Na primjer, mnoge aplikacije koje izrađujem, uključujući SystemUI Tuner i Widgeti zaključanog zaslona, koristite hrpu različitih skrivenih API-ja. SystemUI Tuner treba pristupiti nekima za pravilno praćenje, promjenu i poništavanje opcija. Lockscreen Widgets koristi neke za prikaz pozadine ispod sebe, između ostalog.

Većina programera ne mora pristupiti skrivenim API-jima, ali ponekad mogu biti vrlo korisni.

Izlaskom Androida 9 (Pie), Google je predstavio skrivenu crnu listu API-ja. Nije uključen svaki skriveni API, a postojale su i različite razine popisa. Skrivenim API-jima na popisu dopuštenih može pristupiti svatko. Skrivenim API-jima na svijetlo-sivom popisu može pristupiti bilo koja aplikacija, ali bi mogli biti nedostupni u budućim verzijama Androida. Svemu na tamno-sivom popisu mogle su pristupiti samo aplikacije koje ciljaju API razine prije Pie (tj. prije API razine 28). Aplikacijama koje ciljaju Pie i novije bit će odbijen pristup. Konačno, skrivenim API-jima na crnoj listi nije mogla pristupiti nijedna aplikacija koja nije na sustavu (ili nije na popisu dopuštenih), bez obzira na ciljni API.

Android 10 promijenio je način organizacije popisa i malo ih pojednostavio, ali ideja je ostala ista. Aplikacije su mogle pristupiti određenim skrivenim API-jima dok su drugi bili blokirani. Android 11 pojačano otkrivanje pristupa do blokirati obilaznicu koristi se za pitu i 10.

U svim verzijama Androida, svaki put kada aplikacija treće strane pokuša pristupiti skrivenom API-ju na crnoj listi, Android će izbaciti odgovarajuću pogrešku "nije pronađeno".

Zapravo postoji dosta načina da se prođe skrivena crna lista API-ja. Ovisno o vašim potrebama, možete odabrati one koji rade za sve verzije Androida, one koji rade samo za Android 9 i 10, one koji koriste izvorni C++ kod i one koji su u potpunosti temeljeni na Javi. Postoji čak i zaobilazno rješenje samo za razvoj pomoću ADB-a.

ADB zaobilazno rješenje

Ako vaš uređaj koristi Android Pie, pokrenite sljedeće dvije ADB naredbe kako biste omogućili skriveni API pristup.

adb shell settings put global hidden_api_policy_pre_p_apps 1
adb shell settings put global hidden_api_policy_p_apps 1

Ako vaš uređaj koristi Android 10 ili noviji, pokrenite sljedeću ADB naredbu da biste omogućili skriveni API pristup.

adb shell settings put global hidden_api_policy 1

Za povratak na zadano ponašanje samo zamijenite put s delete i uklonite 1.

Očito, ove naredbe nisu baš korisne za proizvodnu aplikaciju. Iz prve ruke vam mogu reći da je ispravno podučavanje korisnika o tome kako koristiti ADB nevjerojatno teško. Ali mogu biti korisni ako morate ažurirati staru aplikaciju kako bi bila u skladu s novim ograničenjima.

Izvorno/JNI zaobilazno rješenje

Postoje dva načina na koje možete zaobići skrivenu crnu listu API-ja koristeći JNI u svojoj Android aplikaciji. Jedan radi za Android 9 i 10, a drugi za Android 9 i novije.

Android 9 i 10

Ako već imate izvorni dio svoje aplikacije, to će biti lako implementirati. Samo koristite JNI_OnLoad() funkcija.

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);
...
}

Imajte na umu da ova metoda radi samo na Androidu 9 i 10.

Android 9 i noviji

Za bilo koju verziju Androida imate izbor između dvije biblioteke za zaobilaženje skrivenog API ograničenja: FreeReflection i RestrictionBypass.

Oba su jednostavna za implementaciju i korištenje.

Za implementaciju FreeReflection, dodajte ovisnost svom build.gradle na razini modula.

implementation 'me.weishu: free_reflection: 3.0.1'

Zatim nadjačaj attachBaseContext() u vašoj klasi aplikacije.

@Override
protectedvoidattachBaseContext(Context base){
super.attachBaseContext(base);
Reflection.unseal(base);
}

Ako nemate klasu Application, možete je dodati vrlo jednostavno. Napravite novu klasu koja se proširuje Application a zatim pokažite na njega u svom AndroidManifest.xml.

Primjer:

publicclassAppextendsApplication{
...
@Override
protectedvoidattachBaseContext(Context base){
super.attachBaseContext(base);

Reflection.unseal(base);
}
}

<manifest>
...
...
name=".App">
...
application>
manifest>

Za implementaciju RestrictionBypass, dodajte JitPack repozitorij u svoj build.gradle na razini projekta.

allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}

Zatim dodajte ovisnost svom build.gradle na razini modula.

implementation 'com.github.ChickenHook: RestrictionBypass: 2.2'

I to je to. Ova biblioteka automatski uklanja ograničenja crne liste.

Java zaobilazno rješenje

Iako su JNI rješenja učinkovita, ponekad možda nećete htjeti koristiti izvorni kod. Ako već ne radite stvari u C++-u, to vašoj aplikaciji može dodati nepotrebnu veličinu, zajedno s ograničenjima platforme. Srećom, postoje načini da se zaobiđe skrivena crna lista API-ja samo pomoću Jave.

Android 9 i 10

U Androidu 9 i 10 možete koristiti ono što se može nazvati dvostrukim odrazom ili meta-odrazom da biste zaobišli skrivenu crnu listu API-ja. Budući da sustav provjerava samo ono što pozivaju aplikacije trećih strana, dvostruka refleksija ga vara da misli da sustav upućuje skrivene API pozive.

Ovaj se trik može upotrijebiti za pozivanje metode koja vašoj aplikaciji daje skrivena API izuzeća, prikladno nazvana setHiddenApiExemptions(). Jednostavno dodajte sljedeći kod negdje rano u životnom ciklusu svoje aplikacije (kao što je aplikacija onCreate() metoda) i riješit će zaobilaženje crne liste.

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" } });

Ako je vaša aplikacija kompatibilna s verzijama Androida starijim od 9, ne zaboravite to uključiti u provjeru verzije.

Android 9 i noviji

Da biste zaobišli skrivenu crnu listu API-ja na Androidu 9 i bilo kojoj novijoj verziji, možete koristiti biblioteku LSPosed. Ova biblioteka koristi Javin Unsafe API, tako da je malo vjerojatno da će se ikada pokvariti.

Da biste ga implementirali, samo dodajte ovisnost u svoj build.gradle na razini modula.

implementation 'org.lsposed.hiddenapibypass: hiddenapibypass: 2.0'

Zatim ga upotrijebite za zaobilaženje crne liste.

HiddenApiBypass.addHiddenApiExemptions("L");

Ako je vaša aplikacija kompatibilna s verzijama Androida starijim od 9, ne zaboravite to uključiti u provjeru verzije.

Zaključak i više informacija

Postoji mnogo opcija za zaobilaženje skrivene API crne liste na Androidu, bez obzira koju verziju platforme ciljate ili koristite. Ako ste znatiželjni saznati više o tome kako te metode i biblioteke funkcioniraju, svakako provjerite sljedeće poveznice.

  • Moja Stack Overflow pitanja i odgovori.
  • LSposedova Hidden API Bypass biblioteka na GitHubu.
  • ChickenHook-ova biblioteka RestrictionBypass na GitHubu.
  • tiannova biblioteka FreeReflection na GitHubu.
  • Googleova dokumentacija o skrivenoj crnoj listi API-ja.