Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何以编程方式查找根设备?_Android - Fatal编程技术网

Android 如何以编程方式查找根设备?

Android 如何以编程方式查找根设备?,android,Android,在安装我的应用程序之前,我希望它检查设备是否是根设备 private static boolean isRooted() return findBinary("su"); } public static boolean findBinary(String binaryName) { boolean found = false; if (!found) { String[] pl

在安装我的应用程序之前,我希望它检查设备是否是根设备

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;
    } 
   Public static boolean checkRootMethod1()

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

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

            return true;
        }

        return false;
    }
它工作正常。但我听说文件名“su”可以更改,也可以在非根设备中创建一个名为“su”的文件。在这种情况下,此源不可靠。因此我想知道除了搜索“su”以外的其他查找根设备的方法。 我使用了以下代码

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;
    } 
   Public static boolean checkRootMethod1()

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

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

            return true;
        }

        return false;
    }
它工作不正常。对于根设备,它按预期工作。但对于某些非根设备,它也显示为根设备。由于不同设备的输出不同,我无法找到解决方案。如有任何帮助,将不胜感激。

请尝试以下代码:-

 /**
   * 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;
  }
请参阅以下链接:-


如果你想限制你的应用在根设备上的使用,那么你必须考虑两点:
1) 限制在根设备中下载应用程序。
2) 在根设备中限制应用程序的侧面加载。

按照以下步骤限制从play store下载:
1) 转到游戏商店控制台。
2) 在左侧菜单上,转至发布管理。
3) 在其中,转到设备目录。
4) 然后您将获得3个选项卡选项,转到排除的设备。
5) 您将获得一个指定排除规则的选项。单击管理排除规则。
6) 您可以看到SafetyNet排除的选择器。选择选项:排除未通过基本完整性的设备,以及未经谷歌认证的设备。

按照以下步骤限制应用程序的侧向加载:
1) 使用以下方法获取API密钥:

2) 在gradle文件中添加safetynet依赖项。
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;
    }
安全网检查API密钥是在第一步中获得的密钥

认证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基本完整性



参考资料:

仔细研究一下。没有真正的解决方案,因为您可以通过多种方式为设备设置根目录。尝试获得最广泛的方法我对根开发了解不多,仍然是一个想法。尝试访问根权限,如果失败,则意味着设备没有根权限,或者用户不会授予您根权限。无论是哪种情况,该设备都不适合您。它会工作吗?这里只是一个猜测:尝试在需要根访问权限的目录中创建一个文件。如果你成功了,你就有根了。如果没有-您没有根,或者根访问被拒绝。这看起来不是一种非常可靠的检测根的方法。有一些可用的工具可以隐藏
su
/
超级用户的存在,从而使根检测更加困难。@nani我的新检查链接Yep michael。也就是说,我正在寻找其他方法。查找buildtags也给了我不可靠的解决方案。您好,答案很好,您能告诉我
CallSafetyNetattentionapi()
方法是异步还是阻塞?要使用它,任何基本活动只有在异步模式下进行检查时才是很好的。此外,刚刚发现这有每日配额限制,不适用于拥有大量用户群的应用程序。文档明确指出,SafetyNet API不是为根检查而设计的。