- «Сердце робота»: Как использовать системный API Android в личных целях
- Содержание статьи
- Немного теории
- Linux для хакера
- Уровень доступа privileged
- Уровень доступа signature
- Уровень доступа development
- Как использовать системный API?
- WRITE_SECURE_SETTINGS
- INSTALL_PACKAGES
- Вместо выводов
- Евгений Зобнин
- Realme 3 Pro : Error : java.lang.SecurityException: Permission denial: writing to settings requires:android.permission.WRITE_SECURE_SETTINGS #13802
- Comments
- Aakashgoyal89 commented Jan 6, 2020
- Environment
- Details
- Link to Appium logs
- mykola-mokhnach commented Jan 6, 2020
- mykola-mokhnach commented Jan 9, 2020
- yuneeksehgal commented Feb 18, 2020
- iamakashrao commented Mar 31, 2020
- stenes90 commented Jun 24, 2020
- zulfikarayub commented Jul 23, 2020
- Ranjith1140 commented Aug 19, 2020
- siva017 commented Oct 2, 2020
- JuanEstrellaM commented Oct 5, 2020
- priyanka-tomer commented Oct 6, 2020
«Сердце робота»: Как использовать системный API Android в личных целях
Содержание статьи
Любой, кто писал более или менее серьезный софт для разных мобильных ОС, знает, что Android — самая открытая для разработчика ОС. Доступный для сторонних приложений API здесь гораздо шире, сама система гибче, а правила размещения приложений в маркете очень либеральные. Однако и в Android есть ряд системных API, скрытых от сторонних приложений и доступных только стоковому софту. В этой статье мы попробуем разобраться, как получить доступ к этим API и какие возможности они открывают.
Немного теории
Как мы все знаем, в Android есть такое понятие — полномочия приложений (permissions, разрешения). Полномочия прописываются в файл Manifest.xml каждого приложения и определяют то, к каким функциям API сможет получить доступ приложение. Хочешь работать с камерой — добавь в Manifest.xml строку . Нужен доступ к карте памяти — android.permission.READ_EXTERNAL_STORAGE . Все просто и логично, к тому же все доступные приложениям полномочия хорошо документированы.
Есть, однако, в этой стройной схеме одна очень важная деталь, которую сами создатели Android называют уровень доступа (protection level). Чтобы понять, что это такое, попробуй добавить в Manifest.xml любого своего приложения следующую строку:
По идее, данное полномочие должно открыть доступ к API, позволяющему переводить смартфон в режим полета, включать/выключать GPS и делать другие полезные вещи. Но IDE так не считает и поэтому сразу подчеркивает строку как ошибку с формулировкой «Permission is only granted to system apps». Это и есть предупреждение о нарушении того самого уровня доступа. IDE как бы говорит нам: да, ты можешь попробовать дать своему приложению полномочие WRITE_SECURE_SETTINGS , но Android все равно не разрешит тебе использовать закрепленный за ним API до тех пор, пока ты не сделаешь свое приложение системным. А что значит «системным» в данном случае? Это значит: подпишешь его тем же цифровым ключом, каким подписана сама прошивка (иди попробуй раздобыть такой ключ у какой-нибудь Samsung или LG!).
Linux для хакера
Официально в Android существует четыре уровня доступа:
- normal — «обычные» полномочия, дающие приложению доступ к безобидным функциям, которые не получится зловредно использовать (примеры: SET_ALARM, ACCESS_NETWORK_STATE, VIBRATE). Система даже не скажет тебе, что приложение вообще их использует;
- dangerous — «опасные» полномочия, юзер будет информирован о них при установке приложения либо увидит окошко с предупреждением в Android 6.0 (примеры: READ_SMS, SEND_SMS, CALL_PHONE, READ_CALL_LOG);
- signature — доступны только приложениям, подписанным ключом прошивки (примеры: GET_TASKS, MANAGE_USERS, WRITE_SETTINGS, MOUNT_UNMOUNT_FILESYSTEMS);
- privileged — доступны приложениям, располагающимся в каталоге /system/priv-app .
В большинстве случаев уровни доступа signature и privileged равноценны. Например, чтобы получить полномочие MANAGE_USERS, приложение должно быть либо подписано ключом прошивки, либо размещено в каталоге /system/priv-app . Но есть и исключения: например, полномочие MANAGE_DEVICE_ADMIN имеет уровень доступа signature, то есть единственный способ его получить — подписать приложение ключом прошивки.
Есть также набор внутренних уровней доступа, введенных в Android для решения определенных проблем: installer, development, preinstalled, appop, pre23. По сути, это костыли, и на данном этапе ты можешь о них не думать, однако к уровню доступа development мы еще вернемся, и он нам очень сильно пригодится. А пока поговорим о том, как получить нужные нам уровни доступа и что они дают.
Уровень доступа privileged
Privileged не самый высокий уровень доступа и позволяет использовать далеко не весь API Android. Однако в большинстве случаев он оказывается вполне достаточным, так как позволяет устанавливать и удалять приложения и пользователей (INSTALL_PACKAGES, DELETE_PACKAGES, MANAGE_USERS), управлять статусной строкой (STATUS_BAR), управлять некоторыми настройками питания (WRITE_SECURE_SETTINGS), читать и изменять настройки Wi-Fi (READ_WIFI_CREDENTIAL, OVERRIDE_WIFI_CONFIG), отключать приложения и их компоненты (CHANGE_COMPONENT_ENABLED_STATE) и многое другое.
Чтобы приложение получило уровень доступа privileged, оно должно быть установлено в каталог /system/priv-app , а это значит — поставляться предустановленным в составе прошивки. Однако, имея root, мы можем поместить свое приложение в данный каталог с помощью двух функций:
Функцию runCommandWait я описывать не буду, она просто выполняет shell-команду и ждет ее завершения (подробнее читай в моей статье про написание приложений с правами root). Функция makeAppSystem, в свою очередь, принимает полное имя приложения (это то самое com.example.app, которое ты указываешь при создании нового проекта в Android Studio) и переносит его в /system/priv-app или /system/app , в зависимости от используемой версии Android. Код может показаться тебе несколько странным, на самом деле он абсолютно корректен и учитывает два фактора:
- до Android 4.4 (API Level: 20) каталога /system/priv-app не существовало и все системные приложения размещались в /system/app ;
- начиная с Android 5.0 (API Level: 21) пакеты с приложениями не просто складируются в /data/app и /system/priv-app , а размещаются внутри своих обособленных подкаталогов.
Как использовать этот код? Очень просто: ты определяешь в Manifest.xml своего приложения все privileged-полномочия, которые ему нужны, не обращая внимания на ошибки IDE. Затем в самое начало кода приложения вставляешь вызов makeAppSystem с именем самого приложения в качестве аргумента, компилируешь и запускаешь. После запуска приложение перемещает само себя в /system/priv-app , перезагружает смартфон, и ему открываются все privileged API.
Список privileged-полномочий можно посмотреть в исходниках Android. Просто ищи по слову privileged. О том, как их использовать, — чуть позже.
Уровень доступа signature
Подпись ключом прошивки позволяет получить самый высокий уровень доступа к API — signature. Имеющее такой доступ приложение может делать практически все что угодно: манипулировать любыми настройками Android (WRITE_SETTINGS, WRITE_SECURE_SETTINGS), наделять приложения правами администратора (MANAGE_DEVICE_ADMINS), программно нажимать кнопки и вводить данные в любое окно (INJECT_EVENTS) и многое другое.
Получить такой уровень доступа на стоковой прошивке почти невозможно. Ни один производитель смартфонов не предоставит тебе ключ для подписи своих прошивок. Но если речь идет о кастомной прошивке, то все становится немного проще. Например, ночные сборки того же CyanogenMod (а я напомню, что пользователей у нее больше, чем юзеров всех версий Windows Phone, вместе взятых) подписываются тестовым ключом, а его особенность в том, что он есть в открытом доступе.
Но это еще не все, в CyanogenMod есть механизм безопасности, который, в отличие от чистого Android, позволяет получать уровень доступа signature не абсолютно всем приложениям, подписанным ключом прошивки, а только тем, что размещены в /system/priv-app . Поэтому, чтобы получить уровень доступа signature в CyanogenMod (не в Cyanogen OS, я подчеркиваю), необходимо:
- Добавить в Manifest.xml приложения необходимые полномочия.
- Добавить в приложение вызов функции makeAppSystem(), описанной в предыдущем разделе.
- Подписать релизную версию приложения ключом platform из репозитория CyanogenMod.
Уровень доступа development
В Android есть специальный уровень доступа development, отличие которого заключается в том, что приложения получают его не по факту размещения в /system/priv-app или использования цифровой подписи прошивки, а динамически. То есть система может дать такой уровень доступа любому приложению, а может и отозвать обратно. Но самое важное, что, имея права root, приложение может наделить себя таким уровнем доступа самостоятельно.
Чтобы это сделать, достаточно использовать примерно такой код:
В данном случае приложение appName получит полномочие WRITE_SECURE_SETTINGS вне зависимости от того, где оно размещено и каким ключом подписано. Круто? Вне сомнения, однако WRITE_SECURE_SETTINGS — фактически единственное полезное полномочие с уровнем доступа development. Остальные четырнадцать — это полномочия для отладки и тестирования (чтение логов, дампы памяти и так далее).
Полномочия development в исходниках Android
Как использовать системный API?
Основная проблема, с которой ты столкнешься при работе с системным API, — это полное (за небольшими исключениями) отсутствие документации. Ни в официальных руководствах, ни в неофициальных ты не найдешь почти никаких упоминаний об этом. Информацию придется собирать по крупицам, прошаривая сотни страниц форумов и читая тысячи страниц исходников Android. Однако хоть и небольшую, но отправную точку в виде парочки полезных примеров мы тебе дадим.
WRITE_SECURE_SETTINGS
Полномочие WRITE_SECURE_SETTINGS появилось в Android 4.2 для защиты некоторых критически важных настроек Android. Среди таких настроек: включение/выключение режима полета, управление настройками местоположения и передачи данных. Оно защищено сразу тремя уровнями доступа: signature, privileged и development. То есть ты можешь использовать любой из перечисленных выше способов получения уровня доступа, чтобы наделить свое приложение полномочием WRITE_SECURE_SETTINGS.
Как использовать открывшиеся возможности? Например, так:
Это очень простой код, который тупо переключает смартфон в режим полета или наоборот в зависимости от текущего состояния. Все просто и лаконично.
INSTALL_PACKAGES
Как ясно из названия, полномочие INSTALL_PACKAGES позволяет «втихую» устанавливать в систему APK-пакеты. Использовать эту возможность могут либо подписанные ключом прошивки приложения (signature), либо установленные в /system/priv-app . При этом даже не обязательно использовать Java API, достаточно вызвать консолью команду pm (Package Manager) с нужными параметрами:
После отработки команды пакет apkPath будет установлен в систему. Ты можешь возразить, что то же самое можно сделать и с правами root, и будешь прав: в данном случае достаточно изменить последний аргумент функции runCommandWait() на true. Однако стоит иметь в виду, что приложения с правами root, во-первых, приводят к появлению окна запроса соответствующих полномочий у юзера, а во-вторых, логируются тем же SuperSU. А так достаточно один раз прописать свою софтину в /system/priv-app , и она сможет устанавливать сколько угодно софта без всяких вопросов.
Вместо выводов
Вот и все. Доступ к закрытому API в Android не так уж и сложно получить. С другой стороны, с легитимным софтом использовать его в большинстве случаев не имеет смысла, проще получить права root и вызывать соответствующие консольные команды: settings для изменения настроек, pm для установки/удаления приложений, setprop для изменения низкоуровневых настроек и так далее. Однако если речь идет о не совсем обычном программном обеспечении.
Евгений Зобнин
Редактор рубрики X-Mobile. По совместительству сисадмин. Большой фанат Linux, Plan 9, гаджетов и древних видеоигр.
Источник
Realme 3 Pro : Error : java.lang.SecurityException: Permission denial: writing to settings requires:android.permission.WRITE_SECURE_SETTINGS #13802
Comments
Aakashgoyal89 commented Jan 6, 2020
I am getting below error when try to automate calculator or Amazon app in my Real device(Realme 3 Pro) with USB debugging mode enabled
Exception in thread «main» org.openqa.selenium.SessionNotCreatedException: Unable to create a new remote session. Please check the server log for more details. Original error: An unknown server-side error occurred while processing the command. Original error: Error executing adbExec. Original error: ‘Command ‘C:\Users\aakas\AppData\Local\Android\Sdk\platform-tools\adb.exe -P 5037 -s 8d226962 shell settings delete global hidden_api_policy_pre_p_apps’ exited with code 255′; Stderr: ‘Security exception: Permission denial: writing to settings requires:android.permission.WRITE_SECURE_SETTINGS
Environment
- Appium version (or git revision) that exhibits the issue: Appium v1.15.1
- Desktop OS/version used to run Appium: Windows 10
- Mobile platform/version under test: Android 9
- Real device : Realme 3 Pro
- Appium.app|exe:
Details
I have enabled USB debugging under developer option my phone, also enabled verify apps over USB option
Running ADB device also gives following result
C:\Users\aakas>adb devices
List of devices attached
8d226962 device
Still on running my code I get Above error
Link to Appium logs
Code To Reproduce Issue
public class Amazon <
private static AndroidDriver driver;
public static void main(String[] args) throws MalformedURLException, InterruptedException <
The text was updated successfully, but these errors were encountered:
mykola-mokhnach commented Jan 6, 2020
It looks like this device has additional security limitations made by its vendor. Please use another device model for the automation purposes or contact its vendor about how these restrictions could be relaxed or removed
mykola-mokhnach commented Jan 9, 2020
Closed as third party issue
yuneeksehgal commented Feb 18, 2020
This can be fixed by enabling all these highlighted options from your android
iamakashrao commented Mar 31, 2020
In your phone developer options (Security settings), enable USB Debugging or (or and) Disable permission monitoring. All of these settings are in your dev options.
stenes90 commented Jun 24, 2020
This can be fixed by enabling all these highlighted options from your android
Dude this helped. Thanks a lot
zulfikarayub commented Jul 23, 2020
This can be fixed by enabling all these highlighted options from your android
Dude this helped. Thanks a lot
This works perfectly !!
Thank a lot
Ranjith1140 commented Aug 19, 2020
This can be fixed by enabling all these highlighted options from your android
siva017 commented Oct 2, 2020
This can be fixed by enabling all these highlighted options from your android
Dude this helped. Thanks a lot
JuanEstrellaM commented Oct 5, 2020
I have the same error, with my phone (Realme C3), I solved with the following way:
First Enable Developer Option second step enable USB Debugging
And very important Step:
Step 3. Search for «Disable Permission Monitoring» and Enable it.
priyanka-tomer commented Oct 6, 2020
I am still facing the same error, with my phone (Realme X), i have follwed the below steps
First Enable Developer Option second step enable USB Debugging
And very important Step:
Step 3. Search for «Disable Permission Monitoring» and Enable it.
eclipse error log:
below error i am recived after follwing above steps:
Источник