Как найти рутованное устройство программно?

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

private static boolean isRooted()

                 return findBinary("su");
        }
    public static boolean findBinary(String binaryName) {

        boolean found = false;
        if (!found) {

            String[] places = {"/sbin/", "/system/bin/", "/system/xbin/", "/data/local/xbin/",
                    "/data/local/bin/", "/system/sd/xbin/", "/system/bin/failsafe/", "/data/local/"};
            for (String where : places) {
                if ( new File( where + binaryName ).exists() ) {

                    found = true;
                    break;
                }
            }
        }
        return found;
    } 

Он работает должным образом. Но я слышал, что имя файла "su" можно изменить, а также файл с именем "su" может быть создан на нерутированных устройствах. В этом случае этот источник не является надежным. Поэтому я хочу знать какой-то другой способ найти корневое устройство, кроме поиска "su". Я использовал следующий код

   Public static boolean checkRootMethod1()

     {
        String buildTags = android.os.Build.TAGS;

        if (buildTags != null && buildTags.contains("test-keys")) {

            return true;
        }

        return false;
    }

Он не работает должным образом. Для рутованных устройств он работает как положено. Но для НЕКОТОРЫХ нерутированных устройств он также отображается как рутированный. Так как выходные данные меняются для разных устройств, я не могу найти решение... любая помощь будет оценена

4 ответа

Если вы хотите ограничить использование вашего приложения на корневом устройстве, вам нужно подумать о 2 пунктах:
1) Ограничить загрузку приложения на корневом устройстве.
2) Ограничьте загрузку неопубликованных приложений на корневом устройстве.

Выполните следующие шаги, чтобы ограничить загрузку из магазина воспроизведения:
1) Перейдите в консоль магазина воспроизведения.
2) В меню слева перейдите к управлению выпусками.
3) При этом перейдите в каталог устройств.
4) Затем вы получите 3 варианта вкладки, перейдите в Исключенные устройства. 6) Вы можете увидеть средство выбора исключения из сети SafetyNet. выберите вариант: исключить устройства, не прошедшие базовую целостность, а также устройства, не сертифицированные Google.
5) Вы получите возможность указать правила исключения. нажмите на управление правилами исключения.

Выполните следующие шаги, чтобы ограничить загрузку неопубликованных приложений:
1) Получите ключ API, используя: https://developer.android.com/training/safetynet/attestation.html

2) Добавьте зависимость safetynet в свой gradle файл.
implementation 'com.google.android.gms:play-services-safetynet:17.0.0'

3) Я поместил ниже код в мою BaseActivity, который расширяет мои другие действия, поэтому, если хакер с рутированным устройством пытается выполнить боковую загрузку и пытается войти в любое действие, выполняется следующий код.

    private void ifGooglePlayServicesValid() {
        if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(getApplicationContext())
                == ConnectionResult.SUCCESS) {
            // The SafetyNet Attestation API is available.
            callSafetyNetAttentationApi();

        } else {
            // Prompt user to update Google Play services.
        }
    }

    private void callSafetyNetAttentationApi() {
        SafetyNet.getClient(this).attest(generateNonce(), SAFETY_NET_CHECK_API_KEY)
            .addOnSuccessListener(this,
                response -> {
                    // Use response.getJwsResult() to get the result data.
                    String jwsResponse = decodeJws(response.getJwsResult());
                    try {
                        JSONObject attestationResponse = new JSONObject(jwsResponse);
                        boolean ctsProfileMatch = attestationResponse.getBoolean("ctsProfileMatch");
                        boolean basicIntegrity = attestationResponse.getBoolean("basicIntegrity");
                        if (!ctsProfileMatch || !basicIntegrity) {
                            // this indicates it's rooted/tampered device
                        }
                    } catch (JSONException e) {
                        // json exception
                    }
                })
            .addOnFailureListener(this, e -> {
                // An error occurred while communicating with the service.
            });
    }

    public String decodeJws(String jwsResult) {
        if (jwsResult == null) {
            return null;
        }
        final String[] jwtParts = jwsResult.split("\\.");
        if (jwtParts.length == 3) {
            return new String(Base64.decode(jwtParts[1], Base64.DEFAULT));
        } else {
            return null;
        }
    }

    private byte[] generateNonce() {
        byte[] nonce = new byte[16];
        new SecureRandom().nextBytes(nonce);
        return nonce;
    }

SAFETY_NET_CHECK_API_KEY - это ключ, полученный на 1-м шаге.

API аттестации возвращает ответ JWS, который выглядит следующим образом:

{
  "timestampMs": 9860437986543,
  "nonce": "R2Rra24fVm5xa2Mg",
  "apkPackageName": "com.package.name.of.requesting.app",
  "apkCertificateDigestSha256": ["base64 encoded, SHA-256 hash of the
                                  certificate used to sign requesting app"],
  "ctsProfileMatch": true,
  "basicIntegrity": true,
}

Ответ JWS содержит ctsProfileMatch и basicIntegrity, которые указывают состояние устройства. Ссылка: https://developer.android.com/training/safetynet/attestation.html


public static boolean checkRooted()
{
    try
    {
        Process p = Runtime.getRuntime().exec("su", null, new File("/"));
        DataOutputStream os = new DataOutputStream( p.getOutputStream());
        os.writeBytes("pwd\n");
        os.writeBytes("exit\n");
        os.flush();
        p.waitFor();
        p.destroy();
    }
    catch (Exception e)
    {
        return false;
    }

    return true;
}

Ранее мы обнаруживали устройства с root-правами и взломанными устройствами с помощью API аттестации SafetyNet. однако этот API устарел, поэтому нам необходимо переключиться на Play Integrity API.

Play Integrity API предоставит приведенную ниже информацию.

  1. Было ли приложение установлено из вашего списка Google Play Store или нет? Это поможет вам гарантировать, что ваши пользователи не используют подделанные версии вашего приложения.
  2. Является ли приложение лицензионным и было куплено пользователем в Play Store - после оплаты, или это пиратская версия?
  3. Является ли само устройство доверенным устройством или оно является рутированным, подделанным или иным образом не считается безопасным устройством.

Аттестация SafetyNet — https://developer.android.com/training/safetynet/attestation.

Play Integrity API – https://developer.android.com/google/play/integrity/overview.

Попробуйте ниже код:-

 /**
   * Checks if the device is rooted.
   *
   * @return <code>true</code> if the device is rooted, <code>false</code> otherwise.
   */
  public static boolean isRooted() {

    // get from build info
    String buildTags = android.os.Build.TAGS;
    if (buildTags != null && buildTags.contains("test-keys")) {
      return true;
    }

    // check if /system/app/Superuser.apk is present
    try {
      File file = new File("/system/app/Superuser.apk");
      if (file.exists()) {
        return true;
      }
    } catch (Exception e1) {
      // ignore
    }

    // try executing commands
    return canExecuteCommand("/system/xbin/which su")
        || canExecuteCommand("/system/bin/which su") || canExecuteCommand("which su");
  }

  // executes a command on the system
  private static boolean canExecuteCommand(String command) {
    boolean executedSuccesfully;
    try {
      Runtime.getRuntime().exec(command);
      executedSuccesfully = true;
    } catch (Exception e) {
      executedSuccesfully = false;
    }

    return executedSuccesfully;
  }

см. ссылку ниже:-

Определите, работает ли на рутированном устройстве

Определение, если устройство Android рутируется программно?

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