Сегодня в выпуске: скрываем приложение от троянов, боремся с утечками памяти, создаем неубиваемый сервис, работаем с сенсорами температуры, отлаживаем приложение прямо на устройстве и готовим свое приложение к ограничениям Android Q. А также: подборка первоклассных инструментов пентестера и библиотек для разработчиков.
 

Почитать

 

Как скрыть приложение от троянов

Mobile Malware Analysis: Overlay and How to Counter it (partly) — небольшая статья о том, как скрыть имя пакета приложения от трояна.

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

  1. Читают список процессов, чтобы узнать, какое приложение в данный момент находится на экране.
  2. Если имя пакета текущего приложения совпадает с именем пакета целевого приложения (банковский клиент, например), троян показывает оверлей поверх окна приложения с поддельными полями ввода данных (логин:пароль, номер банковской карты и так далее).

Инженеры Google знают об этой проблеме, поэтому начиная с Android 7 получить доступ к списку запущенных приложений можно только с помощью API UsageStats или сервиса Accessibility. И тот и другой требуют от пользователя перейти в настройки, активировать переключатель напротив нужного приложения и согласиться с предупреждающим сообщением. Однако на версиях Android ниже 7 (API < 24) все гораздо проще — достаточно вызвать одну функцию или прочитать синтетический файл:

  • <= 19: runningTask.get(0).topActivity
  • 20, 21: getRunningAppProcesses().get(0).processName
  • 22, 23: файлы /proc/pid/cmdline и /proc/pid/stat

Автор задался вопросом, можно ли защитить пользователей Android 6 и ниже от фишинга, и в итоге пришел к следующему решению:

try { 
    Method setter = android.os.Process.class.getMethod("setArgV0", String.class); 
    setter.invoke(android.os.Process.class, text); } 
    catch (NoSuchMethodException e) { e.printStackTrace(); } 
    catch (IllegalAccessException e) { e.printStackTrace(); }
    catch (InvocationTargetException e) { e.printStackTrace(); }
}

Данный код использует рефлексию для доступа к методу Process.setArgv0(), который меняет первый переданный процессу аргумент (в UNIX-системах он равен имени приложения, а в Android имя приложения равно имени его пакета). Способ работает на всех версиях Android до Q, где данный метод был внесен в черный список.

 

Разработчику

 

Боремся с утечками памяти

Everything you need to know about Memory Leaks in Android — большая статья об утечках памяти и о том, как их избежать. Автор приводит три типичных примера утечек.

Пример 1. Потоки

public class ThreadActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_async_task);
        new DownloadTask().start();
    }

    private class DownloadTask extends Thread {
        @Override
        public void run() {
           SystemClock.sleep(2000 * 10);
        }
    }
}

Данный код создает поток, который спит 20 секунд (в реальном приложении это может быть какая-либо длительная работа). Проблема здесь в том, что в Java объекты вложенных классов (в данном случае DownloadTask) хранят ссылку на внешний объект (Activity), поэтому, даже если пользователь закроет активность, сборщик мусора не сможет освободить занятую ей память до тех пор, пока метод run не закончит свою работу и занятая объектом класса DownloadTask память не будет освобождена.

Пример 2. Синглтоны

public class SingletonManager {
    private static SingletonManager singleton;
    private Context context;

    private SingletonManager(Context context) {
        this.context = context;
    }

    public synchronized static SingletonManager getInstance(Context context) {
        if (singleton == null) {
            singleton = new SingletonManager(context);
        }
        return singleton;
    }
}

В данном случае проблема кроется не в самом коде, а в способе его использования:

public class LoginActivity extends Activity {
      @Override
    protected void onCreate(Bundle savedInstanceState) {
        //...
        SingletonManager.getInstance(this);
    }
}

В этом примере в качестве аргумента Context при создании синглтона передает this, то есть текущая активность. А это значит, что синглтон будет хранить ссылку на активность на протяжении всей жизни приложения. Чтобы избежать этой проблемы, вместо ссылки на активность следует использовать ссылку на контекст всего приложения:

SingletonManager.getInstance(getApplicationContext());

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    1 Комментарий
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии