Розкриваємо, модифікуємо і запаковуємо Android-додатки

  1. Зміст статті Іноді деякі додатки на Android чимось не влаштовують користувача. Як приклад можна...
  2. декомпіляція додатків
  3. Пристрій APK-пакетів і їх отримання
  4. Перегляд і модифікація
  5. Препарування. відключаємо рекламу
  6. WARNING
  7. INFO
  8. підсумки

Зміст статті

Іноді деякі додатки на Android чимось не влаштовують користувача. Як приклад можна привести настирливу рекламу. А то буває і так - всім хороша програма, та тільки переклад в ній або кривої, або зовсім відсутній. Або, наприклад, програма тріальна, а отримати повну версію можливості немає. Як же змінити ситуацію?

Вступ

У цій статті ми поговоримо про те, як розібрати пакет APK з додатком, розглянемо його внутрішню структуру, дізассембліруем і декомпіліруем байт-код, а також спробуємо внести в додатку кілька змін, які можуть принести нам ту чи іншу вигоду.

Щоб зробити все це самостійно, будуть потрібні хоча б початкові знання мови Java, на якому пишуться програми для Android, і мови XML, який використовується в Android повсюдно - від опису самого додатка і його прав доступу до зберігання рядків, які будуть виведені на екран. Також знадобиться вміння поводитися зі спеціалізованим консольним софтом.

Отже, що ж являє собою пакет APK, в якому поширюється абсолютно весь софт для Android?

декомпіляція додатків

У статті ми працювали тільки з дизасемблювати кодом програми, однак якщо в великі програми вносити більш серйозні зміни, розібратися в коді smali буде набагато складніше. На щастя, ми можемо декомпілювати код dex в Java-код, який буде хоч і не оригінальним і не компільовані назад, але набагато більш легким для читання і розуміння логіки роботи програми. Щоб зробити це, нам знадобляться два інструменти:

  • dex2jar - транслятор байт-коду Dalvik в байт-код JVM, на основі якого ми зможемо отримати код на мові Java ;
  • jd-gui - сам декомпілятор, що дозволяє отримати з байт-коду JVM читається код Java . В якості альтернативи можна використовувати Jad (www.varaneckas.com/jad); хоч він і досить старий, але в деяких випадках генерує більше читається код, ніж Jd-gui.

Використовувати їх слід так. Спочатку запускаємо dex2jar, вказуючи в якості аргументу шлях до apk-пакета:

% Dex2jar.sh mail.apk

В результаті в поточному каталозі з'явиться Java-пакет mail.jar, який вже можна відкрити в jd-gui для перегляду Java-коду.

Пристрій APK-пакетів і їх отримання

Пакет додатки Android, по суті, є звичайним ZIP-файлом, для перегляду вмісту і розпакування якого ніяких спеціальних інструментів не потрібно. Досить мати архіватор - 7zip для Windows або консольний unzip в Linux. Але це що стосується обгортки. А що всередині? Усередині ж у нас в загальному випадку така структура:

  • META-INF / - містить цифровий сертифікат програми, що засвідчує його творця, і контрольні суми файлів пакета;
  • res / - різні ресурси, які додаток використовує в своїй роботі, наприклад зображення, декларативне опис інтерфейсу, а також інші дані;
  • AndroidManifest.xml - опис програми. Сюди входить, наприклад, список необхідних дозволів, необхідна версія Android і необхідний дозвіл екрана;
  • classes.dex - компілює байт-код додатка для віртуальної машини Dalvik;
  • resources.arsc - теж ресурси, але іншого роду - зокрема, рядки (так-так, цей файл можна використовувати для русифікації!).

Перераховані файли і каталоги є якщо не у всіх, то, мабуть, в абсолютній більшості APK. Однак варто згадати ще кілька не таких поширених файлів / каталогів:

  • assets - аналог ресурсів. Основна відмінність - для доступу до ресурсу необхідно знати його ідентифікатор, список asset'ов ж можна отримувати динамічно, використовуючи метод AssetManager.list () в коді програми;
  • lib - нативні Linux-бібліотеки, написані за допомогою NDK (Native Development Kit).

Цей каталог використовують виробники ігор, поміщаючи туди движок гри, написаний на C / C ++, а також творці високопродуктивних додатків (наприклад, Google Chrome). З пристроєм розібралися. Але як же отримати сам файл пакета цікавить програми? Оскільки без рута з пристрою забрати файли APK не представляється можливим (вони лежать в каталозі / data / app), а рутіть не завжди доцільно, є як мінімум три способи отримати файл додатка на комп'ютер:

Який з них використовувати - справа смаку; ми вважаємо за краще використовувати окремі додатки, тому опишемо використання Real APK Leecher, тим більше що написаний він на Java і, відповідно, працювати буде хоч в винде, хоч в Нікс.

Після запуску програми необхідно заповнити три поля: Email, Password і Device ID - і вибрати мову. Перші два - e-mail і пароль твого гуглоаккаунта, який ти використовуєш на пристрої. Третій же є ідентифікатором пристрою, і його можна отримати, набравши на номеронабирачі код # # 8255 # # і потім знайшовши рядок Device ID. При заповненні треба ввести тільки ID без префікса android-.

При заповненні треба ввести тільки ID без префікса android-

Налаштування Real APK Leecher

Після заповнення та збереження нерідко вискакує повідомлення "Error while connecting to server». Воно не має відношення до Google Play, тому сміливо його ігноруй і шукай цікавлять тебе пакети.

Перегляд і модифікація

Припустимо, ти знайшов цікавий для тебе пакет, скачав, розпакував ... і при спробі перегляду якого-небудь XML-файла з подивом виявив, що файл не текстовий. Чим же його декомпілювати і як взагалі працювати з пакетами? Невже необхідно ставити SDK? Ні, SDK ставити зовсім не обов'язково. Насправді для всіх кроків з розпакування, модифікації і упаковці пакетів APK потрібні такі інструменти:

  • архіватор ZIP для розпакування і запаковування;
  • smali - асемблер / дизассемблер байт-коду віртуальної машини Dalvik ( code.google.com/p/smali );
  • aapt - інструмент для запаковування ресурсів (за замовчуванням ресурси зберігаються в бінарному вигляді для оптимізації продуктивності програми). Входить до складу Android SDK, але може бути отриманий і окремо;
  • signer - інструмент для цифрового підпису модифікованого пакета ( bit.ly/Rmrv4M ).

Використовувати всі ці інструменти можна і окремо, але це незручно, тому краще скористатися більш високорівневих софтом, побудованим на їх основі. Якщо ти працюєш в Linux або Mac OS X, то тут є інструмент під назвою apktool . Він дозволяє розпаковувати ресурси в оригінальний вид (в тому числі бінарні XML- і arsc-файли), збирати заново пакет зі зміненими ресурсами, але не вміє підписувати пакети, так що запускати утиліту signer доведеться вручну. Незважаючи на те що утиліта написана на Java, її установка досить нестандартна. Спочатку слід отримати сам jar-файл:

$ Cd / tmp $ wget http://bit.ly/WC3OCz $ tar -xjf apktool1.5.1.tar.bz2

Далі нам знадобиться скрипт-обв'язка для запуску apktool (він, до речі, доступний і для Windows), що включає в себе ще й утиліту aapt, яка знадобиться для запаковування пакета:

$ Wget http://bit.ly/WRjEc7 $ tar -xjf apktool-install-linux-r05-ibot.tar.bz2

Далі просто звалюємо вміст обох архівів в каталог ~ / bin і додаємо його в $ PATH:

$ Mv apktool.jar ~ / bin $ mv apktool-install-linux-r05-ibot / * ~ / bin $ export PATH = ~ / bin: $ PATH

Якщо ж ти працюєш в Windows, то для неї є чудовий інструмент під назвою Virtuous Ten Studio , Який також акумулює в собі всі ці інструменти (включаючи сам apktool), але замість CLI-інтерфейсу надає користувачеві інтуїтивно зрозумілий графічний інтерфейс, за допомогою якого можна виконувати операції з розпакування, дизассемблирования і декомпіляцію в кілька кліків. Інструмент цей Donation-ware, тобто іноді з'являються віконця з пропозицією отримати ліцензію, але це, врешті-решт, можна і потерпіти. Описувати його не має ніякого сенсу, тому що розібратися в інтерфейсі можна за кілька хвилин. А ось apktool, внаслідок його консольної природи, слід обговорити докладніше.

А ось apktool, внаслідок його консольної природи, слід обговорити докладніше

Імпорт APK в Virtuous Ten Studio

Розглянемо опції apktool. Якщо коротко, то є три основні команди: d (decode), b (build) та if (install framework). Якщо з першими двома командами все зрозуміло, то що робить третя, умовний оператор? Вона розпаковує вказаний UI-фреймворк, який необхідний в тих випадках, коли ти препаріруешь будь-якої системний пакет.

Розглянемо найбільш цікаві опції першої команди:

  • -s - НЕ дизасемблювати файли dex;
  • -r - НЕ розпаковувати ресурси;
  • -b - не вставляти зневадження в результати дизассемблирования файлу dex;
  • -Frame-path - використовувати вказаний UI-фреймворк замість вбудованого в apktool. Тепер розглянемо пару опцій для команди b:
  • -f - форсована збірка без перевірки змін;
  • -a - вказуємо шлях до aapt (засіб для складання APK-архіву), якщо ти з якоїсь причини хочеш використовувати його з іншого джерела.

Користуватися apktool дуже просто, для цього достатньо вказати одну з команд і шлях до APK, наприклад:

$ Apktool d mail.apk

Після цього в каталозі mail з'являться всі витягнуті і аналізувати код файли пакета.

Препарування. відключаємо рекламу

Теорія - це, звичайно, добре, але навіщо вона потрібна, якщо ми не знаємо, що робити з розпакованим пакетом? Спробуємо застосувати теорію з користю для себе, а саме модифікуємо якусь софтину так, щоб вона не показувала нам рекламу. Для прикладу нехай це буде Virtual Torch - віртуальний факел. Для нас ця софтина підійде ідеально, тому що вона під зав'язку набита дратівливою рекламою і до того ж досить проста, щоб не загубитися в нетрях коду.

Для нас ця софтина підійде ідеально, тому що вона під зав'язку набита дратівливою рекламою і до того ж досить проста, щоб не загубитися в нетрях коду

Пошук коду реклами в jd-gui

Отже, за допомогою одного з наведених способів скачай додаток з маркету . Якщо ти вирішив використовувати Virtuous Ten Studio, просто відкрий APK-файл в додатку і розпакуйте його, для чого створи проект (File -> New project), потім в контекстному меню проекту вибери Import File. Якщо ж твій вибір припав на apktool, то досить виконати одну команду:

$ Apktool d com.kauf.particle.virtualtorch.apk

Після цього в каталозі com.kauf.particle.virtualtorch з'явиться файлове дерево, схоже на описане в попередньому розділі, але з додатковим каталогом smali замість dex-файлів і файлом apktool.yml. Перший містить дизасемблювати код виконуваного dex-файлу програми, другий - службову інформацію, необхідну apktool для зборки пакета назад.

Перше місце, куди ми повинні заглянути, - це, звичайно ж, AndroidManifest.xml. І тут ми відразу зустрічаємо наступний рядок:

<Uses-permission android: name = "android.permission.INTERNET" />

Неважко здогадатися, що вона відповідає за надання додатком повноважень на використання інтернет-з'єднання. По суті, якщо ми хочемо просто позбутися від реклами, нам, швидше за все, досить буде заборонити додатком інтернет. Спробуємо це зробити. Видаляємо зазначений рядок і пробуємо зібрати софтину за допомогою apktool:

$ Apktool b com.kauf.particle.virtualtorch

В каталозі com.kauf.particle.virtualtorch / build / з'явиться результуючий APK-файл. Однак встановити його не вийде, так як він не має цифрового підпису та контрольних сум файлів (в ньому просто немає каталогу META-INF /). Ми повинні підписати пакет за допомогою утиліти apk-signer. Запустили. Інтерфейс складається з двох вкладок - на першій (Key Generator) створюємо ключі, на другий (APK Signer) підписуємо. Щоб створити наш приватний ключ, заповнюємо наступні поля:

  • Target File - вихідний файл сховища ключів; в ньому зазвичай зберігається одна пара ключів;
  • Password і Confirm - пароль для сховища;
  • Alias - ім'я ключа в сховище;
  • Alias password і Confirm - пароль секретного ключа;
  • Validity - термін дії (в роках). Значення за замовчуванням оптимально.

Решта поля, в общем-то, не є обов'язковими - але необхідно заповнити хоча б одне.

Решта поля, в общем-то, не є обов'язковими - але необхідно заповнити хоча б одне

Створення ключа в apk-signer

WARNING

Щоб підписати додаток за допомогою apk-signer, ти повинен встановити Android SDK і вказати повний шлях до нього в налаштуваннях програми.

Вся інформація надана виключно в ознайомлювальних цілях. Ні редакція, ні автор не несуть відповідальності за будь-можливу шкоду, заподіяну матеріалами даної статті.

Тепер цим ключем можна підписати APK. На вкладці APK Signer вибираємо тільки що згенерований файл, вводимо пароль, алиас ключа і пароль до нього, потім знаходимо файл APK і сміливо тиснемо кнопку «Sign». Якщо все пройде нормально, пакет буде підписаний.

INFO

Так як ми підписали пакет нашим власним ключем, він буде конфліктувати з оригінальним додатком, а це значить, що при спробі оновити софтину через маркет ми отримаємо помилку.

Цифровий підпис необхідна тільки сторонньому софту, тому якщо ти займаєшся модифікацією системних додатків, які встановлюються копіюванням в каталог / system / app /, то підписувати їх не потрібно.

Після цього скидаємо пакет на смартфон, встановлюємо і запускаємо. Вуаля, реклама зникла! Замість неї, однак, з'явилося повідомлення, що у нас немає інтернету або відсутні відповідні дозволи. За ідеєю, цього могло б і вистачити, але повідомлення виглядає дратівливо, та й, якщо чесно, нам просто пощастило з тупим додатком. Нормально написана софтіна, швидше за все, уточнить свої повноваження або перевірить наявність інтернет-з'єднання і в іншому випадку просто відмовиться запускатися. Як бути в цьому випадку? Звичайно, правити код.

Зазвичай автори додатків створюють спеціальні класи для виведення реклами і викликають методи цих класів під час запуску програми або однієї з його «активностей» (спрощено кажучи, екранів додатка). Спробуємо знайти ці класи. Йдемо в каталог smali, далі com (в org лежить тільки відкрита графічна бібліотека cocos2d), далі kauf (саме туди, тому що це ім'я розробника і там лежить весь його код) - і ось він, каталог marketing. Всередині знаходимо купу файлів з розширенням smali. Це класи, і найбільш примітний з них клас Ad.smali, за назвою якого неважко здогадатися, що саме він виводить рекламу.

Ми могли б змінити логіку його роботи, але набагато простіше буде тупо прибрати виклики будь-яких його методів з самого додатка. Тому виходимо з каталогу marketing і йдемо в сусідній каталог particle, а потім в virtualtorch. На особливу увагу тут заслуговує файл MainActivity.smali. Це стандартний для Android клас, який створюється Android SDK і встановлюється в якості точки входу в додаток (аналог функції main в Сі). Відкриваємо файл на редагування.

Всередині знаходиться код smali (місцевий асемблер). Він досить заплутаний і важкий для читання в силу своєї низкоуровневой природи, тому ми не будемо його вивчати, а просто знайдемо всі згадки класу Ad в коді і закомментіруем їх. Забиваємо рядок «Ad» в пошуку і потрапляємо на рядок 25:

.field private ad: Lcom / kauf / marketing / Ad;

Тут створюється поле ad для зберігання об'єкта класу Ad. Коментуємо за допомогою установки знака ### перед рядком. Продовжуємо пошук. Рядок 423:

new-instance v3, Lcom / kauf / marketing / Ad;

Тут відбувається створення об'єкта. Коментуємо. Продовжуємо пошук і знаходимо в рядках 433, 435, 466, 468, 738, 740, 800 і 802 звернення до методів класу Ad. Коментуємо. Начебто все. Зберігаємо. Тепер пакет необхідно зібрати назад і перевірити його працездатність і наявність реклами. Для чистоти експерименту повертаємо віддалену з AndroidManifest.xml рядок, збираємо пакет, підписуємо і встановлюємо.

Наш піддослідний кролик. видно реклама Наш піддослідний кролик Він же, але вже без реклами

Оп-па! Реклама пропала тільки під час роботи програми, але залишилася в головному меню, яке ми бачимо, коли запускаємо софтину. Так, почекайте, але ж точка входу - це клас MainActivity, а реклама зникла під час роботи програми, але залишилася в головному меню, значить, точка входу інша? Щоб виявити справжню точку входу, знову відкриваємо файл AndroidManifest.xml. І так, в ньому є такі рядки:

<Activity android: label = "@ string / app_name" android: name = ". Start" android: screenOrientation = "portrait"> <intent-filter> <action android: name = "android.intent.action.MAIN" /> <category android: name = "android.intent.category.LAUNCHER" /> </ intent-filter> </ activity>

Вони кажуть нам (і, що важливіше, андроиду) про те, що активність з ім'ям Start повинна бути запущена у відповідь на генерацію ІНТЕНТ (події) android.intent.action.MAIN з категорії android.intent.category.LAUNCHER. Ця подія генерується при тапе на іконку програми в ланчера, тому воно і визначає точку входу, а саме клас Start. Швидше за все, програміст спочатку написав додаток без головного меню, точкою входу в яке був стандартний клас MainActivity, а потім додав нове вікно (активність), що містить меню і описане в класі Start, і вручну зробив його точкою входу.

Відкриваємо файл Start.smali і знову шукаємо рядок «Ad», знаходимо в рядках 153 і 155 згадка класу FirstAd. Він теж є в исходниках і, судячи з назви, як раз і відповідає за показ оголошень на головному екрані. Дивимося далі, йде створення екземпляра класу FirstAd і ІНТЕНТ, по контексту має відношення до цього примірника, а далі мітка cond_10, умовний перехід на яку здійснюється якраз перед створенням екземпляра класу:

if-ne p1, v0,: cond_10 .line 74 new-instance v0, Landroid / content / Intent; ...: cond_10

Швидше за все, програма якимось випадковому чином обчислює, чи потрібно показувати рекламу на головному екрані, і, якщо немає, перескакує відразу на cond_10. Ок, спростимо їй завдання і замінимо умовний перехід на безумовний:

# If-ne p1, v0,: cond_10 goto: cond_10

Більше згадок FirstAd в коді немає, тому закриваємо файл і знову збираємо наш віртуальний факел з допомогою apktool. Копіюємо на смартфон, встановлюємо, запускаємо. Вуаля, вся реклама зникла, з чим нас усіх і вітаємо.

підсумки

Ця стаття лише короткий вступ в методи розтину і модифікації Android-додатків. За кадром залишилися багато питань, такі як зняття захисту, розбір обфусцірованного коду, переклад і заміна ресурсів програми, а також модифікація додатків, написаних з використанням Android NDK. Однак, маючи базові знання, розібратися у всьому цьому - лише питання часу.

Як же змінити ситуацію?
Отже, що ж являє собою пакет APK, в якому поширюється абсолютно весь софт для Android?
А що всередині?
Але як же отримати сам файл пакета цікавить програми?
Чим же його декомпілювати і як взагалі працювати з пакетами?
Невже необхідно ставити SDK?
Якщо з першими двома командами все зрозуміло, то що робить третя, умовний оператор?
Як бути в цьому випадку?
Так, почекайте, але ж точка входу - це клас MainActivity, а реклама зникла під час роботи програми, але залишилася в головному меню, значить, точка входу інша?