html текст
All interests
  • All interests
  • Design
  • Food
  • Gadgets
  • Humor
  • News
  • Photo
  • Travel
  • Video
Click to see the next recommended page
Like it
Don't like
Add to Favorites

Android: куда смартфоны сливают данные, 10 вопросов о Kotlin и запуск shell-кода с помощью JIT

Сегодня в выпуске: выполнение shell-кода с помощью JIT-компилятора, рассказ о том, куда смартфоны сливают данные, десять самых популярных вопросов о Kotlin, рассказ о WorkManager и Slices, представленных на Google I/O, и, конечно же, подборка свежих инструментов и библиотек.
 

Инструменты

  • House — основанный на Frida инструмент для динамического анализа приложений под Android. Позволяет быстро сгенерировать скрипт и внедрить его в приложение;
  • node-applesign — модуль Node.js и утилита командной строки для подписи приложений iOS (файлов IPA);
  • frida-ipa-dump — скрипт для извлечения расшифрованных iOS-приложений с устройства;
  • iOS writeups — огромное количество документов и книг, посвященных безопасности iOS.
 
Почитать
 
Выполнение shell-кода с помощью JIT-компилятора

Back To The Future | Going Back In Time To Abuse Android’s JIT — презентация, посвященная внедрению shell-кода в Android путем эксплуатации уязвимости в виртуальной машине Dalvik. Как мы все знаем, приложения для Android написаны на Java (или Kotlin) и скомпилированы в так называемый байт-код, исполняет который, в отличие от машинных инструкций, не процессор напрямую, а виртуальная машина.

В Android эта виртуальная машина изначально носила имя Dalvik, но была достаточно медлительной из-за того, что интерпретировала байт-код последовательно. С выходом версии Android 2.1 разработчики это поправили, внедрив в Dalvik так называемый JIT-компилятор (в версии Android 5.0 он был заменен на AOT-компилятор, но в 7.0 вернулся). Он транслирует в машинные инструкции целые куски байт-кода, так что виртуальной машине не приходится делать это последовательно, расходуя драгоценное время.

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

Виртуальная машина хранит ссылки на участки памяти со скомпилированными машинными инструкциями в структурах JitEntry, которые организованы в таблицу JitTable. Используя рефлексию и классы libcore.io.Posix (содержит методы mmap и munmap для манипуляции памятью), а также классы libcore.io.Memory и libcore.io.MemoryBlock, в память можно загрузить shell-код, а затем подменить адрес в JitEntry, чтобы вместо актуального машинного кода он ссылался на shell-код.

Механизм выполнения shell-кода отличается в разных версиях Android, но возможен и в 4.4.4, и в 7.1. А вот в Android P, скорее всего, начнутся проблемы, так как она запрещает вызов закрытых от сторонних приложений API. Также авторы исследования не упомянули, работает ли этот метод в отношении других приложений и системы в целом или только текущего процесса. Ведь Android запускает каждое приложение в собственной виртуальной машине, и память одной виртуальной машины не пересекается с другой.

 
К каким доменам чаще всего подключаются смартфоны

1984 called — очень короткая, но занятная статья о том, какие веб-сайты и сервисы следят за пользователями Android. Автор написал блокировщик рекламы для смартфонов Samsung, который перенаправляет DNS-запросы устройства на специальные DNS-серверы. Вместо IP-адресов рекламных и трекинговых сетей эти серверы возвращают 127.0.0.1, чем блокируют рекламу и трекеры.

Спустя несколько месяцев работы серверы накопили статистику заблокированных адресов. И первые три места с большим отрывом занимают следующие адреса:

  • graph.facebook.com
  • mobile.pipe.aria.microsoft.com
  • www.googleadservices.com

Facebook, как всегда, впереди.

К каким доменам чаще всего подключаются смартфоны
К каким доменам чаще всего подключаются смартфоны
 
Разработчику
 
10 самых популярных вопросов о Kotlin

Top 10 Kotlin Stack Overflow questions — десять (на самом деле девять) наиболее часто задаваемых вопросов о Kotlin на Stack Overflow и ответы на них. Приводим очень краткую выжимку (лучше все-таки почитать оригинал).

1. Чем отличаются Array и IntArray?

Первый создает массив высокоуровневого типа Integer, второй — примитивного типа int. IntArray более высокопроизводительный и рекомендуется к использованию в любых ситуациях.

2. Чем отличается Iterable и Sequence?

Iterable — это стандартный интерфейс Java. Реализующие его классы (List и Set, например) обрабатывают всю коллекцию целиком, что может плохо сказаться на производительности. Например, следующий код выполнит две операции (filter и map) над всеми элементами списка, перед тем как взять первые пять элементов (take):

val people: List<Person> = getPeople()
val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)

Sequence, с другой стороны, обрабатывает коллекции в ленивом режиме. Такой подход позволяет более эффективно обрабатывать коллекции в несколько проходов (как в этом примере) и выполнять процессинг только необходимого количества элементов:

val people: List<Person> = getPeople()
val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

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

Что использовать? В случае небольших коллекций Iterable показывает лучшую производительность. Но если ты имеешь дело с очень большой коллекцией, тогда лучше задуматься о применении Sequence. Если же тебе нужна генерируемая на лету бесконечная коллекция, то Sequence (с его функцией generateSequence()) — твой единственный выход. Подробная статья об этом.

3. Проход по элементам коллекции

В Kotlin есть множество способов обойти все элементы коллекции в цикле. Однако самые производительные из них следующие:

for (arg in args) {
    println(arg)
}

args.forEach { arg ->
    println(arg)
}

В своей работе они используют Iterator, и это быстрее, чем последовательное получение каждого элемента из списка.

Вариант с индексами:

for ((index, arg) in args.withIndex()) {
    println("$index: $arg")
}

args.forEachIndexed { index, arg ->
    println("$index: $arg")
}

4. SAM-преобразования

Как и Java 8, Kotlin поддерживает SAM-преобразования (Single Abstract Method). Это значит, что вместо такого кода:

button.setListener(object: OnClickListener {
    override fun onClick(button: Button) {
        println("Clicked!")
    }
})

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

button.setListener {
    println("Clicked!")
}

и компилятор поймет, что к чему.

Но есть несколько нюансов.

  • Если ты используешь SAM-преобразование, ты не можешь обратиться к анонимному объекту, созданному в процессе (объекту OnClickListener, если говорить о примере выше).
  • Ты можешь столкнуться с ошибкой компилятора, который заявит, что тип возвращаемого значения не совпадает. Такое происходит, если оригинальный метод требует вернуть значение определенного типа, а внутри лямбды ты вызываешь функцию, которая возвращает другой тип. В этом случае надо лишь добавить в конце лямбды значение нужного типа, например true или false, если необходимо вернуть Boolean.
5. Статические поля и методы

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

object Foo {
    fun x() { ... }
}

Если же нужно сделать статическими только отдельные поля и методы, используй companion object:

class Foo {
    companion object {
        fun x() { ... }
    }
    fun y() { ... }
}

Если какой-то метод должен быть запущен только один раз независимо от количества созданных на основе класса объектов, используй статический инициализатор:

class X {
    companion object {
        init {
            println("Static initialization!")
        } 
    }
}
6. Умное приведение типов и null

Если ты попробуешь сделать так:

class Dog(var toy: Toy? = null) {
    fun play() {
        if (toy != null) {
            toy.chew()
        }
    }
}

Kotlin сообщит тебе, что не может использовать умное приведение типов, потому что toy — это изменяемое свойство. Так происходит потому, что компилятор не может быть уверен, что между проверкой toy на null и вызовом метода chew() другой поток не сделает toy = null.

Чтобы это исправить, достаточно сделать так:

class Dog(var toy: Toy? = null) {
    fun play() {
        it?.chew()
    }
}

Или так:

class Dog(var toy: Toy? = null) {
    fun play() {
        toy?.let { 
            it.chew()
        }
    }
}

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

7. Что конкретно делает оператор !!?

Оператор !!, заставляющий среду исполнения Kotlin выполнить код даже в том случае, если его левая часть равна null, на самом деле выполняет то же самое, что такая функция-расширение:

fun <T> T?.forceNonNull(): T {
    if (this == null) {
        throw KotlinNullPointerException("Oops, found null")
    } else {
        return this as T
    }
}

Следующие две строки равнозначны:

airdate!!.getWeekday()
airdate.forceNonNull().getWeekday()
8. Что делать с аргументами при переопределении функции Java?

Программируя на Kotlin, ты всегда знаешь, может ли аргумент метода быть null. Но что делать, если ты переопределяешь метод, написанный на Java — языке, который не умеет сообщать, может ли аргумент быть null?

В этом случае тебе ничего не остается, кроме как всегда проверять аргументы на null. Это избыточно и не очень красиво выглядит в коде, но лучше перестраховаться.

9. Как использовать несколько функций-расширений с одинаковыми именами?

Одна из самых интересных возможностей Kotlin — это функции-расширения. Ты можешь в любое время добавить к любому доступному тебе классу любой дополнительный метод, независимо от того, имеешь ты доступ к коду класса или нет.

Но возникает одна проблема: если ты захочешь использовать две функции-расширения с одинаковыми именами, ты не сможешь обратиться к ним, используя полное имя пакета (например, com.example.code.indent()). В этом случае следует сделать так:

import com.example.code.indent as indent4
import com.example.square.indent as indent2

То есть просто импортировать функции под разными именами.

 
Список доступных для использования системных API

An Update on non-SDK restrictions in Android P. Разработчики Android уже рассказывали об ограничениях, которые Android P будет накладывать на использование недокументированных/скрытых API. Вкратце: если ты попытаешься использовать рефлексию, чтобы получить доступ к скрытым от сторонних приложений API, то ОС выбросит исключение NoSuchFieldException или NoSuchMethodException.

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

Какие API доступны, а какие уже нельзя использовать? Вот так называемый серый список. В нем более 11 тысяч методов и полей.

 
Что такое Slices в Android P и как их использовать?

A Closer look at Slices on Android — статья с рассказом о так называемых слайсах (Slice), новой функции Android, которая появилась в Android P, но вряд ли будет активирована к релизу (а может, и будет).

Слайсы — это часть новой подсистемы Actions on Google, которая позволяет разработчикам интегрировать свои приложения в Google Assistent. Работает это так: Google придумала ряд новых интентов, таких как actions.intent.PLAY_GAME и actions.intent.GET_CRYPTOCURRENCY_PRICE, которые отправляются приложениям, когда пользователь делает определенный запрос в ассистенте. В данном случае это может быть что-то вроде «хочу поиграть в игру» и «цена биткойна».

Ассистент обрабатывает запрос, вычленяет из него семантическую часть, затем рассылает приложениям соответствующий интент. Приложение может ответить на этот интент с помощью SliceProvider’а, который позволяет запрограммировать карточку с информацией для Google Assistent. Эту карточку Google Assistent выведет на экран.

Пример слайса с ответом на запрос «цена биткойна»
Пример слайса с ответом на запрос «цена биткойна»
 
Как работать с WorkManager

Doing work with Android’s new WorkManager — хорошая краткая статья о том, как использовать WorkManager, новую support-библиотеку Google для выполнения фоновой работы.

WorkManager был разработан как ответ на бардак в средствах фонового исполнения в разных версиях Android. До Android 5.0 нам предлагали использовать AlarmManager и сервисы для выполнения фоновых задач. Начиная с Android 5.0 появился JobScheduler, который толком не работал до версии Android 6.0, и вместо него приходилось использовать Firebase JobDispatcher, хотя сервисы продолжали нормально поддерживаться вплоть до версии Android 8, где Google ввела ограничение на их исполнение в несколько минут при уходе приложения в сон или получении push-уведомления.

WorkManager скрывает все эти нюансы и предлагает простой в использовании API для запуска фоновых задач. В зависимости от версии Android, на которой будет запущено приложение, он сам выберет лучший способ исполнения задачи, позволив тебе выбросить всю эту кашу из головы.

В простейшем случае создание и запуск задачи с помощью WorkManager выглядит так. Создаем задачу, наследуясь от класса Worker:

class YourWorker: Worker {
    override fun WorkerResult doWork() {
        // Делаем свои дела
        return WorkerResult.SUCCESS
    }
}

Затем создаем запрос на запуск задачи и ставим ее в очередь:

val work: OneTimeWorkRequest  = OneTimeWorkRequest.Builder(YourWorker::class.java).build()
WorkManager.getInstance().enqueue(work)

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

Добавим условия:

val constraints: Constraints = Constraints.Builder()
   .setRequiredNetworkType(NetworkType.CONNECTED)
   .setRequiresCharging(true)
   .build()

val work: OneTimeWorkRequest = OneTimeWorkRequest.Builder(SomeWorker::class.java)
    .setConstraints(constraints)
    .build()

Чтобы запустить периодическую (повторяющуюся) задачу, используем PeriodicWorkRequest:

val recurringWork: PeriodicWorkRequest = PeriodicWorkRequest.Builder(YourWorker::class.java, 3, TimeUnit.HOURS).build()
WorkManager.getInstance().enqueue(recurringWork)

Задачи также можно объединять в цепочки:

WorkManager.getInstance()
    .beginWith(firstWork)
    .then(secondWork)
    .then(thirdWork)
    .enqueue()
 
Инструменты
  • Bundletool — утилита для манипуляции Android App Bundle, позволяет собирать, разбирать бандлы и генерировать APK для разных устройств;
  • Swarmer — инструмент для запуска нескольких Android-эмуляторов одновременно;
  • adb-enhanced — скрипт-обертка для ADB, позволяющий выполнить множество различных действий: включение/выключение Doze, мобильных данных, режима полета, разрешений, нажатие кнопок, снятие скриншотов и многие другие.
 
Библиотеки
  • Android-IO18 — коллекция ссылок на презентации, документацию, семплы кода и все, что было связано с Android на Google I/O 2018;
  • CryptoPrefs — библиотека для шифрования настроек Android, созданных с помощью SharedPrefences;
  • JsonToKotlinClass — плагин Android Studio для генерации data-классов Kotlin из JSON;
  • KotlinTest — удобный фреймворк для тестирования приложений, написан на Kotlin с применением DSL;
  • KTFLITE — приложение-пример, демонстрирующее использование Tensorflow Lite для реализации компьютерного зрения;
  • PhotoEditor — библиотека с реализацией редактора фотографий: инструменты рисования, фильтры, эмоджи-стикеры и другое;
  • AndroidButtonProgress — два в одном: кнопка и прогрессбар;
  • FilePicker — диалог выбора файлов;
  • TheGlowingLoader — красивый индикатор загрузки;
  • morph-bottom-navigation — нижняя панель навигации;
  • SaveState — библиотека для автоматического сохранения состояния без необходимости реализовать методы onSaveInstanceState и onRestoreInstanceState.
Читать дальше
Twitter
Одноклассники
Мой Мир

материал с xakep.ru

1

      Add

      You can create thematic collections and keep, for instance, all recipes in one place so you will never lose them.

      No images found
      Previous Next 0 / 0
      500
      • Advertisement
      • Animals
      • Architecture
      • Art
      • Auto
      • Aviation
      • Books
      • Cartoons
      • Celebrities
      • Children
      • Culture
      • Design
      • Economics
      • Education
      • Entertainment
      • Fashion
      • Fitness
      • Food
      • Gadgets
      • Games
      • Health
      • History
      • Hobby
      • Humor
      • Interior
      • Moto
      • Movies
      • Music
      • Nature
      • News
      • Photo
      • Pictures
      • Politics
      • Psychology
      • Science
      • Society
      • Sport
      • Technology
      • Travel
      • Video
      • Weapons
      • Web
      • Work
        Submit
        Valid formats are JPG, PNG, GIF.
        Not more than 5 Мb, please.
        30
        surfingbird.ru/site/
        RSS format guidelines
        500
        • Advertisement
        • Animals
        • Architecture
        • Art
        • Auto
        • Aviation
        • Books
        • Cartoons
        • Celebrities
        • Children
        • Culture
        • Design
        • Economics
        • Education
        • Entertainment
        • Fashion
        • Fitness
        • Food
        • Gadgets
        • Games
        • Health
        • History
        • Hobby
        • Humor
        • Interior
        • Moto
        • Movies
        • Music
        • Nature
        • News
        • Photo
        • Pictures
        • Politics
        • Psychology
        • Science
        • Society
        • Sport
        • Technology
        • Travel
        • Video
        • Weapons
        • Web
        • Work

          Submit

          Thank you! Wait for moderation.

          Тебе это не нравится?

          You can block the domain, tag, user or channel, and we'll stop recommend it to you. You can always unblock them in your settings.

          • xakep.ru
          • домен xakep.ru

          Get a link

          Спасибо, твоя жалоба принята.

          Log on to Surfingbird

          Recover
          Sign up

          or

          Welcome to Surfingbird.com!

          You'll find thousands of interesting pages, photos, and videos inside.
          Join!

          • Personal
            recommendations

          • Stash
            interesting and useful stuff

          • Anywhere,
            anytime

          Do we already know you? Login or restore the password.

          Close

          Add to collection

             

            Facebook

            Ваш профиль на рассмотрении, обновите страницу через несколько секунд

            Facebook

            К сожалению, вы не попадаете под условия акции