一枚酸心果子

果子果子果子果子果子~~~

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

Shamiko模块概述

模块基本信息

开发团队:LSPosed团队
技术基础:基于Zygisk框架
主要功能:绕过各种Root检测

核心特性

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

Shamiko安装方法:

1. 下载Shamiko模块

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

  • 打开Magisk Manager应用。
  • 打开 Magisk – 设置 – 开启 Zygisk
  • 模块 – 从本地安装
  • alt text
  • 选择下载的Shamiko模块文件。
  • 安装好 Shamiko 模块,选择隐藏模式(推荐白名单模式)

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

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

Shamiko技术原理

核心隐藏机制

1
2
3
4
5
6
7
应用检测RootShamiko拦截 → 伪造系统信息 → 返回正常结果

检测su命令 → 隐藏su文件 → 返回不存在

检测Root属性 → 伪造属性值 → 返回正常值

检测Root进程 → 隐藏进程信息 → 返回空列表

技术架构

1
2
3
4
5
Zygote进程启动 → 加载Shamiko模块 → Hook系统调用 → 隐藏Root特征

应用进程启动 → 继承Shamiko Hook → 自动隐藏Root → 绕过检测

API调用拦截 → 伪造返回值 → 应用无法检测到Root

Shamiko核心实现

1. 模块初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 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;
}

return 0;
}

// 初始化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;
}

return 0;
}

2. 系统调用Hook

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 注册系统调用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);

return 0;
}

3. 文件系统隐藏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Shamiko文件系统隐藏实现
long shamiko_openat(struct pt_regs *regs) {
int dirfd = regs->di;
const char *pathname = (const char *)regs->si;
int flags = regs->dx;
mode_t mode = regs->r10;

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

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

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

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

// 判断是否为Root相关文件
bool is_root_file(const char *pathname) {
const char *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"
};

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

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

if (strstr(pathname, "magisk") != NULL) {
return true;
}

if (strstr(pathname, "superuser") != NULL) {
return true;
}

return false;
}

4. 系统属性伪造

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Shamiko系统属性伪造实现
long shamiko_getprop(struct pt_regs *regs) {
const char *name = (const char *)regs->di;
char *value = (char *)regs->si;
const char *default_value = (const char *)regs->dx;

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

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

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

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

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

if (strstr(name, "zygisk") != NULL) {
return true;
}

if (strstr(name, "su") != NULL) {
return true;
}

return false;
}

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

return "1";
}

5. 进程隐藏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// Shamiko进程隐藏实现
long shamiko_kill(struct pt_regs *regs) {
pid_t pid = regs->di;
int sig = regs->si;

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

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

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

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

FILE *fp = fopen(path, "r");
if (fp == NULL) return false;

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

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

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

return false;
}

6. API Hook实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Shamiko API Hook实现
int enable_api_hooks() {
// Hook Java层API
if (hook_java_apis() != 0) {
return -1;
}

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

return 0;
}

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

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

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

return 0;
}

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

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

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

return result;
}

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

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

return result;
}

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

const char *path_str = (*env)->GetStringUTFChars(env, path_obj, NULL);

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

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

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

return result;
}

Shamiko检测绕过

1. 传统检测绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 传统Root检测绕过
public class TraditionalRootDetector {

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

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

for (String file : rootFiles) {
if (new File(file).exists()) {
return true;
}
}
return false;
}

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

for (String prop : rootProps) {
String value = SystemProperties.get(prop, "1");
if ("0".equals(value)) {
return true;
}
}
return false;
}
}

2. 现代检测绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 现代Root检测绕过
public class ModernRootDetector {

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

private boolean checkMagisk() {
// 检测Magisk特征
if (checkMagiskProps()) return true;
if (checkMagiskFiles()) return true;
if (checkMagiskModules()) return true;
return false;
}

private boolean checkZygisk() {
// 检测Zygisk特征
if (checkZygiskProps()) return true;
if (checkZygiskFiles()) return true;
if (checkZygiskModules()) return true;
return false;
}

private boolean checkShamiko() {
// 检测Shamiko特征
if (checkShamikoProps()) return true;
if (checkShamikoFiles()) return true;
if (checkShamikoModules()) return true;
return false;
}
}

3. 反检测绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 反检测绕过
public class AntiDetection {

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

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

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

结语

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

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

持续输出技术分享,您的支持将鼓励我继续创作!