MagiskRoot隐藏方案:Shamiko模块原理解析

admin 2026-04-16 04:47:56 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细解析了MagiskRoot隐藏方案Shamiko模块的技术原理与实现机制。该模块基于Zygisk框架开发,通过Hook系统调用、伪造系统属性、隐藏Root相关文件和进程等方式绕过各类检测。文章提供了完整的安装配置指南,包括白名单模式设置方法,并深入分析了其核心代码实现逻辑,展示了文件系统隐藏、属性伪造和进程隐藏的具体技术细节。 综合评分: 85 文章分类: 免杀,移动安全,红队,内网渗透,安全工具


cover_image

Magisk Root隐藏方案:Shamiko模块原理解析

哆啦安全

2025年11月1日 10:23 四川

在小说阅读器读本章

去阅读

以下文章来源于一枚酸心果子 ,作者果子

一枚酸心果子 .

不定期的分享和记录,授人以鱼也可以授人以渔,有想看的case欢迎私聊果子

在Magisk Root隐藏技术中,Shamiko模块是最强大的隐藏方案之一。本篇会简单说明他的安装方法以及深入分析Shamiko模块的技术原理,再说明他的反检测机制。

Shamiko模块概述

模块基本信息

开发团队:LSPosed团队

技术基础:基于Zygisk框架

主要功能:绕过各种Root检测

核心特性

  • 绕过SafetyNet检测
  • 绕过银行APP检测
  • 绕过游戏反作弊检测
  • 支持多种检测方法绕过
  • 基于Zygisk框架实现

Shamiko安装方法:

1. 下载Shamiko模块

  • github地址:https://github.com/LSPosed/Shamiko
  • 从LSPosed团队官方渠道下载最新版本的Shamiko模块。

2. 安装Shamiko模块 地址:https://magiskcn.com/shamiko-install.html

  • 打开Magisk Manager应用。

  • 打开 Magisk – 设置 – 开启 Zygisk

  • 模块 – 从本地安装

  • 选择下载的Shamiko模块文件。

  • 安装好 Shamiko 模块,选择隐藏模式(推荐白名单模式)

3. 推荐使用白名单模式 地址:https://magiskcn.com/shamiko-whitelist.html

  • 打开目录 /data/adb/shamiko (推荐使用MT管理器)
  • 创建 whitelist 文件(是文件,不是文件夹。不要搞错了哦)
  • 重启手机,确认已切换成功

Shamiko技术原理

核心隐藏机制

应用检测Root → Shamiko拦截 → 伪造系统信息 → 返回正常结果
    ↓
检测su命令 → 隐藏su文件 → 返回不存在
    ↓
检测Root属性 → 伪造属性值 → 返回正常值
    ↓
检测Root进程 → 隐藏进程信息 → 返回空列表

技术架构

Zygote进程启动 → 加载Shamiko模块 → Hook系统调用 → 隐藏Root特征
    ↓
应用进程启动 → 继承Shamiko Hook → 自动隐藏Root → 绕过检测
    ↓
API调用拦截 → 伪造返回值 → 应用无法检测到Root

Shamiko核心实现

1. 模块初始化

// Shamiko模块初始化
int shamiko_init() {
    // 初始化Shamiko环境
    if (init_shamiko_env() != 0) {
        return-1;
    }

    // 注册系统调用Hook
    if (register_syscall_hooks() != 0) {
        return-1;
    }

    // 启用API Hook
    if (enable_api_hooks() != 0) {
        return-1;
    }

    // 启用属性伪造
    if (enable_prop_fake() != 0) {
        return-1;
    }

    return0;
}

// 初始化Shamiko环境
int init_shamiko_env() {
    // 创建Shamiko工作目录
    mkdir("/data/adb/shamiko", 0755);

    // 加载配置文件
    if (load_shamiko_config() != 0) {
        return-1;
    }

    // 初始化隐藏规则
    if (init_hide_rules() != 0) {
        return-1;
    }

    return0;
}

2. 系统调用Hook

// 注册系统调用Hook
int register_syscall_hooks() {
    // Hook文件系统相关系统调用
    hook_syscall(__NR_openat, shamiko_openat);
    hook_syscall(__NR_faccessat, shamiko_faccessat);
    hook_syscall(__NR_stat, shamiko_stat);
    hook_syscall(__NR_newfstatat, shamiko_newfstatat);
    hook_syscall(__NR_readlinkat, shamiko_readlinkat);

    // Hook进程相关系统调用
    hook_syscall(__NR_kill, shamiko_kill);
    hook_syscall(__NR_tgkill, shamiko_tgkill);
    hook_syscall(__NR_tkill, shamiko_tkill);

    // Hook属性相关系统调用
    hook_syscall(__NR_getprop, shamiko_getprop);
    hook_syscall(__NR_setprop, shamiko_setprop);

    return0;
}

3. 文件系统隐藏

// Shamiko文件系统隐藏实现
long shamiko_openat(struct pt_regs *regs) {
    int dirfd = regs->di;
    constchar *pathname = (constchar *)regs->si;
    int flags = regs->dx;
    mode_t mode = regs->r10;

    // 检查是否为Root相关文件
    if (is_root_file(pathname)) {
        // 返回文件不存在
        regs->ax = -ENOENT;
        return0;
    }

    // 检查是否为su命令
    if (strstr(pathname, "su") != NULL) {
        // 重定向到不存在的文件
        regs->ax = -ENOENT;
        return0;
    }

    // 检查是否为Magisk相关文件
    if (strstr(pathname, "magisk") != NULL) {
        // 重定向到不存在的文件
        regs->ax = -ENOENT;
        return0;
    }

    // 正常文件访问
    return original_openat(regs);
}

// 判断是否为Root相关文件
bool is_root_file(const char *pathname) {
    constchar *root_files[] = {
        "/system/app/Superuser.apk",
        "/sbin/su",
        "/system/bin/su",
        "/system/xbin/su",
        "/data/local/xbin/su",
        "/data/local/bin/su",
        "/system/etc/init.d/99SuperSUDaemon",
        "/dev/com.koushikdutta.superuser.daemon/",
        "/system/app/Kinguser.apk",
        "/system/app/KingRoot.apk",
        "/system/app/360Root.apk",
        "/data/local/tmp/su",
        "/data/local/tmp/daemonsu",
        "/system/bin/.ext/.su",
        "/system/usr/we-need-root/su-backup",
        "/system/xbin/busybox",
        "/system/bin/busybox"
    };

&nbsp; &nbsp;&nbsp;for&nbsp;(int&nbsp;i =&nbsp;0; i <&nbsp;sizeof(root_files)/sizeof(root_files[0]); i++) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(strcmp(pathname, root_files[i]) ==&nbsp;0) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// 检查路径模式
&nbsp; &nbsp;&nbsp;if&nbsp;(strstr(pathname,&nbsp;"su") !=&nbsp;NULL) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returntrue;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;if&nbsp;(strstr(pathname,&nbsp;"magisk") !=&nbsp;NULL) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returntrue;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;if&nbsp;(strstr(pathname,&nbsp;"superuser") !=&nbsp;NULL) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returntrue;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;returnfalse;
}

4. 系统属性伪造

// Shamiko系统属性伪造实现
long&nbsp;shamiko_getprop(struct pt_regs *regs)&nbsp;{
&nbsp; &nbsp;&nbsp;constchar&nbsp;*name = (constchar&nbsp;*)regs->di;
&nbsp; &nbsp;&nbsp;char&nbsp;*value = (char&nbsp;*)regs->si;
&nbsp; &nbsp;&nbsp;constchar&nbsp;*default_value = (constchar&nbsp;*)regs->dx;

&nbsp; &nbsp;&nbsp;// 检查是否为Root相关属性
&nbsp; &nbsp;&nbsp;if&nbsp;(is_root_prop(name)) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 返回伪造的属性值
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;strcpy(value, get_fake_prop_value(name));
&nbsp; &nbsp; &nbsp; &nbsp; regs->ax =&nbsp;0;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return0;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// 正常属性获取
&nbsp; &nbsp;&nbsp;return&nbsp;original_getprop(regs);
}

// 判断是否为Root相关属性
bool&nbsp;is_root_prop(const&nbsp;char&nbsp;*name)&nbsp;{
&nbsp; &nbsp;&nbsp;constchar&nbsp;*root_props[] = {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.debuggable",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.secure",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.build.selinux",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.magisk.version",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.boot.magisk",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"persist.magisk.version",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.zygisk.version",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.boot.zygisk",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"persist.zygisk.version",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.build.tags",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.build.type",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.kernel.qemu",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.hardware",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.product.cpu.abi",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.product.cpu.abilist",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.product.cpu.abilist32",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.product.cpu.abilist64"
&nbsp; &nbsp; };

&nbsp; &nbsp;&nbsp;for&nbsp;(int&nbsp;i =&nbsp;0; i <&nbsp;sizeof(root_props)/sizeof(root_props[0]); i++) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(strcmp(name, root_props[i]) ==&nbsp;0) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// 检查属性名模式
&nbsp; &nbsp;&nbsp;if&nbsp;(strstr(name,&nbsp;"magisk") !=&nbsp;NULL) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returntrue;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;if&nbsp;(strstr(name,&nbsp;"zygisk") !=&nbsp;NULL) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returntrue;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;if&nbsp;(strstr(name,&nbsp;"su") !=&nbsp;NULL) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returntrue;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;returnfalse;
}

// 获取伪造的属性值
const&nbsp;char*&nbsp;get_fake_prop_value(const&nbsp;char&nbsp;*name)&nbsp;{
&nbsp; &nbsp;&nbsp;if&nbsp;(strcmp(name,&nbsp;"ro.debuggable") ==&nbsp;0) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return"0";
&nbsp; &nbsp; }&nbsp;elseif&nbsp;(strcmp(name,&nbsp;"ro.secure") ==&nbsp;0) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return"1";
&nbsp; &nbsp; }&nbsp;elseif&nbsp;(strcmp(name,&nbsp;"ro.build.selinux") ==&nbsp;0) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return"1";
&nbsp; &nbsp; }&nbsp;elseif&nbsp;(strcmp(name,&nbsp;"ro.build.tags") ==&nbsp;0) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return"release-keys";
&nbsp; &nbsp; }&nbsp;elseif&nbsp;(strcmp(name,&nbsp;"ro.build.type") ==&nbsp;0) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return"user";
&nbsp; &nbsp; }&nbsp;elseif&nbsp;(strcmp(name,&nbsp;"ro.kernel.qemu") ==&nbsp;0) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return"0";
&nbsp; &nbsp; }&nbsp;elseif&nbsp;(strstr(name,&nbsp;"magisk") !=&nbsp;NULL) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return"";
&nbsp; &nbsp; }&nbsp;elseif&nbsp;(strstr(name,&nbsp;"zygisk") !=&nbsp;NULL) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return"";
&nbsp; &nbsp; }&nbsp;elseif&nbsp;(strstr(name,&nbsp;"su") !=&nbsp;NULL) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return"";
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;return"1";
}

5. 进程隐藏

// Shamiko进程隐藏实现
long&nbsp;shamiko_kill(struct pt_regs *regs)&nbsp;{
&nbsp; &nbsp;&nbsp;pid_t&nbsp;pid = regs->di;
&nbsp; &nbsp;&nbsp;int&nbsp;sig = regs->si;

&nbsp; &nbsp;&nbsp;// 检查是否为Root相关进程
&nbsp; &nbsp;&nbsp;if&nbsp;(is_root_process(pid)) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 隐藏进程,不执行kill操作
&nbsp; &nbsp; &nbsp; &nbsp; regs->ax =&nbsp;0;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return0;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// 正常进程操作
&nbsp; &nbsp;&nbsp;return&nbsp;original_kill(regs);
}

// 判断是否为Root相关进程
bool&nbsp;is_root_process(pid_t&nbsp;pid)&nbsp;{
&nbsp; &nbsp;&nbsp;char&nbsp;path[256];
&nbsp; &nbsp;&nbsp;char&nbsp;cmdline[256];

&nbsp; &nbsp;&nbsp;snprintf(path,&nbsp;sizeof(path),&nbsp;"/proc/%d/cmdline", pid);

&nbsp; &nbsp; FILE *fp = fopen(path,&nbsp;"r");
&nbsp; &nbsp;&nbsp;if&nbsp;(fp ==&nbsp;NULL)&nbsp;returnfalse;

&nbsp; &nbsp; fgets(cmdline,&nbsp;sizeof(cmdline), fp);
&nbsp; &nbsp; fclose(fp);

&nbsp; &nbsp;&nbsp;// 检查进程名
&nbsp; &nbsp;&nbsp;constchar&nbsp;*root_processes[] = {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"su",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"daemonsu",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"magisk",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"magiskd",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"magiskhide",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"zygisk",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"shamiko",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"kinguser",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"kingroot",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"360root",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"rootmaster"
&nbsp; &nbsp; };

&nbsp; &nbsp;&nbsp;for&nbsp;(int&nbsp;i =&nbsp;0; i <&nbsp;sizeof(root_processes)/sizeof(root_processes[0]); i++) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(strstr(cmdline, root_processes[i]) !=&nbsp;NULL) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;returnfalse;
}

6. API Hook实现

// Shamiko API Hook实现
int&nbsp;enable_api_hooks()&nbsp;{
&nbsp; &nbsp;&nbsp;// Hook Java层API
&nbsp; &nbsp;&nbsp;if&nbsp;(hook_java_apis() !=&nbsp;0) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return-1;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// Hook Native层API
&nbsp; &nbsp;&nbsp;if&nbsp;(hook_native_apis() !=&nbsp;0) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return-1;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;return0;
}

// Hook Java层API
int&nbsp;hook_java_apis()&nbsp;{
&nbsp; &nbsp;&nbsp;// Hook SystemProperties.get
&nbsp; &nbsp;&nbsp;if&nbsp;(hook_java_method("android.os.SystemProperties",&nbsp;"get",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (void*)shamiko_system_properties_get) !=&nbsp;0) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return-1;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// Hook File.exists
&nbsp; &nbsp;&nbsp;if&nbsp;(hook_java_method("java.io.File",&nbsp;"exists",&nbsp;"()Z",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (void*)shamiko_file_exists) !=&nbsp;0) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return-1;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// Hook ProcessBuilder
&nbsp; &nbsp;&nbsp;if&nbsp;(hook_java_method("java.lang.ProcessBuilder",&nbsp;"start",&nbsp;"()Ljava/lang/Process;",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (void*)shamiko_process_builder_start) !=&nbsp;0) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return-1;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;return0;
}

// Hook SystemProperties.get
jstring&nbsp;shamiko_system_properties_get(JNIEnv *env, jclass clazz, jstring key, jstring def)&nbsp;{
&nbsp; &nbsp;&nbsp;constchar&nbsp;*key_str = (*env)->GetStringUTFChars(env, key,&nbsp;NULL);
&nbsp; &nbsp;&nbsp;constchar&nbsp;*def_str = (*env)->GetStringUTFChars(env, def,&nbsp;NULL);

&nbsp; &nbsp;&nbsp;// 检查是否为Root相关属性
&nbsp; &nbsp;&nbsp;if&nbsp;(is_root_prop(key_str)) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 返回伪造的属性值
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;constchar&nbsp;*fake_value = get_fake_prop_value(key_str);
&nbsp; &nbsp; &nbsp; &nbsp; jstring result = (*env)->NewStringUTF(env, fake_value);

&nbsp; &nbsp; &nbsp; &nbsp; (*env)->ReleaseStringUTFChars(env, key, key_str);
&nbsp; &nbsp; &nbsp; &nbsp; (*env)->ReleaseStringUTFChars(env, def, def_str);

&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;result;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// 正常属性获取
&nbsp; &nbsp; jstring result = original_system_properties_get(env, clazz, key, def);

&nbsp; &nbsp; (*env)->ReleaseStringUTFChars(env, key, key_str);
&nbsp; &nbsp; (*env)->ReleaseStringUTFChars(env, def, def_str);

&nbsp; &nbsp;&nbsp;return&nbsp;result;
}

// Hook File.exists
jboolean&nbsp;shamiko_file_exists(JNIEnv *env, jobject thiz)&nbsp;{
&nbsp; &nbsp;&nbsp;// 获取文件路径
&nbsp; &nbsp; jclass file_class = (*env)->GetObjectClass(env, thiz);
&nbsp; &nbsp; jfieldID path_field = (*env)->GetFieldID(env, file_class,&nbsp;"path",&nbsp;"Ljava/lang/String;");
&nbsp; &nbsp; jstring path_obj = (jstring)(*env)->GetObjectField(env, thiz, path_field);

&nbsp; &nbsp;&nbsp;constchar&nbsp;*path_str = (*env)->GetStringUTFChars(env, path_obj,&nbsp;NULL);

&nbsp; &nbsp;&nbsp;// 检查是否为Root相关文件
&nbsp; &nbsp;&nbsp;if&nbsp;(is_root_file(path_str)) {
&nbsp; &nbsp; &nbsp; &nbsp; (*env)->ReleaseStringUTFChars(env, path_obj, path_str);
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;JNI_FALSE;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// 正常文件检查
&nbsp; &nbsp; jboolean result = original_file_exists(env, thiz);

&nbsp; &nbsp; (*env)->ReleaseStringUTFChars(env, path_obj, path_str);

&nbsp; &nbsp;&nbsp;return&nbsp;result;
}

Shamiko检测绕过

1. 传统检测绕过

// 传统Root检测绕过
publicclass&nbsp;TraditionalRootDetector&nbsp;{

&nbsp; &nbsp;&nbsp;public&nbsp;boolean&nbsp;isRooted()&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;checkRootFiles() ||
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;checkRootProps() ||
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;checkRootProcesses();
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;private&nbsp;boolean&nbsp;checkRootFiles()&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp; String[] rootFiles = {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"/system/app/Superuser.apk",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"/sbin/su",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"/system/bin/su",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"/system/xbin/su"
&nbsp; &nbsp; &nbsp; &nbsp; };

&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;for&nbsp;(String file : rootFiles) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(new&nbsp;File(file).exists()) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returnfalse;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;private&nbsp;boolean&nbsp;checkRootProps()&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp; String[] rootProps = {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.debuggable",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.secure",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ro.build.selinux"
&nbsp; &nbsp; &nbsp; &nbsp; };

&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;for&nbsp;(String prop : rootProps) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String value = SystemProperties.get(prop,&nbsp;"1");
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;("0".equals(value)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returnfalse;
&nbsp; &nbsp; }
}

2. 现代检测绕过

// 现代Root检测绕过
publicclass&nbsp;ModernRootDetector&nbsp;{

&nbsp; &nbsp;&nbsp;public&nbsp;boolean&nbsp;isRooted()&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;checkMagisk() ||
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;checkZygisk() ||
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;checkShamiko() ||
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;checkRuntimeDetection();
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;private&nbsp;boolean&nbsp;checkMagisk()&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 检测Magisk特征
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(checkMagiskProps())&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(checkMagiskFiles())&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(checkMagiskModules())&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returnfalse;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;private&nbsp;boolean&nbsp;checkZygisk()&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 检测Zygisk特征
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(checkZygiskProps())&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(checkZygiskFiles())&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(checkZygiskModules())&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returnfalse;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;private&nbsp;boolean&nbsp;checkShamiko()&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 检测Shamiko特征
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(checkShamikoProps())&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(checkShamikoFiles())&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(checkShamikoModules())&nbsp;returntrue;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returnfalse;
&nbsp; &nbsp; }
}

3. 反检测绕过

// 反检测绕过
publicclass&nbsp;AntiDetection&nbsp;{

&nbsp; &nbsp;&nbsp;// Hook系统属性获取
&nbsp; &nbsp;&nbsp;public&nbsp;static&nbsp;String&nbsp;getSystemProperty(String key, String defaultValue)&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 返回伪造的属性值
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(isRootProp(key)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;getFakePropValue(key);
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;SystemProperties.get(key, defaultValue);
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// Hook文件存在检查
&nbsp; &nbsp;&nbsp;public&nbsp;static&nbsp;boolean&nbsp;fileExists(String path)&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 隐藏Root相关文件
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(isRootFile(path)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returnfalse;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returnnew&nbsp;File(path).exists();
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// Hook进程检查
&nbsp; &nbsp;&nbsp;public&nbsp;static&nbsp;boolean&nbsp;isProcessRunning(String processName)&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 隐藏Root相关进程
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(isRootProcess(processName)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returnfalse;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;checkProcessRunning(processName);
&nbsp; &nbsp; }
}

结语

Shamiko模块是很强大的Root隐藏方案,通过全面的系统调用Hook和API拦截,几乎可以绕过所有常见的Root检测。其技术原理基于Zygisk框架,在Zygote进程启动时加载,影响所有应用进程。

它的核心实现原理机制:基于Zygisk框架的系统调用Hook


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:哆啦安全 《Magisk Root隐藏方案:Shamiko模块原理解析》

评论:0   参与:  0