В Android 13 Google ограничит доступ к спец. возможностям
В Google решили ограничить доступ к службам специальных возможностей (API AccessibilityService) приложениям, которые загружены из неизвестных источников. Такое изменение появится на устройствах под управлением Android 13. Выясняем: что это может означать для пользователей с нарушением зрения.
✅ Ограничение обусловлено соображениями безопасности пользователей.
Дело в том, что приложения, обращающиеся к специальным возможностям, получают гораздо больше прав на устройстве, чем обычные приложения. В частности, специальные возможности дают приложению доступ к информации, отображаемой на экране устройства. Эта возможность предназначена для программ экранного доступа для пользователей с нарушением зрения, например: TalkBack и Jieshuo (Commentary) Screenreader. Но и приложения, модифицированные злоумышленниками, могут, пользуясь правами специальных возможностей, отслеживать информацию, появляющуюся на экране, включая личные и платёжные данные. только в отличии от программы экранного доступа, вовсе не с целью озвучить данные для пользователя. Причём владелец устройства может и не подозревать о такой активности приложения.
✅ Ограничение коснётся только приложений, загруженных из неизвестных источников.
На устройство с системой Android пользователь может устанавливать приложения двумя способами:
- Загружать из официальных магазинов приложений (Google Play, F-droid, Samsung Galaxy Store и др.). Считается, что перед публикацией в магазине проводится проверка приложений на безопасность.
- Скачивать файл с расширением APK с других интернет-ресурсов. Такие приложения Google называет загруженными из неизвестных или ненадёжных источников. Есть опасность, что приложение могло быть изменено злоумышленниками.
Популярную среди незрячих пользователей Android-устройств программу экранного доступа Jieshuo (Commentary) Screenreader приходится устанавливать как раз вторым способом.
✅ Кстати, рассматриваемое ограничение — не единственное. Как сообщает сайт о технологиях 4PDA, Google с 11 мая ограничивает доступ к API AccessibilityService сторонним приложениям для записи телефонных разговоров. В прочем, опция записи звонков остаётся легальной для приложений, предустановленных производителями устройств.
Отметим, что пока нет подробностей, сложно с уверенностью говорить о том, как эти изменения отразятся на незрячих пользователях будущей версии системы Android (Android 13). Тем не менее, мы обратились за комментарием к Сергею Екатеринушкину — преподавателю, обучающему начинающих пользователей с нарушением зрения (г. Тамбов).
Комментарий Сергея Екатеринушкина
«Что касается записи звонков: смартфоны фирм Huawei и Xiaomi могут записывать телефонные разговоры через стандартное приложение «Диктофон» либо непосредственно в звонилки, то есть в приложение «Телефон». Китайские производители модифицировали эти приложения таким образом, чтобы они могли записывать звонки, и встроили их в систему. Так что подобные ограничения, вводимые компанией Google, могут быть обойдены производителями устройств на уровне модификации системы.
Что касается основного вопроса о специальных возможностях, то китайский Commentary screenreader работает, например, и на смартфонах Samsung. В устройствах Samsung свой набор сервисов отвечающих за спец. возможности. Приэтом сторонние приложения использующие API AccessibilityService, не могут их задействовать. Так, в тех местах где активируется элемент обычным двойным касанием, например, при срабатывании стандартного будильника, с Commentary screenreader приходится провести двумя пальцами снизу вверх либо в всторону.
Ввод текста на фирменной клавиатуре Samsung тоже не даёт для Commentary весь свой функционал. Так при наборе текста с Commentary и клавиатурой Samsung нужно включить отображение клавиши смены раскладки (Глобус) в настройках самой клавиатуры. Другая проблема — это отсутствие функции «Ввод одним касанием», когда мы отпускаем символ, чтобы его ввести. Приходится вводить букву двойным касанием, как активируем обычный элемент управления на экране. Эти мелкие неудобства обходятся установкой клавиатуры Google.
Также, на некоторых моделях Samsung фирменный браузер Samsung internet не даёт Commentary читать web-странички. Но ведь Android — открытая ОС. Есть альтернативы в виде браузеров Chrome и FireFox.
Таким образом, можно сделать вывод, что возможны небольшие неудобства, с которыми столкнутся незрячие пользователи при обновлении до Android 13. Уверен, что часть проблем решиться заменой некоторых стандартных приложений, таких как клавиатура, либо использованием новых жестов, либо разработчики Commentary screenreader со временем исправят возникшие проблемы, а активное сообщество пользователей в этом поможет.
А если вы — начинающий пользователь, то переждите этот период адаптации и не обновляйте своё устройство до тех пор, пока не решатся критичные для вас проблемы. Но паниковать точно не стоит», — заключает Сергей Екатеринушкин.
Хотите оперативно узнавать о новых публикациях? Присоединяйтесь к нашей группе в WhatsApp.
Благодарим Вас за внимание! Пожалуйста, поделитесь с друзьями в соцсетях.
Контроль над Android. Перехватываем данные и сбрасываем настройки смартфона через самые опасные API


Кроме традиционных разрешений, в Android есть три мета‑разрешения, которые открывают доступ к весьма опасным API, позволяющим в прямом смысле захватить контроль над устройством. В этой статье мы научимся их использовать, чтобы программно нажимать кнопки смартфона, перехватывать уведомления, извлекать текст из полей ввода других приложений и сбрасывать настройки смартфона.
О каких API пойдет речь?
- Администрирование устройства — API, предназначенный для корпоративных приложений. Позволяет сбрасывать и устанавливать пароль экрана блокировки, сбрасывать смартфон до заводских настроек и устанавливать правила минимальной сложности пароля. Одна из особенностей API — запрещено удалять приложения, получившие права администратора, чем с радостью пользуются авторы зловредных приложений.
- Accessibility — API для реализации приложений, ориентированных на людей с ограниченными возможностями. Фактически API позволяет создавать альтернативные способы управления устройством и поэтому открывает поистине огромный простор для злоупотребления. С его помощью можно получить доступ к содержимому экрана практически любого приложения, нажимать кнопки интерфейса и программно нажимать клавиши самого смартфона. Но есть и способ защиты: разработчик приложения может прямо указать, что определенные элементы интерфейса приложения будут недоступны для сервисов Accessibility.
- Уведомления — API, позволяющий получить доступ ко всем уведомлениям, которые отображаются в панели уведомлений. С помощью этого API приложение может прочитать всю информацию об уведомлении, включая заголовок, текст и содержимое кнопок управления, нажать на эти кнопки и даже смахнуть уведомление. API пользуется особой популярностью среди разработчиков всевозможных банковских троянов, с помощью которого они могут читать коды подтверждения и смахивать предупреждающие сообщения от банков.
Получив доступ ко всем этим API, зловредное приложение сможет сделать со смартфоном практически все что угодно. Именно поэтому для их защиты используются не традиционные запросы полномочий, на которые пользователь может машинально ответить «Да», а скрытый глубоко в настройках интерфейс, который при активации покажет угрожающее сообщение. Все, что может сделать приложение, чтобы получить нужное полномочие, — это перебросить пользователя в окно настроек, после чего тот должен будет найти нужное приложение, включить напротив него переключатель и согласиться с предупреждающим сообщением.
Заставить пользователя дать разрешение на использование этих API можно обманом. Зачастую зловреды прикидываются легитимными приложениями, которым разрешение нужно для работы ключевой функциональности. К примеру, это может быть приложение для ведения журнала уведомлений или приложение для альтернативной жестовой навигации (такому приложению нужен сервис Accessibility для нажатия кнопок навигации). Также можно использовать атаку Cloak & Dagger, чтобы перекрыть окно настроек другим безобидным окном.
Нажимаем кнопки смартфона
Простейший сервис Accessibility может выглядеть так (код на Kotlin):
Чтобы система узнала о нашем сервисе, его необходимо объявить в AndroidManifest.xml :
Это описание ссылается на конфигурационный файл accessibility_service_config.xml , который должен быть определен в каталоге xml проекта. Для нашего случая достаточно будет такого конфига:
После того как пользователь включит наш сервис Accessibility в окне «Настройки → Спец. возможности», система автоматически запустит сервис и мы сможем выполнить функцию pressHome() , чтобы нажать кнопку «Домой»:
// Если service не null — значит, система успешно запустила сервисif (AccessService.service != null)
Одной лишь только этой функциональности достаточно, чтобы реализовать Ransomware, который будет вызывать функцию pressHome() в цикле и бесконечно возвращать пользователя на домашний экран, не давая нормально использовать устройство.
![]() |
| Окно включения сервиса Accessibility в Android 11 |
Однако настоящая мощь Accessibility кроется не в нажатии кнопок навигации, а в возможности контролировать другие приложения.
Перехватываем содержимое полей ввода
API Accessibility был создан для людей с ограниченными возможностями. С его помощью можно, например, создать приложение, которое будет зачитывать все надписи интерфейса и позволит нажимать элементы интерфейса голосом. Все это достижимо благодаря тому, что Accessibility дает полный доступ к интерфейсу приложений в виде дерева элементов: можно пройти по нему и выполнить над элементами определенные операции.
Продолжение доступно только участникам
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Присоединяйся к сообществу «Xakep.ru»!
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Что стоит учесть при разработке приложения для специальных возможностей в Android?
Я наткнулся на проблему описанную в вопросе на этом же форуме — см. Служба специальных возможностей неисправна. Покапавшись в сети я нашел этот сайт — см. Сервис работает некорректно Xiaomi спец возможности. В нем написано следующие:
- Включите администрирование устройства. Сделав это, пришло время заглянуть в меню «Администрирование устройства». Приложения с правами администратора устройства остаются в памяти и редко отключаются в настройках специальных возможностей.
Что, конечно, не является техническим ликбезом, но это всё что я нашел, что хоть косвенно, но связано с этой проблемой.
Моему приложению выдано разрешение IGNORE_BATTERY_OPTIMIZATIONS, Wake Lock также используется.
Тогда у меня возник вопрос, а как другие разработчики с этим справляются?
Вопросы
-
Правильно ли я делаю, включая Wake Lock только в ресивере:
public class ScreenReceiver extends BroadcastReceiver < public static boolean wasScreenOn = true; @Override public void onReceive(final Context context, final Intent intent) < if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) < // do whatever you need to do here wasScreenOn = false; System.out.println("Экран: выключен"); // Включить блокировку спящего режима для своего приложения: MyService.wakeLock.acquire(); System.out.println("Включить блокировку спящего режима для своего приложения"); >else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) < // and do whatever you need to do here wasScreenOn = true; System.out.println("Экран: включен"); // Выключить блокировку спящего режима для своего приложения: MyService.wakeLock.release(); System.out.println("Выключить блокировку спящего режима для своего приложения"); >> >
Ну, т.е в MyService и в AccessibilityService нет включений кода:
MyService.wakeLock.release() и MyService.wakeLock.acquire()
Отслеживать
17.9k 11 11 золотых знаков 25 25 серебряных знаков 57 57 бронзовых знаков
задан 11 июл 2023 в 15:01
27 2 2 бронзовых знака
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Тогда у меня возник вопрос, а как другие разработчики с этим справляются?
С проблемой спец возможности работают некорректно, можно справится поставив wake lock, но не там где я поставил.
- Wake lock обычно прописывают в классах, у которых есть свой жизненный цикл. Таких как Activity, Service, IntentService. В AccessibilityService прописывать wake lock не нужно, т.к он является автономным и его жизненный цикл управляется непосредственно Android OS. У ресиверов жизненный цикл отсутствует вовсе. Их код просто переодически вызывается системой и только тогда код ресивера активный.
- Также я заметил, что в службах прописывать код Wake Lock также не требуется, если служба работает не постоянно, а запускается той которая работает постоянно. Т.е если MainService запускает службу GPSTraker и после какого-то времени служба отключается, в ней реализовывать wake lock не обязательно(у меня это и так работает).
в службе или активности нужно прописывать код создания Wake Lock:
PowerManager.WakeLock wakeLock = null; @Override public void onTaskRemoved(Intent rootIntent) < if (wakeLock != null) < if (wakeLock.isHeld() == true) < wakeLock.release(); >> > @Override public void onDestroy() < super.onDestroy(); if (wakeLock != null) < if (wakeLock.isHeld() == true) < wakeLock.release(); >> > @Override public void onCreate() < super.onCreate(); PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE); if (wakeLock == null) < wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "PeriSecure:MyWakeLock"); >if (wakeLock != null) < if (wakeLock.isHeld() == false) < wakeLock.acquire(); >> >
В каждом классе нужно создать новый WakeLock, а не использовать старый.
Надеюсь я понятно объяснил. Хотя, в Android документации объясняют не лучше..
В моём случае, я не там включал WakeLock и Android перезапускал службу спец возможностей, это видимо и приводило к не корректной работе. Как описывается в Accessibility Service is malfunctioning.
Это не из вашего приложения. После завершения работы вашего приложения системой. При следующей попытке включить службу специальных возможностей всегда не удается запустить службу специальных возможностей. Это ошибка Android. Android не удается запустить службу специальных возможностей после завершения работы службы. Вы ничего не можете с этим поделать. Кто-то уже отправил отчет об ошибке в Google в 2016 году, но это не было исправлено. Проверьте это: issuetracker.google.com/issues/37123359
Что ещё мне стоит знать, чтобы служба спец возможностей работала стабильно и без перебоев?
По сути больше учитывать нечего для работы службы в штатном режиме. Я надеюсь только у меня возник вопрос, а что делать если MainService не задумывался как работающий при выключенном экране, ведь тогда приложение остановится и служба спец возможностей вместе с ним, а обратно уже не запустится..
Моё предложение: по ходу, разберемся )
Автоматизируем работу с программами на Android при помощи Accessibility Service

И программистам, и хакерам, и безопасникам иногда нужны способы автоматизировать пользовательские действия — то есть писать скрипты, которые будут тыкать в кнопки чужих софтин так, чтобы те принимали это чистую монету. Кто сказал «негласно автоматизировать работу с мобильным банком»? Стыдитесь, товарищ! Мы за мирную автоматизацию. В прошлой статье по Accessibility Service мы сфокусировались на получении данных экрана, а сегодня мы научим Accessibility Service делать работу на устройстве за нас!
![]()
WWW
Понажимай эти кнопки за меня
Еще в XIX веке Гегель сказал: «Машиноподобный труд нужно отдать машинам». И тут с одним из творцов немецкой классической философии трудно поспорить: вряд ли Георг Вильгельм Фридрих отказался бы от автоматизации таких действий, как отключение звука и нажатие кнопки «Пропустить рекламу» при просмотре ролика в YouTube или получение ежедневных бонусов за посещение приложения. Тем более что для всего этого у нас уже есть готовый инструментарий!
Как мы говорили в предыдущей статье, Accessibility Service может получать события, происходящие на экране, но он же может и вызывать их. Например, находить нужные элементы в приложении и кликать по ним.
Ставить чужое приложение с подобной функциональностью опасно — все мы знаем репутацию Google Play и примерно представляем себе, что такое приложение может сделать с твоим банковским клиентом на телефоне. Поэтому выхода два: либо декомпилировать чужое ПО и смотреть, куда именно оно нажимает, либо пилить свое, строго под поставленные задачи.
Для исследовательских целей я создал приложение, которое будет само в себя кликать из собственного сервиса :).
Подготовка к работе сервиса
Чтобы наш сервис начал работу, ему нужно предоставить права в специальном разделе настроек. Как перенаправить туда пользователя, ты уже знаешь из первой статьи. Дополнительно мы сами можем перепроверить, есть ли эти права у приложения.
protected boolean checkAccess() < String string = getString(R.string.accessibilityservice_id); for (AccessibilityServiceInfo id : ((AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE)).getEnabledAccessibilityServiceList(AccessibilityEvent.TYPES_ALL_MASK)) < if (string.equals(id.getId())) < return true; >> return false; >
Здесь accessibilityservice_id — это строка вида «имя пакета/.сервис», у нас это ru.androidtools.selfclicker/.ClickService.
Вот описание сервиса из манифеста:
Параметр label отвечает за название приложения в настройках сервиса спецвозможностей. В разделе meta-data задается указание на описание нужных функций для работы сервиса. Вот файл serviceconfig:
В нем мы описываем полномочия сервиса, типы событий, которые он может обрабатывать, и активити, которое запустится для настройки работы сервиса.
Полное описание этих параметров, как всегда, есть в документации.


Рекомендуем почитать:
Xakep #295. Приемы рыбалки
- Содержание выпуска
- Подписка на «Хакер» -60%
Жизненным циклом сервиса управляет система. Сами остановить сервис мы не можем. ОС самостоятельно выгрузит ненужные сервисы — к примеру, зачем крутить сервис для приложения, которое не запущено?
Мы можем привязать сервис к строго нужному приложению. Как только мы дали разрешение на работу, у сервиса вызовется метод onServiceConnected. У него мы должны вызвать метод setServiceInfo() с параметром AccessibilityServiceInfo. За фильтрацию приложений, с которыми работает сервис, отвечает строковый массив packageNames.
@Override protected void onServiceConnected() < super.onServiceConnected(); Log.v(TAG, "onServiceConnected"); AccessibilityServiceInfo info = new AccessibilityServiceInfo(); info.flags = AccessibilityServiceInfo.DEFAULT | AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS; info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC; info.packageNames = new String[]; setServiceInfo(info); >

Работаем с событиями AccessibilityEvent
После раздачи всех разрешений нам надо запустить нужное приложение. Если мы знаем его имя пакета, сделать это несложно:
private void startApp() < Intent launchIntent = getPackageManager().getLaunchIntentForPackage("ru.androidtools.selfclicker"); // Запуск из нужного места без предыстории приложения launchIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(launchIntent); >
Для запуска приложения с чистого листа используем флаг Intent.FLAG_ACTIVITY_CLEAR_TOP. В противном случае приложение может вернуться на экран со старым состоянием, очень далеким от стартового экрана.
Теперь нужно обрабатывать события в методе onAccessibilityEvent. У события есть тип, он поможет определить, что произошло (например, сменилось окно, кликнули по элементу, элемент получил фокус). Чтобы получить источник события AccessibilityNodeInfo, надо у объекта события вызвать метод getSource().
Источник имеет много полезных свойств, помогающих в работе: текст, ID, имя класса. У него могут быть родительский и дочерние элементы.
Он может быть кликабельным isClickable(), и, чтобы щелкнуть по нему, как нормальный пользователь, нужно вызвать метод performAction(AccessibilityNodeInfo.ACTION_CLICK).
Если мы хотим более глобальных действий, например нажать клавишу «Назад» на устройстве, то следует вызвать метод performGlobalAction() с нужным параметром.
Чтобы найти на экране требующуюся AccessibilityNodeInfo, мы можем вызвать один из методов: поиск по ID (findAccessibilityNodeInfosByViewId) и поиск по тексту (findAccessibilityNodeInfosByText). Будь готов к тому, что он вернет нам массив элементов или вообще ни одного.
Потренируемся на кошках, точнее — на окошках
Вот разметка нашего подопытного экрана:
У некоторых элементов есть ID и текст, у других только текст, некоторые некликабельны.
Иногда обработчики кликов устанавливают на области, превышающие своими размерами элемент с текстом или картинкой.
Поизучаем эту задачу с помощью метода debugClick.
private void debugClick(AccessibilityEvent event) < if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) < AccessibilityNodeInfo nodeInfo = event.getSource(); if (nodeInfo == null) < return; >nodeInfo.refresh(); Log.d(TAG, "ClassName:" + nodeInfo.getClassName() + " Text:" + nodeInfo.getText() + " ViewIdResourceName:" + nodeInfo.getViewIdResourceName() + " isClickable:" + nodeInfo.isClickable()); > >
Вот что вышло в лог:
03-03 16:23:15.220 24461-24461/ru.androidtools.selfclicker D/ClickService: ClassName:android.widget.Button Text:ID/BUTTONTEST ViewIdResourceName:ru.androidtools.selfclicker:id/buttonTest isClickable:true 03-03 16:23:26.356 24461-24461/ru.androidtools.selfclicker D/ClickService: ClassName:android.widget.Button Text:БЕЗ ID ViewIdResourceName:null isClickable:true 03-03 16:23:36.697 24461-24461/ru.androidtools.selfclicker D/ClickService: ClassName:android.widget.LinearLayout Text:null ViewIdResourceName:null isClickable:true 03-03 16:23:44.320 24461-24461/ru.androidtools.selfclicker D/ClickService: ClassName:android.widget.Button Text:НЕРАБОЧАЯ КНОПКА ViewIdResourceName:ru.androidtools.selfclicker:id/button3 isClickable:true
Чтобы воспроизвести последовательность кликов, нужно сначала изучить элементы, которые будут нажиматься. Но иногда также важна и последовательность их нажатий.
Для нажатий на первые две кнопки можно использовать findAccessibilityNodeInfosByText и findAccessibilityNodeInfosByViewId. Если текст у элементов повторяется, дополнительно можно проверять на ClassName или родителя.
Чтобы кликнуть в наш LinearLayout, нужно получить его AccessibilityNodeInfo, ID у него нет, но есть дочерние элементы TextView и Button, у которых есть текст.
Для начала нам нужно получить один из них, а потом кликнуть в его родителя.
private boolean linearClick(AccessibilityNodeInfo nodeInfo) < Listlist = nodeInfo.findAccessibilityNodeInfosByText("Нерабочая кнопка"); if (list.size() > 0) < for (AccessibilityNodeInfo node : list) < AccessibilityNodeInfo parent = node.getParent(); parent.performAction(AccessibilityNodeInfo.ACTION_CLICK); >return true; > else return false; >
Бывают и обратные ситуации, когда есть родитель, а кликаем мы в дочерние. Для этого используй nodeInfo.getChildCount() и обращайся к элементу в цикле по ID nodeInfo.getChild(id) (если не ошибаюсь, нумерация ID идет с нуля).
Начинать работу сервиса лучше с события смены окна:
event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
Если весь алгоритм действий уже готов, то можно запускать сервис автоматически через AlarmManager, например раз в сутки.
private void setRepeatTask() < Intent alarmIntent = new Intent(this, ClickService.class); PendingIntent pendingIntent = PendingIntent.getService( this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); // Запускаем в 10:00 Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 10); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, // Повторять каждые 24 часа pendingIntent); >
Отменить запуск можно вот так:
public void cancelRepeat()
Заключение
Класс AccessibilityService позволит избавиться от рутинных операций на твоем Android-устройстве. Его возможностей достаточно, чтобы реализовать почти любую задачу, главное — дать разрешения и найти кликабельный элемент на экране.
