Следующая новость
Предыдущая новость

Android: privacy-новшества Android Q Beta 1 и извлечение SSL-сертификатов приложения из KeyStore

29.03.2019 12:44
Android: privacy-новшества Android Q Beta 1 и извлечение SSL-сертификатов приложения из KeyStore

Содержание статьи

  • Почитать
  • Android Q: privacy
  • Извлекаем SSL-сертификат приложения из KeyStore
  • Разработчику
  • Более удобный if-else для Kotlin
  • Kotlin и параметры вещественного типа
  • Kotlin и польза null
  • Ускорение эмулятора Android
  • Вред (некоторых) выражений Kotlin
  • Ускоряем Android Studio
  • Инструменты
  • Библиотеки

Сегодня в выпуске: privacy-новшества Android Q Beta 1, извлечение SSL-сертификатов подопытного приложения из KeyStore, Kotlin и его параметры вещественного типа, польза значения null, вред языковых конструкций Kotlin и более удобный оператор if-else. А также: метод ускорения Android Studio, дампер, позволяющий снять память любого приложения, и свежая подборка библиотек.

Почитать

Android Q: privacy

Privacy in Android Q — документация Google об изменениях в механизмах доступа к информации в недавно выпущенном Android Q Beta 1. Основные нововведения:

  1. Запрет фонового доступа к местоположению. Раньше, если пользователь разрешал приложению использовать местоположение, оно могло сделать это в любой момент, даже если находилось в фоне. В новой версии у пользователя есть возможность выбрать, в каких ситуациях отдавать приложению свои координаты: в любое время или только пока приложение находится на экране.
  2. Запрет фонового доступа к буферу обмена. В Android нет отдельного разрешения на доступ к буферу обмена, любое приложение может прочитать или записать его содержимое (так получилось из-за технических особенностей этого механизма). Теперь доступ к буферу обмена могут получить только приложения, которые в данный момент находятся на экране либо являются клавиатурами и другими системами ввода. Нововведение убивает целый класс приложений — менеджеры буфера обмена.
  3. Запрет фонового запуска активностей. Текущие версии Android позволяют приложениям запускать другие приложения (а точнее, их активности) в любое время, независимо от того, находятся они на экране или нет. Это может запутать пользователя и открывает возможности для фишинга и других зловредных действий. Android Q запрещает фоновым приложениям запускать активности. В качестве альтернативы предлагается использовать уведомления, которые, в свою очередь, запустят нужную активность с помощью PendingIntent.
  4. Запрет на прямой доступ к карте памяти. С Android Q приложения больше не смогут получить прямой доступ к карте памяти (внутренней или внешней) с помощью разрешений READ_EXTERNAL_STORAGE и WRITE_EXTERNAL_STORAGE. Вместо этого следует использовать либо личный каталог приложения внутри /sdcard/Android (он создается автоматически и не требует разрешений), либо одно из разрешений, допускающих доступ к каталогам с фотографиями, видео и загрузками.
  5. Возможность отзыва разрешений у старых приложений. Система подтверждения разрешений приложений пользователем появилась еще в Android 6.0. Но работала она только в отношении софта, собранного для Android 6.0 и выше. Весь старый софт продолжал получать все нужные ему разрешения автоматически. В Android Q ситуация не изменилась, но теперь при запуске старого приложения пользователь будет видеть экран, с помощью которого сможет отозвать уже выданные системой разрешения.
  6. Запрет на включение/выключение Wi-Fi. В Android Q приложения больше не смогут включать и выключать Wi-Fi, вместо этого они должны использовать новую функцию settings-panels, которая показывает всплывающий диалог с переключателем выбранной настройки.
  7. Ограничение на доступ к IMEI и серийному номеру устройства. Чтобы прочитать эту информацию, теперь требуется разрешение READ_PRIVILEGED_PHONE_STATE.
  8. Запрет на доступ к информации о частоте использования контактов. Приложения, получающие доступ к базе контактов телефона, больше не смогут также получить информацию о том, как часто пользователь контактировал с теми или иными людьми.
  9. Рандомизация MAC-адреса. При скане сетей Android Q будет использовать рандомизированный MAC-адрес вместо настоящего. Это изменение должно защитить от отслеживания пользователя: некоторые магазины используют MAC-адрес для отслеживания посетителей, а торговые центры — для трекинга их перемещения.
  10. Другие изменения: запрет на доступ к файловой системе /proc/net, запрет на чтение серийных номеров подключенных USB-устройств до получения соответствующего разрешения, запрет на чтение параметров камеры без получения разрешения на использование камеры, необходимость иметь разрешение ACCESS_FINE_LOCATION, чтобы получить доступ ко многим функциям телефонии, Wi-Fi и Bluetooth, запрет на скрытое получение содержимого экрана устройства обходными путями.
Окно отзыва разрешений у старого софта

Извлекаем SSL-сертификат приложения из KeyStore

Extracting Android KeyStores from apps — статья об извлечении SSL-сертификатов из приложения с помощью Frida.

Многие приложения хранят приватные данные в KeyStore — специальном хранилище, позволяющем зашифровать и надежно защитить данные с помощью хардварного TEE-модуля смартфона (если такой присутствует). Напрямую извлечь эти данные в большинстве случаев не удастся. Но вместо извлечения данные можно перехватить.

KeyStore имеет методы load(KeyStore.LoadStoreParameter param) и load(InputStream stream, char[] password) для извлечения данных из хранилища. Мы можем переписать код этих функций с помощью Frida и сохранить данные на своей машине.

Код скрипта для Frida выглядит так:

setTimeout(function() {     Java.perform(function () {         keyStoreLoadStream = Java.use('java.security.KeyStore')['load'].overload('java.io.InputStream', '[C');          /* Переписываем функцию Keystore.load */         keyStoreLoadStream.implementation = function(stream, charArray) {             /* Если первый параметр null — запускаем оригинал */             if (stream == null) {                 this.load(stream, charArray);                 return;             }              /* Отправляем сообщение, что функция найдена */             send({event: '+found'});              /* Читаем InputStream в буфер */             var hexString = readStreamToHex (stream);              /* Отправляем тип KeyStore */             send({event: '+type', certType: this.getType()});              /* Отправляем пароль */             send({event: '+pass', password: charArray});              /* Отправляем сертификат в текстовой форме */             send({event: '+write', cert: hexString});              /* Запускаем оригинальную функцию */             this.load(stream, charArray);         }     }); },0);  /* Функция для чтения InputStream и его конвертации в ASCII */ function readStreamToHex (stream) {     var data = [];     var byteRead = stream.read();     while (byteRead != -1)     {         data.push( ('0' + (byteRead & 0xFF).toString(16)).slice(-2) );         /* <------------ binary to hex -----------> */         byteRead = stream.read();     }     stream.close();     return data.join(''); } 

Кроме этого скрипта, также понадобится скрипт, работающий на компе (именно ему приведенный выше скрипт отправляет данные с помощью функции send). Как работать с Frida и запустить скрипт, мы уже рассказывали в статье «Инъекция для андроида».

Android: privacy-новшества Android Q Beta 1 и извлечение SSL-сертификатов приложения из KeyStore
Результат работы скрипта

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

Более удобный if-else для Kotlin

Kotlin: when if-else is too mainstream — краткая заметка о том, как создать более удобный аналог оператора if-else, который можно использовать так:

val condition = true val output = condition then { 1 + 1 } elze { 2 + 2 } 

Реализация такого «оператора» умещается в десять строк:

infix fun <T>Boolean.then(action : () -> T): T? {     return if (this)         action.invoke()     else null }  infix fun <T>T?.elze(action: () -> T): T {     return if (this == null)         action.invoke()     else this } 

Ключевое слово infix используется, чтобы функции-расширения then и elze можно было вызывать без необходимости ставить точку перед ними.

Kotlin и параметры вещественного типа

How Reified Type makes Kotlin so much better — краткая статья о том, как параметры вещественного типа могут облегчить твою жизнь. В официальной документации приводится только один пример использования такого типа параметров — для облегчения передачи классов внутрь функции. Например, вместо того чтобы писать так:

private fun <T : Activity> Activity.startActivity(         context: Context, clazz: Class<T>) {     startActivity(Intent(context, clazz)) }  startActivity(context, NewActivity::class.java) 

можно написать так:

inline fun <reified T : Activity> Activity.startActivity(         context: Context) {     startActivity(Intent(context, T::class.java)) }  startActivity<NewActivity>(context) 

Но на этом полезные качества вещественных типов не заканчиваются. Еще один пример — функция для получения данных из бандла:

fun <T> Bundle.getDataOrNull(): T? {     return getSerializable(DATA_KEY) as? T }  val bundle: Bundle? = Bundle() bundle?.putSerializable(DATA_KEY, "Testing") val strData: String? = bundle?.getDataOrNull() val intData: Int? = bundle?.getDataOrNull() // Crash 

Последняя строка приведет к падению приложения, так как не совпадают ожидаемый тип данных и тип, возвращаемый функцией. Исправить это можно так:

private inline fun <reified T> Bundle.getDataOrNull(): T? {     return getSerializable(DATA_KEY) as? T }  val bundle: Bundle? = Bundle() bundle?.putSerializable(DATA_KEY, "Testing") val strData: String? = bundle?.getDataOrNull() val intData: Int? = bundle?.getDataOrNull() // Null 

Также вещественные типы можно использовать для эмуляции перегрузки методов на основе возвращаемого значения (Kotlin и Java по умолчанию разрешают выполнять перегрузки только на основе аргументов):

inline fun <reified T> Resources.dpToPx(value: Int): T {     val result = TypedValue.applyDimension(         TypedValue.COMPLEX_UNIT_DIP,         value.toFloat(), displayMetrics)      return when (T::class) {         Float::class -> result as T         Int::class -> result.toInt() as T         else -> throw IllegalStateException("Type not supported")     } }  val intValue: Int = resource.dpToPx(64) val floatValue: Float = resource.dpToPx(64) 

Kotlin и польза null

When You Should Use Null in Kotlin — небольшая заметка о пользе значения null.

В среде программистов на Kotlin использование nullable-типов данных считается дурным тоном. Но автор объясняет, что благодаря особенностям Kotlin (null safety) использование null становится скорее преимуществом, чем недостатком.

Значение null можно использовать для индикации отсутствия какого-либо значения или недоступности данных. И если в Java в этом случае ты легко мог совершить «ошибку на миллион долларов» (например, обратиться к методу null-объекта и уронить приложения), то Kotlin просто не позволит тебе этого сделать. Несколько примеров:

  1. Если объект != null, то выполняем код:
iuser?.let {     handleNonNullUser(user) } 
  1. Не выполняем функцию, если аргумент = null:
fun handleUser(user : User?) {     user ?: return     // Твой код } 
  1. Если объект = null, то:
val userName = user?.getName() ?: "Unknown" 

Ускорение эмулятора Android

Android Emulator: Project Marble Improvements — статья разработчиков эмулятора Android об улучшениях в производительности, сделанных в версии 28.1 (доступен в canary-канале). В целом все достаточно просто:

  1. Режим «на батарейке» по дефолту. Раньше эмулятор сообщал работающему в нем Android, что устройство питается от сети, а это приводило к излишней фоновой активности (в частности, система начинала обновлять приложения). Теперь эмулятор «работает» на батарейке.
  2. Возможность остановить эмулятор. Появились две ADB-команды, позволяющие полностью приостановить/возобновить работу эмулятора:

    $ adb emu avd pause $ adb emu avd resum 

    При сборке и установке приложения эмулятор будет разбужен автоматически.

  3. Оптимизация механизма отрисовки. Новый механизм позволил на 8% улучшить производительность стрессового приложения.
  4. Оптимизация I/O-кода на macOS. Версия для macOS теперь использует системный вызов kqueue вместо select для мониторинга дисковых операций. Это позволило сократить оверхед с 10 до 3%.
  5. Headless-режим. Теперь эмулятор можно запустить без интерфейса и вывода картинки на экран. Эту функцию можно использовать для запуска автоматизированных UI-тестов.
Android: privacy-новшества Android Q Beta 1 и извлечение SSL-сертификатов приложения из KeyStore
График использования процессора. Слева: при работе от сети и фоновом обновлении приложений. Справа: при работе от аккумулятора

Вред (некоторых) выражений Kotlin

Advocating against (some) Kotlin expressions — статья о вреде использования некоторых языковых конструкций Kotlin.

Когда ты программируешь на Kotlin, плагин Android Studio настоятельно предлагает конвертировать все подряд в выражение. Особенно раздражающим это бывает, например, когда плагин предлагает вынести return из условного оператора или оператора выбора. Простой пример:

Android: privacy-новшества Android Q Beta 1 и извлечение SSL-сертификатов приложения из KeyStore

Проблема этого кода в том, что он отрывает контекст от значения. Конкретно этот пример не раскрывает проблему целиком, но представь, что оператор выбора получился действительно длинным и не умещается целиком на экран. Ты видишь кусок кода и задаешься вопросом: а что это вообще?

Android: privacy-новшества Android Q Beta 1 и извлечение SSL-сертификатов приложения из KeyStore

Тебе приходится проматывать код вверх, чтобы просто узнать, что происходит со значением rawPizza дальше. А теперь представь, что ты читаешь diff на GitHub, который, кроме измененной строки, показывает только три строки кода сверху и снизу.

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

Android: privacy-новшества Android Q Beta 1 и извлечение SSL-сертификатов приложения из KeyStore

Ускоряем Android Studio

Is Your Android Studio Always Slow? Here’s How to Speed Up Immediately — краткая статья об ускорении Android Studio, интересная только наличием списка плагинов, которые можно безболезненно отключить в 90% случаев:

  • Android APK Support;
  • Android Games;
  • Android NDK;
  • App Links Assistant;
  • Copyright;
  • Coverage;
  • CVS Integration;
  • Editor Config;
  • Fabric for Android Studio;
  • Firebase (App Indexing, Services, Testing);
  • GitHub;
  • Google (Cloud Tools Core, Cloud Tools for Android, Developer Samples, Login, Services);
  • Markdown Support;
  • Mercurial integration;
  • hg4idea;
  • Settings repository;
  • Subversion integration;
  • Task management;
  • Test recorder;
  • TestNG-J;
  • YAML.

Инструменты

  • fridump3 — универсальный дампер памяти на основе Frida, совместим с iOS, Android и Windows;
  • Stringer — инструмент для генерации локализованной базы строк из CSV-файла.

Библиотеки

  • ExpandableBottomBar — кастомизируемая анимированная панель навигации для нижней части экрана приложения;
  • bubble-navigation — еще одна панель навигации;
  • android_dbinspector — библиотека для просмотра содержимого базы данных приложения прямо на устройстве;
  • Android-BackgroundChart — фоновое изображение с графиком;
  • ShowMoreText — кастомный TextView, позволяющий показывать больше текста по клику на ссылку (например, «Подробнее»);
  • headless-wifi-manager — библиотека для управления конфигурацией Wi-Fi других устройств через Nearby API;
  • crashx — очередная библиотека краш-репортинга, показывает окно с информацией об ошибке при падении приложения;
  • MultiProgressBar — множественный прогресс-бар в стиле Instagram Stories;
  • mr-clean — библиотека для очистки логов от важной персональной информации;
  • KBarcode — библиотека для реализации сканера штрих-кодов;
  • ProfileBar — эффектная реализация страницы профиля пользователя/автора/героя;
  • Kaskade — однонаправленный state-контейнер для хранения состояния объектов;
  • audio-visualizer-android — библиотека визуализации аудио;
  • glimpse-android — библиотека для обрезки изображений, учитывающая положение объектов.

Источник

Последние новости