当前位置: 首页 > article >正文

Android 检测设备是否 Root

为了安全起见,很多Android应用会阻止在已 Root 的设备上运行,因为Root设备可能会给恶意应用带来系统级别的权限,进而泄露数据或对系统进行破坏。

在代码层面,可以通过一些方法检测设备是否已经Root。以下是常见的几种方法:

1. 检查常见的Root文件路径

Root后的Android设备通常会包含一些文件或路径,开发者可以检查这些路径来确定设备是否被Root。常见的Root文件和路径包括:

  • /system/bin/su
  • /system/xbin/su
  • /system/app/Superuser.apk
  • /data/data/com.noshufou.android.su/
  • /system/etc/init.d/
public boolean isDeviceRooted() {
    String[] paths = {"/system/bin/su", "/system/xbin/su", "/system/app/Superuser.apk", "/system/etc/init.d/"};
    for (String path : paths) {
        File file = new File(path);
        if (file.exists()) {
            return true;
        }
    }
    return false;
}

2. 检查 su 命令是否可执行

Root设备通常会包含一个名为 su 的二进制文件,它是通过超级用户权限执行命令的工具。你可以通过执行 su 命令来检查设备是否已经Root。

public boolean isSuAvailable() {
    Process process = null;
    try {
        process = Runtime.getRuntime().exec("which su");
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = reader.readLine();
        if (line != null && line.contains("su")) {
            return true;
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (process != null) {
            process.destroy();
        }
    }
    return false;
}

3. 检查 Build 属性

Root设备可能会修改Android的 Build 属性。例如,ro.build.tags 属性可以指示设备是否是开发者版本或Root版本。

public boolean isDeviceRootedByBuildTags() {
    String buildTags = android.os.Build.TAGS;
    return buildTags != null && buildTags.contains("test-keys");
}

4. 尝试执行具有Root权限的命令

你可以尝试通过Shell执行一些需要Root权限的命令(例如 idls)来判断是否能够获取Root权限。如果能成功执行命令,则表示设备已经Root。

public boolean canExecuteRootCommands() {
    try {
        Process process = Runtime.getRuntime().exec("su");
        DataOutputStream os = new DataOutputStream(process.getOutputStream());
        os.writeBytes("id\n");
        os.flush();
        os.close();
        process.waitFor();
        return process.exitValue() == 0;
    } catch (IOException | InterruptedException e) {
        return false;
    }
}

5. 使用 SafetyNet API

Google提供了 SafetyNet API,它可以检测设备的安全状态,包括是否被Root。通过集成SafetyNet API,应用可以获得更准确的Root检测,尤其是在Google Play环境下。

SafetyNet.getClient(this).attest(nonce, apiKey)
    .addOnSuccessListener(this, response -> {
        if (response.getJwsResult() != null) {
            // 根据 response 判断是否为安全设备
        }
    })
    .addOnFailureListener(this, e -> {
        // 处理失败情况
    });

6. 检查系统属性

一些系统属性在Root后的设备上可能会发生变化,比如 ro.debuggablero.secure

public boolean isDeviceRootedBySystemProperties() {
    return checkProperty("ro.debuggable") || checkProperty("ro.secure");
}

private boolean checkProperty(String prop) {
    try {
        String result = getSystemProperty(prop);
        return result != null && !result.equals("1");
    } catch (Exception e) {
        return false;
    }
}

private String getSystemProperty(String prop) {
    String result = null;
    try {
        Class<?> systemProperties = Class.forName("android.os.SystemProperties");
        result = (String) systemProperties.getMethod("get", String.class).invoke(null, prop);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return result;
}

7. 检查运行时是否有root权限

通过 Runtime.getRuntime().exec("su") 来判断当前进程是否能够获得Root权限。

public boolean checkRootPermission() {
    try {
        Process process = Runtime.getRuntime().exec("su");
        process.waitFor();
        return process.exitValue() == 0;
    } catch (IOException | InterruptedException e) {
        return false;
    }
}

8. 检查是否能够访问敏感系统文件

Root后,应用通常能够访问一些系统文件和目录,检查是否能够访问这些文件来判断设备是否已Root。

public boolean checkForRoot() {
    try {
        String[] paths = {"/system/xbin/su", "/system/bin/su"};
        for (String path : paths) {
            if (new File(path).exists()) {
                return true;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

9. 使用Root检测库

有些开源库可以帮助你检测设备是否Root,如RootBeer库。RootBeer是一个专门用来检测Android设备是否Root的开源库,它提供了较为全面的检测方法。

使用RootBeer

  1. 添加依赖:

    build.gradle中添加依赖:

    dependencies {
        implementation 'com.scottyab:rootbeer-lib:0.0.6'
    }
    
  2. 代码使用:

    使用RootBeer库检测Root设备:

    RootBeer rootBeer = new RootBeer(getApplicationContext());
    boolean isRooted = rootBeer.isRooted();
    if (isRooted) {
        // 设备已Root
    } else {
        // 设备未Root
    }
    

10. 通过反向工程和系统漏洞进行检测

可以通过以下方式进行进一步的安全检查,但这并不是一种常见的做法:

  • 检查是否可以调用受保护的API:有些Root工具可能会使得系统API调用变得不稳定或异常,因此可以在应用中通过调用一些不允许在非Root设备上执行的系统方法进行检测。
  • 检查是否存在安全漏洞:有些Root工具利用漏洞获得Root权限,这些漏洞可能在某些系统上存在。检测设备是否有这些漏洞可能有助于判断设备是否Root。

总结

为了准确判断设备是否已经Root,通常可以结合以上几种方法进行检测。单独依赖某一种方法可能会存在误判的风险(例如,某些Root工具会隐藏自己),因此建议使用多个方法的组合来增加检测的准确性。SafetyNet API是推荐的方式,它可以通过Google的服务器来验证设备的安全性,避免了本地Root检测的很多限制。


http://www.kler.cn/a/461121.html

相关文章:

  • overleaf写学术论文常用语法+注意事项+审阅修订
  • 信息科技伦理与道德1:绪论
  • Spring源码分析之事件机制——观察者模式(三)
  • Ubuntu 24.04 LTS 解决网络连接问题
  • 单区域OSPF配置实验
  • 智能手机多源传感器融合的室内定位方法综述
  • 【数据结构】线性数据结构——栈
  • 本地部署Hello-Algo打造私人算法教练让算法学习告别网络限制
  • 解构大语言模型(LLM)
  • 如何免费解锁 IPhone 网络
  • 如何使用 ChatGPT Prompts 写学术论文?
  • 嵌入式单片机中SPI外设控制与实现
  • 网神SecFox运维安全管理与审计系统 /authService/login接口反序列化漏洞复现 [附POC]
  • Vue.js组件开发-实现多级菜单
  • want php学习笔记
  • 【mysql】linux安装mysql客户端
  • 计算机体系结构期末考试
  • PDF怎么压缩得又小又清晰?5种PDF压缩方法
  • WPF合并C1FlexGrid表格,根据多列的值进行合并
  • JavaWeb开发(二)IDEA创建Java Web项目并部署及目录结构
  • Applied Spatial Statistics(十三)带有空间平滑器的 GAM
  • 批量新建工作表,带个性化模板一步到位-Excel易用宝
  • 12.29~12.31[net][review]need to recite[part 2]
  • 电脑主机后置音频插孔无声?还得Realtek高清晰音频管理器调教
  • 【题解】AT_abc386_d AtCoder Beginner Contest 386 D Diagonal Separation
  • 【每日学点鸿蒙知识】List+Swipe滑动冲突、下拉刷新、编译错误定位、监听生命周期、上架应用市场要求