逆向-安卓环境下的检测

🤓5ea1


调用root限定指令

在root后的设备中往往可以使用su来提升用户的权限,那么可以借助process来在app中调用su类似的指令,然后通过读取返回的报错信息或返回的回显,来判断是否是root用户,当然,在不同防护策略下,这种判断方式可能会出现意想不到的错误

su

public static boolean isRoot_su() {
        boolean Root;
        try {
            //启动指令进程
            ProcessBuilder pb = new ProcessBuilder("su");
            pb.redirectErrorStream(true); // 将错误流和输出流合并
            Process process = pb.start();

            //从流数据中读取
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String Line;
            while( (Line = reader.readLine()) != null) {
                Log.d("MyT0ols",Line);
            }
            Root=true;
        }
        catch (IOException e) {
            Root=false;
        }
        return Root;
    }

ProcessBuilder创建shell指令进程

一般而言,只有root后的设备才能调用su命令(即执行/bin/su)来获取权限,但是有些非root设备中也会包含这个文件,但不允许使用,或是某些root设备不允许使用su指令,这使得这种方法相对而言不太稳定

which su

public static boolean isRoot_which() {
        boolean Root = false;
        //throw new RuntimeException("Test crash to check if method is called");
        Log.d("seal", "which output: ");
        try {
            //启动指令进程
            ProcessBuilder pb = new ProcessBuilder("which", "su");
            pb.redirectErrorStream(true);
            Process process = pb.start();

            //输出缓存区
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                Log.d("seal", "which output: " + line);
            }

            //直接获取回显码
            try {
                int exitCode = process.waitFor();
                Log.d("seal",String.valueOf(exitCode));
                if(exitCode == 0) {
                    Log.d("MainActivity","ROOT!");
                    Root = true;
                }
                else {
                    Root = false;
                }
            }
            catch ( InterruptedException e) {
                Root = false;
            }

        }
        catch (IOException e) {
            Root = false;
        }
        Log.d("seal", "which output: ");
        return Root;
    }

和上面的大致相同,但是由于需要读取exitcode,所以需要先输出缓冲区中的数据,否则会卡死

在测试第二种方法的时候,我发现HUAWEI设备会出现一些耐人寻味的问题,它会追踪我的which su进程,将其定义为病毒,并hook我的测试应用,导致检查错误

判定指定文件夹是否可读写

读取特定android属性