R0 CREW

HowTo: Отладка Android APK с помощью Eclipse и DDMS

Оригинал: blog.dornea.nu

После нескольких часов дикого гугления, в поисках вменяемого руководства по отладке APK, решил написать этот мини-туториал по отладке Android APK используя Eclipse и DDMS. Ниже я буду использовать FakeBanker APK, который был исследован в прошлых статьях.

Делаем дамп APK

Прежде всего убедитесь в том, что у вас установлена последняя версия apktool. Свою версию я собрал сам:

# git clone git://github.com/iBotPeaches/Apktool.git
Cloning into 'Apktool'...    
remote: Counting objects: 9605, done.
remote: Compressing objects: 100% (3622/3622), done.
remote: Total 9605 (delta 4556), reused 9494 (delta 4502)
Receiving objects: 100% (9605/9605), 34.27 MiB | 3.89 MiB/s, done.
Resolving deltas: 100% (4556/4556), done.
Checking connectivity... done.

# cd Apktool
# ./gradlew build fatJar
[...]

Полученную свежую версию apktool мы будем использовать во всех последующих шагах:

# find . -name "apktool-cli.jar"
./brut.apktool/apktool-cli/build/libs/apktool-cli.jar

# cp ./brut.apktool/apktool-cli/build/libs/apktool-cli.jar /tmp

Теперь, когда мы подготовили наш основной инструмент, можно сдампить содержимое APK:

# java -jar /tmp/apktool-cli.jar d -d FakeBanker.apk -o source
I: Using Apktool 2.0.0-3d2e93-SNAPSHOT on FakeBanker.apk
I: Loading resource table...
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /home/victor/apktool/framework/1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...

После чего мы получим следующую структуру файлов:

tree -L 2 source 
source
├── AndroidManifest.xml
├── apktool.yml
├── original
│   ├── AndroidManifest.xml
│   └── META-INF
├── res
│   ├── drawable-hdpi
│   ├── drawable-ldpi
│   ├── drawable-mdpi
│   ├── drawable-xhdpi
│   ├── layout
│   ├── menu
│   ├── raw
│   └── values
└── smali
    ├── android
    └── com

14 directories, 3 files

Делаем APK отлаживаемым

После того, как мы сдампили APK его нужно пометить как отлаживаемый (debuggable). Существует несколько способов сделать это:

  • вручную
  • используя apktool

Если вы хотите сделать это в ручную, откройте AndroidManifest.xml и найдите там тэг application. Затем вставьте новый атрибут android:debuggable=’true’, как показано ниже:

...
<application android:theme="@style/AppTheme" android:label="@string/app_name" android:icon="@drawable/ic_launcher1" [B]android:debuggable="true"[/B] android:allowBackup="false">
...

Собираем новое приложение (APP)

Теперь мы готовы собрать наш отлаживаемый APK с помощью apktool:

java -jar /tmp/apktool-cli.jar b -d source FakeBanker.Debug.apk
I: Using Apktool 2.0.0-3d2e93-SNAPSHOT on source
I: Checking whether sources has changed...
I: Smaling smali folder into classes.dex...
I: Checking whether resources has changed...
I: Building resources...
Warning: AndroidManifest.xml already defines debuggable (in [url]http://schemas.android.com/apk/res/android);[/url] using existing value in manifest.
I: Building apk file...

Несколько объяснений относительно используемых параметров:

  • b - запуск apktool в режиме build;
  • -d - сделать APK отлаживаемым (это второй способ, о котором я упоминал раньше).

Извлечение исходного кода

Я буду использовать dex2jar для преобразования dex в jar, а JD-GUI для просмотра исходного java-кода из jar-файла.

Разархивируем наш FakeBanker.Debug.apk:

# unzip FakeBanker.Debug.apk -d unpacked
Archive:  FakeBanker.Debug.apk
 extracting: unpacked/res/drawable-hdpi/ic_launcher1.png  
 extracting: unpacked/res/drawable-hdpi/logo.png  
 extracting: unpacked/res/drawable-ldpi/ic_launcher1.png  
 extracting: unpacked/res/drawable-mdpi/ic_launcher1.png  
 extracting: unpacked/res/drawable-xhdpi/ic_launcher1.png  
  inflating: unpacked/res/layout/actup.xml  
  inflating: unpacked/res/layout/main.xml  
  inflating: unpacked/res/layout/main2.xml  
  inflating: unpacked/res/menu/main.xml  
 extracting: unpacked/res/raw/blfs.key  
  inflating: unpacked/res/raw/config.cfg  
  inflating: unpacked/AndroidManifest.xml  
  inflating: unpacked/classes.dex    
  inflating: unpacked/resources.arsc

Затем дадим dex2jar выполнить свою работу:

# cd unpacked
# dex2jar classes.dex
dex2jar classes.dex -> classes-dex2jar.jar

Теперь откройте jar-файл с помощью JD-GUI и сохраните исходный код как zip-архив:

Подпись APK

Для того чтобы загрузить ваш APK на устройство его нужно подписать. Я сделал это с помощью тестового сертификата и утилиты signapk.jar:

Скачайте signapk.jar:

# git clone [url]https://github.com/appium/sign[/url]
Cloning into 'sign'...
remote: Counting objects: 49, done.
remote: Total 49 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (49/49), done.
Checking connectivity... done.
И подпишите ваше приложение:
# java -jar sign/dist/signapk.jar sign/testkey.x509.pem sign/testkey.pk8 FakeBanker.Debug.apk FakeBanker.Debug.Signed.apk

Установка APK

Теперь, когда у нас есть подписанное приложение, его можно установить на устройство:

# adb devices -l  
List of devices attached 
emulator-5554          device product:sdk model:sdk device:generic
# adb install FakeBanker.Debug.Signed.apk

1628 KB/s (219033 bytes in 0.131s)
    pkg: /data/local/tmp/FakeBanker.Debug.Signed.apk
Success

Добавление исходного кода

Добавим java-код в структуру директории декомпилированного приложения:

# mkdir source/src
# unzip classes-dex2jar.src.zip -d source/src 
Archive:  classes-dex2jar.src.zip
   creating: source/src/android/
   creating: source/src/android/support/
...

Теперь новая структура будет выглядеть следующим образом:

# tree -L 2 source 
source
├── AndroidManifest.xml
├── apktool.yml
├── bin
│   ├── android
│   └── com
├── build
│   └── apk
├── dist
│   └── FakeBanker.apk
├── original
│   ├── AndroidManifest.xml
│   └── META-INF
├── res
│   ├── drawable-hdpi
│   ├── drawable-ldpi
│   ├── drawable-mdpi
│   ├── drawable-xhdpi
│   ├── layout
│   ├── menu
│   ├── raw
│   └── values
├── smali
│   ├── android
│   └── com
└── src
    ├── android
    └── com

23 directories, 4 files

Debug settings

Теперь нужно активировать настройки отладки для отлаживаемого приложения. Перейдите в Device Settings => Select debug app. Так же убедитесь, что у вас активирована опция Wait for debugger. Это предотвратит запуск приложения до того, как присоединиться отладчик.

Настройка Eclipse

Прежде всего убедитесь, что у вас установлен ADT вместе с Android SDK. Убедились? Тогда перейдем к созданию нового проекта.

Создание нового Java-проекта

Сначала создайте новый Java-проект и используйте source в качестве location для проекта.

Добавление папки src в build path

Убедитесь что папка src добавлена в качестве source location в build path.

Проверка свойств проекта (project properties)

Так же желательно проверить свойства проекта щелкнув на него и затем нажав ALT+Enter. У вас должно быть что-то вроде этого:

Ставим брэйкпоинты

После настройки Eclipse, давайте добавим несколько брэйкпойнтов. Сначала найдите onCreate во всех файлах:

В нашем случае, Eclipse нашел несколько совпадений:

Сосредоточимся на MainActivity.java и установим там брэйкпойнт:

Переключившись в Debug-перспективу вы должны увидеть ваши брэйкпойнты (помечены красным цветом):

Запуск приложения

Перед запуском нашего приложения давайте посмотрим на уже запущенные процессы на устройстве:

После запуска вашего приложения в AVD, вы заметите новый процесс:

Красный жук говорит о том, что процесс еще не отлаживался и приложение ждет, когда к нему присоединится какой-либо отладчик:

Debug configuration

Для того, чтобы иметь возможность отлаживать процесс, вам нужно добавить новую debug-конфигурацию:

При настройке конфигурации обратите особое внимание на порт с которым будет соединяться отладчик. Убедитесь в том, что он совпадает с портом, который мы видели ранее в запущенном списке процессов (помечено красным цветом):

Теперь нажмите на кнопку Debug и готовы к отладке приложения. Посмотрите на список запущенных процессов. Вы заметите, что в нем, что-то изменилось:

Теперь жук стал “зелёного цвета”. Это означает, что ваше приложение уже отлаживается.

Остановка на брэйкпойнте

Ранее мы установили брэйкпойнт на метод onCreate. Теперь, когда приложение выполняется, мне нужно “остановиться” на этом брэйкпойнте. Вернувшись в свой AVD я заполнил поля, которые требовало приложение и нажал Enter.

После этого я вернулся в Eclipse и получил следующую картину:

Выполнение приложения было остановлено на брэйкпойнте. Это успех! Теперь я нажал F6 (Step Over) и выполнение перешло дальше:

Заключение

Используя такие прекрасные инструменты как apktool и dex2jar можно подготовить ваш APK к динамическому исследованию в Eclipse. Я думаю Eclipse (наряду с ADT) является очень мощным инструментом, когда дело доходит до динамического анализа. Я могу легко переключаться между участками кода и анализировать ход выполнения программы. Имейте ввиду, что когда исходный код обфусцирован вы можете захотеть отлаживать smali-код. В этом случае убедитесь в том, что вы добавили smali директорию вместо src (описано ранее).

© Translated by Prosper-H from r0 Crew

Ссылки

1 Like