You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 12中Magisk Root应用执行su命令仅返回部分包名求助

Android 12下Magisk Root应用无法读取完整/data/data目录的原因及解决方法

问题根源

Android 12进一步强化了应用存储沙箱与挂载命名空间隔离机制:

  • 普通App调用su时,默认会继承自身的挂载命名空间,该命名空间内的/data/data经过沙箱过滤,仅能看到自身应用及系统公共应用(如com.google.android.gms)的目录。
  • 终端模拟器启动的su会直接切换到全局挂载命名空间(对应系统init进程的命名空间),因此能看到所有应用的data目录。
  • Android 10的存储隔离机制未做如此严格的限制,Magisk的su调用默认进入全局命名空间,所以可以正常获取完整结果。

解决方案

1. 强制切换到全局挂载命名空间执行命令

在命令中加入命名空间切换指令,确保在全局视图下读取目录:
执行的命令修改为:

nsenter --mount=/proc/1/ns/mnt ls /data/data

nsenter工具可让进程进入指定的系统命名空间,/proc/1/ns/mnt是系统init进程的挂载命名空间,对应全局文件系统视图。

2. 优化su命令调用逻辑

避免通过向su进程输入命令的方式执行,改用su -c直接传递命令参数,这种方式能确保命令在正确的Superuser环境下运行,稳定性更高:
替换原代码中的命令执行方法,使用如下实现:

public static String executeCommand(String[] cmd) {
    try {
        Process process = new ProcessBuilder(cmd).start();
        // 等待命令执行完成,替代固定sleep的不可靠方式
        process.waitFor();

        // 读取错误输出
        BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
        StringBuilder errSb = new StringBuilder();
        String line;
        while ((line = errReader.readLine()) != null) {
            errSb.append(line).append("\n");
        }
        String errOutput = errSb.toString();
        if (!errOutput.trim().isEmpty()) {
            Log.e("SystemHelper", "Error: " + errOutput);
        }

        // 读取标准输出
        BufferedReader outReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        StringBuilder outSb = new StringBuilder();
        while ((line = outReader.readLine()) != null) {
            outSb.append(line).append("\n");
        }
        String output = outSb.toString();
        Log.i("SystemHelper", "Output: " + output);
        return output;
    } catch (IOException | InterruptedException e) {
        Log.e("SystemHelper", "Command execute failed", e);
        return "";
    }
}

在onCreate中调用该方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    requestPermission();
    String s = executeCommand(new String[]{"su", "-c", "nsenter --mount=/proc/1/ns/mnt ls /data/data"});
    Log.i("vvvvv", s);
    Toast.makeText(getApplicationContext(), "Result: " + s, Toast.LENGTH_LONG).show();
}

3. 清理无效权限

Manifest中的ACCESS_SUPERUSER是旧版SuperSU的权限,Magisk并不依赖该权限,直接删除即可,避免不必要的混淆。

关键修正点说明

  • 用process.waitFor()替代SystemClock.sleep(3000):固定sleep时间无法适配不同设备的命令执行速度,waitFor()会等待进程执行完毕后再读取输出,结果更可靠。
  • 采用数组传递命令参数:避免命令字符串被shell解析时出现异常,同时确保su直接接管命令的执行环境。

内容的提问来源于stack exchange,提问作者Defi Nghĩa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 23:50:40