Обнаружение, если устройство рутировано без системы

Поскольку бессистемный рут доступен в течение нескольких лет, стало "труднее" определить, является ли устройство рутованным или нет. Я начал искать возможное решение, чтобы определить, является ли устройство рутованным без системы или нет, и я до сих пор не могу найти решение. Проверять, существует ли файл по заданным путям (в / system), не имеет смысла, так как его не может быть, если устройство рутовано без системы. Кроме того, поиск приложений, управляющих корневым доступом, может не иметь смысла, так как пользователь может их не устанавливать / или просто использовать другие, не такие популярные, как Magisk, SuperSu и т. Д.

Итак, что я подумал, выполняет команду "su" и затем проверяет, работает ли оболочка в корневом режиме ("#") или нет ("$"). Но как я могу проверить, в каком режиме он работает? Насколько я знаю, после простого выполнения команды:

       Runtime.getRuntime().exec("su");

Процесс завершается, потому что "пользователь SU" больше не используется (?).

Простое представление о том, что я имею в виду с использованием ADB:

user@user:~$ adb shell
device:/ $ su

если после выполнения этой команды она становится:

device:/ #

будет знать, если устройство рутировано, если возвращено "отказано в разрешении", будет знать, что устройство не рутировано. Можно ли добиться чего-то подобного в приложении для Android?

3 ответа

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

Тем не менее, есть предложенный запрос на получение доступа к rootbeer, который должен иметь возможность обнаруживать Magisk с помощью доменных сокетов Unix, по крайней мере, до тех пор, пока метод не будет исправлен.

Там нет никакого реального способа точно сказать, что устройство не рутировано. Даже ваш тест, чтобы увидеть, существует ли su - они всегда могут просто переименовать приложение в "super" вместо su. Или "фубар". Или используйте пользовательскую версию AOSP, которая скрывает все, что вы ищете. То, что вы пытаетесь сделать, - это работать в ненадежной среде, которую вы не контролируете, и спрашивать, можно ли ей доверять. Это никогда не сработает. Вы можете доказать, что среда не заслуживает доверия, вы никогда не сможете доказать, что она заслуживает доверия.

Лучше всего использовать API SafetyNet. Хотя он не может сказать root конкретно, он даст вам знать, что устройство ненадежно. код также довольно прост.

val nonce = ByteArray(20)
SecureRandom().nextBytes(nonce)
SafetyNet.getClient(context).attest(nonce, API_KEY)
        .addOnSuccessListener(this) { response ->
            // Indicates communication with the service was successful.
            // Use response.jwsResult to get the result data.
            val resultParts = result.jwsResult.split(".")
            if (resultParts.size == 3) {
                val bytes = Base64Utils.decode(resultParts[1])
                val newString = String(bytes)
                val json = JSONObject(newString)
                    // Check json fields to see if device is secure
                    // NOTE best practice is to send this to server instead of handling locally.
                }
        }
        .addOnFailureListener(this) { e: Exception ->
            // An error occurred while communicating with the service.
            if (e is ApiException) {
                // An error with the Google Play services API contains some
                // additional details.
                // You can retrieve the status code using the
                // e.statusCode property.
            } else {
                // A different, unknown type of error occurred.
                Log.d(TAG, "Error: ${e.message}")
            }

        }

Вот разные проверенные сценарии. Пожалуйста, ознакомьтесь с документацией по Android

Другие вопросы по тегам