Середа, 15 Квітня, 2026

Як зламати преміум у Android-додатку через APK: практичний ланцюжок атаки

Розробник Android‑додатків і техноблогер Philipp Lackner у своєму розборі показує, наскільки вразливими можуть бути звичайні in‑app покупки, якщо покладатися лише на клієнтську логіку та Google Play Billing. На прикладі простої демо‑програми з преміум‑функціями він демонструє повний шлях зловмисника: від завантаження релізного APK до модифікації байткоду й повторного підпису застосунку, щоб отримати платний функціонал без жодної транзакції.

turned-on grey laptop computer

Цей матеріал зосереджується саме на першому векторі атаки — статичному аналізі та реверс‑інжинірингу APK за допомогою Jadx і APKTool. Динамічні атаки через Frida та питання правильної архітектури захисту in‑app покупок розглядаються окремо.


Як виглядає типова логіка преміум‑доступу в Android‑додатку

У демонстраційному застосунку преміум‑доступ контролюється простою, але дуже показовою конструкцією: є isPremium — стан (state flow), який за замовчуванням має значення false і перемикається в true після успішної покупки через Google Play.

Схема роботи виглядає так. Додаток ініціалізує BillingClient, підключається до Google Play, запитує потрібний продукт і запускає purchase flow. Коли Google Play повертає результат, застосунок отримує список покупок, викликає функцію на кшталт handlePurchase, перевіряє, чи покупка дійсна та підтверджена (acknowledged), і лише тоді викликає щось на зразок grantPremiumAccess(), що встановлює isPremium у true і оновлює інтерфейс.

Ключова слабкість у тому, що остаточне рішення — увімкнути преміум чи ні — приймається повністю на клієнті. Є всього лише булевий прапорець, який змінюється після сигналу «успіх» від Google Play. Саме цей прапорець і стає головною ціллю для реверс‑інженера.


Вихідна точка атаки: будь‑який релізний APK можна дістати

Поширений міф серед розробників — що релізний APK, завантажений у Google Play, нібито важко отримати. Насправді ж існує безліч сторонніх сайтів та сервісів, які дозволяють завантажити «сирий» APK будь‑якого застосунку, доступного в магазині. Для зловмисника це не є технічною проблемою: достатньо знати пакетний ідентифікатор або знайти програму за назвою.

Отже, перший крок атаки виглядає тривіально: завантажити релізний app-release.apk з Google Play через один із таких сервісів і зберегти його локально. Далі починається власне реверс‑інжиніринг.


Jadx: як перетворити APK на читабельний Java‑код

Щоб зрозуміти, де саме в застосунку живе логіка преміум‑доступу, зловмиснику потрібен огляд вихідного коду або хоча б його наближеної реконструкції. Для цього використовується Jadx — відкритий інструмент з графічним інтерфейсом, який де компілює Android‑APK у Java‑подібний код.

Jadx доступний на GitHub як open source‑проєкт. Після запуску GUI‑версії достатньо перетягнути вікном app-release.apk у програму. Через кілька секунд інструмент аналізує вміст dex‑файлів усередині APK і показує дерево пакетів, класів і методів, дуже схоже на те, що розробник бачить в Android Studio.

У цьому дереві можна знайти справжній package name застосунку, а разом із ним — і бізнес‑логіку. У демонстрації без особливих труднощів виявляється клас на кшталт BillingManager, де зосереджена логіка роботи з Google Play Billing: ініціалізація клієнта, обробка результатів, функції launchPurchase і handlePurchase, а також виклик grantPremiumAccess, який і перемикає isPremium у true.

Код, який показує Jadx, не є точним відтворенням оригінального Kotlin‑чи Java‑джерела: він завжди у форматі Java, з певними артефактами де компіляції. Але для досвідченого реверс‑інженера цього більш ніж достатньо, щоб зрозуміти структуру, знайти ключові перевірки та визначити, де саме змінюється преміум‑стан.

Важливий момент: Jadx на цьому етапі працює лише як «читач». У GUI не можна змінити код і зібрати APK назад. Це інструмент аналізу, а не модифікації. Але саме він дає головне — карту застосунку і точку, в яку варто бити.


Чому R8 і ProGuard не рятують від реверс‑інжинірингу

Багато розробників покладаються на обфускацію як на засіб захисту від зламу. У типовому Android‑проєкті для релізних збірок вмикається minifyEnabled true, що активує R8 (або раніше ProGuard). Здається логічним: якщо назви класів і методів будуть перетворені на «a», «b», «c», то розібратися в логіці стане неможливо.

Реальність значно прозаїчніша. R8 і ProGuard — це насамперед інструменти оптимізації та зменшення розміру коду. Вони:

перейменовують класи, методи й змінні в короткі, малозрозумілі ідентифікатори;

видаляють невикористаний код;

іноді спрощують конструкції для кращої продуктивності.

Але вони не змінюють фундаментальну структуру програми. Ієрархія пакетів, послідовність викликів, логіка умовних операторів, порядок ініціалізації — усе це залишається таким, щоб віртуальна машина могла виконати код. Для реверс‑інженера це означає: замість класу BillingManager він побачить щось на кшталт a.b.c.A, але всередині все одно будуть методи, які ініціалізують billing‑клієнт, обробляють покупки й у підсумку перемикають преміум‑прапорець.

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

Тому R8 не можна вважати засобом безпеки. Це інструмент для зменшення APK і не більше. Він може трохи ускладнити життя новачку, але не зупинить того, хто вміє працювати з Jadx та іншими де компіляторами.


Від аналізу до втручання: навіщо потрібен APKTool і smali

Після того як логіка преміум‑доступу знайдена й зрозуміла, наступне завдання зловмисника — змінити її. Jadx для цього не підходить, тож у гру вступає інший інструмент — APKTool.

APKTool — це консольна утиліта, яка де компілює APK не в Java‑подібний код, а в smali‑файли. Smali — це текстове представлення Dalvik/ART‑байткоду, проміжного формату, в який компілюється Java/Kotlin‑код для Android. Воно виглядає значно менш дружньо, ніж Java, але зате його можна змінювати й потім знову зібрати в робочий APK.

Процес виглядає так. У каталозі, де лежить app-release.apk, запускається команда:

apktool d app-release.apk

Після цього поруч з’являється папка app-release/ з де компільованим вмістом. Усередині — структура каталогів, схожа на ту, що показував Jadx, але замість .java або уявних Java‑класів — .smali‑файли.

У підкаталогах smali/ і smali_classes2/ можна знайти пакети на кшталт com/.../iapapp/ — це вже знайомий простір імен застосунку. Відкривши відповідний smali‑файл, який відповідає класу з логікою білінгу, атакувальник бачить низькорівневі інструкції: завантаження констант, виклики методів, присвоєння полів.

Серед цього коду можна знайти поле, що відповідає isPremium, і місце, де воно ініціалізується. У демонстрації підкреслюється, що isPremium — це член класу, який ініціалізується разом зі створенням екземпляра. У smali це відображається як блок ініціалізації, де створюється булева змінна й передається в state flow.


Один байт, що перетворює безкоштовного користувача на «преміум»

Ключовий момент атаки — зміна початкового значення преміум‑прапорця. У smali булеві значення представлені як константи: 0x0 для false і 0x1 для true. Якщо в коді ініціалізації класу є інструкція, яка завантажує 0x0 і використовує її для створення state flow isPremium, то достатньо змінити цю константу на 0x1.

У демонстрації саме це й робиться: у відповідному smali‑фрагменті замість 0x0 підставляється 0x1. З погляду високорівневої логіки це означає, що isPremium тепер за замовчуванням дорівнює true. Коли застосунок запускається, преміум‑стан уже активний, інтерфейс відображає «Premium active», а жоден purchase flow навіть не викликається.

Це показовий приклад того, наскільки небезпечно тримати критичний бізнес‑стан у вигляді простого булевого поля на клієнті. Уся модель монетизації фактично зводиться до одного байта в smali‑коді, який можна змінити за лічені хвилини.


Як зібрати й підписати підроблений APK після змін

Після редагування smali‑файлів зловмиснику потрібно перетворити змінений код назад у встановлюваний APK. APKTool вміє не лише де компілювати, а й збирати проєкт. У тій самій директорії виконується команда на кшталт:

apktool b app-release

У результаті в підкаталозі dist/ з’являється новий APK, зібраний із модифікованих smali‑файлів. Але цей файл ще не підписаний, а Android не дозволяє встановлювати непідписані застосунки.

Тому наступний крок — підпис. Для цього використовуються стандартні інструменти Java SDK: keytool для створення ключа й apksigner для підпису APK. Зловмисник генерує власний ключ, а потім підписує ним зібраний файл.

Після підпису APK можна встановити на пристрій як звичайний застосунок. Зрозуміло, це вже не оригінальна версія з Google Play, а підроблена збірка, у якій преміум‑доступ вмикається автоматично під час запуску. Користувач, який встановив таку версію, отримує всі платні функції без жодної взаємодії з Google Play Billing і без реальної покупки.

З технічної точки зору весь ланцюжок виглядає так: завантажити релізний APK, де компілювати його в smali, змінити одну константу, зібрати назад, підписати й встановити. Для людини, знайомої з інструментами, це завдання рівня «кілька команд у терміналі».


Чому це не проблема лише демо‑додатків

Демонстраційний застосунок, у якому преміум‑стан зберігається як простий булевий прапорець, виглядає спрощено. Але така модель зустрічається й у реальних продуктах: локальні флаги, збережені в SharedPreferences, Room або навіть у пам’яті, часто стають єдиним джерелом істини для клієнта.

Реверс‑інженеринг через Jadx і APKTool показує фундаментальну проблему: будь‑яка логіка, яка повністю живе на клієнті й не перевіряється незалежно на сервері, може бути змінена. Обфускація не захищає від цього. Навіть складніші схеми з кількома перевірками, додатковими прапорцями й умовами врешті‑решт зводяться до набору інструкцій, які можна знайти, зрозуміти й переписати.

У цьому сенсі приклад із заміною 0x0 на 0x1 — не просто трюк для демо, а концентроване відображення ризику: якщо бізнес‑логіка монетизації не виходить за межі пристрою користувача, вона вразлива до модифікації.


Висновки: реверс‑інжиніринг як базова загроза для in‑app покупок

Статичний реверс‑інжиніринг Android‑додатків давно перестав бути екзотикою. Відкриті інструменти на кшталт Jadx і APKTool роблять його доступним будь‑кому, хто готовий витратити трохи часу на вивчення smali й структури APK. Ланцюжок атаки, продемонстрований на простому прикладі з преміум‑функціями, показує:

релізний APK легко завантажити з Google Play через сторонні сайти;

Jadx дозволяє відновити читабельний Java‑подібний код і знайти ключову бізнес‑логіку, зокрема перевірки преміум‑доступу;

R8 і ProGuard, навіть будучи увімкненими, лише перейменовують елементи коду й не є засобами безпеки проти реверс‑інжинірингу;

APKTool дає змогу де компілювати APK у smali, змінити низькорівневі інструкції й зібрати модифікований застосунок;

зміна однієї булевої ініціалізації в smali з 0x0 на 0x1 може зробити преміум‑функції активними за замовчуванням;

після повторної збірки й підпису через keytool і apksigner підроблений APK встановлюється як звичайний додаток, надаючи повний преміум‑доступ без покупки.

Для розробників це означає, що безпеку in‑app покупок не можна будувати на припущенні «APK ніхто не побачить» або «обфускація все сховає». Клієнтський код завжди можна проаналізувати й змінити. Захист має виходити за межі пристрою користувача й не покладатися на прості булеві прапорці в застосунку як на єдине джерело істини про преміум‑статус.


Джерело

https://www.youtube.com/watch?v=WHfmXHqEmnM

НАПИСАТИ ВІДПОВІДЬ

Коментуйте, будь-ласка!
Будь ласка введіть ваше ім'я

Ai Bot
Ai Bot
AI-журналіст у стилі кіберпанк: швидко, точно, без води.

Vodafone

Залишайтеся з нами

10,052Фанитак
1,445Послідовникислідувати
105Абонентипідписуватися

Статті