Hur man kringgår den dolda API-svarta listan på Android 9+

click fraud protection

Google införde begränsningar i Android 9 för vilka API: er kan nås av utvecklare. Så här kringgår du de dolda API-begränsningarna.

Redan 2018 släppte Google Android Pie. Bland ändringarna i användargränssnittet och nya funktioner fanns det också några förändringar på utvecklarsidan. Dessa ändringar inkluderade nya API: er, buggfixar för befintliga API: er och även begränsningar för åtkomst till dolda API: er.

Lyckligtvis finns det dock sätt att komma runt dessa begränsningar. Innan jag går in på hur man kringgår begränsningarna bör jag förklara lite om vad dolda API: er är, varför de var begränsade i första hand och varför du kanske vill komma åt dem.

Dolda API: er är API: er i Android som apputvecklare normalt inte kan se. Om du tar en titt på AOSP: s kod kommer du att se en hel massa klasser, variabler och metoder som har en @hide anteckning i ett kommentarsblock ovanför dem.

Den här anteckningen instruerar vilket verktyg Google än använder när SDK: n kompileras för att utesluta objektet under det. Denna SDK distribueras sedan till utvecklare i SDK: erna som laddas ner via Android Studio. Om du inte använder en modifierad SDK kommer Android Studio att tro att något av dessa dolda objekt helt enkelt inte existerar. Om du försöker använda en direkt, kommer den att visa den i rött och vägra att kompilera.

Det finns många anledningar till varför ett API kan döljas. Vissa saker är endast avsedda att användas av interna appar eller systemappar och fungerar inte om de används av en tredjepartsapp. Andra är experimentella eller instabila och kan tas bort eller ändras i framtiden. Vissa är till och med bara API: er Google vill helt enkelt inte använda den normala avskrivningscykeln till om de någonsin tas bort.

Medan standard Android SDK har en massa i den räcker det ibland inte. Ibland finns det något du vill göra som redan finns i Android, men som bara inte är offentligt exponerat.

Till exempel många av de appar jag gör, inklusive SystemUI-tuner och Låsskärmswidgetar, använd en massa olika dolda API: er. SystemUI Tuner behöver komma åt några för att kunna spåra, ändra och återställa alternativ. Lockscreen Widgets använder vissa för att visa bakgrunden under den, bland annat.

De flesta utvecklare behöver inte komma åt dolda API: er, men ibland kan de vara ganska användbara.

Med lanseringen av Android 9 (Pie) introducerade Google den dolda API-svartlistan. Inte alla dolda API inkluderades, och det fanns olika nivåer av listor. Dolda API: er på vitlistan kunde nås av vem som helst. Dolda API: er på den ljusgrå listan kan nås av alla appar, men kan vara otillgängliga i framtida versioner av Android. Allt på den mörkgrå listan kunde endast nås av appar som riktade in sig på API-nivåer före Pie (dvs. före API-nivå 28). Appar som är inriktade på Pie och senare kommer att nekas åtkomst. Slutligen kunde dolda API: er på den svarta listan inte nås av någon icke-systemapp (eller icke-vitlistad) app, oavsett mål-API.

Android 10 ändrade hur listorna var organiserade och förenklade dem något, men idén förblev densamma. Vissa dolda API: er kunde nås av appar medan andra blockerades. Android 11 stärkte åtkomstdetekteringen till blockera en förbifart används för Pie och 10.

I alla Android-versioner, varje gång en tredjepartsapp försöker få åtkomst till ett svartlistat dolt API, kommer Android att skicka det lämpliga felet "hittades inte".

Det finns faktiskt en hel del sätt att komma förbi den dolda API-svartlistan. Beroende på dina behov kan du välja de som fungerar för alla Android-versioner, de som bara fungerar för Android 9 och 10, de som använder inbyggd C++-kod och de som är helt Java-baserade. Det finns till och med en lösning endast för utveckling med ADB.

ADB-lösning

Om din enhet kör Android Pie, kör följande två ADB-kommandon för att aktivera dold API-åtkomst.

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

Om din enhet kör Android 10 eller senare, kör följande ADB-kommando för att aktivera dold API-åtkomst.

adb shell settings put global hidden_api_policy 1

För att återgå till standardbeteendet, ersätt bara put med delete och ta bort 1.

Uppenbarligen är dessa kommandon inte direkt användbara för en produktionsapp. Jag kan tala om för dig att det är otroligt svårt att instruera användare på rätt sätt om hur man använder ADB. Men de kan vara användbara om du behöver uppdatera en gammal app för att följa de nya begränsningarna.

Native/JNI-lösning

Det finns två sätt att kringgå den dolda API-svarta listan med JNI i din Android-app. Den ena fungerar för Android 9 och 10, och den andra fungerar för Android 9 och senare.

Android 9 och 10

Om du redan har en inbyggd del av din app är detta enkelt att implementera. Använd bara JNI_OnLoad() fungera.

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

Tänk på att den här metoden bara fungerar på Android 9 och 10.

Android 9 och senare

För alla versioner av Android kan du välja mellan två bibliotek för att kringgå den dolda API-begränsningen: FreeReflection och RestrictionBypass.

Båda är lätta att implementera och använda.

Att implementera FreeReflection, lägg till beroendet till din build.gradle på modulnivå.

implementation 'me.weishu: free_reflection: 3.0.1'

Åsidosätt sedan attachBaseContext() i din applikationsklass.

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

Om du inte har en applikationsklass kan du lägga till den ganska enkelt. Skapa en ny klass som sträcker sig Application och peka sedan på den i din AndroidManifest.xml.

Exempel:

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

Reflection.unseal(base);
}
}

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

För att implementera RestrictionBypass, lägg till JitPack-förvaret till din build.gradle på projektnivå.

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

Lägg sedan till beroendet till din build.gradle på modulnivå.

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

Och det är allt. Detta bibliotek tar automatiskt bort begränsningarna för svarta listan.

Java lösning

Även om JNI-lösningarna är effektiva, finns det tillfällen du kanske inte vill använda inbyggd kod. Om du inte redan gör saker i C++ kan det lägga till onödig storlek, tillsammans med plattformsbegränsningar, till din app. Lyckligtvis finns det sätt att kringgå den dolda API-svarta listan med bara Java.

Android 9 och 10

I Android 9 och 10 kan du använda vad som kan kallas dubbelreflektion eller metareflektion för att kringgå den dolda API-svarta listan. Eftersom systemet bara kontrollerar vad tredjepartsappar anropar, lurar dubbelreflektion det att tro att systemet gör de dolda API-anropen.

Det här tricket kan användas för att anropa en metod för att ge din app dolda API-undantag, passande namn setHiddenApiExemptions(). Lägg bara till följande kod någonstans tidigt i din apps livscykel (som applikationens onCreate() metod), och den kommer att hantera förbikoppling av den svarta listan.

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

Om din app är kompatibel med versioner av Android lägre än 9, kom ihåg att slå in detta i en versionskontroll.

Android 9 och senare

För att kringgå den dolda API-svarta listan på Android 9 och senare versioner kan du använda LSPoseds bibliotek. Det här biblioteket använder Javas osäkra API, så det är osannolikt att det någonsin går sönder.

För att implementera det, lägg bara till beroendet till din modulnivå build.gradle.

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

Använd den sedan för att kringgå den svarta listan.

HiddenApiBypass.addHiddenApiExemptions("L");

Om din app är kompatibel med versioner av Android lägre än 9, kom ihåg att slå in detta i en versionskontroll.

Slutsats och mer info

Det finns många alternativ för att kringgå den dolda API-svarta listan på Android, oavsett vilken plattformsversion du riktar in dig på eller använder. Om du är nyfiken på att lära dig mer om hur dessa metoder och bibliotek fungerar, se till att kolla in följande länkar.

  • My Stack Overflow Q&A.
  • LSposeds Hidden API Bypass-bibliotek på GitHub.
  • ChickenHooks RestrictionBypass-bibliotek på GitHub.
  • tianns FreeReflection-bibliotek på GitHub.
  • Googles dokumentation om den dolda API-svartlistan.