Если приложение данных, подписанное ключом поставщика, сможет запустить 'su' - PullRequest
0 голосов
/ 08 сентября 2018

Справочная информация : Я разрабатываю устройство вывесок, которое должно управляться дистанционно. Мне нужно приложение, которое может

  • Загрузка и установка новых пакетов
  • Перезагрузите устройство (для устранения неполадок)

У меня нерутированное устройство Android. У меня также есть файлы, которые, как мне говорят, являются ключами платформы.

Я разработал приложение, которое пытается запустить процесс su.

Process p = Runtime.getRuntime().exec("su");

До того, как я подписал приложение с ключами платформы, он выдавал IOException с сообщением Permission Denied.

Я подписал приложение этими ключами платформы и все еще получаю исключение Permission Denied.

Вот три противоречивых утверждения. Какое из этих утверждений (если есть) является правильным?

Устав 1 : Это должно сработать. Приложение, даже если оно хранится в /data/app, должно иметь возможность запускать su. Либо у меня неправильные ключи, либо есть другая запись, которую мне нужно добавить в манифест, чтобы он заработал.

Заявление 2 : Это не должно работать. Несмотря на то, что оно подписано ключом платформы, приложение находится в /data/app, так что это приложение для обработки данных, а не системное приложение. Приложения для обработки данных не могут запускать su на неподключенных устройствах. Если это приложение было установлено в /system/app, оно сможет запускать su. (И я не могу получить его в /system/app, потому что он не рутирован, поэтому я застрял).

Устав 3 : Это никогда не сработает. Если устройство не имеет root-прав, то НИЧЕГО не может запустить su, даже если это подписанное системное приложение.

Ответы [ 2 ]

0 голосов
/ 08 сентября 2018

Android даже не должен иметь двоичный файл su, если вы не прошивали какой-либо корневой метод для устройства, такой как Magisk или SuperSU.

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

А зачем вам вообще нужен доступ к su в качестве приложения для подписи? В любом случае у вас есть полный доступ к устройству. Если вам нужно запустить команду, у вас не должно возникнуть проблем, независимо от того, что вы запускаете, если это выполняется из пакета, подписанного платформой. Но поскольку у вас есть полный доступ, нативные API-интерфейсы должны позволять вам делать все, что вам нужно.

Что касается IOException, возвращаемого при попытке выполнить su в Процессе, это просто странная причуда Android. Если двоичный файл su не установлен, он иногда возвращает command not found, а иногда permission denied, в зависимости от устройства.

Я хочу сказать, что, если ваше приложение не является корневым менеджером, вы можете быть частью system_server и по-прежнему иметь такой же доступ к su, как и все остальные. С каким утверждением я согласен, я думаю, что № 3, хотя я не полностью согласен с этим, потому что шансов на то, что su просто не существует, или это глупый двоичный файл.

Я объяснил, почему # 1 не должно быть правдой, а # 2 просто неверно. Если вы посмотрите на платформенный манифест , каждое разрешение, которое требует привилегированного приложения, также может быть предоставлено приложениям подписи. Поэтому, даже если вы переместите свое приложение на /system/priv-app/ (/system/app/ не сделает его привилегированным), это не будет иметь значения. По сути, если ваше приложение подписано подписью платформы, не имеет значения, где оно установлено.

EDIT:

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

Чтобы использовать API, сначала добавьте следующее разрешение на AndroidManifest:

<uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />

Теперь, когда вам нужно вызвать действие перезагрузки, используйте следующий код:

IStatusBarService bar = IStatusBarService.Stub.asInterface(ServiceManager.getService(Context.STATUS_BAR_SERVICE));
bar.reboot(false); //using true here will reboot to Safe Mode

Этот метод является скрытым, поэтому, если вы используете Android Studio для редактирования и компиляции, произойдет ошибка. Вы можете использовать отражение или использовать Android Hidden API для прямого доступа к нему.

Вот как System UI реализует это в меню питания: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java

Это класс, реализующий сервис IStatusBar: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/services/core/java/com/android/server/statusbar/StatusBarManagerService.java#L969

0 голосов
/ 08 сентября 2018

Я бы пошел с Утверждением 3. Это никогда не будет работать на устройстве без рутированного Android. По крайней мере, не на последних версиях ОС Android (я понятия не имею, может ли это работать на действительно старых устройствах Android).

«su» - это приложение - для его выполнения на диске должен быть бинарный файл «su», а Android по умолчанию не предоставляет бинарный файл «su» в целях безопасности. Когда вы используете сторонние руткиты, они устанавливают свой собственный двоичный файл "su", чтобы предоставить пользователю механизм для повышения своих привилегий до уровня root.

Если ваше приложение подписано специальным ключом и получило повышенные привилегии при запуске, зачем вам в любом случае выполнять "su"?

...