Карта сайта Хакер в RSS Энциклопедия Хакера PDA версия сайта Почтовые рассылки Хакера    Хакер в Twitter Хакер в ВКонтакте Приложение Хакер для Facebook Хакер на Formspring.me
Журнал Новости Форум Видео Life Xakep Live (блоги)
Bugtrack Статьи Блог Поиск English
Полный гид по накрутке онлайн-голосований Полный гид по накрутке онлайн-голосований
Конкурсы с голосованием привлекают большое количество посетителей, а трафик, как известно, — это деньги. Особый интерес вызывают конкурсы, где за победу предлагаются лакомые призы....
Итоги конкурса Group-IB Итоги конкурса Group-IB
Настало время подведения итогов нашего конкурса, который мы проводили совместно с компанией Group-IB, специализирующейся на расследовании инцидентов информационной безопасности....

SMS-сендер для Android: исследуем недра операционной системы с помощью дебаггера и не только

Bookmark and Share

Когда OS Android только появилась, многие, и я в том числе, мечтали, чтобы на нее как можно скорее портировали Qt. К сожалению, корпорация добра не оправдала наших надежд, сообщив, что SDK Андроида будет только на Java. Новость о покупке Trolltech корпорацией Nokia тоже не добавила оптимизма.

Спустя некоторое время к нам привалила нежданная радость — для Андроида вышел NDK для нативной разработки на C++, и, конечно же, нашлись люди, которые стали портировать Qt на Android. На данный момент порт уже более-менее юзабелен — работают (и почти не глючат) практически все модули. Ну что ж, посмотрим, какие возможности открывает нам этот порт.

Как оно работает?

Поначалу кажется, что данный порт — это очень большой костыль. Без Java все равно не обошлось — с помощью NDK нельзя создавать исполняемые файлы, можно только библиотеки .so. На Java, по сути, нужно написать всего одну строчку, которая загружает нашу библиотеку на Qt. Далее виртуальная машина Android запускает Java-приложение, которое, в свою очередь, грузит нашу либу.

Сборка QT

Весь процесс очень хорошо описан в Wiki проекта, но он содержит несколько граблей, поэтому кое-какие пояснения нам дать все же придется.

Небольшая оговорка — процесс описывается для Ubuntu 10.04, но на других дистрибутивах, в принципе, все должно происходить так же. А вот для того, чтобы провернуть это дело под виндой, тебе придется немного попрыгать с бубном (какая тонкая ирония, а?).

Итак, поехали:

Создаем директорию для SDK. Пишем в консоль:

wget http://android-lighthouse.googlecode.com/files/qadk-1.x-2.x-rtti-exceptions.tar.lzma
tar xvfa qadk-1.x-2.x-rtti-exceptions.tar.lzma

Клонируем репозиторий Lighthouse:

git clone git://gitorious.org/~taipan/qt/androidlighthouse.git

Редактируем файл mkspecs/android-g++/qmake.conf. В нем нужно изменить NDK_ROOT и ANDROID_PLATFORM (у меня — /data/local/qt и android-5 соответственно). Эти параметры отвечают за расположение собранной библиотеки и ее версию. Также нужно отредактировать файл androidconfig.sh. Настоятельно рекомендую заменить shared на static (для статической сборки библиотеки и приложений). Все, конфигурируем (./androidconfig.sh) и собираем (make -j X, где X — количество ядер твоего процессора).

Все? Не тут-то было! Не знаю, как обстоят дела с другими дистрибутивами, но на Ubuntu "make" вылетал с ошибкой, говорящей о недоступности заголовочных файлов OpenGL. Чего только я не предпринимал… Поставил все, что можно было, но решение оказалось куда проще — надо было просто переустановить имеющиеся в системе заголовочные файлы OpenGL. После этого можно повторять команду make -j X и идти… нет, не пить пиво, а курить мануалы по разработке под Android — информация лишней не бывает никогда, а собираться оно будет долго =).

Создание приложения

Запускай Qt Creator, создавай новое GUI-приложение. В нем (вернее, в файле .pro) нам нужно будет изменить несколько строчек. Они должны выглядеть так:

TEMPLATE = lib
CONFIG += dll

В настройках Qt Creator нужно также указать путь до нашего (андроидовского) qmake — у меня это /data/local/qt/bin/qmake.

Вообще, я бы посоветовал сначала дебажить приложение как десктопное и только потом изменять параметры сборки.

Кстати, я ведь еще не говорил, что за приложение мы будем писать? Это будет приложение для отправки СМС на номера самых различных операторов. Это возможно благодаря сервису smste.ru, который мы и будем использовать. Не буду вдаваться в подробности сниффинга, скажу только, что я использую для этих целей Wireshark.

Разберем алгоритм отправки сообщения:

  1. Делаем GET рута — главной страницы сайта, выдираем оттуда нужные нам значения input’ов (те, которые hidden), а заодно и кукисы.
  2. Запрашиваем капчу по номеру телефона и показываем ее пользователю.
  3. Отправляем POST-запрос с сообщением.

Для отправки HTTP-запросов в Qt существует класс QHttp. Кстати, не забудь подключить модуль QtNetwork (QT += network) в файле проекта!

Набросай форму (мою ты можешь увидеть на скриншоте) и приступай к кодингу.

От объекта http класса QHtpp нам требуются только два сигнала — done() и readyRead(). Сразу при создании главного виджета отправим GET-запрос главной страницы:

http.setHost("smste.ru");
http.get("/");

Сигнал done(), по сути, и не используется — по нему можно будет только опознать ошибку сетевого уровня (например, отключение Wi-Fi). Рассмотрим некоторые части слота onHttpReadyRead(const QHttpResponseHeader&resp):

QString str(http.readAll());
qint32 index=str.indexOf("value=\"code")+7;
if ( index != 6 )
codeMod = str.mid(index, str.indexOf("\" />", index) - index);

Здесь мы копируем "спрятанную" (hidden) переменную codeMod из исходника страницы. Идем дальше:

QString cookieStr;
for ( qint8 i = 0; i < resp.values().count(); i++ )
{
if ( resp.values().at(i).first == "Set-Cookie" ) cookieStr.append(resp.values().at(i).second+'\n');
}
cookies = QNetworkCookie::parseCookies(cookieStr.toAscii());

Ну, а в этом куске кода, как ты, наверное, догадался, мы парсим печеньки. cookies — это QList из QnetworkCookie.

qint32 index = str.indexOf("<image>/pix/") + 12;
image = str.mid(index,str.indexOf(".jpg") - index);
QHttpRequestHeader header = createHeader("GET",QString("/pix/%1.jpg").arg(image));
http.request(header);

Здесь копируется адрес капчи (запрос адреса я покажу чуть позже) и посылается запрос этого самого JPEG’а.

А вот так он сохраняется:

if ( resp.value("Content-Type") == "image/jpeg")
{
ui->captchaLb->setPixmap(QPixmap::fromImage(QImage::fromData(http.readAll())));
return;
}

Так, с этим слотом разобрались.

Капчу нужно запрашивать, как только пользователь введет номер телефона, то есть, когда закончится редактирование текста ui->numberLE. Для этого есть специальный слот:

void MainWidget::on_numberLE_editingFinished()
{
if ( ui->numberLE->text().length() != 11 )
return;
QHttpRequestHeader header = createHeader("GET", QString("/netxml.php?number=%1&rnd=94728").arg(ui->numberLE->text()));
http.request(header);
}

Функцию createHeader() смотри на врезке — она создает хедер HTTP-запроса (вообще, можно и проще, но нам надо отправлять еще и куки).

Создание HTTP-заголовка

QHttpRequestHeader MainWidget::createHeader(
const QString &method,
const QString &path
)
{
QHttpRequestHeader header(method, path);
header.addValue("Host", "smste.ru");
header.addValue("Connection", "keep-alive");
header.addValue("User-Agent", "Mozilla/5.0");
header.addValue("Referer", "http://smste.ru");
header.addValue("Accept", "*/*");
QString cookie;
for ( qint8 i = 0; i < cookies.length(); i++ )
cookie += ( cookies.at(i).toRawForm(QNetworkCookie::NameAndValueOnly) + "; ");
header.addValue("Cookie", cookie);
return header;
}

Остался последний слот — нажатие кнопки "Отправить", и он предельно прост:

QHttpRequestHeader header = createHeader("POST", "/");
header.addValue("", QString("number=%1& message=%2&sign=ax-soft.ru&event=%3& codemod=%4&%5=%6"). arg(ui->numberLE-> text()). arg(ui->textPTE->toPlainText()). arg(image). arg(codeMod). arg(codeMod). arg(ui->captchaLE->text()));
qDebug() << header.toString();
http.request(header);

Вот и все! Делай Build All, собирай .apk-пакет :).

Создание виртуальной машины

Для тестирования приложения нам нужно создать виртуальную машину. Кстати, надеюсь, у тебя установлена Java Runtime Environment? Если нет, то поставь, вещь нужная. Кроме того, для создания .apk-пакетов понадобится ant. Ставится он легко — sudo apt-get install ant. Теперь переходи в сабдиректорию tools в Android SDK и вводи ./android. Запустится менеджер настроек и виртуальных машин.

Сначала скачай нужные API (разобраться нетрудно, для этого примера нужна версия 8), далее переходи на вкладку Virtual Devices, жми New. В Name — любое имя, Target — Android 2.2, Skin — какой хочешь (я выбрал WVGA800), и нажимай Create AVD. Затем выбирай машину и жми Start, Launch. Все, будем ждать. На моем нетбуке оно запускалось около десяти минут, на десктопе — 1,5-2 минуты. Работает эмулятор так же медленно, как и запускается (ибо эмулирует ARM с помощью QEMU). С одной стороны это плохо, что все тормозит, а с другой стороны — мы получаем достоверные на 100% результаты. Как только появится рабочий стол Android, виртуальную машину можно будет оставить в покое.

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

Переходим в директорию tools Android SDK (в консоли). Открываем документацию, начинаем вкуривать. Вводим: ./android create project. Опс, ошибочка! Смотрим, чего от нас хотят. Ага, мы не указали параметры нашего будущего проекта, а точнее: цель. Нужна версия API, путь до проекта, его имя, имя Activity и имя пространства имен для приложения. У меня получилось вот так:

./android create project --target 8 --name hello --path ./TestPro --activity helloActivity --package com.example.hello

Делаем ls… ага, вот она — директория TestPro. Входим в нее, и опять вызываем ls. Далее в директории libs нужно создать сабдиректорию armeabi. В нее мы копируем нашу собранную Qt’шную либу (.so).

В каталог src/ надо скопировать все содержимое androidlighthouse/src/android/java/com, чтобы получилось src/com/nokia/qt. После этого идем в src/com/example/hello/ и редактируем там главный Activity — helloActivity.java. Удаляем onCreate, добавляем функцию:

public helloActivity()
{
setApplication("Hello");
}

Здесь Hello — имя приложения. Следовательно, наша библиотека .so должна называться libHello.so.

Ну и, наконец, идем в консоли в корень проекта и командуем ant install. Ждем (долго, поскольку либа статическая и весит много. У меня, например — 12.5 Мб). После того, как в консоли появится заветное SUCCESSFUL, можно идти в главное меню Андроида и запускать оттуда свое приложение.

Заключение

Когда-то (то ли в 2007, то ли в 2008) у меня на телефоне (Motorola A1200e, один из первых телефонов с Linux, и, кстати, с гуем, написанным на Qt 2) появилась QTopia, также известная как Qt Embedded — встраиваемая ОС от Trolltech на базе Linux Kernel 2.6 с оболочкой на Qt 4, заброшенная после покупки троллей нокией. Появилась она благодаря труженикам с форума motofan, сумевшим портировать ее на ядро 2.4 (другого у A1200 не было и не будет, поэтому не будет и Андроида). Так вот, когда я ее поставил, был удивлен простотой портирования приложений с десктопа на телефон — иногда требовалось просто пересобрать его кросс-компилятором, и все!

К сожалению, новомодного Qt 4.5 платформа не получила (и зря — на мой взгляд, она была не хуже, чем Maemo). Теперь такой метод портирования возможен и на Android, а ведь за ним будущее. И, кстати, вовсю идет портирование Qt Mobility, классного фреймворка для телефонов Nokia. Жаль, пока что портированием занимается только один, пусть и очень крутой человек (кстати, помочь не желаешь?). В общем, нам осталось дождаться портирования Qt на iOS (там, к сожалению, все далеко не так радужно), и тогда можно будет смело заявлять, что лозунг Qt Software не высосан из пальца.

Qt Everywhere!

Thanks to:

Огромное спасибо румыну taipanromania (автор порта) и marflon (раньше, кстати, писал в ][) за помощь с созданием .apk, ну и, традиционно, группе И-3-1 (Прикладная Математика) МГТУ "Станкин".

WARNING

Неожиданный пункт, не правда ли? Не бойся ничего противозаконного, только один ньюанс — со статически собранной библиотекой, при использовании QtWebkit и Phonon, лицензия твоего приложения не должна отличаться от LGPL.

INFO

У меня не получилось наладить отправку на "Мегафон". Может быть, это получится у тебя?

LINKS

http://code.google.com/p/android-lighthouse/ — страница проекта Qt for Android на гуглокоде.

http://developer.android.com/sdk/index.html — Android SDK, must have!



Теги: Android , программирование





СЛЕДУЮЩИЕ СТАТЬИ
Ударь копирайтом по работодателю: возвращаем финансы, честно заработанные на служебных произведениях
Руткит в сетевухе: фантазии программиста о создании непобедимого руткита
Чемпионаты по программированию и не только
Алгоритмическая симфония из одной строчки кода
Kinect: разбираемся с новым девайсом и учимся писать для него приложения
Программное обеспечение: поглощая мир
SMS-похититель для Android: Sсriрting Layer for Android - интересная среда разработки для мобильного телефона
13 утилит для безопасной разработки: инструменты от Microsoft для написания надежного кода
Silverlight: защита и нападение
Кроссплатформенный кодинг для мобильных платформ: покоряем iOS, Android, Bada, Symbian и WM с помощью AirPlaySDK
ПРЕДЫДУЩИЕ СТАТЬИ
Брутим дедики по-новому: свежий подход к программированию RDP-брутфорсеров
Подглядываем через веб-камеру: учимся использовать встроенную веб-камеру в своих целях
$1000 на Android: зарабатываем на приложениях для мобильной платформы от Google
Модифицируем подписанные библиотеки в .NET
Проникаем в Extended SMRAM или еще раз о потусторонней памяти №2
.NET Remoting: программим системы распределенных grid-вычислений
Реал-тайм в Вебе: технология Comet для построения быстрых веб-приложений
Оболочку на прокачку: советы по оптимизации команд и скриптов Powershell 2.0
Мобильные шаровары: как разрабатывать и продавать программы для Symbian
Проникаем в Extended SMRAM или еще раз о потусторонней памяти №1
ОБСУЖДЕНИЕ СТАТЬИ
Логин:
Пароль:
Если у вас есть форумный логин - вы можете использовать его, иначе анонимный гостевой доступ.

Для оставления комментария вы можете зарегистрироваться по упрощенной процедуре.

Обсуждение этой статьи на forum.xakep.ru
Для отправки сообщения введите код, указанный на картинке
Сообщение

UserГость
06.10.2010 15:14:24
Ответить Ссылка
"А вот для того, чтобы провернуть это дело под виндой, тебе придется немного попрыгать с бубном (какая тонкая ирония, а?)." - тоньше некуда. А вообще в чем смысл статьи? Похоже на статьи типа "Пишем свой Блокнот". Хакер начинает писать ряд статей по программированию для Android? Кстати не могу понять почему под виндой надо прыгать с бубном...вроде все нормально
UserГость
06.10.2010 22:07:01
Ответить Ссылка
благодарю за интересную статью, очень приятно слышать, что под Android таки можно писать на C++.
вот прикуплю себе смарт и буду под него прогать ;)
Avatarpadonnak
07.10.2010 2:48:54
Ответить Ссылка
))
UserГость
08.10.2010 15:54:18
Ответить Ссылка
видно конечно что писал студент, но интересно, спасибо. забыли только исходники проекта выложить
UserГость
09.10.2010 22:11:47
Ответить Ссылка
Насчет "исследуем недра операционной системы с помощью дебаггера и не только" - пинать верстальщиков ;)

>> тоньше некуда. А вообще в чем смысл статьи? Похоже на статьи типа "Пишем свой Блокнот". Хакер начинает писать ряд статей по программированию для Android?
Ты прикидываешься, или правда такой? (

>> не могу понять почему под виндой надо прыгать с бубном...вроде все нормально

Ну это только по-твоему - данный SDK запускается под виндой только в Cygwin, и с нефиговыми плясками

>>видно конечно что писал студент
Палюсь xD
==============================

Если что - вопросы можно задать по мылу rankor777@gmail.com
UserГость
14.10.2010 16:06:40
Ответить Ссылка
а где исходники можно взять?




Keywords: zPOSTz zHOMEz, zSOFTz, zHOWz, zINFOz, zYANDEXz z53445z
Для Авторов: edit Lock delete Lock



    Rambler's Top100