Hoe u de verborgen API-zwarte lijst op Android 9+ kunt omzeilen

click fraud protection

Google heeft in Android 9 beperkingen geïntroduceerd waarop API's toegankelijk zijn voor ontwikkelaars. Hier leest u hoe u deze verborgen API-beperkingen kunt omzeilen.

Lang geleden in 2018 bracht Google Android Pie uit. Onder de wijzigingen in de gebruikersinterface en nieuwe functies waren er ook enkele wijzigingen aan de ontwikkelaarszijde. Deze wijzigingen omvatten nieuwe API's, bugfixes voor bestaande API's, enzovoort beperkingen op de toegang tot verborgen API's.

Gelukkig zijn er manieren om deze beperkingen te omzeilen. Voordat ik inga op het omzeilen van de beperkingen, moet ik eerst iets uitleggen over wat verborgen API's zijn, waarom ze in de eerste plaats beperkt waren en waarom je er misschien toegang toe zou willen hebben.

Verborgen API's zijn de API's in Android die app-ontwikkelaars normaal gesproken niet kunnen zien. Als je naar de code van AOSP kijkt, zie je een hele reeks klassen, variabelen en methoden met een @hide annotatie in een commentaarblok erboven.

Deze annotatie geeft aan welke tool Google ook gebruikt bij het samenstellen van de SDK om het onderliggende item uit te sluiten. Die SDK wordt vervolgens gedistribueerd naar ontwikkelaars binnen de SDK's die zijn gedownload via Android Studio. Tenzij u een aangepaste SDK gebruikt, zal Android Studio denken dat al deze verborgen items gewoon niet bestaan. Als u er een rechtstreeks probeert te gebruiken, wordt deze in het rood weergegeven en weigert deze te compileren.

Er zijn veel redenen waarom een ​​API verborgen kan zijn. Sommige dingen zijn alleen bedoeld voor gebruik door interne apps of systeemapps en werken niet als ze worden gebruikt door een app van derden. Andere zijn experimenteel of onstabiel en kunnen in de toekomst worden verwijderd of gewijzigd. Sommige zijn zelfs slechts API's waar Google de normale beëindigingscyclus niet op wil toepassen als ze ooit worden verwijderd.

Hoewel de standaard Android SDK een kavel erin, soms is het niet genoeg. Soms is er iets dat je wilt doen dat al bestaat in Android, maar dat nog niet openbaar is gemaakt.

Veel van de apps die ik maak bijvoorbeeld, inclusief SystemUI-tuner En Vergrendelschermwidgets, maak gebruik van een aantal verschillende verborgen API's. SystemUI Tuner heeft toegang tot sommige nodig om opties correct te kunnen volgen, wijzigen en opnieuw instellen. Lockscreen Widgets gebruikt er enkele om onder andere de achtergrond eronder weer te geven.

De meeste ontwikkelaars hebben geen toegang nodig tot verborgen API's, maar soms kunnen ze behoorlijk handig zijn.

Met de release van Android 9 (Pie) introduceerde Google de verborgen API-blacklist. Niet elke verborgen API was inbegrepen en er waren verschillende niveaus van lijsten. Verborgen API’s op de witte lijst zijn voor iedereen toegankelijk. Verborgen API's op de lichtgrijze lijst zijn toegankelijk voor elke app, maar zijn mogelijk niet meer toegankelijk in toekomstige versies van Android. Alles op de donkergrijze lijst was alleen toegankelijk voor apps die zich richtten op API-niveaus vóór Pie (dat wil zeggen vóór API-niveau 28). Apps die Pie en hoger targeten, zouden de toegang worden geweigerd. Ten slotte waren verborgen API's op de zwarte lijst niet toegankelijk voor apps die niet op de systeemlijst (of niet op de witte lijst staan), ongeacht de doel-API.

Android 10 veranderde de manier waarop de lijsten waren georganiseerd en vereenvoudigde ze enigszins, maar het idee bleef hetzelfde. Bepaalde verborgen API's waren toegankelijk voor apps, terwijl andere geblokkeerd waren. Androïde 11 versterkte de toegangsdetectie naar een bypass blokkeren gebruikt voor taart en 10.

In alle Android-versies zal Android elke keer dat een app van derden probeert toegang te krijgen tot een op de zwarte lijst geplaatste verborgen API, de juiste foutmelding 'niet gevonden' genereren.

Er zijn eigenlijk nogal wat manieren om voorbij de verborgen API-zwarte lijst te komen. Afhankelijk van uw behoeften kunt u versies kiezen die voor alle Android-versies werken, versies die alleen voor Android 9 en 10 werken, versies die native C++-code gebruiken en versies die volledig op Java zijn gebaseerd. Er is zelfs een oplossing die alleen voor ontwikkeling is, waarbij gebruik wordt gemaakt van ADB.

ADB-oplossing

Als uw apparaat Android Pie gebruikt, voert u de volgende twee ADB-opdrachten uit om verborgen API-toegang in te schakelen.

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

Als uw apparaat Android 10 of hoger gebruikt, voert u de volgende ADB-opdracht uit om verborgen API-toegang in te schakelen.

adb shell settings put global hidden_api_policy 1

Om terug te keren naar het standaardgedrag hoeft u alleen maar te vervangen put met delete en verwijder de 1.

Het is duidelijk dat deze opdrachten niet bepaald nuttig zijn voor een productie-app. Ik kan u uit de eerste hand vertellen dat het ongelooflijk moeilijk is om gebruikers correct te instrueren over het gebruik van ADB. Maar ze kunnen handig zijn als u een oude app moet bijwerken om aan de nieuwe beperkingen te voldoen.

Native/JNI-oplossing

Er zijn twee manieren waarop u de verborgen API-blacklist kunt omzeilen met JNI in uw Android-app. De ene werkt voor Android 9 en 10, en de andere werkt voor Android 9 en hoger.

Android 9 en 10

Als u al een native gedeelte van uw app heeft, is dit eenvoudig te implementeren. Gebruik gewoon de JNI_OnLoad() functie.

statische kunst:: Runtime* runtime = nullptr;

extern "C"jint JNI_OnLoad(JavaVM *vm, void *reserved){
...
runtime = reinterpret_cast<: javavmext>(vm)->GetRuntime();
runtime->SetHiddenApiEnforcementPolicy(art:: hiddenapi:: EnforcementPolicy:: kNoChecks);
...
}

Houd er rekening mee dat deze methode alleen werkt op Android 9 en 10.

Android 9 en hoger

Voor elke versie van Android heb je de keuze uit twee bibliotheken om de verborgen API-beperking te omzeilen: FreeReflection en RestrictionBypass.

Beide zijn eenvoudig te implementeren en te gebruiken.

Om FreeReflection te implementeren, voeg de afhankelijkheid toe aan uw build.gradle op moduleniveau.

implementation 'me.weishu: free_reflection: 3.0.1'

Dan overschrijven attachBaseContext() in uw toepassingsklasse.

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

Als u geen Application-klasse heeft, kunt u deze vrij eenvoudig toevoegen. Maak een nieuwe klasse die uitbreidt Application en wijs ernaar in uw AndroidManifest.xml.

Voorbeeld:

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

Reflection.unseal(base);
}
}

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

Om RestrictionBypass te implementeren, voeg de JitPack-repository toe aan uw build.gradle op projectniveau.

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

Voeg vervolgens de afhankelijkheid toe aan uw build.gradle op moduleniveau.

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

En dat is het. Deze bibliotheek verwijdert automatisch de blacklist-beperkingen.

Java-oplossing

Hoewel de JNI-oplossingen effectief zijn, kan het voorkomen dat u geen native code wilt gebruiken. Als u nog geen dingen in C++ doet, kan dit onnodige omvang en platformbeperkingen aan uw app toevoegen. Gelukkig zijn er manieren om de verborgen API-zwarte lijst te omzeilen door alleen Java te gebruiken.

Android 9 en 10

In Android 9 en 10 kun je zogenaamde dubbele reflectie of meta-reflectie gebruiken om de verborgen API-zwarte lijst te omzeilen. Omdat het systeem alleen controleert wat apps van derden aanroepen, zorgt dubbele reflectie ervoor dat het systeem denkt dat het systeem de verborgen API-aanroepen doet.

Deze truc kan worden gebruikt om een ​​methode aan te roepen om uw app verborgen API-vrijstellingen te geven, toepasselijk genaamd setHiddenApiExemptions(). Voeg eenvoudigweg de volgende code ergens vroeg in de levenscyclus van uw app toe (zoals Application's onCreate() methode), en het zal de zwarte lijst omzeilen.

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

Als uw app compatibel is met versies van Android lager dan 9, vergeet dan niet om dit in een versiecontrole te verwerken.

Android 9 en hoger

Om de verborgen API-zwarte lijst op Android 9 en latere versies te omzeilen, kunt u de bibliotheek van LSPosed gebruiken. Deze bibliotheek maakt gebruik van de Unsafe API van Java, dus het is onwaarschijnlijk dat deze ooit kapot gaat.

Om het te implementeren, voegt u gewoon de afhankelijkheid toe aan uw build.gradle op moduleniveau.

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

Gebruik het dan om de zwarte lijst te omzeilen.

HiddenApiBypass.addHiddenApiExemptions("L");

Als uw app compatibel is met versies van Android lager dan 9, vergeet dan niet om dit in een versiecontrole te verwerken.

Conclusie en meer informatie

Er zijn tal van opties om de verborgen API-zwarte lijst op Android te omzeilen, ongeacht welke platformversie u target of gebruikt. Als je nieuwsgierig bent naar meer informatie over hoe deze methoden en bibliotheken werken, bekijk dan zeker de volgende links.

  • Mijn Stack Overflow-vragen en antwoorden.
  • LSposed's Hidden API Bypass-bibliotheek op GitHub.
  • ChickenHook's RestrictionBypass-bibliotheek op GitHub.
  • Tiann's FreeReflection-bibliotheek op GitHub.
  • Documentatie van Google over de verborgen API-zwarte lijst.