Сегодня в выпуске: отличия облегченного Android Go от стандартного Android, новые механизмы защиты Android P, инструкция по внедрению обратного TCP-шелла в Android с помощью Frida, распознавание лиц и текста с помощью ML Kit, генерация кода Kotlin с помощью аннотаций и описание новейшего MotionLayout. А также: подборка ссылок на ресурсы, облегчающие дизайн UI, и 14 свежих библиотек.
 

Инструменты и ресурсы

  • XDebug — не новый, но весьма полезный модуль Xposed, который позволяет отлаживать любое установленное на смартфон приложение;
  • exploit_playground — подборка эксплоитов с комментариями.
 

Почитать

 

Чем отличается Android Go от обычного Android

Android Go — How does Google’s lightweight ecosystem compare to the original? — статья с описанием отличий облегченной версии Android от полноценной. Основные тезисы:

  • В отличие от устройств Android One, которые поставляются на рынок с «чистым Android», смартфоны на Android Go будут продаваться с модификациями и приложениями производителя смартфона (если он этого пожелает).
  • Единственное заметное пользователю отличие Android Go от обычного Android — дизайн окна запущенных приложений.
  • В Android Go отключены некоторые ненужные большинству пользователей функции: Daydream VR, функция разделения экрана, поддержка Android Auto и Android Wear, Android for Work.
  • По умолчанию в Android Go отключено шифрование, однако некоторые устройства позволят его включить.
  • Android Go гораздо более агрессивен в уничтожении фоновых приложений (он старается убрать из памяти все, что не связано с самой операционной системой).
  • В Android Go по умолчанию включен zRAM, сжимающий данные в оперативной памяти для ее экономии.
  • Некоторые предустановленные приложения Android Go — это веб-приложения; например, Gmail Go и Google Maps Go — это WebView, в котором открывается написанный на HTML5/JS интерфейс, причем Google Maps Go весит 1 Мбайт, а Gmail Go больше стандартного приложения Gmail.
  • Часть приложений из комплекта Android Go сильно урезаны: YouTube Go не поддерживает комментарии и не позволяет ставить лайки, Assistant Go не имеет каких-либо опций, другие, наоборот, предоставляют полный набор функций: Google Maps Go почти в точности повторяет оригинальное приложение.
Gmail Go и Google Maps Go

Gmail Go и Google Maps Go

Gmail Go и Google Maps Go
 

Новые защитные функции Android P

Compiler-based security mitigations in Android P — пост разработчиков Android с рассказом о том, какие функции компилятора LLVM/Clang они применили в Android P для защиты от разного вида атак.

1. Control Flow Integrity. В современных эксплоитах важным шагом часто бывает модификация указателей на функцию и адресов возврата. Она позволяет обойти ограничение на исполнение стека и сегмента данных с помощью переиспользования кусков самого приложения.

Технология Control Flow Integrity (CFI) предназначена для борьбы с такими эксплоитами. При ее включении компилятор строит граф вызовов функций и встраивает код сверки с этим графом перед каждым вызовом функции. Если вызов происходит по отклоняющемуся от графа адресу, приложение завершается.

Разработчики Android уже включили CFI для нескольких системных компонентов в Android 8. В Android P покрытие расширилось и теперь включает в себя медиафреймворки, а также стек NFC и Bluetooth. Тестовая поддержка также реализована для ядра.

2. Integer Overflow Sanitization. Данная технология предназначена для защиты от целочисленного переполнения. Компилятор встраивает в результирующий код приложений функции проверки, которые используются для подтверждения, что исполняемая арифметическая операция не вызовет переполнения.

Впервые технология была использована в Android 7 для защиты медиастека, в котором обнаружили целый комплекс удаленных уязвимостей Stagefright. В Android P она также используется для защиты следующих компонентов: libui, libnl, libmediaplayerservice, libexif, libdrmclearkeyplugin и libreverbwrapper.

Код вызова функции с отключенным и включенным CFI
Код вызова функции с отключенным и включенным CFI
 

Обратный TCP-шелл с помощью Frida

Shellcoding an Arm64 In-Memory Reverse TCP Shell with Frida — статья с рассказом, как внедрить в Android обратный TCP-шелл с помощью Frida.

Это возможно благодаря классу Arm64Writer, который появился во Frida 10.4. Он позволяет записывать инструкции ARM64 прямо в память, а затем исполнять их. Чтобы создать обратный шелл, автор статьи написал его на языке ассемблера, а затем с помощью Arm64Write поместил в память процесса system_server (в Android это один из центральных компонентов операционной системы).

Часть кода обратного шелла:

var impl = Memory.alloc(Process.pageSize);
Memory.patchCode(impl, Process.pageSize, function (code) {
    var arm64Writer = new Arm64Writer(code, { pc: impl });
    // SUB             SP, SP, #0x50
    arm64Writer.putSubRegRegImm('sp', 'sp', 0x50);
    // STP             X29, X30, [SP, #0x40]
    arm64Writer.putStpRegRegRegOffset('x29', 'x30', 'sp', 0x40, 'pre-adjust');
    // ADD             X29, SP, #0x40
    arm64Writer.putAddRegRegImm('x29', 'sp', 0x40);

    ...

    arm64Writer.putRet();
    armWriter.flush();
});
 

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

 

Генерация кода Kotlin с помощью аннотаций

Generating Code via Annotations in Kotlin — статья об использовании процессора аннотаций kapt и генератора кода KotlinPoet для генерации кода из аннотаций на примере биндинга View. Алгоритм создания процессора достаточно несложный и состоит из четырех основных шагов:

  1. Объявляем аннотацию:

    @Retention(AnnotationRetention.SOURCE)
    @Target(AnnotationTarget.FUNCTION)
    annotation class BindField( val viewIds : Array<String>, val viewName : String)
    
  2. Создаем класс — процессор аннотации:

    @AutoService(Processor::class) // For registering the service
    @SupportedSourceVersion(SourceVersion.RELEASE_8) // to support Java 8
    @SupportedOptions(BindFieldsProcessor.KAPT_KOTLIN_GENERATED_OPTION_NAME)
    class BindFieldsProcessor: AbstractProcessor()
    
  3. Внутри функции process класса-процесса создаем цикл, который проходит по всем элементам, объявленным с помощью нашей аннотации, и, когда необходимо, возвращает ошибки при неправильном использовании аннотации (в данном случае при использовании в отношении нефункции):

    roundEnv.getElementsAnnotatedWith(BindField::class.java).forEach { methodElement ->
        if (methodElement.kind != ElementKind.METHOD) {
            processingEnv.messager.errormessage { 
                "Can only be applied to functions,  element: $methodElement " 
            }
            return false
        }
        ...
    }
    
  4. Генерируем код с помощью KotlinPoet:

    val funcBuilder = FunSpec.builder("bindFields")
          .addModifiers(KModifier.PUBLIC)
          .addParameter(variable.simpleName.toString(), variableAsElement.asType().asTypeName())
          .addParameter(method.getAnnotation(BindField::class.java).viewName, ClassName("android.view", "View"))
    annotationArgs.forEachIndexed { index, viewId ->
      funcBuilder.addStatement(
              "%L.findViewById<%T>(R.id.%L).text = %L.%L",
              method.getAnnotation(BindField::class.java).viewName,
              ClassName("android.widget", "TextView"),
              viewId,
              variable.simpleName,
              fieldsInArgument[index].simpleName
      )
    }
    
 

Распознавание лиц с помощью нейронной сети

Building a real-time face detector in Android with ML Kit — статья о создании приложения с функцией распознавания лиц в режиме реального времени с помощью Firebase ML Kit (комплекс алгоритмов распознавания объектов на базе нейронных сетей).

Задача: сделать систему, которая будет выделять лица в видоискателе камеры в режиме реального времени. Делается это в четыре шага:

  1. Подключаем библиотеку Firebase к своему проекту.
  2. Создаем простейший View, который рисует прямоугольники в заданных местах.
  3. Создаем CameraView с наложенным поверх него нашим кастомным View.
  4. Подключаем к CameraView процессор фреймов, который передает фреймы в ML Kit, а затем обновляет на основе полученной информации кастомный View (который рисует прямоугольники вокруг лиц).

Ключевая часть приложения:

class FaceDetector(private val faceBoundsOverlay: FaceBoundsOverlay) {
    private fun detectFacesIn(frame: Frame) {
        firebaseFaceDetectorWrapper.process(
                image = convertFrameToImage(frame),
                onSuccess = {
                    faceBoundsOverlay.updateFaces( /* Faces */)
                },
                onError = { /* Display error message */ })
    }

    ...
}
 

Распознавание текста с помощью нейронной сети

Text Recognition with ML Kit — еще одна статья об использовании Firebase ML Kit. В отличие от предыдущей статья подробно рассказывает о том, что такое ML Kit, как добавить свой проект в Firebase и подключить библиотеку к проекту.

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

Распознавание текста на устройстве происходит так.

  1. Подготавливаем изображение и детектор:

    val image = FirebaseVisionImage.fromBitmap(selectedImage)
    val detector = FirebaseVision.getInstance().visionTextDetector
    
  2. Запускаем процесс распознавания, указав колбэк, который будет выполнен после его завершения:

    detector.detectInImage(image)
        .addOnSuccessListener { texts ->
            processTextRecognitionResult(texts)
        }
        .addOnFailureListener { e ->
            e.printStackTrace()
        }
    
  3. В качестве аргумента колбэк получит объект типа FirebaseVisionText, он будет содержать массив обнаруженных блоков текста, а сами блоки будут содержать элементы со строками, с которыми можно работать (например, подсветить):

    private fun processTextRecognitionResult(texts: FirebaseVisionText) {
        view.hideProgress()
            val blocks = texts.blocks
            if (blocks.size == 0) {
                view.showNoTextMessage()
                    return
            }
        blocks.forEach { block ->
            block.lines.forEach { line ->
                line.elements.forEach { element ->
                    if (looksLikeHandle(element.text)) {
                        view.showHandle(element.text, element.boundingBox)
                    }
                }
            }
        }
    }
    

Распознавание текста в облаке выполняется похожим образом, но имеет несколько отличий. Например, облачная нейронная сеть умеет распознавать параграфы и давать информацию об отдельных символах, и это надо учитывать во время прохода по полученным блокам текста.

 

Создание анимаций с помощью MotionLayout

Creating Animations With MotionLayout for Android — статья о MotionLayout, расширении ConstraintLayout, позволяющем описывать анимации декларативно прямо в XML-файле.

MotionLayout основан на идее сцен движения (motion scene), которые описывают начальное, конечное и промежуточные состояния графического элемента во время анимации, а также способ переключения между этими состояниями.

Например, следующая сцена описывает анимацию перемещения элемента actor из правого нижнего угла экрана в левый верхний:

<?xml version="1.0" encoding="utf-8"?>
<MotionScene
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ConstraintSet android:id="@+id/starting_set">
        <Constraint android:id="@+id/actor"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            android:layout_width="60dp"
            android:layout_height="60dp"
            />
    </ConstraintSet>

    <ConstraintSet android:id="@+id/ending_set">
        <Constraint android:id="@+id/actor"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            android:layout_width="60dp"
            android:layout_height="60dp"
            />
    </ConstraintSet>

    <Transition
        android:id="@+id/my_transition"
        app:constraintSetStart="@+id/starting_set"
        app:constraintSetEnd="@+id/ending_set"
        app:duration="2000">
</MotionScene>

Запустить анимацию можно примерно так:

motion_container.transitionToEnd()
 

Инструменты дизайна для инди-разработчика

Solo Android Developer? Here are all the design tools you’ll ever need — список ресурсов, которые пригодятся в создании дизайна приложения.

Иконки:

Инструменты подбора цветов:

Примеры дизайна и готовые макеты:

 

Инструменты

  • androme — утилита для конвертирования HTML-страниц в набор XML-лайотов Android;
  • SDK Search — приложение для Android и плагин для Google Chrome для поиска по документации Android SDK;
  • deep-clean — скрипт для очистки всех кешей сборки Gradle.
 

Библиотеки

  • kotlin-extensions — несколько полезных функций-расширений Kotlin;
  • ColorPickerView — очередной диалог выбора цветов;
  • android-material-color-picker-dialog — и еще один диалог выбора цветов, в этот раз в стиле Material с ползунками;
  • Indicator Fast Scroll — фаст-скроллер, показывающий алфавитный указатель и пузырь с буквой;
  • Easy NLU — библиотека семантического парсинга строк, подходит для создания приложений-ассистентов;
  • QuickPermissions-Kotlin — простая и удобная в использовании Kotlin-библиотека для runtime-проверки полномочий;
  • Pixel Color Reader — Android — библиотека для чтения цвета пикселей с экрана;
  • DB Preferences — альтернатива стандартному API Preference на основе зашифрованной библиотеки;
  • UnderlinePageIndicator — индикатор переключения табов, совместимый с ViewPager;
  • android-face-detector — библиотека для распознавания лиц на основе Firebase ML Kit;
  • vector-analog-clock — view с реализацией векторных аналоговых часов;
  • LazyDatePicker — диалог выбора даты с ручным вводом;
  • FastList — библиотека для быстрого создания списков на основе RecyclerView без использования адаптера view holder’ов;
  • TypeWriterView — view с эффектом печатной машинки (посимвольный набор текста).

Оставить мнение

Check Also

Миллионы Android-приложений уязвимы перед проблемой Man-in-the-Disk

Эксперты Check Point описали новый вектор атак на Android-устройства — Man-in-the-Disk (Mi…