在安装我的应用程序之前,我希望它检查设备是否已 root。我使用了以下代码
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;
}
Run Code Online (Sandbox Code Playgroud)
它工作正常。但我听说可以更改文件名“su”,并且可以在非根设备中创建名为“su”的文件。在这种情况下,此源不可靠。所以我想除了搜索“su”之外,还知道其他一些方法来找到有根设备。我使用了以下代码
Public static boolean checkRootMethod1()
{
String buildTags = android.os.Build.TAGS;
if (buildTags != null && buildTags.contains("test-keys")) {
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
它不能正常工作。对于有根设备,它按预期工作。但对于某些无根设备,它也显示为有根设备。由于不同设备的输出不同,我找不到解决方案..任何帮助将不胜感激
Kal*_*kar 20
如果您想限制在 root 设备中使用您的应用程序,那么您必须考虑 2 点:
1) 限制在 root 设备中下载应用程序。
2) 限制在有根设备中加载应用程序。
按照以下步骤限制从 Play 商店下载:
1) 转到 Play 商店控制台。
2) 在左侧菜单中,转到版本管理。
3)在那里,转到设备目录。
4) 然后您将获得 3 个选项卡选项,转到排除的设备。
5) 您将获得指定排除规则的选项。单击管理排除规则。
6) 您可以看到 SafetyNet 排除的选择器。选择选项:排除未通过基本完整性的设备,以及未经 google 认证的设备。
按照以下步骤限制应用程序的侧载:
1) 使用以下方法获取 API 密钥:https
: //developer.android.com/training/safetynet/attestation.html#obtain-api-key
2) 在您的 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;
}
Run Code Online (Sandbox Code Playgroud)
SAFETY_NET_CHECK_API_KEY 是第一步得到的密钥。
证明 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,
}
Run Code Online (Sandbox Code Playgroud)
JWS 响应包含指示设备状态的ctsProfileMatch和basicIntegrity。
参考:https : //developer.android.com/training/safetynet/attestation.html
尝试下面的代码:-
/**
* 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;
}
Run Code Online (Sandbox Code Playgroud)
请参阅下面的链接:-
归档时间: |
|
查看次数: |
13890 次 |
最近记录: |