You've already forked ReZygisk
mirror of
https://github.com/PerformanC/ReZygisk.git
synced 2025-09-06 06:37:01 +00:00
Compare commits
9 Commits
48238521df
...
v1.0.0-rc.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc1b757bb8 | ||
|
|
a0a54f2153 | ||
|
|
295a62b649 | ||
|
|
b6f02b39b3 | ||
|
|
e036b1f40a | ||
|
|
9a3b2f4a79 | ||
|
|
9810eb3974 | ||
|
|
823623a96f | ||
|
|
a75b2fe2b8 |
@@ -6,13 +6,13 @@
|
||||
- **es_ES** by [@LuchoModzzz](https://github.com/Lxchoooo)
|
||||
- **es_MX** by [@LuchoModzzz](https://github.com/Lxchoooo)
|
||||
- **fr_FR** by [@GhostFRR](https://github.com/GhostFRR)
|
||||
- **ja_JP** by [@Fyphen1223](https://github.com/Fyphen1223)
|
||||
- **ja_JP** by [@Fyphen1223](https://github.com/Fyphen1223) & [@reindex-ot](https://github.com/reindex-ot)
|
||||
- **id_ID** by [@bpanca05](https://github.com/bpanca05) & [@LuckyKiddos](https://github.com/GuitarHeroStyles)
|
||||
- **it_IT** by [@thasave14](https://github.com/thasave14)
|
||||
- **pt_BR** by [@ThePedroo](https://github.com/ThePedroo)
|
||||
- **ro_RO** by [@ExtremeXT](https://github.com/ExtremeXT)
|
||||
- **ru_RU** by [@Emulond](https://github.com/Emulond) & [@AJleKcAHgP68](https://github.com/AJleKcAHgP68)
|
||||
- **tr_TR** by [@dyingwillow](https://github.com/dyingwillow)
|
||||
- **tr_TR** by [@witchfuneral](https://github.com/witchfuneral)
|
||||
- **uk_UA** by [@Kittyskj](https://github.com/Kittyskj)
|
||||
- **vi_VN** by [@RainyXeon](https://github.com/RainyXeon)
|
||||
- **zh_CN** by [@Meltartica](https://github.com/Meltartica) & [@SheepChef](https://github.com/SheepChef)
|
||||
|
||||
97
loader/src/injector/clear.c
Normal file
97
loader/src/injector/clear.c
Normal file
@@ -0,0 +1,97 @@
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/audit.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
static bool seccomp_filters_visible() {
|
||||
FILE *status_file = fopen("/proc/self/status", "r");
|
||||
if (!status_file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *needle = "Seccomp_filters:";
|
||||
char line[256];
|
||||
|
||||
while (fgets(line, sizeof(line), status_file)) {
|
||||
if (strncmp(line, needle, strlen(needle)) == 0) {
|
||||
fclose(status_file);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(status_file);
|
||||
return false;
|
||||
}
|
||||
|
||||
void send_seccomp_event() {
|
||||
if (seccomp_filters_visible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
__u32 args[4] = {0};
|
||||
|
||||
int rnd_fd = open("/dev/urandom", O_RDONLY);
|
||||
if (rnd_fd == -1) {
|
||||
PLOGE("send_seccomp_event: open(/dev/urandom)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (read(rnd_fd, &args, sizeof(args)) != sizeof(args)) {
|
||||
PLOGE("send_seccomp_event: read(rnd_fd)");
|
||||
close(rnd_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
close(rnd_fd);
|
||||
|
||||
args[0] |= 0x10000;
|
||||
|
||||
struct sock_filter filter[] = {
|
||||
/* INFO: Check syscall number */
|
||||
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
|
||||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_exit_group, 0, 9),
|
||||
|
||||
/* INFO: Load and check arg0 (lower 32 bits) */
|
||||
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, args[0])),
|
||||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, args[0], 0, 7),
|
||||
|
||||
/* INFO: Load and check arg1 (lower 32 bits) */
|
||||
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, args[1])),
|
||||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, args[1], 0, 5),
|
||||
|
||||
/* INFO: Load and check arg2 (lower 32 bits) */
|
||||
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, args[2])),
|
||||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, args[2], 0, 3),
|
||||
|
||||
/* INFO: Load and check arg3 (lower 32 bits) */
|
||||
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, args[3])),
|
||||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, args[3], 0, 1),
|
||||
|
||||
/* INFO: All match: return TRACE => will trigger PTRACE_EVENT_SECCOMP */
|
||||
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRACE),
|
||||
|
||||
/* INFO: Default: allow */
|
||||
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
};
|
||||
|
||||
struct sock_fprog prog = {
|
||||
.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
|
||||
.filter = filter,
|
||||
};
|
||||
|
||||
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
|
||||
PLOGE("send_seccomp_event: prctl(SECCOMP)");
|
||||
return;
|
||||
}
|
||||
|
||||
/* INFO: This will trigger a ptrace event, syscall will not execute due to tracee_skip_syscall */
|
||||
syscall(__NR_exit_group, args[0], args[1], args[2], args[3]);
|
||||
}
|
||||
@@ -25,4 +25,5 @@ void entry(void* addr, size_t size, const char* path) {
|
||||
|
||||
void *module_addrs[1] = { addr };
|
||||
clean_trace(path, module_addrs, 1, 1, 0, false);
|
||||
send_seccomp_event();
|
||||
}
|
||||
|
||||
@@ -773,15 +773,18 @@ void ZygiskContext::app_specialize_pre() {
|
||||
update_mnt_ns(Clean, true);
|
||||
}
|
||||
|
||||
if ((info_flags & (PROCESS_IS_MANAGER | PROCESS_ROOT_IS_MAGISK)) == (PROCESS_IS_MANAGER | PROCESS_ROOT_IS_MAGISK)) {
|
||||
if ((info_flags & PROCESS_IS_MANAGER) == PROCESS_IS_MANAGER) {
|
||||
LOGD("Manager process detected. Notifying that Zygisk has been enabled.");
|
||||
|
||||
/* INFO: This environment variable is related to Magisk Zygisk/Manager. It
|
||||
it used by Magisk's Zygisk to communicate to Magisk Manager whether
|
||||
Zygisk is working or not.
|
||||
Zygisk is working or not, allowing Zygisk modules to both work properly
|
||||
and for the manager to mark Zygisk as enabled.
|
||||
|
||||
To allow Zygisk modules to both work properly and for the manager to
|
||||
identify Zygisk, being it not built-in, as working, we also set it. */
|
||||
However, to enhance capabilities of root managers, it is also set for
|
||||
any other supported manager, so that, if they wish, they can recognize
|
||||
if Zygisk is enabled.
|
||||
*/
|
||||
setenv("ZYGISK_ENABLED", "1", 1);
|
||||
} else {
|
||||
/* INFO: Because we load directly from the file, we need to do it before we umount
|
||||
|
||||
@@ -8,3 +8,5 @@ extern size_t block_size;
|
||||
void hook_functions();
|
||||
|
||||
void clean_trace(const char *path, void **module_addrs, size_t module_addrs_length, size_t load, size_t unload, bool spoof_maps);
|
||||
|
||||
extern "C" void send_seccomp_event();
|
||||
|
||||
@@ -403,7 +403,7 @@ bool trace_zygote(int pid) {
|
||||
|
||||
int status;
|
||||
|
||||
if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_O_EXITKILL) == -1) {
|
||||
if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_O_EXITKILL | PTRACE_O_TRACESECCOMP) == -1) {
|
||||
PLOGE("seize");
|
||||
|
||||
return false;
|
||||
|
||||
@@ -522,6 +522,32 @@ int fork_dont_care() {
|
||||
return pid;
|
||||
}
|
||||
|
||||
void tracee_skip_syscall(int pid) {
|
||||
struct user_regs_struct regs;
|
||||
if (!get_regs(pid, ®s)) {
|
||||
LOGE("failed to get seccomp regs");
|
||||
exit(1);
|
||||
}
|
||||
regs.REG_SYSNR = -1;
|
||||
if (!set_regs(pid, ®s)) {
|
||||
LOGE("failed to set seccomp regs");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* INFO: It might not work, don't check for error */
|
||||
#if defined(__aarch64__)
|
||||
int sysnr = -1;
|
||||
struct iovec iov = {
|
||||
.iov_base = &sysnr,
|
||||
.iov_len = sizeof (int),
|
||||
};
|
||||
ptrace(PTRACE_SETREGSET, pid, NT_ARM_SYSTEM_CALL, &iov);
|
||||
#elif defined(__arm__)
|
||||
ptrace(PTRACE_SET_SYSCALL, pid, 0, (void*) -1);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void wait_for_trace(int pid, int *status, int flags) {
|
||||
while (1) {
|
||||
pid_t result = waitpid(pid, status, flags);
|
||||
@@ -532,7 +558,13 @@ void wait_for_trace(int pid, int *status, int flags) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!WIFSTOPPED(*status)) {
|
||||
if (*status >> 8 == (SIGTRAP | (PTRACE_EVENT_SECCOMP << 8))) {
|
||||
tracee_skip_syscall(pid);
|
||||
|
||||
ptrace(PTRACE_CONT, pid, 0, 0);
|
||||
|
||||
continue;
|
||||
} else if (!WIFSTOPPED(*status)) {
|
||||
char status_str[64];
|
||||
parse_status(*status, status_str, sizeof(status_str));
|
||||
|
||||
|
||||
@@ -37,18 +37,22 @@ void free_maps(struct maps *maps);
|
||||
#define REG_SP rsp
|
||||
#define REG_IP rip
|
||||
#define REG_RET rax
|
||||
#define REG_SYSNR orig_rax
|
||||
#elif defined(__i386__)
|
||||
#define REG_SP esp
|
||||
#define REG_IP eip
|
||||
#define REG_RET eax
|
||||
#define REG_SYSNR orig_eax
|
||||
#elif defined(__aarch64__)
|
||||
#define REG_SP sp
|
||||
#define REG_IP pc
|
||||
#define REG_RET regs[0]
|
||||
#define REG_SYSNR regs[8]
|
||||
#elif defined(__arm__)
|
||||
#define REG_SP uregs[13]
|
||||
#define REG_IP uregs[15]
|
||||
#define REG_RET uregs[0]
|
||||
#define REG_SYSNR uregs[7]
|
||||
#define user_regs_struct user_regs
|
||||
#endif
|
||||
|
||||
|
||||
93
webroot/lang/ja_JP.json
Normal file
93
webroot/lang/ja_JP.json
Normal file
@@ -0,0 +1,93 @@
|
||||
{
|
||||
"langName": "日本語",
|
||||
"global": {
|
||||
"unknown": "不明"
|
||||
},
|
||||
"smallPage": {
|
||||
"language": {
|
||||
"header": "言語を選択してください"
|
||||
},
|
||||
"theme": {
|
||||
"header": "テーマを選択してください",
|
||||
"dark": "ダーク",
|
||||
"light": "ライト",
|
||||
"system": "システムベース"
|
||||
},
|
||||
"errorh": {
|
||||
"buttons": {
|
||||
"copy": "コピー",
|
||||
"clear": "すべてのログを消去"
|
||||
},
|
||||
"header": "エラーの履歴",
|
||||
"placeholder": "エラーログは記録されていません!"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"home": {
|
||||
"header": "ホーム",
|
||||
"status": {
|
||||
"notWorking": "動作していません",
|
||||
"ok": "動作中",
|
||||
"partially": "部分的に動作中"
|
||||
},
|
||||
"info": {
|
||||
"version": "バージョン",
|
||||
"root": "Root の実装",
|
||||
"zygote": {
|
||||
"injected": "インジェクト済み",
|
||||
"notInjected": "未インジェクト",
|
||||
"unknown": "不明"
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": {
|
||||
"header": "モジュール",
|
||||
"notAvaliable": "Zygisk を使用するモジュールはありません。",
|
||||
"arch": "アーキテクチャ: "
|
||||
},
|
||||
"actions": {
|
||||
"header": "アクション",
|
||||
"monitorButton": {
|
||||
"start": "開始",
|
||||
"stop": "停止",
|
||||
"pause": "一時停止"
|
||||
},
|
||||
"monitor": "監視",
|
||||
"status": {
|
||||
"tracing": "トレース中",
|
||||
"stopping": "停止中",
|
||||
"stopped": "停止済み",
|
||||
"exiting": "終了中",
|
||||
"unknown": "不明"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"header": "設定",
|
||||
"font": {
|
||||
"header": "システムフォントを有効化",
|
||||
"description": "現在の WebUI でシステムフォントの使用を有効化します。注意: FlipFont との互換性がない場合があります"
|
||||
},
|
||||
"theme": {
|
||||
"header": "システムテーマ",
|
||||
"description": "WebUI のシステムテーマを変更します"
|
||||
},
|
||||
"language": {
|
||||
"header": "言語の変更",
|
||||
"description": "言語を変更します"
|
||||
},
|
||||
"logs": {
|
||||
"header": "エラーの履歴",
|
||||
"description": "すべてのエラーログを表示します"
|
||||
},
|
||||
"credits": {
|
||||
"module": "モジュールの開発者",
|
||||
"original": "オリジナルの開発者",
|
||||
"web": "WebUI の開発者"
|
||||
},
|
||||
"license": {
|
||||
"module": "モジュールのライセンス",
|
||||
"web": "WebUI のライセンス"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ void root_impls_setup(void) {
|
||||
impl.impl = Multiple;
|
||||
} else if (state_ksu.state == Supported) {
|
||||
impl.impl = KernelSU;
|
||||
impl.variant = state_ksu.variant;
|
||||
} else if (state_apatch.state == Supported) {
|
||||
impl.impl = APatch;
|
||||
} else if (state_magisk.state == Supported) {
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
#define CMD_GET_VERSION 2
|
||||
#define CMD_UID_GRANTED_ROOT 12
|
||||
#define CMD_UID_SHOULD_UMOUNT 13
|
||||
#define CMD_GET_MANAGER_UID 16
|
||||
#define CMD_HOOK_MODE 0xC0DEAD1A
|
||||
|
||||
static enum kernelsu_variants variant = KOfficial;
|
||||
|
||||
static bool supports_manager_uid_retrieval = false;
|
||||
|
||||
void ksu_get_existence(struct root_impl_state *state) {
|
||||
int version = 0;
|
||||
@@ -42,6 +48,26 @@ void ksu_get_existence(struct root_impl_state *state) {
|
||||
}
|
||||
|
||||
state->state = Supported;
|
||||
|
||||
char mode[16] = { 0 };
|
||||
prctl((signed int)KERNEL_SU_OPTION, CMD_HOOK_MODE, mode, 0, 0);
|
||||
|
||||
if (mode[0] != '\0') state->variant = KNext;
|
||||
else state->variant = KOfficial;
|
||||
|
||||
variant = state->variant;
|
||||
|
||||
/* INFO: CMD_GET_MANAGER_UID is a KernelSU Next feature, however we won't
|
||||
limit to KernelSU Next only in case other forks wish to implement
|
||||
it. */
|
||||
int reply_ok = 0;
|
||||
prctl((signed int)KERNEL_SU_OPTION, CMD_GET_MANAGER_UID, 0, 0, &reply_ok);
|
||||
|
||||
if (reply_ok == KERNEL_SU_OPTION) {
|
||||
LOGI("KernelSU implementation supports CMD_GET_MANAGER_UID.\n");
|
||||
|
||||
supports_manager_uid_retrieval = true;
|
||||
}
|
||||
}
|
||||
else if (version >= 1 && version <= MIN_KSU_VERSION - 1) state->state = TooOld;
|
||||
else state->state = Abnormal;
|
||||
@@ -68,8 +94,24 @@ bool ksu_uid_should_umount(uid_t uid) {
|
||||
}
|
||||
|
||||
bool ksu_uid_is_manager(uid_t uid) {
|
||||
/* INFO: If the manager UID is set, we can use it to check if the UID
|
||||
is the manager UID, which is more reliable than checking
|
||||
the KSU manager data directory, as spoofed builds of
|
||||
KernelSU Next have different package names.
|
||||
*/
|
||||
if (supports_manager_uid_retrieval) {
|
||||
uid_t manager_uid = 0;
|
||||
prctl(KERNEL_SU_OPTION, CMD_GET_MANAGER_UID, &manager_uid, NULL, NULL);
|
||||
|
||||
return uid == manager_uid;
|
||||
}
|
||||
|
||||
const char *manager_path = NULL;
|
||||
if (variant == KOfficial) manager_path = "/data/user_de/0/me.weishu.kernelsu";
|
||||
else if (variant == KNext) manager_path = "/data/user_de/0/com.rifsxd.ksunext";
|
||||
|
||||
struct stat s;
|
||||
if (stat("/data/user_de/0/me.weishu.kernelsu", &s) == -1) {
|
||||
if (stat(manager_path, &s) == -1) {
|
||||
if (errno != ENOENT) {
|
||||
LOGE("Failed to stat KSU manager data directory: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
|
||||
#include "../constants.h"
|
||||
|
||||
enum kernelsu_variants {
|
||||
KOfficial,
|
||||
KNext
|
||||
};
|
||||
|
||||
void ksu_get_existence(struct root_impl_state *state);
|
||||
|
||||
bool ksu_uid_granted_root(uid_t uid);
|
||||
|
||||
@@ -28,7 +28,7 @@ char *magisk_managers[] = {
|
||||
#define DEBUG_RAMDISK_MAGISK lp_select("/debug_ramdisk/magisk32", "/debug_ramdisk/magisk64")
|
||||
#define BITLESS_DEBUG_RAMDISK_MAGISK "/debug_ramdisk/magisk"
|
||||
|
||||
enum magisk_variants variant = Official;
|
||||
static enum magisk_variants variant = MOfficial;
|
||||
/* INFO: Longest path */
|
||||
static char path_to_magisk[sizeof(DEBUG_RAMDISK_MAGISK)] = { 0 };
|
||||
bool is_using_sulist = false;
|
||||
@@ -74,7 +74,7 @@ void magisk_get_existence(struct root_impl_state *state) {
|
||||
return;
|
||||
}
|
||||
|
||||
state->variant = (uint8_t)Official;
|
||||
state->variant = (uint8_t)MOfficial;
|
||||
|
||||
for (unsigned long i = 0; i < sizeof(supported_variants) / sizeof(supported_variants[0]); i++) {
|
||||
if (strstr(magisk_info, supported_variants[i])) {
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
#include "../constants.h"
|
||||
|
||||
enum magisk_variants {
|
||||
Official,
|
||||
Kitsune
|
||||
MOfficial,
|
||||
MKitsune
|
||||
};
|
||||
|
||||
void magisk_get_existence(struct root_impl_state *state);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "utils.h"
|
||||
#include "root_impl/common.h"
|
||||
#include "root_impl/kernelsu.h"
|
||||
#include "root_impl/magisk.h"
|
||||
|
||||
int clean_namespace_fd = 0;
|
||||
@@ -436,7 +437,8 @@ void stringify_root_impl_name(struct root_impl impl, char *restrict output) {
|
||||
break;
|
||||
}
|
||||
case KernelSU: {
|
||||
strcpy(output, "KernelSU");
|
||||
if (impl.variant == KOfficial) strcpy(output, "KernelSU");
|
||||
else strcpy(output, "KernelSU Next");
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -446,11 +448,8 @@ void stringify_root_impl_name(struct root_impl impl, char *restrict output) {
|
||||
break;
|
||||
}
|
||||
case Magisk: {
|
||||
if (impl.variant == 0) {
|
||||
strcpy(output, "Magisk Official");
|
||||
} else {
|
||||
strcpy(output, "Magisk Kitsune");
|
||||
}
|
||||
if (impl.variant == MOfficial) strcpy(output, "Magisk Official");
|
||||
else strcpy(output, "Magisk Kitsune");
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -786,7 +785,7 @@ int save_mns_fd(int pid, enum MountNamespaceState mns_state, struct root_impl im
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (impl.impl == Magisk && impl.variant == Kitsune && mns_state == Clean) {
|
||||
if (impl.impl == Magisk && impl.variant == MKitsune && mns_state == Clean) {
|
||||
LOGI("[Magisk] Magisk Kitsune detected, will skip cache first.");
|
||||
|
||||
/* INFO: MagiskSU of Kitsune has a special behavior: It is only mounted
|
||||
|
||||
Reference in New Issue
Block a user