Skip to content

Commit c1e45e9

Browse files
committed
add: zygiskd C99 APatch support
This commit adds support for zygiskd C99 to recognize APatch rooted devices.
1 parent 19d2a17 commit c1e45e9

13 files changed

Lines changed: 481 additions & 207 deletions

File tree

zygiskd/build.gradle.kts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ fun getLatestNDKPath(): String {
1414
throw Exception("NDK not found at $ndkPath")
1515
}
1616

17-
val ndkVersion = ndkDir.toFile().listFiles().filter { it.isDirectory }.map { it.name }.sorted().last()
17+
// get 2nd latest version
18+
val ndkVersion = ndkDir.toFile().listFiles().filter { it.isDirectory }.map { it.name }.sorted().reversed().getOrNull(1)
1819
return ndkPath + "/" + ndkVersion
1920
}
2021

@@ -26,6 +27,14 @@ val verCode: Int by rootProject.extra
2627
val verName: String by rootProject.extra
2728
val commitHash: String by rootProject.extra
2829

30+
val CStandardFlags = arrayOf(
31+
"-DMIN_APATCH_VERSION=$minAPatchVersion",
32+
"-DMIN_KSU_VERSION=$minKsuVersion",
33+
"-DMAX_KSU_VERSION=$maxKsuVersion",
34+
"-DMIN_MAGISK_VERSION=$minMagiskVersion",
35+
"-DZKSU_VERSION=\"$verName\""
36+
)
37+
2938
val CFlagsRelease = arrayOf(
3039
"-D_GNU_SOURCE", "-std=c99", "-Wpedantic", "-Wall", "-Wextra", "-Werror",
3140
"-Wformat", "-Wuninitialized", "-Wshadow", "-Wno-zero-length-array",
@@ -41,6 +50,7 @@ val CFlagsDebug = arrayOf(
4150
)
4251

4352
val Files = arrayOf(
53+
"root_impl/apatch.c",
4454
"root_impl/common.c",
4555
"root_impl/kernelsu.c",
4656
"companion.c",
@@ -94,7 +104,7 @@ task("buildAndStrip") {
94104
x86OutputDir.mkdirs()
95105
x86_64OutputDir.mkdirs()
96106

97-
val compileArgs = if (isDebug) CFlagsDebug else CFlagsRelease
107+
val compileArgs = (if (isDebug) CFlagsDebug else CFlagsRelease) + CStandardFlags
98108

99109
exec {
100110
commandLine(aarch64Compiler, "-o", Paths.get(aarch64OutputDir.toString(), "zygiskd").toString(), *compileArgs, *Files)

zygiskd/src/companion.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,20 @@
1717
#include "dl.h"
1818
#include "utils.h"
1919

20-
typedef void (*ZygiskCompanionEntryFn)(int);
20+
typedef void (*zygisk_companion_entry_func)(int);
2121

22-
ZygiskCompanionEntryFn load_module(int fd) {
22+
zygisk_companion_entry_func load_module(int fd) {
2323
char path[PATH_MAX];
2424
snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
2525

2626
void *handle = android_dlopen(path, RTLD_NOW);
2727
void *entry = dlsym(handle, "zygisk_companion_entry");
2828
if (entry == NULL) return NULL;
2929

30-
return (ZygiskCompanionEntryFn)entry;
30+
return (zygisk_companion_entry_func)entry;
3131
}
3232

33-
void *ExecuteNew(void *arg) {
33+
void *call_entry(void *arg) {
3434
int fd = *((int *)arg);
3535

3636
struct stat st0;
@@ -65,13 +65,10 @@ void *ExecuteNew(void *arg) {
6565
return NULL;
6666
}
6767

68-
6968
void entry(int fd) {
7069
LOGI("companion entry fd: |%d|\n", fd);
7170

7271
char name[256 + 1];
73-
74-
/* INFO: Getting stuck here */
7572
ssize_t ret = read_string(fd, name, sizeof(name) - 1);
7673
if (ret == -1) return;
7774

@@ -84,7 +81,7 @@ void entry(int fd) {
8481

8582
LOGI("Library fd: %d\n", library_fd);
8683

87-
ZygiskCompanionEntryFn entry = load_module(library_fd);
84+
zygisk_companion_entry_func entry = load_module(library_fd);
8885

8986
LOGI("Library loaded\n");
9087

@@ -95,31 +92,43 @@ void entry(int fd) {
9592
if (entry == NULL) {
9693
LOGI("No companion entry for: %s\n", name);
9794

98-
write(fd, (void *)0, 1);
95+
uint8_t response[1] = { 0 };
96+
write(fd, &response, sizeof(response));
97+
98+
exit(0);
9999

100100
return;
101101
}
102102

103103
LOGI("Companion process created for: %s\n", name);
104104

105-
uint8_t response = 1;
105+
uint8_t response[1] = { 1 };
106106
write(fd, &response, sizeof(response));
107107

108108
while (1) {
109+
if (!check_unix_socket(fd, true)) {
110+
LOGI("Something went wrong. Bye!\n");
111+
112+
exit(0);
113+
114+
break;
115+
}
116+
109117
int client_fd;
110118
recv_fd(fd, &client_fd);
111119

112120
LOGI("New companion request from module \"%s\" with fd \"%d\"\n", name, client_fd);
113121

114122
write(fd, &response, sizeof(response));
115123

124+
/* TODO: Do we really need to allocate this..? */
116125
int *client_fd_ptr = malloc(sizeof(int));
117126
*client_fd_ptr = client_fd;
118127

119128
LOGI("Creating new thread for companion request\n");
120129

121130
pthread_t thread;
122-
pthread_create(&thread, NULL, ExecuteNew, (void *)client_fd_ptr);
131+
pthread_create(&thread, NULL, call_entry, (void *)client_fd_ptr);
123132
pthread_detach(thread);
124133
}
125134
}

zygiskd/src/constants.h

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,6 @@
77
#define true 1
88
#define false 0
99

10-
// #define MIN_APATCH_VERSION (atoi(getenv("MIN_APATCH_VERSION")))
11-
// #define MIN_KSU_VERSION (atoi(getenv("MIN_KSU_VERSION")))
12-
// #define MAX_KSU_VERSION (atoi(getenv("MAX_KSU_VERSION")))
13-
// #define MIN_MAGISK_VERSION (atoi(getenv("MIN_MAGISK_VERSION")))
14-
// #define ZKSU_VERSION (getenv("ZKSU_VERSION"))
15-
16-
#define MIN_APATCH_VERSION 0
17-
// val minKsudVersion by extra(11425)
18-
// val maxKsuVersion by extra(20000)
19-
#define MIN_KSU_VERSION 11425
20-
#define MAX_KSU_VERSION 20000
21-
#define MIN_MAGISK_VERSION 0
22-
#define ZKSU_VERSION "1.0.0"
23-
2410
#if DEBUG == false
2511
#define MAX_LOG_LEVEL ANDROID_LOG_VERBOSE
2612
#else
@@ -64,6 +50,7 @@ enum ProcessFlags: uint32_t {
6450
enum RootImplState {
6551
Supported,
6652
TooOld,
53+
Inexistent,
6754
Abnormal
6855
};
6956

zygiskd/src/main.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,7 @@
1414
int __android_log_print(int prio, const char *tag, const char *fmt, ...);
1515

1616
int main(int argc, char *argv[]) {
17-
errno = 0;
18-
/* Initialize android logger */
19-
LOGI("Initializing zygiskd\n");
20-
21-
LOGI("Argc: %d\n", argc);
22-
for (int i = 0; i < argc; i++) {
23-
LOGI("argv[%d] = %s\n", i, argv[i]);
24-
}
17+
LOGI("Initializing zygiskd: %s\n", argv[0]);
2518

2619
if (argc > 1) {
2720
if (strcmp(argv[1], "companion") == 0) {
@@ -63,10 +56,14 @@ int main(int argc, char *argv[]) {
6356
case KernelSU: {
6457
LOGI("KernelSU root implementation found.\n");
6558

59+
return 0;
60+
}
61+
case APatch: {
62+
LOGI("APatch root implementation found.\n");
63+
6664
return 0;
6765
}
6866
}
69-
7067

7168
return 0;
7269
}

zygiskd/src/root_impl/apatch.c

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
#include <stdlib.h>
2+
#include <string.h>
3+
#include <sys/stat.h>
4+
#include <unistd.h>
5+
#include <errno.h>
6+
7+
#include "../constants.h"
8+
#include "../utils.h"
9+
10+
#include "apatch.h"
11+
12+
enum RootImplState apatch_get_existence(void) {
13+
struct stat s;
14+
if (stat("/data/adb/apd", &s) != 0) {
15+
LOGE("APATCH | Failed to stat /data/adb/apd: %s\n", strerror(errno));
16+
17+
return Inexistent;
18+
}
19+
20+
char apatch_version[32];
21+
char *const argv[] = { "apd", "-V", NULL };
22+
23+
LOGI("APATCH | Checking for apd existence\n");
24+
if (!exec_command(apatch_version, sizeof(apatch_version), "/data/adb/apd", argv)) {
25+
LOGE("APATCH | Failed to execute apd binary: %s\n", strerror(errno));
26+
errno = 0;
27+
28+
return Inexistent;
29+
}
30+
31+
int version = atoi(apatch_version + strlen("apd "));
32+
LOGI("APATCH | apd version: %d\n", version);
33+
if (version == 0) return Abnormal;
34+
35+
if (version >= MIN_APATCH_VERSION && version <= 999999) return Supported;
36+
if (version >= 1 && version <= MIN_APATCH_VERSION - 1) return TooOld;
37+
38+
return Inexistent;
39+
}
40+
41+
struct package_config {
42+
uid_t uid;
43+
bool root_granted;
44+
bool umount_needed;
45+
};
46+
47+
struct packages_config {
48+
struct package_config *configs;
49+
size_t size;
50+
};
51+
52+
bool _apatch_get_package_config(struct packages_config *config) {
53+
FILE *fp = fopen("/data/adb/ap/package_config", "r");
54+
if (fp == NULL) {
55+
LOGE("APATCH | Failed to open package_config: %s\n", strerror(errno));
56+
57+
return false;
58+
}
59+
60+
char line[256];
61+
/* INFO: Skip the CSV header */
62+
fgets(line, sizeof(line), fp);
63+
64+
while (fgets(line, sizeof(line), fp) != NULL) {
65+
config->configs = realloc(config, (config->size + 1) * sizeof(struct package_config));
66+
if (config->configs == NULL) {
67+
LOGE("APATCH | Failed to realloc package config: %s\n", strerror(errno));
68+
69+
fclose(fp);
70+
71+
return false;
72+
}
73+
74+
strtok(line, ",");
75+
76+
char *exclude_str = strtok(NULL, ",");
77+
if (exclude_str == NULL) continue;
78+
79+
char *allow_str = strtok(NULL, ",");
80+
if (allow_str == NULL) continue;
81+
82+
char *uid_str = strtok(NULL, ",");
83+
if (uid_str == NULL) continue;
84+
85+
config->configs[config->size].uid = atoi(uid_str);
86+
config->configs[config->size].root_granted = strcmp(allow_str, "1") == 0;
87+
config->configs[config->size].umount_needed = strcmp(exclude_str, "1") == 0;
88+
89+
config->size++;
90+
}
91+
92+
fclose(fp);
93+
94+
return true;
95+
}
96+
97+
bool apatch_uid_granted_root(uid_t uid) {
98+
struct packages_config *config = NULL;
99+
if (!_apatch_get_package_config(config)) {
100+
free(config);
101+
102+
return false;
103+
}
104+
105+
for (size_t i = 0; i < config->size; i++) {
106+
if (config->configs[i].uid == uid) {
107+
free(config);
108+
109+
return config->configs[i].root_granted;
110+
}
111+
}
112+
113+
free(config);
114+
115+
return false;
116+
}
117+
118+
bool apatch_uid_should_umount(uid_t uid) {
119+
struct packages_config *config = NULL;
120+
if (!_apatch_get_package_config(config)) {
121+
free(config);
122+
123+
return false;
124+
}
125+
126+
for (size_t i = 0; i < config->size; i++) {
127+
if (config->configs[i].uid == uid) {
128+
free(config);
129+
130+
return config->configs[i].umount_needed;
131+
}
132+
}
133+
134+
free(config);
135+
136+
return false;
137+
}
138+
139+
bool apatch_uid_is_manager(uid_t uid) {
140+
struct stat s;
141+
if (stat("/data/user_de/0/me.bmax.apatch", &s) == -1) return false;
142+
143+
return s.st_uid == uid;
144+
}

zygiskd/src/root_impl/apatch.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef APATCH_H
2+
#define APATCH_H
3+
4+
#include "../constants.h"
5+
6+
enum RootImplState apatch_get_existence(void);
7+
8+
bool apatch_uid_granted_root(uid_t uid);
9+
10+
bool apatch_uid_should_umount(uid_t uid);
11+
12+
bool apatch_uid_is_manager(uid_t uid);
13+
14+
#endif

0 commit comments

Comments
 (0)