Як обійти прихований чорний список API на Android 9+

click fraud protection

Google ввів обмеження в Android 9 щодо того, які API можуть отримати доступ розробники. Ось як обійти ці приховані обмеження API.

У далекому 2018 році Google випустив Android Pie. Серед змін інтерфейсу користувача та нових функцій також були деякі зміни на стороні розробника. Ці зміни включали нові API, виправлення помилок для існуючих API, а також обмеження доступу до прихованих API.

На щастя, є способи обійти ці обмеження. Перш ніж перейти до того, як обійти обмеження, я повинен трохи пояснити, що таке приховані API, чому вони взагалі були обмежені та чому ви можете отримати до них доступ.

Приховані API – це API в Android, які розробники програм зазвичай не бачать. Якщо ви подивитеся на код AOSP, ви побачите цілу купу класів, змінних і методів, які мають @hide анотації всередині блоку коментарів над ними.

Ця анотація вказує будь-якому інструменту, який Google використовує під час компіляції SDK, щоб виключити відповідний елемент. Цей SDK потім розповсюджується серед розробників у SDK, завантажених через Android Studio. Якщо ви не використовуєте модифікований SDK, Android Studio вважатиме, що жодного з цих прихованих елементів просто не існує. Якщо ви спробуєте використати його безпосередньо, він покаже його червоним кольором і відмовиться компілювати.

Існує багато причин, чому API може бути прихованим. Деякі речі призначені для використання лише внутрішніми або системними програмами та не працюватимуть, якщо їх використовує стороння програма. Інші є експериментальними або нестабільними та можуть бути видалені або змінені в майбутньому. Деякі з них навіть є просто API, але Google не хоче використовувати звичайний цикл припинення підтримки, якщо вони колись будуть видалені.

Хоча стандартний Android SDK має a багато в ньому іноді не вистачає. Іноді є те, що ви хочете зробити, що вже існує в Android, але просто не оприлюднено.

Наприклад, багато додатків, які я роблю, в тому числі Тюнер SystemUI і Віджети екрану блокування, використовувати купу різних прихованих API. SystemUI Tuner потребує доступу до деяких параметрів, щоб правильно відстежувати, змінювати та скидати параметри. Віджети Lockscreen використовують деякі для відображення шпалер під ними, серед іншого.

Більшості розробників не потрібен доступ до прихованих API, але іноді вони можуть бути дуже корисними.

З випуском Android 9 (Pie) Google представив прихований чорний список API. Не всі приховані API були включені, і були різні рівні списків. Будь-хто може отримати доступ до прихованих API у білому списку. Будь-яка програма може отримати доступ до прихованих API у світло-сірому списку, але вони можуть бути недоступні в майбутніх версіях Android. До будь-якого темно-сірого списку могли отримати доступ лише програми, націлені на рівні API до Pie (тобто до рівня API 28). Додаткам, націленим на Pie і пізнішим, буде заборонено доступ. Нарешті, до прихованих API у чорному списку не може отримати доступ жодна несистемна (або не внесена до білого списку) програма, незалежно від цільового API.

Android 10 змінив спосіб організації списків і трохи спростив їх, але ідея залишилася незмінною. Програми могли отримати доступ до певних прихованих API, тоді як інші були заблоковані. Android 11 посилено виявлення доступу до блокувати обхід використовується для Pie і 10.

У всіх версіях Android щоразу, коли програма третьої сторони намагається отримати доступ до прихованого API з чорного списку, Android видасть відповідну помилку «не знайдено».

Насправді існує чимало способів подолати прихований чорний список API. Залежно від ваших потреб ви можете вибрати ті, які працюють для всіх версій Android, ті, які працюють лише для Android 9 і 10, ті, які використовують рідний код C++, і ті, які повністю базуються на Java. Існує навіть обхідний шлях лише для розробки за допомогою ADB.

Обхідний шлях ADB

Якщо на вашому пристрої встановлено Android Pie, запустіть наступні дві команди ADB, щоб увімкнути прихований доступ до API.

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

Якщо ваш пристрій працює під керуванням Android 10 або новішої версії, виконайте наступну команду ADB, щоб увімкнути прихований доступ до API.

adb shell settings put global hidden_api_policy 1

Щоб повернутися до типової поведінки, просто замініть put з delete і видаліть 1.

Очевидно, що ці команди не дуже корисні для робочої програми. Я можу вам сказати з перших вуст, що належним чином навчити користувачів, як використовувати ADB, неймовірно важко. Але вони можуть бути корисними, якщо вам потрібно оновити стару програму, щоб відповідати новим обмеженням.

Рідний/JNI обхідний шлях

Існує два способи обійти прихований чорний список API за допомогою JNI у вашому додатку для Android. Один працює для Android 9 і 10, а інший працює для Android 9 і новіших версій.

Android 9 і 10

Якщо у вас уже є нативна частина вашої програми, це буде легко реалізувати. Просто використовуйте JNI_OnLoad() функція.

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

Майте на увазі, що цей метод працює лише на Android 9 і 10.

Android 9 і новіших версій

Для будь-якої версії Android у вас є вибір із двох бібліотек для обходу прихованих обмежень API: FreeReflection і RestrictionBypass.

Обидва прості у реалізації та використанні.

Щоб реалізувати FreeReflection, додайте залежність до вашого build.gradle на рівні модуля.

implementation 'me.weishu: free_reflection: 3.0.1'

Потім перевизначити attachBaseContext() у вашому класі програми.

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

Якщо у вас немає класу Application, ви можете додати його досить легко. Створіть новий клас, який розширюється Application а потім вкажіть на нього у своєму AndroidManifest.xml.

приклад:

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

Reflection.unseal(base);
}
}

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

Щоб реалізувати RestrictionBypass, додайте репозиторій JitPack до свого проекту build.gradle.

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

Потім додайте залежність у свій build.gradle на рівні модуля.

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

І це все. Ця бібліотека автоматично знімає обмеження чорного списку.

Обхідний шлях Java

Хоча рішення JNI є ефективними, бувають випадки, коли ви можете не захотіти використовувати рідний код. Якщо ви ще не працюєте на C++, ваш додаток може збільшити непотрібний розмір разом із обмеженнями платформи. На щастя, є способи обійти прихований чорний список API, використовуючи лише Java.

Android 9 і 10

В Android 9 і 10 ви можете використовувати те, що можна назвати подвійним відображенням або метавідображенням, щоб обійти прихований чорний список API. Оскільки система перевіряє лише те, що викликають програми сторонніх розробників, подвійне відображення змушує її думати, що система здійснює приховані виклики API.

Цей трюк можна використати для виклику методу, щоб надати вашій програмі приховані винятки API з влучною назвою setHiddenApiExemptions(). Просто додайте наступний код десь на початку життєвого циклу вашої програми (наприклад, програму onCreate() метод), і він обійде чорний список.

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

Якщо ваша програма сумісна з версіями Android, молодшими за 9, не забудьте завершити це перевіркою версії.

Android 9 і новіших версій

Щоб обійти прихований чорний список API на Android 9 і будь-якій пізнішій версії, ви можете скористатися бібліотекою LSPosed. Ця бібліотека використовує небезпечний API Java, тому навряд чи вона коли-небудь зламається.

Щоб реалізувати це, просто додайте залежність до свого модуля build.gradle.

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

Потім використовуйте його, щоб обійти чорний список.

HiddenApiBypass.addHiddenApiExemptions("L");

Якщо ваша програма сумісна з версіями Android, молодшими за 9, не забудьте завершити це перевіркою версії.

Висновок та додаткова інформація

Існує багато варіантів обходу прихованого чорного списку API на Android, незалежно від того, яку версію платформи ви використовуєте. Якщо вам цікаво дізнатися більше про те, як працюють ці методи та бібліотеки, обов’язково перегляньте наступні посилання.

  • Мої запитання та відповіді Stack Overflow.
  • Бібліотека Hidden API Bypass LSposed на GitHub.
  • Бібліотека RestrictionBypass від ChickenHook на GitHub.
  • бібліотека FreeReflection від tiann на GitHub.
  • Документація Google про прихований чорний список API.