О чем статья
В этом статье я сжато, без «воды», расскажу как отлаживать приложения для Android не имея их исходного кода на Java. Статья не совсем для новичков. Она пригодиться прежде всего тем кто более или менее понимает синтаксис Smali и имеет некоторый опыт в reversing engineering приложений для Android.
Инструменты
Нам понадобится Apk-tool 1.4.1 и NetBeans 6.8. Да-да, именно эти древние версии! С более новыми версиями отладка к сожалению «не заводится», о чем уже неоднократно упоминалось в различных обсуждениях (см. например тут и тут).
На установке подробно не останавливаюсь. NetBeans устанавливается по умолчанию, просто запускам инсталляцию и кликаем Next-Next-Next. Установка Apk-tools заключается в обычной распаковке файла apktool.jar
в любую папку.
Отладка
В этом разделе дана пошаговая инструкция. Она писалась для Windows, но вероятно сработает и на Linux и Mac OS. Черновик этой инструкции на английском также есть у меня в блоге, но ссылку не дам, ибо правила. Эта инструкция более или менее повторяет оригинальную инструкцию с Apk-tool wiki, однако содержит некоторые дополнительные пункты, без которых отладка может «не завестись». В своё время у меня не заводилась, и я нашел эти дополнительные пункты методом усиленного гугления и «научного тыка». Надеюсь, теперь мой опыт кому-то сэкономит время.
Пожалуйста, следуйте инструкции в точности – это важно!
- Декодируйте свой .apk файл в директорию
out
с помощью Apk-tool. Для этого используйте опцию-d
:java -jar apktool.jar d -d my.app.apk out
В результате в директории
out/smali
у вас будет куча .java файлов с закомментированным Smali кодом внутри. Это нормально, так и должно быть. - Добавьте атрибут
android:debuggable="true"
в секцию<application>
файлаout/AndroidManifest.xml
- Соберите директорию
out
обратно в .apk файл:java -jar apktool.jar b -d out my.app.to.debug.apk
- Подпишите файл
my.app.to.debug.apk
и установите его на реальное устройство или эмулятор, на котором вы собираетесь его отлаживать. - Удалите директорию
out/build
(она может помешать создать проект на шаге 6 и 7). - Запустите NetBeans, кликните «File» -> «New Project». Выберите «Java» -> «Java Project with Existing Sources». Кликните «Next».
- Укажите
out
в качестве «Project Folder». Кликните «Next». - Добавьте директорию
out/smali
в список «Source Package Folder». Кликните «Next», а затем «Finish». В результате в проект будут добавлены те самые .java файлы с закомментированным Smali кодом внутри. - Запустите
my.app.to.debug.apk
на реальном устройстве или эмуляторе (если вы используете реальное устройство, то убедитесь что оно подключено к вашему компьютеры с помощью USB кабеля и ваша система его «видит»). - Запустите DDMS, найдите своё приложение в списке и кликните на него. Запомните информацию в последней колонке, это номер порта, обычно что-то вроде
86xx / 8700
". - В Netbeans кликните «Debug» -> «Attach Debugger» -> выберите «JPDA» и введите в поле «Port»
8700
(или какой там номер порта у вас был на предыдущем шаге). Остальные поля оставте без изменений. Кликните «OK». - Теперь вы можете отлаживать приложение: на панели Netbeans станет можно кликать на соответствующие кнопки
- Установите breakpoint на интересующую вас инструкцию (да-да, на одну из тех инструкция из закомментированного Smali кода внутри тех самых .java файлов о которых я уже дважды до этого упоминал). Помните, что вы не можете устанавливать breakpoints на строчки начинающиеся с ".", ":" или "#". Только на инструкции Smali кода!
- Сделайте что-нибудь в приложении, что бы ваша breakpoint сработала. После этого вы сможете делать пошаговую отладку, просматривать значения полей и переменных и т.д.
Вот и всё, если вкратце.
Подводные камни
Без подвоха тут конечно никак. Обычно всё идёт хорошо, строго по инструкции, аж до шага 13. А вот на шаге 13 люди часто ставят breakpoint в самом начале кода приложения: например в методе onCreate(...)
в activity с которой начинается выполнение приложения. Оно вроде бы и логично – если не совсем понятно откуда начинать отлаживать приложение, лучше начинать с самого начала. Однако в большинстве случаев дело не идёт. Отлаживаемое приложение работает себе как ни в чем не бывало, а подлый breakpoint в onCreate(...)
ни в какую не желает срабатывать.
Это происходит из-за того что мы подсоединяем отладчик к уже работающему приложению. Это значит код в начале приложения (например в том же методе onCreate в activity с которой начинается выполнение приложения) уже выполнился, и ставить на него breakpoint'ы как правило (хотя не всегда конечно) бесполезно. Более того, когда мы присоединяем отладчик к работающему приложению, оно не останавливается пока не сработает наш breakpoint или пока мы его сами не остановим – об этом моменте также стоит помнить.
Уважаемое читатели дало мне инвайт, и следующей статье я покажу пару трюков, которые позволяют отлаживать Java приложения для Android без исходного кода с самого начала, т.е. именно с того самого первого метода onCreate(...)
(или даже конструктора) в activity с которой начинается выполнение приложения.
Если есть вопросы – пожалуйста задавайте их в комментариях или в личных сообщениях. Постараюсь ответить по-возможности оперативно, но если буду тупить – пожалуйста наберитесь терпения. Постараюсь ответить всем.
Автор: dimakovalenko