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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
| // security_detector.c
#define FLAG_ROOTED (1 << 0)
#define FLAG_EMULATOR (1 << 1)
#define FLAG_DEBUGGED (1 << 2)
#define FLAG_HOOKED (1 << 3)
#define FLAG_TAMPERED (1 << 4)
// Root 检测
static int detect_root(void) {
const char* su_paths[] = {
"/system/bin/su",
"/system/xbin/su",
"/sbin/su",
"/data/local/su",
"/data/local/bin/su",
};
for (int i = 0; i < sizeof(su_paths)/sizeof(su_paths[0]); i++) {
if (access(su_paths[i], F_OK) == 0) {
return 1;
}
}
// 检测 Magisk
if (access("/sbin/.magisk", F_OK) == 0) {
return 1;
}
return 0;
}
// 模拟器检测
static int detect_emulator(void) {
char buf[256];
// 检查 Build 属性
__system_property_get("ro.product.model", buf);
if (strstr(buf, "sdk") || strstr(buf, "Emulator")) {
return 1;
}
// 检查 QEMU 特征文件
if (access("/dev/qemu_pipe", F_OK) == 0 ||
access("/dev/goldfish_pipe", F_OK) == 0) {
return 1;
}
// 检查 CPU 特征
read_file_svc("/proc/cpuinfo", buf, sizeof(buf));
if (strstr(buf, "goldfish") || strstr(buf, "ranchu")) {
return 1;
}
return 0;
}
// Frida 检测
static int detect_frida(void) {
// 1. 检测默认端口
struct sockaddr_in addr;
int sock = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(27042); // Frida 默认端口
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
close(sock);
return 1; // 端口开放,可能有 Frida
}
close(sock);
// 2. 扫描 /proc/self/maps 查找 Frida 模块
FILE* f = fopen("/proc/self/maps", "r");
if (f) {
char line[512];
while (fgets(line, sizeof(line), f)) {
if (strstr(line, "frida") || strstr(line, "gadget")) {
fclose(f);
return 1;
}
}
fclose(f);
}
// 3. 检测 Frida 特征字符串
// (遍历内存查找 "LIBFRIDA" 等特征)
return 0;
}
// 调试器检测
static int detect_debugger(void) {
// 1. 检查 TracerPid
char buf[256];
read_file_svc("/proc/self/status", buf, sizeof(buf));
char* tracer = strstr(buf, "TracerPid:");
if (tracer) {
int pid = atoi(tracer + 10);
if (pid != 0) {
return 1;
}
}
// 2. ptrace 自检
if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) {
return 1; // 已被 ptrace
}
ptrace(PTRACE_DETACH, 0, NULL, NULL);
return 0;
}
// 综合安全检测
jint rc_check(JNIEnv* env, jobject thiz) {
int flags = 0;
if (detect_root()) flags |= FLAG_ROOTED;
if (detect_emulator()) flags |= FLAG_EMULATOR;
if (detect_debugger()) flags |= FLAG_DEBUGGED;
if (detect_frida()) flags |= FLAG_HOOKED;
return flags;
}
|