更新KernelSU(修改makefile固定版本号,不然获取失败),修正手柄home键
This commit is contained in:
parent
2b56932e17
commit
252366dee1
|
@ -17,25 +17,17 @@ ccflags-y += -I$(objtree)/security/selinux -include $(srctree)/include/uapi/asm-
|
|||
obj-$(CONFIG_KSU) += kernelsu.o
|
||||
|
||||
# .git is a text file while the module is imported by 'git submodule add'.
|
||||
ifeq ($(shell test -e $(srctree)/$(src)/../.git; echo $$?),0)
|
||||
$(shell cd $(srctree)/$(src); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin [ -f ../.git/shallow ] && git fetch --unshallow)
|
||||
KSU_GIT_VERSION := $(shell cd $(srctree)/$(src); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin git rev-list --count HEAD)
|
||||
#ifeq ($(shell test -e $(srctree)/$(src)/../.git; echo $$?),0)
|
||||
#$(shell cd $(srctree)/$(src); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin [ -f ../.git/shallow ] && git fetch --unshallow)
|
||||
KSU_GIT_VERSION := 1695
|
||||
# ksu_version: major * 10000 + git version + 200 for historical reasons
|
||||
$(eval KSU_VERSION=$(shell expr 10000 + $(KSU_GIT_VERSION) + 200))
|
||||
$(info -- KernelSU version: $(KSU_VERSION))
|
||||
ccflags-y += -DKSU_VERSION=$(KSU_VERSION)
|
||||
else # If there is no .git file, the default version will be passed.
|
||||
$(warning "KSU_GIT_VERSION not defined! It is better to make KernelSU a git submodule!")
|
||||
ccflags-y += -DKSU_VERSION=16
|
||||
endif
|
||||
|
||||
ifeq ($(shell grep -q " current_sid(void)" $(srctree)/security/selinux/include/objsec.h; echo $$?),0)
|
||||
ccflags-y += -DKSU_COMPAT_HAS_CURRENT_SID
|
||||
endif
|
||||
|
||||
ifeq ($(shell grep -q "struct selinux_state " $(srctree)/security/selinux/include/security.h; echo $$?),0)
|
||||
ccflags-y += -DKSU_COMPAT_HAS_SELINUX_STATE
|
||||
endif
|
||||
#else # If there is no .git file, the default version will be passed.
|
||||
#$(warning "KSU_GIT_VERSION not defined! It is better to make KernelSU a git submodule!")
|
||||
#ccflags-y += -DKSU_VERSION=16
|
||||
#endif
|
||||
|
||||
ifndef KSU_EXPECTED_SIZE
|
||||
KSU_EXPECTED_SIZE := 0x033b
|
||||
|
@ -56,13 +48,6 @@ $(info -- KernelSU Manager signature hash: $(KSU_EXPECTED_HASH))
|
|||
ccflags-y += -DEXPECTED_SIZE=$(KSU_EXPECTED_SIZE)
|
||||
ccflags-y += -DEXPECTED_HASH=\"$(KSU_EXPECTED_HASH)\"
|
||||
|
||||
ifeq ($(shell grep -q "int path_umount" $(srctree)/fs/namespace.c; echo $$?),0)
|
||||
ccflags-y += -DKSU_UMOUNT
|
||||
else
|
||||
$(info -- Did you know you can backport path_umount to fs/namespace.c from 5.9?)
|
||||
$(info -- Read: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#how-to-backport-path-umount)
|
||||
endif
|
||||
|
||||
ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat
|
||||
ccflags-y += -Wno-declaration-after-statement -Wno-unused-function
|
||||
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/version.h>
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
||||
#include <linux/compiler_types.h>
|
||||
#endif
|
||||
|
||||
#include "ksu.h"
|
||||
#include "klog.h" // IWYU pragma: keep
|
||||
|
|
|
@ -18,19 +18,11 @@
|
|||
#define __PT_SP_REG sp
|
||||
#define __PT_IP_REG pc
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
|
||||
#define PRCTL_SYMBOL "__arm64_sys_prctl"
|
||||
#define SYS_READ_SYMBOL "__arm64_sys_read"
|
||||
#define SYS_NEWFSTATAT_SYMBOL "__arm64_sys_newfstatat"
|
||||
#define SYS_FACCESSAT_SYMBOL "__arm64_sys_faccessat"
|
||||
#define SYS_EXECVE_SYMBOL "__arm64_sys_execve"
|
||||
#else
|
||||
#define PRCTL_SYMBOL "sys_prctl"
|
||||
#define SYS_READ_SYMBOL "sys_read"
|
||||
#define SYS_NEWFSTATAT_SYMBOL "sys_newfstatat"
|
||||
#define SYS_FACCESSAT_SYMBOL "sys_faccessat"
|
||||
#define SYS_EXECVE_SYMBOL "sys_execve"
|
||||
#endif
|
||||
|
||||
#elif defined(__x86_64__)
|
||||
|
||||
|
@ -47,19 +39,11 @@
|
|||
#define __PT_RC_REG ax
|
||||
#define __PT_SP_REG sp
|
||||
#define __PT_IP_REG ip
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
|
||||
#define PRCTL_SYMBOL "__x64_sys_prctl"
|
||||
#define SYS_READ_SYMBOL "__x64_sys_read"
|
||||
#define SYS_NEWFSTATAT_SYMBOL "__x64_sys_newfstatat"
|
||||
#define SYS_FACCESSAT_SYMBOL "__x64_sys_faccessat"
|
||||
#define SYS_EXECVE_SYMBOL "__x64_sys_execve"
|
||||
#else
|
||||
#define PRCTL_SYMBOL "sys_prctl"
|
||||
#define SYS_READ_SYMBOL "sys_read"
|
||||
#define SYS_NEWFSTATAT_SYMBOL "sys_newfstatat"
|
||||
#define SYS_FACCESSAT_SYMBOL "sys_faccessat"
|
||||
#define SYS_EXECVE_SYMBOL "sys_execve"
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error "Unsupported arch"
|
||||
|
@ -83,10 +67,6 @@
|
|||
#define PT_REGS_SP(x) (__PT_REGS_CAST(x)->__PT_SP_REG)
|
||||
#define PT_REGS_IP(x) (__PT_REGS_CAST(x)->__PT_IP_REG)
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
|
||||
#define PT_REAL_REGS(regs) ((struct pt_regs *)PT_REGS_PARM1(regs))
|
||||
#else
|
||||
#define PT_REAL_REGS(regs) ((regs))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -98,11 +98,7 @@ static void setup_groups(struct root_profile *profile, struct cred *cred)
|
|||
put_group_info(group_info);
|
||||
return;
|
||||
}
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
|
||||
group_info->gid[i] = kgid;
|
||||
#else
|
||||
GROUP_AT(group_info, i) = kgid;
|
||||
#endif
|
||||
}
|
||||
|
||||
groups_sort(group_info);
|
||||
|
@ -219,6 +215,14 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
|||
return 0;
|
||||
}
|
||||
|
||||
// TODO: find it in throne tracker!
|
||||
uid_t current_uid_val = current_uid().val;
|
||||
uid_t manager_uid = ksu_get_manager_uid();
|
||||
if (current_uid_val != manager_uid &&
|
||||
current_uid_val % 100000 == manager_uid) {
|
||||
ksu_set_manager_uid(current_uid_val);
|
||||
}
|
||||
|
||||
bool from_root = 0 == current_uid().val;
|
||||
bool from_manager = is_manager();
|
||||
|
||||
|
@ -441,14 +445,12 @@ static bool should_umount(struct path *path)
|
|||
return false;
|
||||
}
|
||||
|
||||
static int ksu_umount_mnt(struct path *path, int flags)
|
||||
static void ksu_umount_mnt(struct path *path, int flags)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) || defined(KSU_UMOUNT)
|
||||
return path_umount(path, flags);
|
||||
#else
|
||||
// TODO: umount for non GKI kernel
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
int err = path_umount(path, flags);
|
||||
if (err) {
|
||||
pr_info("umount %s failed: %d\n", path->dentry->d_iname, err);
|
||||
}
|
||||
}
|
||||
|
||||
static void try_umount(const char *mnt, bool check_mnt, int flags)
|
||||
|
@ -469,10 +471,7 @@ static void try_umount(const char *mnt, bool check_mnt, int flags)
|
|||
return;
|
||||
}
|
||||
|
||||
err = ksu_umount_mnt(&path, flags);
|
||||
if (err) {
|
||||
pr_warn("umount %s failed: %d\n", mnt, err);
|
||||
}
|
||||
ksu_umount_mnt(&path, flags);
|
||||
}
|
||||
|
||||
int ksu_handle_setuid(struct cred *new, const struct cred *old)
|
||||
|
@ -549,14 +548,8 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs)
|
|||
int option = (int)PT_REGS_PARM1(real_regs);
|
||||
unsigned long arg2 = (unsigned long)PT_REGS_PARM2(real_regs);
|
||||
unsigned long arg3 = (unsigned long)PT_REGS_PARM3(real_regs);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
|
||||
// PRCTL_SYMBOL is the arch-specificed one, which receive raw pt_regs from syscall
|
||||
unsigned long arg4 = (unsigned long)PT_REGS_SYSCALL_PARM4(real_regs);
|
||||
#else
|
||||
// PRCTL_SYMBOL is the common one, called by C convention in do_syscall_64
|
||||
// https://elixir.bootlin.com/linux/v4.15.18/source/arch/x86/entry/common.c#L287
|
||||
unsigned long arg4 = (unsigned long)PT_REGS_CCALL_PARM4(real_regs);
|
||||
#endif
|
||||
unsigned long arg5 = (unsigned long)PT_REGS_PARM5(real_regs);
|
||||
|
||||
return ksu_handle_prctl(option, arg2, arg3, arg4, arg5);
|
||||
|
@ -616,23 +609,7 @@ static int ksu_task_prctl(int option, unsigned long arg2, unsigned long arg3,
|
|||
ksu_handle_prctl(option, arg2, arg3, arg4, arg5);
|
||||
return -ENOSYS;
|
||||
}
|
||||
// kernel 4.4 and 4.9
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI)
|
||||
static int ksu_key_permission(key_ref_t key_ref, const struct cred *cred,
|
||||
unsigned perm)
|
||||
{
|
||||
if (init_session_keyring != NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (strcmp(current->comm, "init")) {
|
||||
// we are only interested in `init` process
|
||||
return 0;
|
||||
}
|
||||
init_session_keyring = cred->session_keyring;
|
||||
pr_info("kernel_compat: got init_session_keyring\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ksu_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
|
||||
struct inode *new_inode, struct dentry *new_dentry)
|
||||
{
|
||||
|
@ -650,19 +627,11 @@ static struct security_hook_list ksu_hooks[] = {
|
|||
LSM_HOOK_INIT(task_prctl, ksu_task_prctl),
|
||||
LSM_HOOK_INIT(inode_rename, ksu_inode_rename),
|
||||
LSM_HOOK_INIT(task_fix_setuid, ksu_task_fix_setuid),
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI)
|
||||
LSM_HOOK_INIT(key_permission, ksu_key_permission)
|
||||
#endif
|
||||
};
|
||||
|
||||
void __init ksu_lsm_hook_init(void)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||
security_add_hooks(ksu_hooks, ARRAY_SIZE(ksu_hooks), "ksu");
|
||||
#else
|
||||
// https://elixir.bootlin.com/linux/v4.10.17/source/include/linux/lsm_hooks.h#L1892
|
||||
security_add_hooks(ksu_hooks, ARRAY_SIZE(ksu_hooks));
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
|
@ -1,39 +1,10 @@
|
|||
#include <linux/version.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/nsproxy.h>
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
|
||||
#include <linux/sched/task.h>
|
||||
#else
|
||||
#include <linux/sched.h>
|
||||
#endif
|
||||
#include <linux/uaccess.h>
|
||||
#include "klog.h" // IWYU pragma: keep
|
||||
#include "kernel_compat.h" // Add check Huawei Device
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI)
|
||||
#include <linux/key.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/cred.h>
|
||||
struct key *init_session_keyring = NULL;
|
||||
|
||||
static inline int install_session_keyring(struct key *keyring)
|
||||
{
|
||||
struct cred *new;
|
||||
int ret;
|
||||
|
||||
new = prepare_creds();
|
||||
if (!new)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = install_session_keyring_to_cred(new, keyring);
|
||||
if (ret < 0) {
|
||||
abort_creds(new);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return commit_creds(new);
|
||||
}
|
||||
#endif
|
||||
#include "kernel_compat.h"
|
||||
|
||||
extern struct task_struct init_task;
|
||||
|
||||
|
@ -79,13 +50,6 @@ void ksu_android_ns_fs_check()
|
|||
|
||||
struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode)
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI)
|
||||
if (init_session_keyring != NULL && !current_cred()->session_keyring &&
|
||||
(current->flags & PF_WQ_WORKER)) {
|
||||
pr_info("installing init session keyring for older kernel\n");
|
||||
install_session_keyring(init_session_keyring);
|
||||
}
|
||||
#endif
|
||||
// switch mnt_ns even if current is not wq_worker, to ensure what we open is the correct file in android mnt_ns, rather than user created mnt_ns
|
||||
struct ksu_ns_fs_saved saved;
|
||||
if (android_context_saved_enabled) {
|
||||
|
@ -108,69 +72,17 @@ struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode)
|
|||
ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count,
|
||||
loff_t *pos)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
||||
return kernel_read(p, buf, count, pos);
|
||||
#else
|
||||
loff_t offset = pos ? *pos : 0;
|
||||
ssize_t result = kernel_read(p, offset, (char *)buf, count);
|
||||
if (pos && result > 0) {
|
||||
*pos = offset + result;
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t ksu_kernel_write_compat(struct file *p, const void *buf, size_t count,
|
||||
loff_t *pos)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
||||
return kernel_write(p, buf, count, pos);
|
||||
#else
|
||||
loff_t offset = pos ? *pos : 0;
|
||||
ssize_t result = kernel_write(p, buf, count, offset);
|
||||
if (pos && result > 0) {
|
||||
*pos = offset + result;
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||
long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
|
||||
long count)
|
||||
{
|
||||
return strncpy_from_user_nofault(dst, unsafe_addr, count);
|
||||
}
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
|
||||
long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
|
||||
long count)
|
||||
{
|
||||
return strncpy_from_unsafe_user(dst, unsafe_addr, count);
|
||||
}
|
||||
#else
|
||||
// Copied from: https://elixir.bootlin.com/linux/v4.9.337/source/mm/maccess.c#L201
|
||||
long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
|
||||
long count)
|
||||
{
|
||||
mm_segment_t old_fs = get_fs();
|
||||
long ret;
|
||||
|
||||
if (unlikely(count <= 0))
|
||||
return 0;
|
||||
|
||||
set_fs(USER_DS);
|
||||
pagefault_disable();
|
||||
ret = strncpy_from_user(dst, unsafe_addr, count);
|
||||
pagefault_enable();
|
||||
set_fs(old_fs);
|
||||
|
||||
if (ret >= count) {
|
||||
ret = count;
|
||||
dst[ret - 1] = '\0';
|
||||
} else if (ret > 0) {
|
||||
ret++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -24,10 +24,6 @@ extern long ksu_strncpy_from_user_nofault(char *dst,
|
|||
const void __user *unsafe_addr,
|
||||
long count);
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI)
|
||||
extern struct key *init_session_keyring;
|
||||
#endif
|
||||
|
||||
extern void ksu_android_ns_fs_check();
|
||||
extern struct file *ksu_filp_open_compat(const char *filename, int flags,
|
||||
umode_t mode);
|
||||
|
|
|
@ -94,7 +94,4 @@ module_exit(kernelsu_exit);
|
|||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("weishu");
|
||||
MODULE_DESCRIPTION("Android KernelSU");
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||
MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
|
||||
#endif
|
||||
|
|
|
@ -6,14 +6,7 @@
|
|||
#include <linux/file.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/version.h>
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
|
||||
#include <linux/input-event-codes.h>
|
||||
#else
|
||||
#include <uapi/linux/input.h>
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)
|
||||
#include <linux/aio.h>
|
||||
#endif
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/types.h>
|
||||
|
@ -470,27 +463,6 @@ bool ksu_is_safe_mode()
|
|||
|
||||
#ifdef CONFIG_KPROBES
|
||||
|
||||
// https://elixir.bootlin.com/linux/v5.10.158/source/fs/exec.c#L1864
|
||||
static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
int *fd = (int *)&PT_REGS_PARM1(regs);
|
||||
struct filename **filename_ptr =
|
||||
(struct filename **)&PT_REGS_PARM2(regs);
|
||||
struct user_arg_ptr argv;
|
||||
#ifdef CONFIG_COMPAT
|
||||
argv.is_compat = PT_REGS_PARM3(regs);
|
||||
if (unlikely(argv.is_compat)) {
|
||||
argv.ptr.compat = PT_REGS_CCALL_PARM4(regs);
|
||||
} else {
|
||||
argv.ptr.native = PT_REGS_CCALL_PARM4(regs);
|
||||
}
|
||||
#else
|
||||
argv.ptr.native = PT_REGS_PARM3(regs);
|
||||
#endif
|
||||
|
||||
return ksu_handle_execveat_ksud(fd, filename_ptr, &argv, NULL, NULL);
|
||||
}
|
||||
|
||||
static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *real_regs = PT_REAL_REGS(regs);
|
||||
|
@ -514,18 +486,6 @@ static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
|||
NULL);
|
||||
}
|
||||
|
||||
// remove this later!
|
||||
__maybe_unused static int vfs_read_handler_pre(struct kprobe *p,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
struct file **file_ptr = (struct file **)&PT_REGS_PARM1(regs);
|
||||
char __user **buf_ptr = (char **)&PT_REGS_PARM2(regs);
|
||||
size_t *count_ptr = (size_t *)&PT_REGS_PARM3(regs);
|
||||
loff_t **pos_ptr = (loff_t **)&PT_REGS_CCALL_PARM4(regs);
|
||||
|
||||
return ksu_handle_vfs_read(file_ptr, buf_ptr, count_ptr, pos_ptr);
|
||||
}
|
||||
|
||||
static int sys_read_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *real_regs = PT_REAL_REGS(regs);
|
||||
|
@ -545,35 +505,16 @@ static int input_handle_event_handler_pre(struct kprobe *p,
|
|||
return ksu_handle_input_handle_event(type, code, value);
|
||||
}
|
||||
|
||||
#if 1
|
||||
static struct kprobe execve_kp = {
|
||||
.symbol_name = SYS_EXECVE_SYMBOL,
|
||||
.pre_handler = sys_execve_handler_pre,
|
||||
};
|
||||
#else
|
||||
static struct kprobe execve_kp = {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
|
||||
.symbol_name = "do_execveat_common",
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
|
||||
.symbol_name = "__do_execve_file",
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
|
||||
.symbol_name = "do_execveat_common",
|
||||
#endif
|
||||
.pre_handler = execve_handler_pre,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
static struct kprobe vfs_read_kp = {
|
||||
.symbol_name = SYS_READ_SYMBOL,
|
||||
.pre_handler = sys_read_handler_pre,
|
||||
};
|
||||
#else
|
||||
static struct kprobe vfs_read_kp = {
|
||||
.symbol_name = "vfs_read",
|
||||
.pre_handler = vfs_read_handler_pre,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static struct kprobe input_event_kp = {
|
||||
.symbol_name = "input_event",
|
||||
|
|
|
@ -9,9 +9,7 @@
|
|||
#include "linux/lsm_audit.h"
|
||||
#include "xfrm.h"
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||
#define SELINUX_POLICY_INSTEAD_SELINUX_SS
|
||||
#endif
|
||||
|
||||
#define KERNEL_SU_DOMAIN "su"
|
||||
#define KERNEL_SU_FILE "ksu_file"
|
||||
|
@ -21,18 +19,8 @@
|
|||
static struct policydb *get_policydb(void)
|
||||
{
|
||||
struct policydb *db;
|
||||
// selinux_state does not exists before 4.19
|
||||
#ifdef KSU_COMPAT_USE_SELINUX_STATE
|
||||
#ifdef SELINUX_POLICY_INSTEAD_SELINUX_SS
|
||||
struct selinux_policy *policy = rcu_dereference(selinux_state.policy);
|
||||
db = &policy->policydb;
|
||||
#else
|
||||
struct selinux_ss *ss = rcu_dereference(selinux_state.ss);
|
||||
db = &ss->policydb;
|
||||
#endif
|
||||
#else
|
||||
db = &policydb;
|
||||
#endif
|
||||
return db;
|
||||
}
|
||||
|
||||
|
@ -181,8 +169,7 @@ static int get_object(char *buf, char __user *user_object, size_t buf_sz,
|
|||
// reset avc cache table, otherwise the new rules will not take effect if already denied
|
||||
static void reset_avc_cache()
|
||||
{
|
||||
#if ((!defined(KSU_COMPAT_USE_SELINUX_STATE)) || \
|
||||
LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0))
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0))
|
||||
avc_ss_reset(0);
|
||||
selnl_notify_policyload(0);
|
||||
selinux_status_update_policyload(0);
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
#include "objsec.h"
|
||||
#include "linux/version.h"
|
||||
#include "../klog.h" // IWYU pragma: keep
|
||||
#ifndef KSU_COMPAT_USE_SELINUX_STATE
|
||||
#include "avc.h"
|
||||
#endif
|
||||
|
||||
#define KERNEL_SU_DOMAIN "u:r:su:s0"
|
||||
|
||||
|
@ -55,32 +52,20 @@ if (!is_domain_permissive) {
|
|||
void setenforce(bool enforce)
|
||||
{
|
||||
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
|
||||
#ifdef KSU_COMPAT_USE_SELINUX_STATE
|
||||
selinux_state.enforcing = enforce;
|
||||
#else
|
||||
selinux_enforcing = enforce;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool getenforce()
|
||||
{
|
||||
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
|
||||
#ifdef KSU_COMPAT_USE_SELINUX_STATE
|
||||
if (selinux_state.disabled) {
|
||||
#else
|
||||
if (selinux_disabled) {
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
|
||||
#ifdef KSU_COMPAT_USE_SELINUX_STATE
|
||||
return selinux_state.enforcing;
|
||||
#else
|
||||
return selinux_enforcing;
|
||||
#endif
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
|
@ -131,7 +116,7 @@ bool is_zygote(void *sec)
|
|||
return result;
|
||||
}
|
||||
|
||||
#define DEVPTS_DOMAIN "u:object_r:devpts:s0"
|
||||
#define DEVPTS_DOMAIN "u:object_r:ksu_file:s0"
|
||||
|
||||
u32 ksu_get_devpts_sid()
|
||||
{
|
||||
|
@ -142,4 +127,4 @@ u32 ksu_get_devpts_sid()
|
|||
pr_info("get devpts sid err %d\n", err);
|
||||
}
|
||||
return devpts_sid;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,6 @@
|
|||
#include "linux/types.h"
|
||||
#include "linux/version.h"
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) || defined(KSU_COMPAT_HAS_SELINUX_STATE)
|
||||
#define KSU_COMPAT_USE_SELINUX_STATE
|
||||
#endif
|
||||
|
||||
void setup_selinux(const char *);
|
||||
|
||||
void setenforce(bool);
|
||||
|
|
|
@ -524,7 +524,6 @@ static bool add_filename_trans(struct policydb *db, const char *s,
|
|||
return false;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)
|
||||
struct filename_trans_key key;
|
||||
key.ttype = tgt->value;
|
||||
key.tclass = cls->value;
|
||||
|
@ -532,13 +531,8 @@ static bool add_filename_trans(struct policydb *db, const char *s,
|
|||
|
||||
struct filename_trans_datum *last = NULL;
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
|
||||
struct filename_trans_datum *trans =
|
||||
policydb_filenametr_search(db, &key);
|
||||
#else
|
||||
struct filename_trans_datum *trans =
|
||||
hashtab_search(&db->filename_trans, &key);
|
||||
#endif
|
||||
while (trans) {
|
||||
if (ebitmap_get_bit(&trans->stypes, src->value - 1)) {
|
||||
// Duplicate, overwrite existing data and return
|
||||
|
@ -567,39 +561,6 @@ static bool add_filename_trans(struct policydb *db, const char *s,
|
|||
|
||||
db->compat_filename_trans_count++;
|
||||
return ebitmap_set_bit(&trans->stypes, src->value - 1, 1) == 0;
|
||||
#else // < 5.7.0, has no filename_trans_key, but struct filename_trans
|
||||
|
||||
struct filename_trans key;
|
||||
key.ttype = tgt->value;
|
||||
key.tclass = cls->value;
|
||||
key.name = (char *)o;
|
||||
|
||||
struct filename_trans_datum *trans =
|
||||
hashtab_search(db->filename_trans, &key);
|
||||
|
||||
if (trans == NULL) {
|
||||
trans = (struct filename_trans_datum *)kcalloc(sizeof(*trans),
|
||||
1, GFP_ATOMIC);
|
||||
if (!trans) {
|
||||
pr_err("add_filename_trans: Failed to alloc datum\n");
|
||||
return false;
|
||||
}
|
||||
struct filename_trans *new_key =
|
||||
(struct filename_trans *)kmalloc(sizeof(*new_key),
|
||||
GFP_ATOMIC);
|
||||
if (!new_key) {
|
||||
pr_err("add_filename_trans: Failed to alloc new_key\n");
|
||||
return false;
|
||||
}
|
||||
*new_key = key;
|
||||
new_key->name = kstrdup(key.name, GFP_ATOMIC);
|
||||
trans->otype = def->value;
|
||||
hashtab_insert(db->filename_trans, new_key, trans);
|
||||
}
|
||||
|
||||
return ebitmap_set_bit(&db->filename_trans_ttypes, src->value - 1, 1) ==
|
||||
0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool add_genfscon(struct policydb *db, const char *fs_name,
|
||||
|
@ -626,7 +587,6 @@ static void *ksu_realloc(void *old, size_t new_size, size_t old_size)
|
|||
|
||||
static bool add_type(struct policydb *db, const char *type_name, bool attr)
|
||||
{
|
||||
#ifdef KSU_SUPPORT_ADD_TYPE
|
||||
struct type_datum *type = symtab_search(&db->p_types, type_name);
|
||||
if (type) {
|
||||
pr_warn("Type %s already exists\n", type_name);
|
||||
|
@ -656,7 +616,6 @@ static bool add_type(struct policydb *db, const char *type_name, bool attr)
|
|||
return false;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
|
||||
struct ebitmap *new_type_attr_map_array =
|
||||
ksu_realloc(db->type_attr_map_array,
|
||||
value * sizeof(struct ebitmap),
|
||||
|
@ -703,171 +662,6 @@ static bool add_type(struct policydb *db, const char *type_name, bool attr)
|
|||
}
|
||||
|
||||
return true;
|
||||
#elif defined(CONFIG_IS_HW_HISI)
|
||||
/*
|
||||
* Huawei use type_attr_map and type_val_to_struct.
|
||||
* And use ebitmap not flex_array.
|
||||
*/
|
||||
size_t new_size = sizeof(struct ebitmap) * db->p_types.nprim;
|
||||
struct ebitmap *new_type_attr_map =
|
||||
(krealloc(db->type_attr_map, new_size, GFP_ATOMIC));
|
||||
|
||||
struct type_datum **new_type_val_to_struct =
|
||||
krealloc(db->type_val_to_struct,
|
||||
sizeof(*db->type_val_to_struct) * db->p_types.nprim,
|
||||
GFP_ATOMIC);
|
||||
|
||||
if (!new_type_attr_map) {
|
||||
pr_err("add_type: alloc type_attr_map failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!new_type_val_to_struct) {
|
||||
pr_err("add_type: alloc type_val_to_struct failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
char **new_val_to_name_types =
|
||||
krealloc(db->sym_val_to_name[SYM_TYPES],
|
||||
sizeof(char *) * db->symtab[SYM_TYPES].nprim,
|
||||
GFP_KERNEL);
|
||||
if (!new_val_to_name_types) {
|
||||
pr_err("add_type: alloc val_to_name failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
db->type_attr_map = new_type_attr_map;
|
||||
ebitmap_init(&db->type_attr_map[value - 1], HISI_SELINUX_EBITMAP_RO);
|
||||
ebitmap_set_bit(&db->type_attr_map[value - 1], value - 1, 1);
|
||||
|
||||
db->type_val_to_struct = new_type_val_to_struct;
|
||||
db->type_val_to_struct[value - 1] = type;
|
||||
|
||||
db->sym_val_to_name[SYM_TYPES] = new_val_to_name_types;
|
||||
db->sym_val_to_name[SYM_TYPES][value - 1] = key;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < db->p_roles.nprim; ++i) {
|
||||
ebitmap_set_bit(&db->role_val_to_struct[i]->types, value - 1,
|
||||
1);
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
// flex_array is not extensible, we need to create a new bigger one instead
|
||||
struct flex_array *new_type_attr_map_array =
|
||||
flex_array_alloc(sizeof(struct ebitmap), db->p_types.nprim,
|
||||
GFP_ATOMIC | __GFP_ZERO);
|
||||
|
||||
struct flex_array *new_type_val_to_struct =
|
||||
flex_array_alloc(sizeof(struct type_datum *), db->p_types.nprim,
|
||||
GFP_ATOMIC | __GFP_ZERO);
|
||||
|
||||
struct flex_array *new_val_to_name_types =
|
||||
flex_array_alloc(sizeof(char *), db->symtab[SYM_TYPES].nprim,
|
||||
GFP_ATOMIC | __GFP_ZERO);
|
||||
|
||||
if (!new_type_attr_map_array) {
|
||||
pr_err("add_type: alloc type_attr_map_array failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!new_type_val_to_struct) {
|
||||
pr_err("add_type: alloc type_val_to_struct failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!new_val_to_name_types) {
|
||||
pr_err("add_type: alloc val_to_name failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// preallocate so we don't have to worry about the put ever failing
|
||||
if (flex_array_prealloc(new_type_attr_map_array, 0, db->p_types.nprim,
|
||||
GFP_ATOMIC | __GFP_ZERO)) {
|
||||
pr_err("add_type: prealloc type_attr_map_array failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (flex_array_prealloc(new_type_val_to_struct, 0, db->p_types.nprim,
|
||||
GFP_ATOMIC | __GFP_ZERO)) {
|
||||
pr_err("add_type: prealloc type_val_to_struct_array failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (flex_array_prealloc(new_val_to_name_types, 0,
|
||||
db->symtab[SYM_TYPES].nprim,
|
||||
GFP_ATOMIC | __GFP_ZERO)) {
|
||||
pr_err("add_type: prealloc val_to_name_types failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
int j;
|
||||
void *old_elem;
|
||||
// copy the old data or pointers to new flex arrays
|
||||
for (j = 0; j < db->type_attr_map_array->total_nr_elements; j++) {
|
||||
old_elem = flex_array_get(db->type_attr_map_array, j);
|
||||
if (old_elem)
|
||||
flex_array_put(new_type_attr_map_array, j, old_elem,
|
||||
GFP_ATOMIC | __GFP_ZERO);
|
||||
}
|
||||
|
||||
for (j = 0; j < db->type_val_to_struct_array->total_nr_elements; j++) {
|
||||
old_elem = flex_array_get_ptr(db->type_val_to_struct_array, j);
|
||||
if (old_elem)
|
||||
flex_array_put_ptr(new_type_val_to_struct, j, old_elem,
|
||||
GFP_ATOMIC | __GFP_ZERO);
|
||||
}
|
||||
|
||||
for (j = 0; j < db->symtab[SYM_TYPES].nprim; j++) {
|
||||
old_elem =
|
||||
flex_array_get_ptr(db->sym_val_to_name[SYM_TYPES], j);
|
||||
if (old_elem)
|
||||
flex_array_put_ptr(new_val_to_name_types, j, old_elem,
|
||||
GFP_ATOMIC | __GFP_ZERO);
|
||||
}
|
||||
|
||||
// store the pointer of old flex arrays first, when assigning new ones we
|
||||
// should free it
|
||||
struct flex_array *old_fa;
|
||||
|
||||
old_fa = db->type_attr_map_array;
|
||||
db->type_attr_map_array = new_type_attr_map_array;
|
||||
if (old_fa) {
|
||||
flex_array_free(old_fa);
|
||||
}
|
||||
|
||||
ebitmap_init(flex_array_get(db->type_attr_map_array, value - 1));
|
||||
ebitmap_set_bit(flex_array_get(db->type_attr_map_array, value - 1),
|
||||
value - 1, 1);
|
||||
|
||||
old_fa = db->type_val_to_struct_array;
|
||||
db->type_val_to_struct_array = new_type_val_to_struct;
|
||||
if (old_fa) {
|
||||
flex_array_free(old_fa);
|
||||
}
|
||||
flex_array_put_ptr(db->type_val_to_struct_array, value - 1, type,
|
||||
GFP_ATOMIC | __GFP_ZERO);
|
||||
|
||||
old_fa = db->sym_val_to_name[SYM_TYPES];
|
||||
db->sym_val_to_name[SYM_TYPES] = new_val_to_name_types;
|
||||
if (old_fa) {
|
||||
flex_array_free(old_fa);
|
||||
}
|
||||
flex_array_put_ptr(db->sym_val_to_name[SYM_TYPES], value - 1, key,
|
||||
GFP_ATOMIC | __GFP_ZERO);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < db->p_roles.nprim; ++i) {
|
||||
ebitmap_set_bit(&db->role_val_to_struct[i]->types, value - 1,
|
||||
1);
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool set_type_state(struct policydb *db, const char *type_name,
|
||||
|
@ -902,18 +696,7 @@ static bool set_type_state(struct policydb *db, const char *type_name,
|
|||
static void add_typeattribute_raw(struct policydb *db, struct type_datum *type,
|
||||
struct type_datum *attr)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
|
||||
struct ebitmap *sattr = &db->type_attr_map_array[type->value - 1];
|
||||
#elif defined(CONFIG_IS_HW_HISI)
|
||||
/*
|
||||
* HISI_SELINUX_EBITMAP_RO is Huawei's unique features.
|
||||
*/
|
||||
struct ebitmap *sattr = &db->type_attr_map[type->value - 1],
|
||||
HISI_SELINUX_EBITMAP_RO;
|
||||
#else
|
||||
struct ebitmap *sattr =
|
||||
flex_array_get(db->type_attr_map_array, type->value - 1);
|
||||
#endif
|
||||
ebitmap_set_bit(sattr, attr->value - 1, 1);
|
||||
|
||||
struct hashtab_node *node;
|
||||
|
|
|
@ -8,11 +8,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/version.h>
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||
#include <linux/sched/task_stack.h>
|
||||
#else
|
||||
#include <linux/sched.h>
|
||||
#endif
|
||||
|
||||
#include "objsec.h"
|
||||
#include "allowlist.h"
|
||||
|
@ -184,15 +180,9 @@ int ksu_handle_devpts(struct inode *inode)
|
|||
return 0;
|
||||
|
||||
if (ksu_devpts_sid) {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
|
||||
struct inode_security_struct *sec = selinux_inode(inode);
|
||||
#else
|
||||
struct inode_security_struct *sec = (struct inode_security_struct *) inode->i_security;
|
||||
#endif
|
||||
if (sec) {
|
||||
sec->sid = ksu_devpts_sid;
|
||||
inode->i_uid.val = 0;
|
||||
inode->i_gid.val = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,18 +191,6 @@ int ksu_handle_devpts(struct inode *inode)
|
|||
|
||||
#ifdef CONFIG_KPROBES
|
||||
|
||||
__maybe_unused static int faccessat_handler_pre(struct kprobe *p,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
int *dfd = (int *)&PT_REGS_PARM1(regs);
|
||||
const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs);
|
||||
int *mode = (int *)&PT_REGS_PARM3(regs);
|
||||
// Both sys_ and do_ is C function
|
||||
int *flags = (int *)&PT_REGS_CCALL_PARM4(regs);
|
||||
|
||||
return ksu_handle_faccessat(dfd, filename_user, mode, flags);
|
||||
}
|
||||
|
||||
static int sys_faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *real_regs = PT_REAL_REGS(regs);
|
||||
|
@ -224,43 +202,16 @@ static int sys_faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
|||
return ksu_handle_faccessat(dfd, filename_user, mode, NULL);
|
||||
}
|
||||
|
||||
__maybe_unused static int newfstatat_handler_pre(struct kprobe *p,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
int *dfd = (int *)&PT_REGS_PARM1(regs);
|
||||
const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||
// static int vfs_statx(int dfd, const char __user *filename, int flags, struct kstat *stat, u32 request_mask)
|
||||
int *flags = (int *)&PT_REGS_PARM3(regs);
|
||||
#else
|
||||
// int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,int flag)
|
||||
int *flags = (int *)&PT_REGS_CCALL_PARM4(regs);
|
||||
#endif
|
||||
|
||||
return ksu_handle_stat(dfd, filename_user, flags);
|
||||
}
|
||||
|
||||
static int sys_newfstatat_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *real_regs = PT_REAL_REGS(regs);
|
||||
int *dfd = (int *)&PT_REGS_PARM1(real_regs);
|
||||
const char __user **filename_user =
|
||||
(const char **)&PT_REGS_PARM2(real_regs);
|
||||
const char __user **filename_user = (const char **)&PT_REGS_PARM2(real_regs);
|
||||
int *flags = (int *)&PT_REGS_SYSCALL_PARM4(real_regs);
|
||||
|
||||
return ksu_handle_stat(dfd, filename_user, flags);
|
||||
}
|
||||
|
||||
// https://elixir.bootlin.com/linux/v5.10.158/source/fs/exec.c#L1864
|
||||
static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
int *fd = (int *)&PT_REGS_PARM1(regs);
|
||||
struct filename **filename_ptr =
|
||||
(struct filename **)&PT_REGS_PARM2(regs);
|
||||
|
||||
return ksu_handle_execveat_sucompat(fd, filename_ptr, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *real_regs = PT_REAL_REGS(regs);
|
||||
|
@ -271,72 +222,34 @@ static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
|||
NULL);
|
||||
}
|
||||
|
||||
#if 1
|
||||
static struct kprobe faccessat_kp = {
|
||||
.symbol_name = SYS_FACCESSAT_SYMBOL,
|
||||
.pre_handler = sys_faccessat_handler_pre,
|
||||
};
|
||||
#else
|
||||
static struct kprobe faccessat_kp = {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
||||
.symbol_name = "do_faccessat",
|
||||
#else
|
||||
.symbol_name = "sys_faccessat",
|
||||
#endif
|
||||
.pre_handler = faccessat_handler_pre,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
static struct kprobe newfstatat_kp = {
|
||||
.symbol_name = SYS_NEWFSTATAT_SYMBOL,
|
||||
.pre_handler = sys_newfstatat_handler_pre,
|
||||
};
|
||||
#else
|
||||
static struct kprobe newfstatat_kp = {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||
.symbol_name = "vfs_statx",
|
||||
#else
|
||||
.symbol_name = "vfs_fstatat",
|
||||
#endif
|
||||
.pre_handler = newfstatat_handler_pre,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
static struct kprobe execve_kp = {
|
||||
.symbol_name = SYS_EXECVE_SYMBOL,
|
||||
.pre_handler = sys_execve_handler_pre,
|
||||
};
|
||||
#else
|
||||
static struct kprobe execve_kp = {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
|
||||
.symbol_name = "do_execveat_common",
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
|
||||
.symbol_name = "__do_execve_file",
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
|
||||
.symbol_name = "do_execveat_common",
|
||||
#endif
|
||||
.pre_handler = execve_handler_pre,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int devpts_get_priv_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
static int pts_unix98_lookup_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct inode *inode;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
|
||||
struct dentry *dentry = (struct dentry *)PT_REGS_PARM1(regs);
|
||||
inode = dentry->d_inode;
|
||||
#else
|
||||
inode = (struct inode *)PT_REGS_PARM1(real_regs);
|
||||
#endif
|
||||
struct file *file = (struct file *)PT_REGS_PARM2(regs);
|
||||
inode = file->f_path.dentry->d_inode;
|
||||
|
||||
return ksu_handle_devpts(inode);
|
||||
}
|
||||
|
||||
static struct kprobe devpts_get_priv_kp = { .symbol_name = "devpts_get_priv",
|
||||
.pre_handler =
|
||||
devpts_get_priv_pre };
|
||||
static struct kprobe pts_unix98_lookup_kp = { .symbol_name =
|
||||
"pts_unix98_lookup",
|
||||
.pre_handler =
|
||||
pts_unix98_lookup_pre };
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -351,7 +264,7 @@ void ksu_sucompat_init()
|
|||
pr_info("sucompat: newfstatat_kp: %d\n", ret);
|
||||
ret = register_kprobe(&faccessat_kp);
|
||||
pr_info("sucompat: faccessat_kp: %d\n", ret);
|
||||
ret = register_kprobe(&devpts_get_priv_kp);
|
||||
ret = register_kprobe(&pts_unix98_lookup_kp);
|
||||
pr_info("sucompat: devpts_kp: %d\n", ret);
|
||||
#endif
|
||||
}
|
||||
|
@ -362,6 +275,6 @@ void ksu_sucompat_exit()
|
|||
unregister_kprobe(&execve_kp);
|
||||
unregister_kprobe(&newfstatat_kp);
|
||||
unregister_kprobe(&faccessat_kp);
|
||||
unregister_kprobe(&devpts_get_priv_kp);
|
||||
unregister_kprobe(&pts_unix98_lookup_kp);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include "allowlist.h"
|
||||
#include "klog.h" // IWYU pragma: keep
|
||||
|
@ -16,8 +15,7 @@
|
|||
|
||||
uid_t ksu_manager_uid = KSU_INVALID_UID;
|
||||
|
||||
#define SYSTEM_PACKAGES_LIST_PATH "/data/system/packages.list"
|
||||
static struct work_struct ksu_update_uid_work;
|
||||
#define SYSTEM_PACKAGES_LIST_PATH "/data/system/packages.list.tmp"
|
||||
|
||||
struct uid_data {
|
||||
struct list_head list;
|
||||
|
@ -94,8 +92,25 @@ static void crown_manager(const char *apk, struct list_head *uid_data)
|
|||
}
|
||||
}
|
||||
|
||||
#define DATA_PATH_LEN 384 // 384 is enough for /data/app/<package>/base.apk
|
||||
|
||||
struct data_path {
|
||||
char dirpath[DATA_PATH_LEN];
|
||||
int depth;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct apk_path_hash {
|
||||
unsigned int hash;
|
||||
bool exists;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static struct list_head apk_path_hash_list = LIST_HEAD_INIT(apk_path_hash_list);
|
||||
|
||||
struct my_dir_context {
|
||||
struct dir_context ctx;
|
||||
struct list_head *data_path_list;
|
||||
char *parent_dir;
|
||||
void *private_data;
|
||||
int depth;
|
||||
|
@ -119,8 +134,7 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
|
|||
{
|
||||
struct my_dir_context *my_ctx =
|
||||
container_of(ctx, struct my_dir_context, ctx);
|
||||
struct file *file;
|
||||
char dirpath[384]; // 384 is enough for /data/app/<package>/base.apk
|
||||
char dirpath[DATA_PATH_LEN];
|
||||
|
||||
if (!my_ctx) {
|
||||
pr_err("Invalid context\n");
|
||||
|
@ -134,8 +148,8 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
|
|||
if (!strncmp(name, "..", namelen) || !strncmp(name, ".", namelen))
|
||||
return FILLDIR_ACTOR_CONTINUE; // Skip "." and ".."
|
||||
|
||||
if (snprintf(dirpath, sizeof(dirpath), "%s/%.*s", my_ctx->parent_dir,
|
||||
namelen, name) >= sizeof(dirpath)) {
|
||||
if (snprintf(dirpath, DATA_PATH_LEN, "%s/%.*s", my_ctx->parent_dir,
|
||||
namelen, name) >= DATA_PATH_LEN) {
|
||||
pr_err("Path too long: %s/%.*s\n", my_ctx->parent_dir, namelen,
|
||||
name);
|
||||
return FILLDIR_ACTOR_CONTINUE;
|
||||
|
@ -143,29 +157,44 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
|
|||
|
||||
if (d_type == DT_DIR && my_ctx->depth > 0 &&
|
||||
(my_ctx->stop && !*my_ctx->stop)) {
|
||||
struct my_dir_context sub_ctx = { .ctx.actor = my_actor,
|
||||
.parent_dir = dirpath,
|
||||
.private_data =
|
||||
my_ctx->private_data,
|
||||
.depth = my_ctx->depth - 1,
|
||||
.stop = my_ctx->stop };
|
||||
file = ksu_filp_open_compat(dirpath, O_RDONLY | O_NOFOLLOW, 0);
|
||||
if (IS_ERR(file)) {
|
||||
pr_err("Failed to open directory: %s, err: %ld\n",
|
||||
dirpath, PTR_ERR(file));
|
||||
struct data_path *data = kmalloc(sizeof(struct data_path), GFP_ATOMIC);
|
||||
|
||||
if (!data) {
|
||||
pr_err("Failed to allocate memory for %s\n", dirpath);
|
||||
return FILLDIR_ACTOR_CONTINUE;
|
||||
}
|
||||
|
||||
iterate_dir(file, &sub_ctx.ctx);
|
||||
filp_close(file, NULL);
|
||||
strscpy(data->dirpath, dirpath, DATA_PATH_LEN);
|
||||
data->depth = my_ctx->depth - 1;
|
||||
list_add_tail(&data->list, my_ctx->data_path_list);
|
||||
} else {
|
||||
if ((namelen == 8) && (strncmp(name, "base.apk", namelen) == 0)) {
|
||||
struct apk_path_hash *pos, *n;
|
||||
unsigned int hash = full_name_hash(NULL, dirpath, strlen(dirpath));
|
||||
list_for_each_entry(pos, &apk_path_hash_list, list) {
|
||||
if (hash == pos->hash) {
|
||||
pos->exists = true;
|
||||
return FILLDIR_ACTOR_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_manager = is_manager_apk(dirpath);
|
||||
pr_info("Found base.apk at path: %s, is_manager: %d\n",
|
||||
pr_info("Found new base.apk at path: %s, is_manager: %d\n",
|
||||
dirpath, is_manager);
|
||||
if (is_manager) {
|
||||
crown_manager(dirpath, my_ctx->private_data);
|
||||
*my_ctx->stop = 1;
|
||||
|
||||
// Manager found, clear APK cache list
|
||||
list_for_each_entry_safe(pos, n, &apk_path_hash_list, list) {
|
||||
list_del(&pos->list);
|
||||
kfree(pos);
|
||||
}
|
||||
} else {
|
||||
struct apk_path_hash *apk_data = kmalloc(sizeof(struct apk_path_hash), GFP_ATOMIC);
|
||||
apk_data->hash = hash;
|
||||
apk_data->exists = true;
|
||||
list_add_tail(&apk_data->list, &apk_path_hash_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,22 +204,58 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
|
|||
|
||||
void search_manager(const char *path, int depth, struct list_head *uid_data)
|
||||
{
|
||||
struct file *file;
|
||||
int stop = 0;
|
||||
struct my_dir_context ctx = { .ctx.actor = my_actor,
|
||||
.parent_dir = (char *)path,
|
||||
.private_data = uid_data,
|
||||
.depth = depth,
|
||||
.stop = &stop };
|
||||
int i, stop = 0;
|
||||
struct list_head data_path_list;
|
||||
INIT_LIST_HEAD(&data_path_list);
|
||||
|
||||
file = ksu_filp_open_compat(path, O_RDONLY | O_NOFOLLOW, 0);
|
||||
if (IS_ERR(file)) {
|
||||
pr_err("Failed to open directory: %s\n", path);
|
||||
return;
|
||||
// Initialize APK cache list
|
||||
struct apk_path_hash *pos, *n;
|
||||
list_for_each_entry(pos, &apk_path_hash_list, list) {
|
||||
pos->exists = false;
|
||||
}
|
||||
|
||||
iterate_dir(file, &ctx.ctx);
|
||||
filp_close(file, NULL);
|
||||
// First depth
|
||||
struct data_path data;
|
||||
strscpy(data.dirpath, path, DATA_PATH_LEN);
|
||||
data.depth = depth;
|
||||
list_add_tail(&data.list, &data_path_list);
|
||||
|
||||
for (i = depth; i > 0; i--) {
|
||||
struct data_path *pos, *n;
|
||||
|
||||
list_for_each_entry_safe(pos, n, &data_path_list, list) {
|
||||
struct my_dir_context ctx = { .ctx.actor = my_actor,
|
||||
.data_path_list = &data_path_list,
|
||||
.parent_dir = pos->dirpath,
|
||||
.private_data = uid_data,
|
||||
.depth = pos->depth,
|
||||
.stop = &stop };
|
||||
struct file *file;
|
||||
|
||||
if (!stop) {
|
||||
file = ksu_filp_open_compat(pos->dirpath, O_RDONLY | O_NOFOLLOW, 0);
|
||||
if (IS_ERR(file)) {
|
||||
pr_err("Failed to open directory: %s, err: %ld\n", pos->dirpath, PTR_ERR(file));
|
||||
goto skip_iterate;
|
||||
}
|
||||
|
||||
iterate_dir(file, &ctx.ctx);
|
||||
filp_close(file, NULL);
|
||||
}
|
||||
skip_iterate:
|
||||
list_del(&pos->list);
|
||||
if (pos != &data)
|
||||
kfree(pos);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove stale cached APK entries
|
||||
list_for_each_entry_safe(pos, n, &apk_path_hash_list, list) {
|
||||
if (!pos->exists) {
|
||||
list_del(&pos->list);
|
||||
kfree(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_uid_exist(uid_t uid, char *package, void *data)
|
||||
|
@ -209,14 +274,13 @@ static bool is_uid_exist(uid_t uid, char *package, void *data)
|
|||
return exist;
|
||||
}
|
||||
|
||||
static void do_update_uid(struct work_struct *work)
|
||||
void track_throne()
|
||||
{
|
||||
struct file *fp =
|
||||
ksu_filp_open_compat(SYSTEM_PACKAGES_LIST_PATH, O_RDONLY, 0);
|
||||
if (IS_ERR(fp)) {
|
||||
pr_err("do_update_uid, open " SYSTEM_PACKAGES_LIST_PATH
|
||||
" failed: %ld\n",
|
||||
PTR_ERR(fp));
|
||||
pr_err("%s: open " SYSTEM_PACKAGES_LIST_PATH " failed: %ld\n",
|
||||
__func__, PTR_ERR(fp));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -303,14 +367,9 @@ out:
|
|||
}
|
||||
}
|
||||
|
||||
void track_throne()
|
||||
{
|
||||
ksu_queue_work(&ksu_update_uid_work);
|
||||
}
|
||||
|
||||
void ksu_throne_tracker_init()
|
||||
{
|
||||
INIT_WORK(&ksu_update_uid_work, do_update_uid);
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
void ksu_throne_tracker_exit()
|
||||
|
|
|
@ -3,6 +3,7 @@ import com.android.build.gradle.internal.api.BaseVariantOutputImpl
|
|||
plugins {
|
||||
alias(libs.plugins.agp.app)
|
||||
alias(libs.plugins.kotlin)
|
||||
alias(libs.plugins.compose.compiler)
|
||||
alias(libs.plugins.ksp)
|
||||
alias(libs.plugins.lsplugin.apksign)
|
||||
id("kotlin-parcelize")
|
||||
|
@ -39,10 +40,6 @@ android {
|
|||
jvmTarget = "21"
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get()
|
||||
}
|
||||
|
||||
packaging {
|
||||
jniLibs {
|
||||
useLegacyPackaging = true
|
||||
|
|
|
@ -38,6 +38,7 @@ import me.weishu.kernelsu.ui.component.rememberConfirmDialog
|
|||
import me.weishu.kernelsu.ui.screen.destinations.InstallScreenDestination
|
||||
import me.weishu.kernelsu.ui.screen.destinations.SettingScreenDestination
|
||||
import me.weishu.kernelsu.ui.util.*
|
||||
import me.weishu.kernelsu.ui.util.module.LatestVersionInfo
|
||||
|
||||
@RootNavGraph(start = true)
|
||||
@Destination
|
||||
|
@ -100,13 +101,18 @@ fun HomeScreen(navigator: DestinationsNavigator) {
|
|||
@Composable
|
||||
fun UpdateCard() {
|
||||
val context = LocalContext.current
|
||||
val newVersion by produceState(initialValue = Triple(0, "", "")) {
|
||||
value = withContext(Dispatchers.IO) { checkNewVersion() }
|
||||
val latestVersionInfo = LatestVersionInfo()
|
||||
val newVersion by produceState(initialValue = latestVersionInfo) {
|
||||
value = withContext(Dispatchers.IO){
|
||||
checkNewVersion()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val currentVersionCode = getManagerVersion(context).second
|
||||
val newVersionCode = newVersion.first
|
||||
val newVersionUrl = newVersion.second
|
||||
val changelog = newVersion.third
|
||||
val newVersionCode = newVersion.versionCode
|
||||
val newVersionUrl = newVersion.downloadUrl
|
||||
val changelog = newVersion.changelog
|
||||
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val title = stringResource(id = R.string.module_changelog)
|
||||
|
@ -122,7 +128,9 @@ fun UpdateCard() {
|
|||
message = stringResource(id = R.string.new_version_available).format(newVersionCode),
|
||||
MaterialTheme.colorScheme.outlineVariant
|
||||
) {
|
||||
if (changelog.isNotEmpty()) {
|
||||
if (changelog.isEmpty()) {
|
||||
uriHandler.openUri(newVersionUrl)
|
||||
} else {
|
||||
updateDialog.showConfirm(
|
||||
title = title,
|
||||
content = changelog,
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
package me.weishu.kernelsu.ui.screen
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.database.Cursor
|
||||
import android.net.Uri
|
||||
import android.provider.OpenableColumns
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
|
@ -20,25 +26,34 @@ import androidx.compose.material.icons.filled.DeleteForever
|
|||
import androidx.compose.material.icons.filled.DeveloperMode
|
||||
import androidx.compose.material.icons.filled.Fence
|
||||
import androidx.compose.material.icons.filled.RemoveModerator
|
||||
import androidx.compose.material.icons.filled.Save
|
||||
import androidx.compose.material.icons.filled.Share
|
||||
import androidx.compose.material.icons.filled.Update
|
||||
import androidx.compose.material3.BottomSheetScaffold
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.LineHeightStyle
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.content.FileProvider
|
||||
import com.maxkeppeker.sheets.core.models.base.Header
|
||||
import com.maxkeppeker.sheets.core.models.base.IconSource
|
||||
|
@ -65,12 +80,16 @@ import me.weishu.kernelsu.ui.component.rememberLoadingDialog
|
|||
import me.weishu.kernelsu.ui.screen.destinations.AppProfileTemplateScreenDestination
|
||||
import me.weishu.kernelsu.ui.screen.destinations.FlashScreenDestination
|
||||
import me.weishu.kernelsu.ui.util.getBugreportFile
|
||||
import me.weishu.kernelsu.ui.util.getFileNameFromUri
|
||||
import me.weishu.kernelsu.ui.util.shrinkModules
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
/**
|
||||
* @author weishu
|
||||
* @date 2023/1/1.
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Destination
|
||||
@Composable
|
||||
fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
|
@ -151,6 +170,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||
enableWebDebugging = it
|
||||
}
|
||||
|
||||
var showBottomsheet by remember { mutableStateOf(false) }
|
||||
|
||||
ListItem(
|
||||
leadingContent = {
|
||||
|
@ -161,34 +181,127 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||
},
|
||||
headlineContent = { Text(stringResource(id = R.string.send_log)) },
|
||||
modifier = Modifier.clickable {
|
||||
scope.launch {
|
||||
val bugreport = loadingDialog.withLoading {
|
||||
withContext(Dispatchers.IO) {
|
||||
getBugreportFile(context)
|
||||
}
|
||||
}
|
||||
|
||||
val uri: Uri =
|
||||
FileProvider.getUriForFile(
|
||||
context,
|
||||
"${BuildConfig.APPLICATION_ID}.fileprovider",
|
||||
bugreport
|
||||
)
|
||||
|
||||
val shareIntent = Intent(Intent.ACTION_SEND)
|
||||
shareIntent.putExtra(Intent.EXTRA_STREAM, uri)
|
||||
shareIntent.setDataAndType(uri, "application/zip")
|
||||
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
|
||||
context.startActivity(
|
||||
Intent.createChooser(
|
||||
shareIntent,
|
||||
context.getString(R.string.send_log)
|
||||
)
|
||||
)
|
||||
}
|
||||
showBottomsheet = true
|
||||
}
|
||||
)
|
||||
if (showBottomsheet){
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = { showBottomsheet = false },
|
||||
content = {
|
||||
Row(modifier = Modifier.padding(10.dp)
|
||||
.align(Alignment.CenterHorizontally)
|
||||
|
||||
) {
|
||||
Box{
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp)
|
||||
.clickable {
|
||||
scope.launch {
|
||||
val bugreport = loadingDialog.withLoading {
|
||||
withContext(Dispatchers.IO) {
|
||||
getBugreportFile(context)
|
||||
}
|
||||
}
|
||||
|
||||
val uri: Uri =
|
||||
FileProvider.getUriForFile(
|
||||
context,
|
||||
"${BuildConfig.APPLICATION_ID}.fileprovider",
|
||||
bugreport
|
||||
)
|
||||
val filename = getFileNameFromUri(context , uri)
|
||||
val savefile = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = "application/zip"
|
||||
putExtra(Intent.EXTRA_STREAM, uri)
|
||||
putExtra(Intent.EXTRA_TITLE, filename)
|
||||
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
}
|
||||
context.startActivity(
|
||||
Intent.createChooser(
|
||||
savefile,
|
||||
context.getString(R.string.save_log)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
Icons.Filled.Save,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.save_log),
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
textAlign = TextAlign.Center.also {
|
||||
LineHeightStyle(
|
||||
alignment = LineHeightStyle.Alignment.Center,
|
||||
trim = LineHeightStyle.Trim.None
|
||||
)
|
||||
}
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
Box{
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp)
|
||||
.clickable {
|
||||
scope.launch {
|
||||
val bugreport = loadingDialog.withLoading {
|
||||
withContext(Dispatchers.IO) {
|
||||
getBugreportFile(context)
|
||||
}
|
||||
}
|
||||
|
||||
val uri: Uri =
|
||||
FileProvider.getUriForFile(
|
||||
context,
|
||||
"${BuildConfig.APPLICATION_ID}.fileprovider",
|
||||
bugreport
|
||||
)
|
||||
|
||||
val shareIntent = Intent(Intent.ACTION_SEND)
|
||||
shareIntent.putExtra(Intent.EXTRA_STREAM, uri)
|
||||
shareIntent.setDataAndType(uri, "application/zip")
|
||||
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
|
||||
context.startActivity(
|
||||
Intent.createChooser(
|
||||
shareIntent,
|
||||
context.getString(R.string.send_log)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
Icons.Filled.Share,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.send_log),
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
textAlign = TextAlign.Center.also {
|
||||
LineHeightStyle(
|
||||
alignment = LineHeightStyle.Alignment.Center,
|
||||
trim = LineHeightStyle.Trim.None
|
||||
)
|
||||
}
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
}
|
||||
|
||||
val shrink = stringResource(id = R.string.shrink_sparse_image)
|
||||
val shrinkMessage = stringResource(id = R.string.shrink_sparse_image_message)
|
||||
|
@ -237,7 +350,6 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun UninstallItem(
|
||||
navigator: DestinationsNavigator,
|
||||
|
|
|
@ -11,6 +11,7 @@ import android.os.Build
|
|||
import android.os.Environment
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import me.weishu.kernelsu.ui.util.module.LatestVersionInfo
|
||||
|
||||
/**
|
||||
* @author weishu
|
||||
|
@ -61,9 +62,10 @@ fun download(
|
|||
downloadManager.enqueue(request)
|
||||
}
|
||||
|
||||
fun checkNewVersion(): Triple<Int, String, String> {
|
||||
fun checkNewVersion(): LatestVersionInfo {
|
||||
val url = "https://api.github.com/repos/tiann/KernelSU/releases/latest"
|
||||
val defaultValue = Triple(0, "", "")
|
||||
// default null value if failed
|
||||
val defaultValue = LatestVersionInfo()
|
||||
runCatching {
|
||||
okhttp3.OkHttpClient().newCall(okhttp3.Request.Builder().url(url).build()).execute()
|
||||
.use { response ->
|
||||
|
@ -88,7 +90,11 @@ fun checkNewVersion(): Triple<Int, String, String> {
|
|||
val versionCode = matchResult.groupValues[2].toInt()
|
||||
val downloadUrl = asset.getString("browser_download_url")
|
||||
|
||||
return Triple(versionCode, downloadUrl, changelog)
|
||||
return LatestVersionInfo(
|
||||
versionCode,
|
||||
downloadUrl,
|
||||
changelog
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package me.weishu.kernelsu.ui.util
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.os.Parcelable
|
||||
import android.os.SystemClock
|
||||
import android.provider.OpenableColumns
|
||||
import android.util.Log
|
||||
import com.topjohnwu.superuser.CallbackList
|
||||
import com.topjohnwu.superuser.Shell
|
||||
|
@ -48,6 +52,18 @@ inline fun <T> withNewRootShell(
|
|||
return createRootShell(globalMnt).use(block)
|
||||
}
|
||||
|
||||
fun getFileNameFromUri(context: Context, uri: Uri): String? {
|
||||
var fileName: String? = null
|
||||
val contentResolver: ContentResolver = context.contentResolver
|
||||
val cursor: Cursor? = contentResolver.query(uri, null, null, null, null)
|
||||
cursor?.use {
|
||||
if (it.moveToFirst()) {
|
||||
fileName = it.getString(it.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME))
|
||||
}
|
||||
}
|
||||
return fileName
|
||||
}
|
||||
|
||||
fun createRootShell(globalMnt: Boolean = false): Shell {
|
||||
Shell.enableVerboseLogging = BuildConfig.DEBUG
|
||||
val builder = Shell.Builder.create()
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
package me.weishu.kernelsu.ui.util
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.system.Os
|
||||
import com.topjohnwu.superuser.ShellUtils
|
||||
import me.weishu.kernelsu.Natives
|
||||
import me.weishu.kernelsu.ui.screen.getManagerVersion
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.FileWriter
|
||||
import java.io.PrintWriter
|
||||
import java.time.LocalDateTime
|
||||
|
@ -108,3 +112,4 @@ fun getBugreportFile(context: Context): File {
|
|||
|
||||
return targetFile
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package me.weishu.kernelsu.ui.util.module
|
||||
|
||||
data class LatestVersionInfo(
|
||||
val versionCode : Int = 0,
|
||||
val downloadUrl : String = "",
|
||||
val changelog : String = ""
|
||||
)
|
|
@ -130,4 +130,5 @@
|
|||
<string name="selected_lkm">صورة lkm المحددة: %s</string>
|
||||
<string name="settings_restore_stock_image_message">استعادة صورة المصنع المخزنة (في حالة وجود نسخة احتياطية)، والتي تُستخدم عادة قبل OTA؛ إذا كنت بحاجة إلى إلغاء تثبيت KernelSU، فيرجى استخدام \"إلغاء التثبيت الدائم\".</string>
|
||||
<string name="settings_uninstall_temporary_message">قم بإلغاء تثبيت KernelSU مؤقتًا، واستعد إلى حالته الأصلية بعد إعادة التشغيل التالية.</string>
|
||||
<string name="save_log">حفظ السجلات</string>
|
||||
</resources>
|
|
@ -78,4 +78,5 @@
|
|||
<string name="force_stop_app">Məcburi dayandır</string>
|
||||
<string name="restart_app">Yenidən başlat</string>
|
||||
<string name="failed_to_update_sepolicy">%s görə SELinux qaydalarını güncəlləmək mümkün olmadı</string>
|
||||
<string name="save_log">Girişləri Saxla</string>
|
||||
</resources>
|
|
@ -48,4 +48,5 @@
|
|||
<string name="module_uninstall_failed">%s আনইনস্টল করা যায়নি</string>
|
||||
<string name="module_version">ভার্সন</string>
|
||||
<string name="module_author">অথার</string>
|
||||
<string name="save_log">লগ সংরক্ষণ করুন</string>
|
||||
</resources>
|
|
@ -64,4 +64,5 @@
|
|||
<string name="profile_namespace_individual">আলাদাভাবে</string>
|
||||
<string name="profile_umount_modules">আনমাউন্ট মোডিউল</string>
|
||||
<string name="require_kernel_version">ম্যানেজার সঠিকভাবে কাজ করার জন্য বর্তমান KernelSU সংস্করণ %d খুবই কম। অনুগ্রহ করে %d বা উচ্চতর সংস্করণে আপগ্রেড করুন!</string>
|
||||
<string name="save_log">লগ সংরক্ষণ করুন</string>
|
||||
</resources>
|
|
@ -79,4 +79,5 @@
|
|||
<string name="profile_template">Šablon</string>
|
||||
<string name="profile_custom">Prilagođeno</string>
|
||||
<string name="profile_name">Naziv profila</string>
|
||||
<string name="save_log">Sačuvaj Dnevnike</string>
|
||||
</resources>
|
|
@ -79,4 +79,5 @@
|
|||
<string name="profile_selinux_rules">Regler</string>
|
||||
<string name="restart_app">Genstart</string>
|
||||
<string name="require_kernel_version">Den nuværende KernelSU version %d er for lav til manageren for at fungere ordentligt. Opgrader til version %d eller højere!</string>
|
||||
<string name="save_log">Gem Logfiler</string>
|
||||
</resources>
|
|
@ -117,4 +117,9 @@
|
|||
<string name="open">Öffnen</string>
|
||||
<string name="settings_check_update">Updates suchen</string>
|
||||
<string name="settings_check_update_summary">Automatisch nach Updates suchen beim Öffnen der App</string>
|
||||
<string name="settings_uninstall_temporary">Temporär deinstallieren</string>
|
||||
<string name="settings_uninstall">Deinstallieren</string>
|
||||
<string name="settings_uninstall_permanent_message">KernelSU (Root und alle Module) vollständig und dauerhaft deinstallieren.</string>
|
||||
<string name="shrink_sparse_image_message">Ändert die Größe des Sparse-Images, in dem sich das Modul befindet, auf seine tatsächliche Größe. Beachten Sie, dass dies dazu führen kann, dass das Modul nicht ordnungsgemäß funktioniert; verwenden Sie es daher nur, wenn es notwendig ist (z. B. für ein Backup).</string>
|
||||
<string name="save_log">Protokolle Speichern</string>
|
||||
</resources>
|
|
@ -103,4 +103,5 @@
|
|||
<string name="app_profile_template_delete">Eliminar</string>
|
||||
<string name="app_profile_template_import_empty">El portapapeles esta vacio!</string>
|
||||
<string name="app_profile_template_view">Ver plantilla</string>
|
||||
<string name="save_log">Guardar Registros</string>
|
||||
</resources>
|
|
@ -108,4 +108,5 @@
|
|||
<string name="settings_check_update_summary">Rakenduse avamisel kontrolli automaatselt uuendusi</string>
|
||||
<string name="open">Ava</string>
|
||||
<string name="enable_web_debugging">Luba WebView silumine</string>
|
||||
<string name="save_log">Salvesta Logid</string>
|
||||
</resources>
|
|
@ -63,4 +63,5 @@
|
|||
<string name="profile_namespace_global">گلوبال</string>
|
||||
<string name="profile_namespace_individual">تکی</string>
|
||||
<string name="profile_umount_modules">جداکردن ماژول ها</string>
|
||||
<string name="save_log">ذخیره گزارشها</string>
|
||||
</resources>
|
||||
|
|
|
@ -66,4 +66,5 @@
|
|||
<string name="profile_name">Pangalan ng profile</string>
|
||||
<string name="profile_namespace_inherited">Minana</string>
|
||||
<string name="settings_umount_modules_default_summary">Ang pangkalahatang default na halaga para sa \"Umount modules\" sa Mga Profile ng App. Kung pinagana, aalisin nito ang lahat ng mga pagbabago sa modyul sa system para sa mga aplikasyon na walang hanay ng Profile.</string>
|
||||
<string name="save_log">I-save ang mga Log</string>
|
||||
</resources>
|
|
@ -118,8 +118,8 @@
|
|||
<string name="install_next">Suivant</string>
|
||||
<string name="select_file_tip">L\'image de la partition %1$s est recommandée</string>
|
||||
<string name="select_kmi">Sélectionner une KMI</string>
|
||||
<string name="shrink_sparse_image">Minimiser l\'image clairsemée</string>
|
||||
<string name="shrink_sparse_image_message">Redimensionne l\'image clairsemée où se trouve le module à sa taille réelle. Notez que cela peut entraîner un dysfonctionnement du module, alors utilisez cette fonctionnalité uniquement lorsque nécessaire (pour la sauvegarde, par exemple)</string>
|
||||
<string name="shrink_sparse_image">Minimiser la taille de l\'image partiellement allouée</string>
|
||||
<string name="shrink_sparse_image_message">Redimensionner à sa taille réelle l\'image partiellement allouée où se trouve le module. Notez que cela peut entraîner un dysfonctionnement du module, utilisez donc cette fonctionnalité uniquement lorsque c\'est nécessaire (par exemple pour la sauvegarde de l\'appareil).</string>
|
||||
<string name="settings_uninstall">Désinstaller</string>
|
||||
<string name="settings_uninstall_temporary">Désinstaller temporairement</string>
|
||||
<string name="settings_uninstall_permanent">Désinstaller définitivement</string>
|
||||
|
@ -131,4 +131,5 @@
|
|||
<string name="selected_lkm">lkm sélectionné : %s</string>
|
||||
<string name="settings_uninstall_permanent_message">Désinstallation complète et permanente de KernelSU (root et tous les modules).</string>
|
||||
<string name="settings_uninstall_temporary_message">Désinstaller KernelSU temporairement et rétablir l\'état original au redémarrage suivant.</string>
|
||||
<string name="save_log">Enregistrer les Journaux</string>
|
||||
</resources>
|
|
@ -80,4 +80,5 @@
|
|||
<string name="about_source_code">%1$s पर स्रोत कोड देखें<br/>हमारे %2$s चैनल से जुड़ें</string>
|
||||
<string name="home_manager_version">मैनेजर वर्जन</string>
|
||||
<string name="new_version_available">नया वर्जन: %s उपलब्ध है,अपग्रेड के लिए क्लिक करें</string>
|
||||
<string name="save_log">लॉग सहेजें</string>
|
||||
</resources>
|
|
@ -79,4 +79,5 @@
|
|||
<string name="launch_app">Pokrenite</string>
|
||||
<string name="force_stop_app">Prisilno Zaustavite</string>
|
||||
<string name="restart_app">Resetujte</string>
|
||||
<string name="save_log">Spremi Zapise</string>
|
||||
</resources>
|
|
@ -102,4 +102,5 @@
|
|||
<string name="app_profile_template_delete">Törlés</string>
|
||||
<string name="app_profile_template_import_empty">A vágólap üres!</string>
|
||||
<string name="app_profile_template_view">Sablon megnézése</string>
|
||||
<string name="save_log">Naplók Mentése</string>
|
||||
</resources>
|
|
@ -131,4 +131,5 @@
|
|||
<string name="selected_lkm">LKM dipilih: %s</string>
|
||||
<string name="flashing">Pasang</string>
|
||||
<string name="flash_failed">Pemasangan Gagal</string>
|
||||
<string name="save_log">Simpan Log</string>
|
||||
</resources>
|
|
@ -130,4 +130,5 @@
|
|||
<string name="flash_failed">Installazione fallita</string>
|
||||
<string name="selected_lkm">LKM selezionato: %s</string>
|
||||
<string name="settings_restore_stock_image_message">Ripristina l\'immagine di fabbrica del produttore (se il backup è presente), solitamente usato prima di applicare l\'OTA; se devi disinstallare KernelSU, utilizza invece \"Disinstalla Permanentemente\".</string>
|
||||
<string name="save_log">Salva Registri</string>
|
||||
</resources>
|
|
@ -80,4 +80,5 @@
|
|||
<string name="about_source_code">ראה את קוד המקור ב%1$s<br/>הצטרף אלינו %2$s בערוץ</string>
|
||||
<string name="home_manager_version">גרסת מנהל</string>
|
||||
<string name="new_version_available">גרסה חדשה עבור: %s זמינה, לחץ כדי לשדרג</string>
|
||||
<string name="save_log">שמור יומנים</string>
|
||||
</resources>
|
|
@ -131,4 +131,5 @@
|
|||
<string name="flash_success">フラッシュ成功</string>
|
||||
<string name="flash_failed">フラッシュ失敗</string>
|
||||
<string name="selected_lkm">選択された lkm: %s</string>
|
||||
<string name="save_log">ログを保存</string>
|
||||
</resources>
|
|
@ -66,4 +66,5 @@
|
|||
<string name="about_source_code">%1$s ನಲ್ಲಿ ಮೂಲ ಕೋಡ್ ಅನ್ನು ವೀಕ್ಷಿಸಿ<br/>ನಮ್ಮ %2$s ಚಾನಲ್ಗೆ ಸೇರಿ</string>
|
||||
<string name="home_manager_version">ಮ್ಯಾನೇಜರ್ ವರ್ಷನ್</string>
|
||||
<string name="new_version_available">ಹೊಸ ಆವೃತ್ತಿ: %s ಲಭ್ಯವಿದೆ, ಅಪ್ಗ್ರೇಡ್ ಮಾಡಲು ಕ್ಲಿಕ್ ಮಾಡಿ</string>
|
||||
<string name="save_log">ಲಾಗ್ಗಳನ್ನು ಉಳಿಸಿ</string>
|
||||
</resources>
|
|
@ -78,4 +78,5 @@
|
|||
<string name="profile_selinux_domain">도메인</string>
|
||||
<string name="launch_app">실행</string>
|
||||
<string name="failed_to_update_sepolicy">다음 앱에 대한 SELinux 규칙 업데이트 실패: %s</string>
|
||||
<string name="save_log">로그 저장</string>
|
||||
</resources>
|
|
@ -80,4 +80,5 @@
|
|||
<string name="settings_umount_modules_default_summary">Visuotinė numatytoji „Modulių atjungimo“ reikšmė programų profiliuose. Jei įjungta, ji pašalins visus sistemos modulio pakeitimus programoms, kurios neturi profilio.</string>
|
||||
<string name="module_changelog">Keitimų žurnalas</string>
|
||||
<string name="require_kernel_version">Ši KernelSU versija %d yra per žema, kad šis vadybininkas galėtų tinkamai funkcionuoti. Prašome atsinaujinti į versiją %d ar aukščiau!</string>
|
||||
<string name="save_log">Saglabāt Žurnālus</string>
|
||||
</resources>
|
|
@ -130,4 +130,5 @@
|
|||
<string name="flash_failed">Instalēšana neizdevās</string>
|
||||
<string name="shrink_sparse_image">Samazināt reto attēlu</string>
|
||||
<string name="shrink_sparse_image_message">Mainīt retā attēla izmēru, kurā atrodas modulis, līdz tā faktiskajam izmēram. Ņemiet vērā, ka tas var izraisīt moduļa neparastu darbību, tāpēc, lūdzu, izmantojiet tikai nepieciešamības gadījumā (piemēram, dublēšanai)</string>
|
||||
<string name="save_log">Išsaugoti Žurnalus</string>
|
||||
</resources>
|
|
@ -78,4 +78,5 @@
|
|||
<string name="force_stop_app">सक्तीने थांबा</string>
|
||||
<string name="launch_app">लाँच करा</string>
|
||||
<string name="restart_app">पुन्हा सुरू करा</string>
|
||||
<string name="save_log">लॉग जतन करा</string>
|
||||
</resources>
|
|
@ -34,4 +34,5 @@
|
|||
<string name="home_not_installed">Tidak terpasang</string>
|
||||
<string name="reboot_bootloader">Mulakan semula ke bootloader</string>
|
||||
<string name="home_manager_version">Versi Manager</string>
|
||||
<string name="save_log">Simpan Log</string>
|
||||
</resources>
|
|
@ -125,4 +125,8 @@
|
|||
<string name="settings_uninstall_permanent">Permanent verwijderen</string>
|
||||
<string name="settings_restore_stock_image">Herstel stockafbeelding</string>
|
||||
<string name="settings_uninstall_temporary_message">Verwijder KernelSU tijdelijk en herstel het naar de oorspronkelijke staat na de volgende herstart.</string>
|
||||
<string name="settings_uninstall_permanent_message">Het verwijderen van KernelSU (Root en alle modules) volledig en permanent.</string>
|
||||
<string name="settings_restore_stock_image_message">Herstel de fabrieksimage (als er een back-up bestaat), meestal gebruikt vóór OTA; als u KernelSU moet verwijderen, gebruik dan \"Permanent verwijderen\".</string>
|
||||
<string name="flashing">Knipperen</string>
|
||||
<string name="save_log">Logboeken Opslaan</string>
|
||||
</resources>
|
|
@ -132,4 +132,5 @@
|
|||
<string name="flash_success">Flashowanie ukończone pomyślnie</string>
|
||||
<string name="flash_failed">Flashowanie nieudane</string>
|
||||
<string name="selected_lkm">Wybrano lkm: %s</string>
|
||||
<string name="save_log">Zapisz Dzienniki</string>
|
||||
</resources>
|
|
@ -131,4 +131,5 @@
|
|||
<string name="flash_failed">Flash falhou</string>
|
||||
<string name="flashing">Flashando</string>
|
||||
<string name="flash_success">Flash bem-sucedido</string>
|
||||
<string name="save_log">Salvar Logs</string>
|
||||
</resources>
|
|
@ -79,4 +79,5 @@
|
|||
<string name="force_stop_app">Forçar parada</string>
|
||||
<string name="new_version_available">Nova versão: %s está disponível, clique para baixar</string>
|
||||
<string name="require_kernel_version">A versão atual do KernelSU %d é muito baixa para o gerenciador funcionar corretamente. Atualize para a versão %d ou superior!</string>
|
||||
<string name="save_log">Salvar Registros</string>
|
||||
</resources>
|
|
@ -128,4 +128,5 @@
|
|||
<string name="flashing">Instalare</string>
|
||||
<string name="flash_success">Instalare reușită</string>
|
||||
<string name="flash_failed">Instalarea a eșuat</string>
|
||||
<string name="save_log">Salvează Jurnale</string>
|
||||
</resources>
|
|
@ -134,4 +134,5 @@
|
|||
<string name="flashing">Установка</string>
|
||||
<string name="flash_failed">Установка не выполнена</string>
|
||||
<string name="selected_lkm">Выбран lkm: %s</string>
|
||||
<string name="save_log">Сохранить Журналы</string>
|
||||
</resources>
|
|
@ -102,4 +102,5 @@
|
|||
<string name="app_profile_template_sync">Sinhroniziraj predloge iz spleta</string>
|
||||
<string name="app_profile_import_export">Uvoz/Izvoz</string>
|
||||
<string name="module_changelog_failed">Napaka pri pridobivanju dnevnika sprememb: %s</string>
|
||||
<string name="save_log">Shrani Dnevnike</string>
|
||||
</resources>
|
|
@ -7,4 +7,5 @@
|
|||
<string name="home_not_installed">Није инсталирано</string>
|
||||
<string name="home_working_version">Верзија: %d</string>
|
||||
<string name="home_working">Ради</string>
|
||||
<string name="save_log">Сачувај Дневнике</string>
|
||||
</resources>
|
|
@ -17,4 +17,5 @@
|
|||
<string name="home_working_version">వెర్షన్: %d</string>
|
||||
<string name="home_superuser_count">సూపర్యూజర్లు: %d</string>
|
||||
<string name="home_module_count">మాడ్యూల్స్: %d</string>
|
||||
<string name="save_log">లాగ్లు సేవ్ చేయండి</string>
|
||||
</resources>
|
|
@ -130,4 +130,5 @@
|
|||
<string name="settings_uninstall_temporary">ถอนการติดตั้งชั่วคราว</string>
|
||||
<string name="settings_uninstall_permanent_message">การถอนการติดตั้ง KernelSU (การรูทและโมดูลทั้งหมด) อย่างสมบูรณ์โดยถาวร</string>
|
||||
<string name="settings_restore_stock_image_message">คืนค่าโรงงานอิมเมจดั้งเดิม (หากมีข้อมูลสำรอง) ส่วนใหญ่มักใช้ก่อนทำการ OTA ซึ่งหากคุณต้องการถอนการติดตั้ง KernelSU โปรดใช้ \"ถอนการติดตั้งถาวร\"</string>
|
||||
<string name="save_log">บันทึกบันทึก</string>
|
||||
</resources>
|
|
@ -132,4 +132,5 @@
|
|||
<string name="selected_lkm">Seçili lkm: %s</string>
|
||||
<string name="flashing">Flaşlanıyor</string>
|
||||
<string name="flash_failed">Flaşlama başarısız</string>
|
||||
<string name="save_log">Günlükleri Kaydet</string>
|
||||
</resources>
|
|
@ -131,4 +131,5 @@
|
|||
<string name="selected_lkm">Обрано lkm: %s</string>
|
||||
<string name="settings_uninstall_permanent_message">Видалити KernelSU (Root і всі модулі) повністю і назавжди.</string>
|
||||
<string name="settings_restore_stock_image_message">Відновити стоковий заводський образ (якщо є резервна копія), зазвичай використовується перед OTA; якщо вам потрібно видалити KernelSU, використовуйте \"Назавжди видалити\".</string>
|
||||
<string name="save_log">Зберегти Журнали</string>
|
||||
</resources>
|
|
@ -131,4 +131,5 @@
|
|||
<string name="select_file_tip">Nên sử dụng hình ảnh phân vùng %1$s</string>
|
||||
<string name="shrink_sparse_image">Giảm thiểu hình ảnh thưa thớt</string>
|
||||
<string name="shrink_sparse_image_message">Thay đổi kích thước hình ảnh thưa nơi đặt mô-đun theo kích thước thực tế của nó. Lưu ý điều này có thể khiến module hoạt động không bình thường nên vui lòng chỉ sử dụng khi cần thiết (chẳng hạn như để sao lưu)</string>
|
||||
<string name="save_log">Lưu Nhật Ký</string>
|
||||
</resources>
|
|
@ -128,4 +128,5 @@
|
|||
<string name="flash_success">刷写完成</string>
|
||||
<string name="flash_failed">刷写失败</string>
|
||||
<string name="selected_lkm">选择的 LKM :%s</string>
|
||||
<string name="save_log">保存日志</string>
|
||||
</resources>
|
|
@ -120,4 +120,5 @@
|
|||
<string name="shrink_sparse_image">最小化稀疏影像</string>
|
||||
<string name="shrink_sparse_image_message">將模組所在的稀疏影像調整為實際大小。 請注意,這可能會導致模組工作異常,因此請僅在必要時使用(例如備份)</string>
|
||||
<string name="settings_uninstall">解除安裝</string>
|
||||
<string name="save_log">保存日志</string>
|
||||
</resources>
|
|
@ -130,4 +130,5 @@
|
|||
<string name="settings_restore_stock_image_message">恢復原廠映像(如果有備份),通常在OTA之前使用;如果需要解除安裝KernelSU,請使用「永久解除安裝」。</string>
|
||||
<string name="flash_failed">寫入失敗</string>
|
||||
<string name="selected_lkm">選擇的 LKM :%s</string>
|
||||
<string name="save_log">儲存日誌</string>
|
||||
</resources>
|
|
@ -35,18 +35,18 @@
|
|||
<string name="reboot_edl">Reboot to EDL</string>
|
||||
<string name="about">About</string>
|
||||
<string name="module_uninstall_confirm">Are you sure you want to uninstall module %s?</string>
|
||||
<string name="module_uninstall_success">%s is uninstalled</string>
|
||||
<string name="module_uninstall_success">%s uninstalled</string>
|
||||
<string name="module_uninstall_failed">Failed to uninstall: %s</string>
|
||||
<string name="module_version">Version</string>
|
||||
<string name="module_author">Author</string>
|
||||
<string name="module_overlay_fs_not_available">overlayfs is not available, module cannot work!</string>
|
||||
<string name="module_overlay_fs_not_available">Modules are unavailable as OverlayFS is disabled by the kernel.</string>
|
||||
<string name="refresh">Refresh</string>
|
||||
<string name="show_system_apps">Show system apps</string>
|
||||
<string name="hide_system_apps">Hide system apps</string>
|
||||
<string name="send_log">Report Log</string>
|
||||
<string name="send_log">Send logs</string>
|
||||
<string name="safe_mode">Safe mode</string>
|
||||
<string name="reboot_to_apply">Reboot to take effect</string>
|
||||
<string name="module_magisk_conflict">Modules are disabled because it is conflict with Magisk\'s!</string>
|
||||
<string name="module_magisk_conflict">Modules are unavailable due to a conflict with Magisk!</string>
|
||||
<string name="home_learn_kernelsu">Learn KernelSU</string>
|
||||
<string name="home_learn_kernelsu_url">https://kernelsu.org/guide/what-is-kernelsu.html</string>
|
||||
<string name="home_click_to_learn_kernelsu">Learn how to install KernelSU and use modules</string>
|
||||
|
@ -69,36 +69,36 @@
|
|||
<string name="failed_to_update_app_profile">Failed to update App Profile for %s</string>
|
||||
<string name="require_kernel_version">The current KernelSU version %d is too low for the manager to function properly. Please upgrade to version %d or higher!</string>
|
||||
<string name="settings_umount_modules_default">Umount modules by default</string>
|
||||
<string name="settings_umount_modules_default_summary">The global default value for \"Umount modules\" in App Profiles. If enabled, it will remove all module modifications to the system for applications that do not have a Profile set.</string>
|
||||
<string name="profile_umount_modules_summary">Enabling this option will allow KernelSU to restore any modified files by the modules for this application.</string>
|
||||
<string name="settings_umount_modules_default_summary">The global default value for \"Umount modules\" in App Profile. If enabled, it will remove all module modifications to the system for apps that don\'t have a Profile set.</string>
|
||||
<string name="profile_umount_modules_summary">Enabling this option will allow KernelSU to restore any modified files by the modules for this app.</string>
|
||||
<string name="profile_selinux_domain">Domain</string>
|
||||
<string name="profile_selinux_rules">Rules</string>
|
||||
<string name="module_update">Update</string>
|
||||
<string name="module_downloading">Downloading module: %s</string>
|
||||
<string name="module_start_downloading">Start downloading: %s</string>
|
||||
<string name="new_version_available">New version: %s is available, click to upgrade</string>
|
||||
<string name="new_version_available">New version %s is available, click to upgrade.</string>
|
||||
<string name="launch_app">Launch</string>
|
||||
<string name="force_stop_app">Force Stop</string>
|
||||
<string name="force_stop_app">Force stop</string>
|
||||
<string name="restart_app">Restart</string>
|
||||
<string name="failed_to_update_sepolicy">Failed to update SELinux rules for: %s</string>
|
||||
<string name="module_changelog">Changelog</string>
|
||||
<string name="settings_profile_template">App Profile Template</string>
|
||||
<string name="settings_profile_template_summary">Manage local and online template of App Profile</string>
|
||||
<string name="app_profile_template_create">Create Template</string>
|
||||
<string name="app_profile_template_edit">Edit Template</string>
|
||||
<string name="app_profile_template_create">Create template</string>
|
||||
<string name="app_profile_template_edit">Edit template</string>
|
||||
<string name="app_profile_template_id">id</string>
|
||||
<string name="app_profile_template_id_invalid">Invalid template id</string>
|
||||
<string name="app_profile_template_name">Name</string>
|
||||
<string name="app_profile_template_description">Description</string>
|
||||
<string name="app_profile_template_save">Save</string>
|
||||
<string name="app_profile_template_delete">Delete</string>
|
||||
<string name="app_profile_template_view">View Template</string>
|
||||
<string name="app_profile_template_view">View template</string>
|
||||
<string name="app_profile_template_readonly">readonly</string>
|
||||
<string name="app_profile_template_id_exist">template id already exists!</string>
|
||||
<string name="app_profile_import_export">Import/Export</string>
|
||||
<string name="app_profile_import_from_clipboard">Import from clipboard</string>
|
||||
<string name="app_profile_export_to_clipboard">Export to clipboard</string>
|
||||
<string name="app_profile_template_export_empty">Can not find local template to export!</string>
|
||||
<string name="app_profile_template_export_empty">Cannot find local template to export!</string>
|
||||
<string name="app_profile_template_import_success">Imported successfully</string>
|
||||
<string name="app_profile_template_sync">Sync online templates</string>
|
||||
<string name="app_profile_template_save_failed">Failed to save template</string>
|
||||
|
@ -110,24 +110,25 @@
|
|||
<string name="open">Open</string>
|
||||
<string name="enable_web_debugging">Enable WebView Debugging</string>
|
||||
<string name="enable_web_debugging_summary">Can be used to debug WebUI, please enable only when needed.</string>
|
||||
<string name="direct_install">Direct Install (Recommended)</string>
|
||||
<string name="select_file">Select a File</string>
|
||||
<string name="install_inactive_slot">Install to Inactive Slot (After OTA)</string>
|
||||
<string name="direct_install">Direct install (Recommended)</string>
|
||||
<string name="select_file">Select a file</string>
|
||||
<string name="install_inactive_slot">Install to inactive slot (After OTA)</string>
|
||||
<string name="install_inactive_slot_warning">Your device will be **FORCED** to boot to the current inactive slot after a reboot!\nOnly use this option after OTA is done.\nContinue?</string>
|
||||
<string name="install_next">Next</string>
|
||||
<string name="select_file_tip">%1$s partition image is recommended</string>
|
||||
<string name="select_kmi">Select KMI</string>
|
||||
<string name="shrink_sparse_image">Minimize sparse image</string>
|
||||
<string name="shrink_sparse_image_message">Resize the sparse image where the module is located to its actual size. Note that this may cause the module to work abnormally, so please only use when necessary (such as for backup)</string>
|
||||
<string name="shrink_sparse_image_message">Resize the sparse image where the module is located to its actual size. Note that this may cause the module to work abnormally, so please only use when necessary (such as for backup).</string>
|
||||
<string name="settings_uninstall">Uninstall</string>
|
||||
<string name="settings_uninstall_temporary">Uninstall Temporarily</string>
|
||||
<string name="settings_uninstall_permanent">Uninstall Permanently</string>
|
||||
<string name="settings_restore_stock_image">Restore Stock Image</string>
|
||||
<string name="settings_uninstall_temporary">Uninstall temporarily</string>
|
||||
<string name="settings_uninstall_permanent">Uninstall permanently</string>
|
||||
<string name="settings_restore_stock_image">Restore stock image</string>
|
||||
<string name="settings_uninstall_temporary_message">Temporarily uninstall KernelSU, restore to original state after next reboot.</string>
|
||||
<string name="settings_uninstall_permanent_message">Uninstalling KernelSU(Root and all modules) completely and permanently.</string>
|
||||
<string name="settings_restore_stock_image_message">Restore the stock factory image (if a backup exists), usually used before OTA; if you need to uninstall KernelSU, please use \"Permanent Uninstall\".</string>
|
||||
<string name="settings_uninstall_permanent_message">Uninstalling KernelSU (Root and all modules) completely and permanently.</string>
|
||||
<string name="settings_restore_stock_image_message">Restore the stock factory image (If a backup exists), usually used before OTA; if you need to uninstall KernelSU, please use \"Uninstall permanently\".</string>
|
||||
<string name="flashing">Flashing</string>
|
||||
<string name="flash_success">Flash success</string>
|
||||
<string name="flash_failed">Flash failed</string>
|
||||
<string name="selected_lkm">Selected lkm: %s</string>
|
||||
</resources>
|
||||
<string name="selected_lkm">Selected LKM: %s</string>
|
||||
<string name="save_log">Save logs</string>
|
||||
</resources>
|
||||
|
|
|
@ -7,6 +7,7 @@ plugins {
|
|||
alias(libs.plugins.agp.app) apply false
|
||||
alias(libs.plugins.agp.lib) apply false
|
||||
alias(libs.plugins.kotlin) apply false
|
||||
alias(libs.plugins.compose.compiler) apply false
|
||||
alias(libs.plugins.lsplugin.cmaker)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
[versions]
|
||||
agp = "8.4.0"
|
||||
kotlin = "1.9.23"
|
||||
ksp = "1.9.23-1.0.20"
|
||||
compose-compiler = "1.5.11"
|
||||
compose-bom = "2024.05.00"
|
||||
lifecycle = "2.7.0"
|
||||
agp = "8.5.0"
|
||||
kotlin = "2.0.0"
|
||||
ksp = "2.0.0-1.0.22"
|
||||
compose-bom = "2024.06.00"
|
||||
lifecycle = "2.8.1"
|
||||
accompanist = "0.34.0"
|
||||
navigation = "2.7.7"
|
||||
activity-compose = "1.9.0"
|
||||
kotlinx-coroutines = "1.8.0"
|
||||
kotlinx-coroutines = "1.8.1"
|
||||
coil-compose = "2.6.0"
|
||||
compose-destination = "1.10.2"
|
||||
sheets-compose-dialogs = "1.3.0"
|
||||
|
@ -25,6 +24,7 @@ agp-app = { id = "com.android.application", version.ref = "agp" }
|
|||
agp-lib = { id = "com.android.library", version.ref = "agp" }
|
||||
|
||||
kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
||||
|
||||
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
|
||||
|
||||
|
@ -75,4 +75,4 @@ sheet-compose-dialogs-core = { group = "com.maxkeppeler.sheets-compose-dialogs",
|
|||
sheet-compose-dialogs-list = { group = "com.maxkeppeler.sheets-compose-dialogs", name = "list", version.ref = "sheets-compose-dialogs" }
|
||||
sheet-compose-dialogs-input = { group = "com.maxkeppeler.sheets-compose-dialogs", name = "input", version.ref = "sheets-compose-dialogs" }
|
||||
|
||||
markdown = { group = "io.noties.markwon", name = "core", version.ref = "markdown" }
|
||||
markdown = { group = "io.noties.markwon", name = "core", version.ref = "markdown" }
|
|
@ -1,5 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
|
|
|
@ -84,47 +84,48 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.13"
|
||||
version = "0.6.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
|
||||
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.6"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
|
||||
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
|
||||
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
|
||||
checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.2"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
|
||||
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
|
@ -132,9 +133,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.82"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
|
||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
|
@ -153,14 +154,14 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.2.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
|
@ -245,12 +246,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.92"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41"
|
||||
checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -291,9 +293,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.4"
|
||||
version = "4.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
|
||||
checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
@ -301,9 +303,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.2"
|
||||
version = "4.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
|
||||
checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
@ -313,14 +315,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.4"
|
||||
version = "4.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
|
||||
checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -331,9 +333,9 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
|||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
|
||||
|
||||
[[package]]
|
||||
name = "const_format"
|
||||
|
@ -378,9 +380,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.0"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
|
||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
@ -400,9 +402,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.12"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95"
|
||||
checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
@ -437,9 +439,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.19"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
|
@ -474,7 +476,7 @@ checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -485,7 +487,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -507,14 +509,14 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.10.0"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
|
||||
checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
|
@ -573,9 +575,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.8"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
|
||||
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
|
@ -604,9 +606,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.28"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
|
||||
checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
|
@ -639,9 +641,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.14"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
|
@ -797,6 +799,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
|
@ -816,9 +824,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.30"
|
||||
version = "0.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "685a7d121ee3f65ae4fddd72b25a04bb36b6af81bc0828f7d5434c0fe60fa3a2"
|
||||
checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
@ -877,7 +885,7 @@ dependencies = [
|
|||
"sha256",
|
||||
"tempdir",
|
||||
"which",
|
||||
"zip 1.2.1",
|
||||
"zip 2.1.3",
|
||||
"zip-extensions",
|
||||
]
|
||||
|
||||
|
@ -889,9 +897,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "libflate"
|
||||
|
@ -921,9 +929,15 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
|||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.13"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
|
||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||
|
||||
[[package]]
|
||||
name = "lockfree-object-pool"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
|
@ -964,9 +978,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.2"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
|
||||
checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
@ -989,34 +1003,13 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
|||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.18"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845"
|
||||
dependencies = [
|
||||
"num_enum_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.32.2"
|
||||
|
@ -1079,15 +1072,6 @@ version = "0.2.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284"
|
||||
dependencies = [
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.20+deprecated"
|
||||
|
@ -1096,9 +1080,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.79"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
||||
checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -1115,7 +1099,7 @@ dependencies = [
|
|||
"hex",
|
||||
"lazy_static",
|
||||
"procfs-core",
|
||||
"rustix 0.38.32",
|
||||
"rustix 0.38.34",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1227,9 +1211,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.4"
|
||||
version = "1.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
|
@ -1280,9 +1264,9 @@ checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
|
|||
|
||||
[[package]]
|
||||
name = "rust-embed"
|
||||
version = "8.3.0"
|
||||
version = "8.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb78f46d0066053d16d4ca7b898e9343bc3530f71c61d5ad84cd404ada068745"
|
||||
checksum = "19549741604902eb99a7ed0ee177a0663ee1eda51a29f71401f166e47e77806a"
|
||||
dependencies = [
|
||||
"include-flate",
|
||||
"rust-embed-impl",
|
||||
|
@ -1292,22 +1276,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rust-embed-impl"
|
||||
version = "8.3.0"
|
||||
version = "8.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b91ac2a3c6c0520a3fb3dd89321177c3c692937c4eb21893378219da10c44fc8"
|
||||
checksum = "cb9f96e283ec64401f30d3df8ee2aaeb2561f34c824381efa24a35f79bf40ee4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rust-embed-utils",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-utils"
|
||||
version = "8.3.0"
|
||||
version = "8.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86f69089032567ffff4eada41c573fc43ff466c7db7c5688b2e7969584345581"
|
||||
checksum = "38c74a686185620830701348de757fd36bef4aa9680fd23c49fc539ddcc1af32"
|
||||
dependencies = [
|
||||
"sha2",
|
||||
"walkdir",
|
||||
|
@ -1315,9 +1299,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
|
@ -1325,7 +1309,7 @@ version = "0.38.30"
|
|||
source = "git+https://github.com/Kernel-SU/rustix.git?branch=main#0e270bce2d97466be6b987bb5f7ea5b1e8d84969"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"errno 0.3.8",
|
||||
"errno 0.3.9",
|
||||
"itoa",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
|
@ -1335,12 +1319,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.32"
|
||||
version = "0.38.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
|
||||
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"errno 0.3.8",
|
||||
"errno 0.3.9",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
|
@ -1348,9 +1332,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.17"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
|
@ -1363,29 +1347,29 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.198"
|
||||
version = "1.0.202"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc"
|
||||
checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.198"
|
||||
version = "1.0.202"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9"
|
||||
checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.116"
|
||||
version = "1.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
|
||||
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -1427,6 +1411,12 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
|
@ -1452,9 +1442,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.58"
|
||||
version = "2.0.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
|
||||
checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1473,22 +1463,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.58"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
|
||||
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.58"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1521,23 +1511,6 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
|
@ -1552,9 +1525,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
|
@ -1611,7 +1584,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
@ -1633,7 +1606,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.65",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@ -1652,7 +1625,7 @@ checksum = "8211e4f58a2b2805adfbefbc07bab82958fc91e3836339b1ab7ae32465dce0d7"
|
|||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"rustix 0.38.32",
|
||||
"rustix 0.38.34",
|
||||
"winsafe",
|
||||
]
|
||||
|
||||
|
@ -1674,11 +1647,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
|||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.6"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||
checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1707,13 +1680,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
|
@ -1722,54 +1696,51 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
|
||||
[[package]]
|
||||
name = "winsafe"
|
||||
|
@ -1799,9 +1770,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "1.2.1"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "006d078b7b6fc587bb25e022ad39e7086f44e5c4fef6076964ea601533241beb"
|
||||
checksum = "775a2b471036342aa69bc5a602bc889cb0a06cda00477d0c69566757d5553d39"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"bzip2",
|
||||
|
@ -1811,21 +1782,36 @@ dependencies = [
|
|||
"displaydoc",
|
||||
"flate2",
|
||||
"indexmap",
|
||||
"num_enum",
|
||||
"memchr",
|
||||
"thiserror",
|
||||
"time",
|
||||
"zopfli",
|
||||
"zstd 0.13.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zip-extensions"
|
||||
version = "0.6.2"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cecf62554c4ff96bce01a7ef123d160c3ffe9180638820f8b4d545c65b221b8c"
|
||||
checksum = "c865b4f0f43f22d1bd7ba05479b5c003e0e98e9090c3a2e4280b5eace59f62df"
|
||||
dependencies = [
|
||||
"zip 0.6.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zopfli"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"crc32fast",
|
||||
"lockfree-object-pool",
|
||||
"log",
|
||||
"once_cell",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.11.2+zstd.1.5.2"
|
||||
|
|
|
@ -10,14 +10,14 @@ rust-version = "1.77.2"
|
|||
anyhow = "1"
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
const_format = "0.2"
|
||||
zip = { version = "1.2", features = [
|
||||
zip = { version = "2", features = [
|
||||
"deflate",
|
||||
"deflate64",
|
||||
"bzip2",
|
||||
"time",
|
||||
"zstd",
|
||||
], default-features = false }
|
||||
zip-extensions = "0.6"
|
||||
zip-extensions = "0.7"
|
||||
java-properties = "2"
|
||||
log = "0.4"
|
||||
env_logger = { version = "0.11", default-features = false }
|
||||
|
@ -60,4 +60,4 @@ android_logger = "0.13"
|
|||
[profile.release]
|
||||
strip = true
|
||||
opt-level = "z"
|
||||
lto = true
|
||||
lto = true
|
Binary file not shown.
Binary file not shown.
|
@ -159,7 +159,11 @@ pub fn restore(
|
|||
let workdir = tmpdir.path();
|
||||
let magiskboot = find_magiskboot(magiskboot_path, workdir)?;
|
||||
|
||||
let (bootimage, bootdevice) = find_boot_image(&image, false, false, workdir)?;
|
||||
let kmi = get_current_kmi().unwrap_or_else(|_| String::from(""));
|
||||
|
||||
let skip_init = kmi.starts_with("android12-");
|
||||
|
||||
let (bootimage, bootdevice) = find_boot_image(&image, skip_init, false, false, workdir)?;
|
||||
|
||||
println!("- Unpacking boot image");
|
||||
let status = Command::new(&magiskboot)
|
||||
|
@ -309,7 +313,16 @@ fn do_patch(
|
|||
let tmpdir = tempdir::TempDir::new("KernelSU").context("create temp dir failed")?;
|
||||
let workdir = tmpdir.path();
|
||||
|
||||
let (bootimage, bootdevice) = find_boot_image(&image, ota, is_replace_kernel, workdir)?;
|
||||
let kmi = if let Some(kmi) = kmi {
|
||||
kmi
|
||||
} else {
|
||||
get_current_kmi().context("Unknown KMI, please choose LKM manually")?
|
||||
};
|
||||
|
||||
let skip_init = kmi.starts_with("android12-");
|
||||
|
||||
let (bootimage, bootdevice) =
|
||||
find_boot_image(&image, skip_init, ota, is_replace_kernel, workdir)?;
|
||||
|
||||
let bootimage = bootimage.display().to_string();
|
||||
|
||||
|
@ -330,11 +343,6 @@ fn do_patch(
|
|||
std::fs::copy(kmod, kmod_file).context("copy kernel module failed")?;
|
||||
} else {
|
||||
// If kmod is not specified, extract from assets
|
||||
let kmi = if let Some(kmi) = kmi {
|
||||
kmi
|
||||
} else {
|
||||
get_current_kmi().context("Unknown KMI, please choose LKM manually")?
|
||||
};
|
||||
println!("- KMI: {kmi}");
|
||||
let name = format!("{kmi}_kernelsu.ko");
|
||||
assets::copy_assets_to_file(&name, kmod_file)
|
||||
|
@ -537,6 +545,7 @@ fn find_magiskboot(magiskboot_path: Option<PathBuf>, workdir: &Path) -> Result<P
|
|||
|
||||
fn find_boot_image(
|
||||
image: &Option<PathBuf>,
|
||||
skip_init: bool,
|
||||
ota: bool,
|
||||
is_replace_kernel: bool,
|
||||
workdir: &Path,
|
||||
|
@ -547,6 +556,10 @@ fn find_boot_image(
|
|||
ensure!(image.exists(), "boot image not found");
|
||||
bootimage = std::fs::canonicalize(image)?;
|
||||
} else {
|
||||
if cfg!(not(target_os = "android")) {
|
||||
println!("- Current OS is not android, refusing auto bootimage/bootdevice detection");
|
||||
bail!("please specify a boot image");
|
||||
}
|
||||
let mut slot_suffix =
|
||||
utils::getprop("ro.boot.slot_suffix").unwrap_or_else(|| String::from(""));
|
||||
|
||||
|
@ -560,7 +573,7 @@ fn find_boot_image(
|
|||
|
||||
let init_boot_exist =
|
||||
Path::new(&format!("/dev/block/by-name/init_boot{slot_suffix}")).exists();
|
||||
let boot_partition = if !is_replace_kernel && init_boot_exist {
|
||||
let boot_partition = if !is_replace_kernel && init_boot_exist && !skip_init {
|
||||
format!("/dev/block/by-name/init_boot{slot_suffix}")
|
||||
} else {
|
||||
format!("/dev/block/by-name/boot{slot_suffix}")
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use anyhow::{bail, Context, Error, Ok, Result};
|
||||
use std::{
|
||||
fs::{create_dir_all, remove_file, write, File, OpenOptions},
|
||||
fs::{self, create_dir_all, remove_file, write, File, OpenOptions},
|
||||
io::{
|
||||
ErrorKind::{AlreadyExists, NotFound},
|
||||
Write,
|
||||
},
|
||||
path::Path,
|
||||
process::Command,
|
||||
sync::OnceLock,
|
||||
};
|
||||
|
||||
use crate::{assets, boot_patch, defs, ksucalls, module, restorecon};
|
||||
|
@ -188,14 +189,66 @@ pub fn has_magisk() -> bool {
|
|||
which::which("magisk").is_ok()
|
||||
}
|
||||
|
||||
fn is_ok_empty(dir: &str) -> bool {
|
||||
use std::result::Result::Ok;
|
||||
|
||||
match fs::read_dir(dir) {
|
||||
Ok(mut entries) => entries.next().is_none(),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn find_temp_path() -> String {
|
||||
use std::result::Result::Ok;
|
||||
|
||||
if is_ok_empty(defs::TEMP_DIR) {
|
||||
return defs::TEMP_DIR.to_string();
|
||||
}
|
||||
|
||||
// Try to create a random directory in /dev/
|
||||
let r = tempdir::TempDir::new_in("/dev/", "");
|
||||
match r {
|
||||
Ok(tmp_dir) => {
|
||||
if let Some(path) = tmp_dir.into_path().to_str() {
|
||||
return path.to_string();
|
||||
}
|
||||
}
|
||||
Err(_e) => {}
|
||||
}
|
||||
|
||||
let dirs = [
|
||||
defs::TEMP_DIR,
|
||||
"/patch_hw",
|
||||
"/oem",
|
||||
"/root",
|
||||
defs::TEMP_DIR_LEGACY,
|
||||
];
|
||||
|
||||
// find empty directory
|
||||
for dir in dirs {
|
||||
if is_ok_empty(dir) {
|
||||
return dir.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to non-empty directory
|
||||
for dir in dirs {
|
||||
if metadata(dir).is_ok() {
|
||||
return dir.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
pub fn get_tmp_path() -> &'static str {
|
||||
if metadata(defs::TEMP_DIR_LEGACY).is_ok() {
|
||||
return defs::TEMP_DIR_LEGACY;
|
||||
}
|
||||
if metadata(defs::TEMP_DIR).is_ok() {
|
||||
return defs::TEMP_DIR;
|
||||
}
|
||||
""
|
||||
static CHOSEN_TMP_PATH: OnceLock<String> = OnceLock::new();
|
||||
|
||||
CHOSEN_TMP_PATH.get_or_init(|| {
|
||||
let r = find_temp_path();
|
||||
log::info!("Chosen temp_path: {}", r);
|
||||
r
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
|
@ -233,8 +286,11 @@ pub fn uninstall(magiskboot_path: Option<PathBuf>) -> Result<()> {
|
|||
module::prune_modules()?;
|
||||
}
|
||||
println!("- Removing directories..");
|
||||
std::fs::remove_dir_all(defs::WORKING_DIR)?;
|
||||
std::fs::remove_file(defs::DAEMON_PATH)?;
|
||||
std::fs::remove_dir_all(defs::WORKING_DIR).ok();
|
||||
std::fs::remove_file(defs::DAEMON_PATH).ok();
|
||||
crate::mount::umount_dir(defs::MODULE_DIR).ok();
|
||||
std::fs::remove_dir_all(defs::MODULE_DIR).ok();
|
||||
std::fs::remove_dir_all(defs::MODULE_UPDATE_TMP_DIR).ok();
|
||||
println!("- Restore boot image..");
|
||||
boot_patch::restore(None, magiskboot_path, true)?;
|
||||
println!("- Uninstall KernelSU manager..");
|
||||
|
|
|
@ -4,7 +4,7 @@ The App Profile is a mechanism provided by KernelSU for customizing the configur
|
|||
|
||||
For applications granted root permissions (i.e., able to use `su`), the App Profile can also be referred to as the Root Profile. It allows customization of the `uid`, `gid`, `groups`, `capabilities`, and `SELinux` rules of the `su` command, thereby restricting the privileges of the root user. For example, it can grant network permissions only to firewall applications while denying file access permissions, or it can grant shell permissions instead of full root access for freeze applications: **keeping the power confined with the principle of least privilege.**
|
||||
|
||||
For ordinary applications without root permissions, the App Profile can control the behavior of the kernel and module system towards these applications. For instance, it can determine whether modifications resulting from modules should be addressed. The kernel and module system can make decisions based on this configuration, such as performing operations akin to "hiding"
|
||||
For ordinary applications without root permissions, the App Profile can control the behavior of the kernel and module system towards these applications. For instance, it can determine whether modifications resulting from modules should be addressed. The kernel and module system can make decisions based on this configuration, such as performing operations akin to "hiding".
|
||||
|
||||
## Root Profile
|
||||
|
||||
|
|
|
@ -4,14 +4,14 @@ Although there are many similarities between KernelSU modules and Magisk modules
|
|||
|
||||
## Similarities
|
||||
|
||||
- Module file format: both use zip format to organize modules, and the format of modules is almost the same
|
||||
- Module installation directory: both located in `/data/adb/modules`
|
||||
- Systemless: both support modifying /system in a systemless way through modules
|
||||
- post-fs-data.sh: the execution time and semantics are exactly the same
|
||||
- service.sh: the execution time and semantics are exactly the same
|
||||
- system.prop: completely the same
|
||||
- sepolicy.rule: completely the same
|
||||
- BusyBox: scripts are run in BusyBox with "standalone mode" enabled in both cases
|
||||
- Module file format: both use zip format to organize modules, and the format of modules is almost the same.
|
||||
- Module installation directory: both located in `/data/adb/modules`.
|
||||
- Systemless: both support modifying /system in a systemless way through modules.
|
||||
- post-fs-data.sh: the execution time and semantics are exactly the same.
|
||||
- service.sh: the execution time and semantics are exactly the same.
|
||||
- system.prop: completely the same.
|
||||
- sepolicy.rule: completely the same.
|
||||
- BusyBox: scripts are run in BusyBox with "standalone mode" enabled in both cases.
|
||||
|
||||
## Differences
|
||||
|
||||
|
@ -20,9 +20,9 @@ Before understanding the differences, you need to know how to differentiate whet
|
|||
Here are some differences:
|
||||
|
||||
- KernelSU modules cannot be installed in Recovery mode.
|
||||
- KernelSU modules do not have built-in support for Zygisk (but you can use Zygisk modules through [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
- KernelSU modules do not have built-in support for Zygisk (but you can use Zygisk modules through [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext)).
|
||||
- The method for replacing or deleting files in KernelSU modules is completely different from Magisk. KernelSU does not support the `.replace` method. Instead, you need to create a same-named file with `mknod filename c 0 0` to delete the corresponding file.
|
||||
- The directories for BusyBox are different. The built-in BusyBox in KernelSU is located in `/data/adb/ksu/bin/busybox`, while in Magisk it is in `/data/adb/magisk/busybox`. **Note that this is an internal behavior of KernelSU and may change in the future!**
|
||||
- KernelSU does not support `.replace` files; however, KernelSU supports the `REMOVE` and `REPLACE` variable to remove or replace files and folders.
|
||||
- KernelSU adds `boot-completed` stage to run some scripts on boot completed.
|
||||
- KernelSU adds `post-mount` stage to run some scripts after mounting overlayfs
|
||||
- KernelSU adds `post-mount` stage to run some scripts after mounting overlayfs.
|
||||
|
|
|
@ -12,11 +12,11 @@ Certainly, yes.
|
|||
|
||||
## Does KernelSU support modules?
|
||||
|
||||
Yes, check [Module Page](module.md) please.
|
||||
Yes, check [Module Guide](module.md) please.
|
||||
|
||||
## Does KernelSU support Xposed?
|
||||
|
||||
Yes, you can use LSPosed on [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext)
|
||||
Yes, you can use LSPosed on [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
|
||||
## Does KernelSU support Zygisk?
|
||||
|
||||
|
@ -26,7 +26,7 @@ KernelSU has no builtin Zygisk support, but you can use [ZygiskNext](https://git
|
|||
|
||||
KernelSU's module system is conflict with Magisk's magic mount, if there is any module enabled in KernelSU, then the whole Magisk would not work.
|
||||
|
||||
But if you only use the `su` of KernelSU, then it will work well with Magisk: KernelSU modify the `kernel` and Magisk modify the `ramdisk`, they can work together.
|
||||
But if you only use the `su` of KernelSU, then it will work well with Magisk: with KernelSU modifying the `kernel` and Magisk modifying the `ramdisk`, both of them can work together simultaneously.
|
||||
|
||||
## Will KernelSU substitute Magisk?
|
||||
|
||||
|
@ -38,18 +38,18 @@ It is possible. But you should download the kernel source and intergrate KernelS
|
|||
|
||||
## Can KernelSU support devices below Android 12?
|
||||
|
||||
It is device's kernel that affect KernelSU's compatability and it has nothing to do with Android version.The only restriction is that devices launched with Android 12 must be kernel 5.10+(GKI devices). So:
|
||||
It is device's kernel that affect KernelSU's compatability and it has nothing to do with Android version. The only restriction is that devices launched with Android 12 must be kernel of a 5.10+ version (GKI devices). So:
|
||||
|
||||
1. Devices launched with Android 12 must be supported.
|
||||
2. Devices which have an old kernel (Some Android 12 devices is also old kernel) are compatible (You should build kernel yourself)
|
||||
2. Devices which have an old kernel (Some Android 12 devices is also old kernel) are compatible (You should build kernel yourself).
|
||||
|
||||
## Can KernelSU support old kernel?
|
||||
|
||||
It is possible, KernelSU is backported to kernel 4.14 now, for older kernel, you need to backport it manully and PRs welcome!
|
||||
It is possible, KernelSU is backported to kernel 4.14 now; for older kernel, you need to backport it manually and PRs welcome!
|
||||
|
||||
## How to integrate KernelSU for old kernel?
|
||||
## How to integrate KernelSU for an older kernel?
|
||||
|
||||
Please refer [Guide](how-to-integrate-for-non-gki)
|
||||
Please refer to the following [Guide](how-to-integrate-for-non-gki).
|
||||
|
||||
## Why my Android version is 13, and the kernel shows "android12-5.10"?
|
||||
|
||||
|
@ -59,17 +59,17 @@ The Kernel version has nothing to do with Android version, if you need to flash
|
|||
|
||||
GKI1 is completely different from GKI2, you must compile kernel by yourself.
|
||||
|
||||
## How can i make `/system` RW?
|
||||
## How can I make `/system` RW?
|
||||
|
||||
We do not recommend you to modify the system partition directly. You should use the [module](module.md) to modify it systemlessly. If you insist on doing this, check [magisk_overlayfs](https://github.com/HuskyDG/magic_overlayfs).
|
||||
|
||||
## Can KernelSU modify hosts? How can i use AdAway?
|
||||
## Can KernelSU modify hosts? How can I use AdAway?
|
||||
|
||||
Of course. But KernelSU doesn't have builtin hosts support, you can install [systemless-hosts](https://github.com/symbuzzer/systemless-hosts-KernelSU-module) to do it.
|
||||
Of course. But KernelSU doesn't have built-in hosts support, you can install [systemless-hosts](https://github.com/symbuzzer/systemless-hosts-KernelSU-module) to do it.
|
||||
|
||||
## Why is there a huge 1 TB file?
|
||||
|
||||
The 1 TB size `modules.img` is a disk image file, **don't worry about its size**, it's a special type of file known as a [sparse file](https://en.wikipedia.org/wiki/Sparse_file), its actual size is only the size of the module you use, and it will dynamically shrink after you delete the module; it does not actually occupy 1 TB of disk space (actually your mobile phone may not have that much space).
|
||||
The 1 TB size `modules.img` is a disk image file, **don't worry about its size**, it's a special type of file known as a [sparse file](https://en.wikipedia.org/wiki/Sparse_file), it's actual size is only the size of the module you use, and it will dynamically shrink after you delete the module; it does not actually occupy 1 TB of disk space (your mobile phone may not actually have that much space).
|
||||
|
||||
If you're really unhappy with the size of this file, you can use the `resize2fs -M` command to make it the actual size; but the module may not work properly at this time, and we won't provide any support for this.
|
||||
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
By default, `/system/bin/sh` loads `/system/etc/mkshrc`.
|
||||
|
||||
You can make su load customized rc file by creating a `/data/adb/ksu/.ksurc` file.
|
||||
You can make su load customized rc file by creating a `/data/adb/ksu/.ksurc` file.
|
||||
|
|
|
@ -6,7 +6,7 @@ First, you should read the Android Official docs for kernel build:
|
|||
2. [GKI Release Builds](https://source.android.com/docs/core/architecture/kernel/gki-release-builds)
|
||||
|
||||
::: warning
|
||||
This page is for GKI devices, if you use an old kernel, please refer [how to integrate KernelSU for old kernel](how-to-integrate-for-non-gki)
|
||||
This page is for GKI devices, if you use an old kernel, please refer [How to integrate KernelSU for non-GKI kernels](how-to-integrate-for-non-gki).
|
||||
:::
|
||||
|
||||
## Build Kernel
|
||||
|
@ -20,19 +20,19 @@ repo init -m manifest.xml
|
|||
repo sync
|
||||
```
|
||||
|
||||
The `<kernel_manifest.xml>` is a manifest file which can determine a build uniquely, you can use the manifest to do a re-preducable build. You should download the manifest file from [Google GKI release builds](https://source.android.com/docs/core/architecture/kernel/gki-release-builds)
|
||||
The `<kernel_manifest.xml>` is a manifest file which can determine a build uniquely, you can use the manifest to do a re-preducable build. You should download the manifest file from [Google GKI release builds](https://source.android.com/docs/core/architecture/kernel/gki-release-builds).
|
||||
|
||||
### Build
|
||||
|
||||
Please check the [official docs](https://source.android.com/docs/setup/build/building-kernels) first.
|
||||
|
||||
For example, we need to build aarch64 kernel image:
|
||||
For example, to build an aarch64 kernel image:
|
||||
|
||||
```sh
|
||||
LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
|
||||
```
|
||||
|
||||
Don't forget to add the `LTO=thin` flag, otherwise the build may fail if your computer's memory is less then 24Gb.
|
||||
Don't forget to add the `LTO=thin` flag, otherwise the build may fail if your computer's memory is less then 24 GB.
|
||||
|
||||
Starting from Android 13, the kernel is built by `bazel`:
|
||||
|
||||
|
@ -41,7 +41,7 @@ tools/bazel build --config=fast //common:kernel_aarch64_dist
|
|||
```
|
||||
|
||||
:::info
|
||||
For some Android 14 Kernel, to make Wi-Fi/Bluetooth work. It may be necessary to remove all the GKI protected exports:
|
||||
For some of the Android 14 kernels, to make Wi-Fi/Bluetooth work, it might be necessary to remove all the GKI protected exports:
|
||||
|
||||
```sh
|
||||
rm common/android/abi_gki_protected_exports_*
|
||||
|
@ -50,7 +50,7 @@ rm common/android/abi_gki_protected_exports_*
|
|||
|
||||
## Build Kernel with KernelSU
|
||||
|
||||
If you can build the kernel successfully, then build KernelSU is so easy, Select any one run in Kernel source root dir:
|
||||
If you're able to build the kernel successfully, then adding KernelSU support to it is relatively easy. In the root of kernel source directory, run any of the command options listed below:
|
||||
|
||||
::: code-group
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# How to integrate KernelSU for non GKI kernels?
|
||||
# How to integrate KernelSU for non-GKI kernels?
|
||||
|
||||
KernelSU can be integrated into non GKI kernels, and was backported to 4.14 and below.
|
||||
KernelSU can be integrated into non-GKI kernels, and was backported to 4.14 and below.
|
||||
|
||||
Due to the fragmentization of non GKI kernels, we do not have a uniform way to build it, so we can not provide non GKI boot images. But you can build the kernel yourself with KernelSU integrated.
|
||||
Due to the fragmentization of non-GKI kernels, we do not have a universal way to build it, so we cannot provide non-GKI boot images. But you can build the kernel yourself with KernelSU integrated.
|
||||
|
||||
First, you should be able to build a bootable kernel from kernel source code. If the kernel is not open source, then it is difficult to run KernelSU for your device.
|
||||
|
||||
|
@ -18,22 +18,26 @@ KernelSU uses kprobe to do kernel hooks, if the *kprobe* runs well in your kerne
|
|||
First, add KernelSU to your kernel source tree:
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.9.5
|
||||
```
|
||||
|
||||
:::info
|
||||
[KernelSU 1.0 and later versions no longer support non-GKI kernels](https://github.com/tiann/KernelSU/issues/1705). The last supported version is `v0.9.5`, please make sure to use the correct version.
|
||||
:::
|
||||
|
||||
Then, you should check if *kprobe* is enabled in your kernel config, if it is not, please add these configs to it:
|
||||
|
||||
```
|
||||
```txt
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_HAVE_KPROBES=y
|
||||
CONFIG_KPROBE_EVENTS=y
|
||||
```
|
||||
|
||||
And build your kernel again, KernelSU should works well.
|
||||
And now when you re-build your kernel, KernelSU should work well.
|
||||
|
||||
If you find that KPROBES is still not activated, you can try enabling `CONFIG_MODULES`. (If it still doesn't take effect, use `make menuconfig` to search for other dependencies of KPROBES)
|
||||
If you find that KPROBES is still not activated, you can try enabling `CONFIG_MODULES`. If it still doesn't take effect, use `make menuconfig` to search for other dependencies of KPROBES.
|
||||
|
||||
But if you encounter a boot loop when integrated KernelSU, it is maybe *kprobe is broken in your kernel*, you should fix the kprobe bug or use the second way.
|
||||
But if you encounter a boot loop when integrated KernelSU, it might be because *kprobe is broken in your kernel*, which means that you should fix the kprobe bug or use another way.
|
||||
|
||||
:::tip How to check if kprobe is broken?
|
||||
|
||||
|
@ -47,7 +51,7 @@ If your kernel is older than 5.9, you should backport `path_umount` to `fs/names
|
|||
|
||||
## Manually modify the kernel source
|
||||
|
||||
If kprobe does not work in your kernel (may be an upstream or kernel bug below 4.8), then you can try this way:
|
||||
If kprobe does not work in your kernel (may be an upstream or kernel bug below 4.8), then you can try the following:
|
||||
|
||||
First, add KernelSU to your kernel source tree:
|
||||
|
||||
|
@ -67,14 +71,14 @@ curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh
|
|||
|
||||
:::
|
||||
|
||||
Keep in mind that on some devices, your defconfig may be in `arch/arm64/configs` or in other cases `arch/arm64/configs/vendor/your_defconfig`. For example in your defconfig, Enable `CONFIG_KSU` with y to enable, or n to disable. Your path will be something like:
|
||||
`arch/arm64/configs/...`
|
||||
```
|
||||
Keep in mind that on some devices, your defconfig may be in `arch/arm64/configs` or in other cases `arch/arm64/configs/vendor/your_defconfig`. For whichever defconfig you're using, make sure to enable `CONFIG_KSU` with `y` to enable or `n` to disable it. For example, in case you chose to enable it, you defconfig should contain the following string:
|
||||
|
||||
```txt
|
||||
# KernelSU
|
||||
CONFIG_KSU=y
|
||||
```
|
||||
|
||||
Then, add KernelSU calls to the kernel source, here are some patches to refer:
|
||||
Then, add KernelSU calls to the kernel source, here are some patches for reference:
|
||||
|
||||
::: code-group
|
||||
|
||||
|
@ -200,12 +204,12 @@ index 376543199b5a..82adcef03ecc 100644
|
|||
|
||||
You should find the four functions in kernel source:
|
||||
|
||||
1. do_faccessat, usually in `fs/open.c`
|
||||
2. do_execveat_common, usually in `fs/exec.c`
|
||||
3. vfs_read, usually in `fs/read_write.c`
|
||||
4. vfs_statx, usually in `fs/stat.c`
|
||||
1. `do_faccessat`, usually in `fs/open.c`
|
||||
2. `do_execveat_common`, usually in `fs/exec.c`
|
||||
3. `vfs_read`, usually in `fs/read_write.c`
|
||||
4. `vfs_statx`, usually in `fs/stat.c`
|
||||
|
||||
If your kernel does not have the `vfs_statx`, use `vfs_fstatat` instead:
|
||||
If your kernel does not have the `vfs_statx` function, use `vfs_fstatat` instead:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/stat.c b/fs/stat.c
|
||||
|
@ -266,10 +270,10 @@ index 2ff887661237..e758d7db7663 100644
|
|||
|
||||
### Safe Mode
|
||||
|
||||
To enable KernelSU's builtin SafeMode, You should also modify `input_handle_event` in `drivers/input/input.c`:
|
||||
To enable KernelSU's built-in SafeMode, you should additionally modify `input_handle_event` function in `drivers/input/input.c`:
|
||||
|
||||
:::tip
|
||||
It is strongly recommended to enable this feature, it is very helpful to prevent bootloops!
|
||||
It is strongly recommended to enable this feature, it is very helpful in preventing bootloops!
|
||||
:::
|
||||
|
||||
```diff
|
||||
|
@ -299,7 +303,7 @@ index 45306f9ef247..815091ebfca4 100755
|
|||
add_input_randomness(type, code, value);
|
||||
```
|
||||
|
||||
:::info Entering safe mode accidiently?
|
||||
:::info Entering safe mode accidentally?
|
||||
If you use manual integration and do not disable `CONFIG_KPROBES`, then the user may trigger safe mode by pressing the volume down button after booting! Therefore if using manual integration you need to disable `CONFIG_KPROBES`!
|
||||
:::
|
||||
|
||||
|
@ -316,7 +320,9 @@ index 32f6f1c68..d69d8eca2 100644
|
|||
return dentry;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_devpts(struct inode*);
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* devpts_get_priv -- get private data for a slave
|
||||
|
@ -325,7 +331,9 @@ index 32f6f1c68..d69d8eca2 100644
|
|||
*/
|
||||
void *devpts_get_priv(struct dentry *dentry)
|
||||
{
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_devpts(dentry->d_inode);
|
||||
+ #endif
|
||||
if (dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC)
|
||||
return NULL;
|
||||
return dentry->d_fsdata;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
Download KernelSU manager APP from [GitHub Releases](https://github.com/tiann/KernelSU/releases) and install it to your device:
|
||||
|
||||
- If the app shows `Unsupported`, it means **You should compile the kernel yourself**, KernelSU won't and never provide a boot image for you to flash.
|
||||
- If the app shows `Unsupported`, it means **you should compile the kernel yourself**, KernelSU won't and never provide a boot image for you to flash.
|
||||
- If the app shows `Not installed`, then your devices is officially supported by KernelSU.
|
||||
|
||||
:::info
|
||||
|
@ -45,15 +45,15 @@ Note that the SubLevel in the kernel version is not part of the KMI! That means
|
|||
|
||||
### Security patch level {#security-patch-level}
|
||||
|
||||
Newer Android devices may have anti-rollback mechanisms in place that do not allow flashing a boot image with an old security patch level. For example, if your device kernel is `5.10.101-android12-9-g30979850fc20`, its security patch is `2023-11`; even if you flash the kernel consistent with the kernel KMI, if the security patch level is older than `2023- 11`(such as `2023-06`), then it may cause bootloop.
|
||||
Newer Android devices may have anti-rollback mechanisms in place that do not allow flashing a boot image with an old security patch level. For example, if your device kernel is `5.10.101-android12-9-g30979850fc20`, it's security patch level is `2023-11`; even if you flash the kernel corresponding to the KMI, if the security patch level is older than `2023- 11` (such as `2023-06`), then it may cause bootloop.
|
||||
|
||||
Therefore, kernels with latest security patch levels are preferred while maintaining KMI consistency.
|
||||
Therefore, kernels with latest security patch levels are preferred for maintaining the correspondence with KMI.
|
||||
|
||||
### Kernel version vs. Android version
|
||||
### Kernel version vs Android version
|
||||
|
||||
Please note: **Kernel version and Android version are not necessarily the same!**
|
||||
|
||||
If you find that your kernel version is `android12-5.10.101`, but your Android system version is Android 13 or other; please don't be surprised, because the version number of the Android system is not necessarily the same as the version number of the Linux kernel; The version number of the Linux kernel is generally consistent with the version of the Android system that comes with the **device when it is shipped**. If the Android system is upgraded later, the kernel version will generally not change. If you need to flash, **please always refer to the kernel version!!**
|
||||
If you find that your kernel version is `android12-5.10.101`, but your Android system version is Android 13 or other, please don't be surprised, because the version number of the Android system is not necessarily the same as the version number of the Linux kernel. The version number of the Linux kernel is generally correspondent to the version of the Android system that comes with the **device when it is shipped**. If the Android system is upgraded later, the kernel version will generally not change. So before flashing anything, **please always refer to the kernel version!**
|
||||
|
||||
## Introduction
|
||||
|
||||
|
@ -62,23 +62,23 @@ Since version `0.9.0`, KernelSU supports two running modes on GKI devices:
|
|||
1. `GKI`: Replace the original kernel of the device with the **Generic Kernel Image** (GKI) provided by KernelSU.
|
||||
2. `LKM`: Load the **Loadable Kernel Module** (LKM) into the device kernel without replacing the original kernel.
|
||||
|
||||
These two modes are suitable for different scenarios, and you can choose according to your needs.
|
||||
These two modes are suitable for different scenarios, and you can choose the one according to your needs.
|
||||
|
||||
### GKI Mode {#gki-mode}
|
||||
### GKI mode {#gki-mode}
|
||||
|
||||
In GKI mode, the original kernel of the device will be replaced with the generic kernel image provided by KernelSU. The advantages of GKI mode are:
|
||||
|
||||
1. Strong universality, suitable for most devices; for example, Samsung has enabled KNOX devices, and LKM mode cannot operate. There are also some niche modified devices that can only use GKI mode;
|
||||
2. Can be used without relying on official firmware; no need to wait for official firmware updates, as long as the KMI is consistent, it can be used;
|
||||
1. Strong universality, suitable for most devices; for example, Samsung has enabled KNOX devices, and LKM mode cannot operate. There are also some niche modified devices that can only use GKI mode.
|
||||
2. Can be used without relying on official firmware; no need to wait for official firmware updates, as long as the KMI is consistent, it can be used.
|
||||
|
||||
### LKM Mode {#lkm-mode}
|
||||
### LKM mode {#lkm-mode}
|
||||
|
||||
In LKM mode, the original kernel of the device will not be replaced, but the loadable kernel module will be loaded into the device kernel. The advantages of LKM mode are:
|
||||
|
||||
1. Will not replace the original kernel of the device; if you have special requirements for the original kernel of the device, or you want to use KernelSU while using a third-party kernel, you can use LKM mode;
|
||||
2. It is more convenient to upgrade and OTA; when upgrading KernelSU, you can directly install it in the manager without manually flashing; after the system OTA, you can directly install it to the second slot without manually flashing;
|
||||
3. Suitable for some special scenarios; for example, LKM can also be loaded with temporary ROOT permissions. Since it does not need to replace the boot partition, it will not trigger avb and will not cause the device to be bricked;
|
||||
4. LKM can be temporarily uninstalled; if you want to temporarily cancel root, you can uninstall LKM, this process does not require flashing partitions, or even rebooting the device; if you want to root again, just reboot the device;
|
||||
1. Will not replace the original kernel of the device; if you have special requirements for the original kernel of the device, or you want to use KernelSU while using a third-party kernel, you can use LKM mode.
|
||||
2. It is more convenient to upgrade and OTA; when upgrading KernelSU, you can directly install it in the manager without flashing manually; after the system OTA, you can directly install it to the second slot without manual flashing.
|
||||
3. Suitable for some special scenarios; for example, LKM can also be loaded with temporary ROOT permissions. Since it does not need to replace the boot partition, it will not trigger avb and will not cause the device to be bricked.
|
||||
4. LKM can be temporarily uninstalled; if you want to temporarily disable root access, you can uninstall LKM, this process does not require flashing partitions, or even rebooting the device; if you want to enable root again, just reboot the device.
|
||||
|
||||
:::tip Coexistence of two modes
|
||||
After opening the manager, you can see the current mode of the device on the homepage; note that the priority of GKI mode is higher than that of LKM. For example, if you use GKI kernel to replace the original kernel, and use LKM to patch the GKI kernel, then LKM will be ignored, and the device will always run in GKI mode.
|
||||
|
@ -88,7 +88,7 @@ After opening the manager, you can see the current mode of the device on the hom
|
|||
|
||||
If your device is a mobile phone, we recommend that you prioritize LKM mode; if your device is an emulator, WSA, or Waydroid, we recommend that you prioritize GKI mode.
|
||||
|
||||
## LKM Installation
|
||||
## LKM installation
|
||||
|
||||
### Get the official firmware
|
||||
|
||||
|
@ -98,15 +98,15 @@ There are many ways to get the official firmware. If your device supports `fastb
|
|||
|
||||
If your device does not support `fastboot boot`, then you may need to manually download the official firmware package and then extract the boot from it.
|
||||
|
||||
Unlike GKI mode, LKM mode will modify the `ramdisk`, so on devices with Android 13, it needs to patch the `init_boot` partition instead of the `boot` partition; while GKI mode always operates the `boot` partition.
|
||||
Unlike GKI mode, LKM mode will modify the `ramdisk`, so on devices with Android 13, it needs to patch the `init_boot` partition instead of the `boot` partition; meanwhile, GKI mode always operates the `boot` partition.
|
||||
|
||||
### Use the manager
|
||||
|
||||
Open the manager, click the installation icon in the upper right corner, and several options will appear:
|
||||
|
||||
1. Select and patch a file; if your phone does not have root permissions, you can choose this option, and then select your official firmware, and the manager will automatically patch it; you only need to flash this patched file to permanently obtain root permissions;
|
||||
2. Install directly; if your phone is already rooted, you can choose this option, the manager will automatically get your device information, and then automatically patch the official firmware, and then flash it; you can consider using `fastboot boot` KernelSU's GKI kernel to get temporary root and install the manager, and then use this option; this is also the main way to upgrade KernelSU;
|
||||
3. Install to another partition; if your device supports A/B partition, you can choose this option, the manager will automatically patch the official firmware, and then install it to another partition; this method is suitable for devices after OTA, you can directly install it to another partition after OTA, and then restart the device;
|
||||
1. Select and patch a file; if your phone does not have root permissions, you can choose this option, and then select your official firmware, the manager will automatically patch it; you only need to flash this patched file to permanently obtain root permissions.
|
||||
2. Install directly; if your phone is already rooted, you can choose this option, the manager will automatically get your device information, and then automatically patch the official firmware, and then flash it; you can consider using `fastboot boot` KernelSU's GKI kernel to get temporary root and install the manager, and then use this option; this is also the main way to upgrade KernelSU.
|
||||
3. Install to another partition; if your device supports A/B partition, you can choose this option, the manager will automatically patch the official firmware, and then install it to another partition; this method is suitable for devices after OTA, you can directly install it to another partition after OTA, and then restart the device.
|
||||
|
||||
### Use the command line
|
||||
|
||||
|
@ -114,7 +114,7 @@ If you don’t want to use the manager, you can also use the command line to ins
|
|||
|
||||
This tool supports macOS, Linux, and Windows. You can download the corresponding version from [GitHub Release](https://github.com/tiann/KernelSU/releases).
|
||||
|
||||
Usage: `ksud boot-patch` You can check the command line help for specific usage.
|
||||
Usage: `ksud boot-patch`. You can check the command line help for specific options.
|
||||
|
||||
```sh
|
||||
oriole:/ # ksud boot-patch -h
|
||||
|
@ -137,8 +137,8 @@ Options:
|
|||
|
||||
A few options that need to be explained:
|
||||
|
||||
1. The `--magiskboot` option can specify the path of magiskboot. If it is not specified, ksud will look for it in the environment variables; if you don’t know how to get magiskboot, you can check [here](#patch-boot-image);
|
||||
2. The `--kmi` option can specify the `KMI` version. If the kernel name of your device does not follow the KMI specification, you can specify it through this option;
|
||||
1. The `--magiskboot` option can specify the path of magiskboot. If it is not specified, ksud will look for it in the environment variables; if you don’t know how to get magiskboot, you can refer to [this](#patch-boot-image).
|
||||
2. The `--kmi` option can specify the `KMI` version. If the kernel name of your device does not follow the KMI specification, you can specify it through this option.
|
||||
|
||||
The most common usage is:
|
||||
|
||||
|
@ -146,14 +146,14 @@ The most common usage is:
|
|||
ksud boot-patch -b <boot.img> --kmi android13-5.10
|
||||
```
|
||||
|
||||
## GKI mode Installation
|
||||
## GKI mode installation
|
||||
|
||||
There are several installation methods for GKI mode, each suitable for a different scenario, so please choose as needed.
|
||||
There are several installation methods for GKI mode, each suitable for a different scenario, so please choose accordingly:
|
||||
|
||||
1. Install with fastboot using the boot.img provided by KernelSU
|
||||
2. Install with a kernel flash app, such as KernelFlasher
|
||||
3. Repair the boot.img manually and install it
|
||||
4. Install with custom Recovery (e.g. TWRP)
|
||||
1. Install with fastboot using the boot.img provided by KernelSU.
|
||||
2. Install with a kernel flash app, such as KernelFlasher.
|
||||
3. Repair the boot.img manually and install it.
|
||||
4. Install with custom Recovery (e.g., TWRP).
|
||||
|
||||
## Install with boot.img provided by KernelSU
|
||||
|
||||
|
@ -161,19 +161,19 @@ If your device's `boot.img` uses a commonly used compression format, you can use
|
|||
|
||||
### Find proper boot.img
|
||||
|
||||
KernelSU provides a generic boot.img for GKI devices and you should flash the boot.img to the boot partition of the device.
|
||||
KernelSU provides a generic boot.img for GKI devices, and you should flash the boot.img to the boot partition of the device.
|
||||
|
||||
You can download boot.img from [GitHub Release](https://github.com/tiann/KernelSU/releases), please note that you should use the correct version of boot.img. If you don't know which file to download, please carefully read the description of [KMI](#kmi) and [Security Patch Level](#security-patch-level) in this document.
|
||||
You can download boot.img from [GitHub Release](https://github.com/tiann/KernelSU/releases), please note that you should use the correct version of boot.img. If you don't know which file to download, please carefully read the description of [KMI](#kmi) and [Security patch level](#security-patch-level) in this document.
|
||||
|
||||
Normally, there are three boot files in different formats under the same KMI and security patch level. They are all the same except for the kernel compression format. Please check the kernel compression format of your original boot.img. You should use the correct format, such as `lz4`, `gz`; if you use an incorrect compression format, you may encounter bootloop after flashing boot.
|
||||
|
||||
:::info Compression format of boot.img
|
||||
1. You can use magiskboot to get the compression format of your original boot; of course you can also ask other, more experienced kids with the same model as your device. Also, the compression format of the kernel usually does not change, so if you boot successfully with a certain compression format, you can try that format later.
|
||||
1. You can use magiskboot to get the compression format of your original boot; alternatively, you can also ask for it from community members/developers with the same model as your device. Also, the compression format of the kernel usually does not change, so if you boot successfully with a certain compression format, you can try that format later as well.
|
||||
2. Xiaomi devices usually use `gz` or **uncompressed**.
|
||||
3. For Pixel devices, follow below instructions.
|
||||
3. For Pixel devices, follow the instructions below.
|
||||
:::
|
||||
|
||||
### flash boot.img to device
|
||||
### Flash boot.img to device
|
||||
|
||||
Use `adb` to connect your device, then execute `adb reboot bootloader` to enter fastboot mode, then use this command to flash KernelSU:
|
||||
|
||||
|
@ -185,9 +185,9 @@ fastboot flash boot boot.img
|
|||
If your device supports `fastboot boot`, you can first use `fastboot boot boot.img` to try to use boot.img to boot the system first. If something unexpected happens, restart it again to boot.
|
||||
:::
|
||||
|
||||
### reboot
|
||||
### Reboot
|
||||
|
||||
After flashing is complete, you should reboot your device:
|
||||
After the flashing process is complete, you should reboot your device:
|
||||
|
||||
```sh
|
||||
fastboot reboot
|
||||
|
@ -195,84 +195,86 @@ fastboot reboot
|
|||
|
||||
## Install with Kernel Flasher
|
||||
|
||||
Step:
|
||||
Steps:
|
||||
|
||||
1. Download the AnyKernel3 zip. If you don't know which file to download, please carefully read the description of [KMI](#kmi) and [Security Patch Level](#security-patch-level) in this document.
|
||||
2. Open the Kernel Flash App (grant necessary root permissions) and use the provided AnyKernel3 zip to flash.
|
||||
|
||||
This way requires the kernel flash App to have root permissions. You can use the following methods to achieve this:
|
||||
|
||||
1. Your device has rooted. For example, you have installed KernelSU and want to upgrade to the latest version, or you have rooted through other methods (such as Magisk).
|
||||
2. If your phone is not rooted, but the phone supports the temporary boot method of `fastboot boot boot.img`, you can use the GKI image provided by KernelSU to temporarily boot your device, obtain temporary root permissions, and then use the kernel flash Flash the writer to obtain permanent root privileges.
|
||||
1. Your device is rooted. For example, you have installed KernelSU and want to upgrade to the latest version, or you have rooted through other methods (such as Magisk).
|
||||
2. If your device is not rooted, but the phone supports the temporary boot method of `fastboot boot boot.img`, you can use the GKI image provided by KernelSU to temporarily boot your device, obtain temporary root permissions, and then use the Kernel Flash App to obtain permanent root privileges.
|
||||
|
||||
Some of kernel flashing apps that can be used for this:
|
||||
|
||||
1. [Kernel Flasher](https://github.com/capntrips/KernelFlasher/releases)
|
||||
2. [Franco Kernel Manager](https://play.google.com/store/apps/details?id=com.franco.kernel)
|
||||
3. [Ex Kernel Manager](https://play.google.com/store/apps/details?id=flar2.exkernelmanager)
|
||||
|
||||
PS. This method is more convenient when upgrading KernelSU and can be done without a computer (backup first!). .
|
||||
P.S. This method is more convenient when upgrading KernelSU and can be done without a computer (make a backup first!).
|
||||
|
||||
## Patch boot.img manually{#patch-boot-image}
|
||||
## Patch boot.img manually {#patch-boot-image}
|
||||
|
||||
For some devices, the boot.img format is not so common, such as not `lz4`, `gz` and uncompressed; the most typical is Pixel, its boot.img format is `lz4_legacy` compressed, ramdisk may be `gz` may also be `lz4_legacy` compression; at this time, if you directly flash the boot.img provided by KernelSU, the phone may not be able to boot; at this time, you can manually patch the boot.img to achieve.
|
||||
For some devices, the boot.img format is not so common, such as not `lz4`, `gz` and uncompressed; the most typical example is a Pixel, it's boot.img format is `lz4_legacy` compressed, ramdisk may be `gz` may also be `lz4_legacy` compression; currently, if you directly flash the boot.img provided by KernelSU, the phone may not be able to boot; as an alternative, and you can manually patch the boot.img to achieve this.
|
||||
|
||||
It's always recommended to use `magiskboot` to patch images, there are two ways:
|
||||
|
||||
1. [magiskboot](https://github.com/topjohnwu/Magisk/releases)
|
||||
2. [magiskboot_build](https://github.com/ookiineko/magiskboot_build/releases/tag/last-ci)
|
||||
|
||||
The official build of `magiskboot` can only run on Android devices, if you want to run it on PC, you can try the second one.
|
||||
The official build of `magiskboot` can only run on Android devices, if you want to run it on PC, you can try the second option.
|
||||
|
||||
::: tip
|
||||
Android-Image-Kitchen is not recommended now, because it doesn't handle the boot metadata(such as security patch level) correctly, thus it may not work on some devices.
|
||||
Android-Image-Kitchen is not recommended for now, as it doesn't handle the boot metadata (such as security patch level) correctly, thus it may not work on some devices.
|
||||
:::
|
||||
|
||||
### Preparation
|
||||
|
||||
1. Get your phone's stock boot.img; you can get it from your device manufacturers, you may need [payload-dumper-go](https://github.com/ssut/payload-dumper-go)
|
||||
1. Get your phone's stock boot.img; you can get it from your device manufacturers, you may need [payload-dumper-go](https://github.com/ssut/payload-dumper-go).
|
||||
2. Download the AnyKernel3 zip file provided by KernelSU that matches the KMI version of your device (you can refer to the *Install with custom Recovery*).
|
||||
3. Unpack the AnyKernel3 package and get the `Image` file, which is the kernel file of KernelSU.
|
||||
|
||||
### Using magiskboot on Android devices {#using-magiskboot-on-Android-devices}
|
||||
|
||||
1. Download latest Magisk from [Release Page](https://github.com/topjohnwu/Magisk/releases)
|
||||
1. Download latest Magisk from [Release Page](https://github.com/topjohnwu/Magisk/releases).
|
||||
2. Rename `Magisk-*(version).apk` to `Magisk-*.zip` and unzip it.
|
||||
3. Push `Magisk-*/lib/arm64-v8a/libmagiskboot.so` to your device by adb: `adb push Magisk-*/lib/arm64-v8a/libmagiskboot.so /data/local/tmp/magiskboot`
|
||||
4. Push stock boot.img and Image in AnyKernel3 to your device.
|
||||
5. Enter adb shell and cd `/data/local/tmp/` directory, then `chmod +x magiskboot`
|
||||
6. Enter adb shell and cd `/data/local/tmp/` directory, execute `./magiskboot unpack boot.img` to unpack `boot.img`, you will get a `kernel` file, this is your stock kernel.
|
||||
7. Replace `kernel` with `Image`: `mv -f Image kernel`
|
||||
8. Execute `./magiskboot repack boot.img` to repack boot img, and you will get a `new-boot.img` file, flash this file to device by fastboot.
|
||||
5. Enter adb shell and run `cd /data/local/tmp/` directory, then `chmod +x magiskboot`
|
||||
6. Enter adb shell and run `cd /data/local/tmp/` directory, execute `./magiskboot unpack boot.img` to unpack `boot.img`, you will get a `kernel` file, this is your stock kernel.
|
||||
7. Replace `kernel` with `Image` by running the command: `mv -f Image kernel`.
|
||||
8. Execute `./magiskboot repack boot.img` to repack boot image, and you will get a `new-boot.img` file, flash this file to device by fastboot.
|
||||
|
||||
### Using magiskboot on Windows/macOS/Linux PC{#using-magiskboot-on-PC}
|
||||
|
||||
1. Download proper `magiskboot` for your OS from [magiskboot_build](https://github.com/ookiineko/magiskboot_build/releases/tag/last-ci)
|
||||
1. Download the corresponding `magiskboot` binary for your OS from [magiskboot_build](https://github.com/ookiineko/magiskboot_build/releases/tag/last-ci).
|
||||
2. Prepare stock boot.img and Image in your PC.
|
||||
3. `chmod +x magiskboot`
|
||||
4. Enter the proper directory, execute `./magiskboot unpack boot.img` to unpack `boot.img`, you will get a `kernel` file, this is your stock kernel.
|
||||
5. Replace `kernel` with `Image`: `mv -f Image kernel`
|
||||
6. Execute `./magiskboot repack boot.img` to repack boot img, and you will get a `new-boot.img` file, flash this file to device by fastboot.
|
||||
3. Run `chmod +x magiskboot`.
|
||||
4. Enter the corresponding directory, execute `./magiskboot unpack boot.img` to unpack `boot.img`, you will get a `kernel` file, this is your stock kernel.
|
||||
5. Replace `kernel` with `Image` by running the command: `mv -f Image kernel`.
|
||||
6. Execute `./magiskboot repack boot.img` to repack the boot image, and you will get a `new-boot.img` file, flash this file to device by fastboot.
|
||||
|
||||
::: info
|
||||
Official `magiskboot` can run `Linux` device normally, if you are a Linux user, you can use official build.
|
||||
Official `magiskboot` can run in Linux environments normally, if you are a Linux user, you can use the official build.
|
||||
:::
|
||||
|
||||
## Install with custom Recovery
|
||||
## Install with Custom Recovery
|
||||
|
||||
Prerequisite: Your device must have a custom Recovery, such as TWRP; if not or only official Recovery is available, use another method.
|
||||
Prerequisite: Your device must have a Custom Recovery, such as TWRP; if there is no custom recovery available for your device, use another method.
|
||||
|
||||
Step:
|
||||
Steps:
|
||||
|
||||
1. From the [Release page](https://github.com/tiann/KernelSU/releases) of KernelSU, download the zip package starting with AnyKernel3 that matches your phone version; for example, the phone kernel version is `android12-5.10. 66`, then you should download the file `AnyKernel3-android12-5.10.66_yyyy-MM.zip` (where `yyyy` is the year and `MM` is the month).
|
||||
2. Reboot the phone into TWRP.
|
||||
3. Use adb to put AnyKernel3-*.zip into the phone /sdcard and choose to install it in the TWRP GUI; or you can directly `adb sideload AnyKernel-*.zip` to install.
|
||||
1. From the [Release page](https://github.com/tiann/KernelSU/releases) of KernelSU, download the zip package starting with `AnyKernel3` that matches your phone version; for example, if the device's kernel version is `android12-5.10. 66`, then you should download the `AnyKernel3-android12-5.10.66_yyyy-MM.zip` file (where `yyyy` is the year and `MM` is the month).
|
||||
2. Reboot the device into TWRP.
|
||||
3. Use adb to place AnyKernel3-*.zip into the device's `/sdcard` location and choose to install it in the TWRP GUI; or you can directly run `adb sideload AnyKernel-*.zip` to install.
|
||||
|
||||
PS. This method is suitable for any installation (not limited to initial installation or subsequent upgrades), as long as you use TWRP.
|
||||
P.S. This method is suitable for any installation (not limited to initial installation or subsequent upgrades), as long as you're using TWRP.
|
||||
|
||||
## Other methods
|
||||
|
||||
In fact, all these installation methods have only one main idea, which is to **replace the original kernel for the one provided by KernelSU**; as long as this can be achieved, it can be installed; for example, the following are other possible methods.
|
||||
In fact, all of these installation methods have only one main idea, which is to **replace the original kernel for the one provided by KernelSU**; as long as this can be achieved, it can be installed; for example, the following are other possible methods.
|
||||
|
||||
1. First install Magisk, get root privileges through Magisk and then use the kernel flasher to flash in the AnyKernel zip from KernelSU.
|
||||
2. Use some flashing toolkit on PCs to flash in the kernel provided KernelSU.
|
||||
1. First install Magisk, get root privileges through Magisk and then use the kernel flasher to flash in the AnyKernel3 zip from KernelSU.
|
||||
2. Use any flashing toolkit on PC to flash the kernel provided by KernelSU.
|
||||
|
||||
But if it doesn't work, please try `magiskboot` way.
|
||||
However, if it doesn't work, please try `magiskboot` approach.
|
||||
|
|
|
@ -24,7 +24,7 @@ If your page contains CSS and JavaScript, you need to place it in this directory
|
|||
|
||||
## JavaScript API
|
||||
|
||||
If it is just a display page, it is no different from a normal web page. More importantly, KernelSU provides a series of system API that allow you to implement the unique functions of the module.
|
||||
If it is just a display page, it is no different from a normal web page. More importantly, KernelSU provides a series of system API that allows you to implement the unique functions of the module.
|
||||
|
||||
KernelSU provides a JavaScript library and [publishes it on npm](https://www.npmjs.com/package/kernelsu), which you can use in the JavaScript code of your web pages.
|
||||
|
||||
|
@ -38,11 +38,11 @@ const { errno, stdout } = exec("getprop ro.product.model");
|
|||
|
||||
For another example, you can make the web page display full screen, or display a toast.
|
||||
|
||||
[API documentation](https://www.npmjs.com/package/kernelsu)
|
||||
[API documentation](https://www.npmjs.com/package/kernelsu).
|
||||
|
||||
If you find that the existing API does not meet your needs or is inconvenient to use, you are welcome to give us suggestions [here](https://github.com/tiann/KernelSU/issues)!
|
||||
|
||||
## Some tips
|
||||
|
||||
1. You can use `localStorage` normally to store some data, but it will be lost after the Manager App is uninstalled. If you need to save persistently, you can write data to some directory yourself.
|
||||
2. For simple pages, I recommend you use [parceljs](https://parceljs.org/) for packaging. It requires zero configuration and is very convenient to use. However, if you are a front-end master or have your own preferences, then just choose one you like!
|
||||
1. You can use `localStorage` normally to store some data, but it will be lost after the Manager App is uninstalled. If you need to save persistently, you can write data to a custom directory yourself.
|
||||
2. For simple pages, I recommend you use [parceljs](https://parceljs.org/) for packaging. It requires zero configuration and is very convenient to use. However, if you are a front-end master or have your own preferences, then just choose the one you like!
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Module guides
|
||||
# Module Guide
|
||||
|
||||
KernelSU provides a module mechanism that achieves the effect of modifying the system directory while maintaining the integrity of the system partition. This mechanism is commonly known as "systemless".
|
||||
|
||||
|
@ -6,22 +6,22 @@ The module mechanism of KernelSU is almost the same as that of Magisk. If you ar
|
|||
|
||||
## WebUI
|
||||
|
||||
KernelSU's modules support displaying interfaces and interacting with users, please refer to the [WebUI documentation](module-webui.md).
|
||||
KernelSU's modules support displaying interfaces and interacting with users. For more, please refer to [WebUI documentation](module-webui.md).
|
||||
|
||||
## Busybox
|
||||
|
||||
KernelSU ships with a feature complete BusyBox binary (including full SELinux support). The executable is located at `/data/adb/ksu/bin/busybox`. KernelSU's BusyBox supports runtime toggle-able "ASH Standalone Shell Mode". What this standalone mode means is that when running in the `ash` shell of BusyBox, every single command will directly use the applet within BusyBox, regardless of what is set as `PATH`. For example, commands like `ls`, `rm`, `chmod` will **NOT** use what is in `PATH` (in the case of Android by default it will be `/system/bin/ls`, `/system/bin/rm`, and `/system/bin/chmod` respectively), but will instead directly call internal BusyBox applets. This makes sure that scripts always run in a predictable environment and always have the full suite of commands no matter which Android version it is running on. To force a command _not_ to use BusyBox, you have to call the executable with full paths.
|
||||
KernelSU ships with a feature-complete BusyBox binary (including full SELinux support). The executable is located at `/data/adb/ksu/bin/busybox`. KernelSU's BusyBox supports runtime toggle-able "ASH Standalone Shell Mode". What this standalone mode means is that when running in the `ash` shell of BusyBox, every single command will directly use the applet within BusyBox, regardless of what is set as `PATH`. For example, commands like `ls`, `rm`, `chmod` will **NOT** use what is in `PATH` (in the case of Android by default it will be `/system/bin/ls`, `/system/bin/rm`, and `/system/bin/chmod` respectively), but will instead directly call internal BusyBox applets. This makes sure that scripts always run in a predictable environment and always have the full suite of commands no matter which Android version it is running on. To force a command _not_ to use BusyBox, you have to call the executable with full paths.
|
||||
|
||||
Every single shell script running in the context of KernelSU will be executed in BusyBox's `ash` shell with standalone mode enabled. For what is relevant to 3rd party developers, this includes all boot scripts and module installation scripts.
|
||||
|
||||
For those who want to use this "Standalone Mode" feature outside of KernelSU, there are 2 ways to enable it:
|
||||
|
||||
1. Set environment variable `ASH_STANDALONE` to `1`<br>Example: `ASH_STANDALONE=1 /data/adb/ksu/bin/busybox sh <script>`
|
||||
1. Set environment variable `ASH_STANDALONE` to `1` <br>Example: `ASH_STANDALONE=1 /data/adb/ksu/bin/busybox sh <script>`
|
||||
2. Toggle with command-line options:<br>`/data/adb/ksu/bin/busybox sh -o standalone <script>`
|
||||
|
||||
To make sure all subsequent `sh` shell executed also runs in standalone mode, option 1 is the preferred method (and this is what KernelSU and the KernelSU manager internally use) as environment variables are inherited down to child processes.
|
||||
To make sure all subsequent `sh` shell executed also runs in standalone mode, option 1 is the preferred method (and this is what KernelSU and the KernelSU manager use internally) as environment variables are inherited down to child processes.
|
||||
|
||||
::: tip difference with Magisk
|
||||
::: tip Difference with Magisk
|
||||
|
||||
KernelSU's BusyBox is now using the binary file compiled directly from the Magisk project. **Thanks to Magisk!** Therefore, you don't have to worry about compatibility issues between BusyBox scripts in Magisk and KernelSU because they are exactly the same!
|
||||
:::
|
||||
|
@ -82,7 +82,7 @@ A KernelSU module is a folder placed in `/data/adb/modules` with the structure b
|
|||
├── .
|
||||
```
|
||||
|
||||
::: tip difference with Magisk
|
||||
::: tip Difference with Magisk
|
||||
KernelSU does not have built-in support for Zygisk, so there is no content related to Zygisk in the module. However, you can use [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) to support Zygisk modules. In this case, the content of the Zygisk module is identical to that supported by Magisk.
|
||||
:::
|
||||
|
||||
|
@ -99,20 +99,20 @@ author=<string>
|
|||
description=<string>
|
||||
```
|
||||
|
||||
- `id` has to match this regular expression: `^[a-zA-Z][a-zA-Z0-9._-]+$`<br>
|
||||
ex: ✓ `a_module`, ✓ `a.module`, ✓ `module-101`, ✗ `a module`, ✗ `1_module`, ✗ `-a-module`<br>
|
||||
- `id` has to match this regular expression: `^[a-zA-Z][a-zA-Z0-9._-]+$` .<br>
|
||||
Example: ✓ `a_module`, ✓ `a.module`, ✓ `module-101`, ✗ `a module`, ✗ `1_module`, ✗ `-a-module`<br>
|
||||
This is the **unique identifier** of your module. You should not change it once published.
|
||||
- `versionCode` has to be an **integer**. This is used to compare versions
|
||||
- `versionCode` has to be an **integer**. This is used to compare versions.
|
||||
- Others that weren't mentioned above can be any **single line** string.
|
||||
- Make sure to use the `UNIX (LF)` line break type and not the `Windows (CR+LF)` or `Macintosh (CR)`.
|
||||
|
||||
### Shell scripts
|
||||
|
||||
Please read the [Boot Scripts](#boot-scripts) section to understand the difference between `post-fs-data.sh` and `service.sh`. For most module developers, `service.sh` should be good enough if you just need to run a boot script, if you need to run the script after boot completed, please use `boot-completed.sh`. If you want to do something after mounting overlayfs, please use `post-mount.sh`.
|
||||
Please read the [Boot scripts](#boot-scripts) section to understand the difference between `post-fs-data.sh` and `service.sh`. For most module developers, `service.sh` should be good enough if you just need to run a boot script, if you need to run the script after boot completed, please use `boot-completed.sh`. If you want to do something after mounting overlayfs, please use `post-mount.sh`.
|
||||
|
||||
In all scripts of your module, please use `MODDIR=${0%/*}` to get your module's base directory path; do **NOT** hardcode your module path in scripts.
|
||||
|
||||
::: tip difference with Magisk
|
||||
::: tip Difference with Magisk
|
||||
You can use the environment variable KSU to determine if a script is running in KernelSU or Magisk. If running in KernelSU, this value will be set to true.
|
||||
:::
|
||||
|
||||
|
@ -134,20 +134,22 @@ REMOVE="
|
|||
"
|
||||
```
|
||||
|
||||
The above list will execute `mknod $MODPATH/system/app/YouTuBe c 0 0` and `mknod $MODPATH/system/app/Bloatware c 0 0`; and `/system/app/YouTube` and `/system/app/Bloatware` will be removed after the module takes effect.
|
||||
The above list will execute `mknod $MODPATH/system/app/YouTube c 0 0` and `mknod $MODPATH/system/app/Bloatware c 0 0`; and `/system/app/YouTube` and `/system/app/Bloatware` will be removed after the module takes effect.
|
||||
|
||||
If you want to replace a directory in the system, you need to create a directory with the same path in your module directory, and then set the attribute `setfattr -n trusted.overlay.opaque -v y <TARGET>` for this directory. This way, the overlayfs system will automatically replace the corresponding directory in the system (without changing the /system partition).
|
||||
|
||||
You can declare a variable named `REPLACE` in your `customize.sh` file, which includes a list of directories to be replaced, and KernelSU will automatically perform the corresponding operations in your module directory. For example:
|
||||
|
||||
```sh
|
||||
REPLACE="
|
||||
/system/app/YouTube
|
||||
/system/app/Bloatware
|
||||
"
|
||||
```
|
||||
|
||||
This list will automatically create the directories `$MODPATH/system/app/YouTube` and `$MODPATH/system/app/Bloatware`, and then execute `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/YouTube` and `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/Bloatware`. After the module takes effect, `/system/app/YouTube` and `/system/app/Bloatware` will be replaced with empty directories.
|
||||
|
||||
::: tip difference with Magisk
|
||||
::: tip Difference with Magisk
|
||||
|
||||
KernelSU's systemless mechanism is implemented through the kernel's overlayfs, while Magisk currently uses magic mount (bind mount). The two implementation methods have significant differences, but the ultimate goal is the same: to modify /system files without physically modifying the /system partition.
|
||||
:::
|
||||
|
@ -177,12 +179,12 @@ module.zip
|
|||
```
|
||||
|
||||
:::warning
|
||||
KernelSU module is NOT supported to be installed in custom recovery!!
|
||||
KernelSU module is **NOT** supported to be installed via a Custom Recovery!
|
||||
:::
|
||||
|
||||
### Customization
|
||||
|
||||
If you need to customize the module installation process, optionally you can create a script in the installer named `customize.sh`. This script will be _sourced_ (not executed!) by the module installer script after all files are extracted and default permissions and secontext are applied. This is very useful if your module require additional setup based on the device ABI, or you need to set special permissions/secontext for some of your module files.
|
||||
If you need to customize the module installation process, optionally you can create a script in the installer named `customize.sh`. This script will be _sourced_ (not executed!) by the module installer script after all files are extracted and default permissions and secontext are applied. This is very useful if your module requires additional setup based on the device ABI, or you need to set special permissions/secontext for some of your module files.
|
||||
|
||||
If you would like to fully control and customize the installation process, declare `SKIPUNZIP=1` in `customize.sh` to skip all default installation steps. By doing so, your `customize.sh` will be responsible to install everything by itself.
|
||||
|
||||
|
@ -191,19 +193,19 @@ The `customize.sh` script runs in KernelSU's BusyBox `ash` shell with "Standalon
|
|||
#### Variables
|
||||
|
||||
- `KSU` (bool): a variable to mark that the script is running in the KernelSU environment, and the value of this variable will always be true. You can use it to distinguish between KernelSU and Magisk.
|
||||
- `KSU_VER` (string): the version string of current installed KernelSU (e.g. `v0.4.0`)
|
||||
- `KSU_VER_CODE` (int): the version code of current installed KernelSU in userspace (e.g. `10672`)
|
||||
- `KSU_KERNEL_VER_CODE` (int): the version code of current installed KernelSU in kernel space (e.g. `10672`)
|
||||
- `BOOTMODE` (bool): always be `true` in KernelSU
|
||||
- `MODPATH` (path): the path where your module files should be installed
|
||||
- `TMPDIR` (path): a place where you can temporarily store files
|
||||
- `ZIPFILE` (path): your module's installation zip
|
||||
- `ARCH` (string): the CPU architecture of the device. Value is either `arm`, `arm64`, `x86`, or `x64`
|
||||
- `IS64BIT` (bool): `true` if `$ARCH` is either `arm64` or `x64`
|
||||
- `API` (int): the API level (Android version) of the device (e.g. `23` for Android 6.0)
|
||||
- `KSU_VER` (string): the version string of currently installed KernelSU (e.g. `v0.4.0`).
|
||||
- `KSU_VER_CODE` (int): the version code of currently installed KernelSU in userspace (e.g. `10672`).
|
||||
- `KSU_KERNEL_VER_CODE` (int): the version code of currently installed KernelSU in kernel space (e.g. `10672`).
|
||||
- `BOOTMODE` (bool): always be `true` in KernelSU.
|
||||
- `MODPATH` (path): the path where your module files should be installed.
|
||||
- `TMPDIR` (path): a place where you can temporarily store files.
|
||||
- `ZIPFILE` (path): your module's installation zip.
|
||||
- `ARCH` (string): the CPU architecture of the device. Value is either `arm`, `arm64`, `x86`, or `x64`.
|
||||
- `IS64BIT` (bool): `true` if `$ARCH` is either `arm64` or `x64`.
|
||||
- `API` (int): the API level (Android version) of the device (e.g., `23` for Android 6.0).
|
||||
|
||||
::: warning
|
||||
In KernelSU, MAGISK_VER_CODE is always 25200 and MAGISK_VER is always v25.2. Please do not use these two variables to determine whether it is running on KernelSU or not.
|
||||
In KernelSU, `MAGISK_VER_CODE` is always `25200` and `MAGISK_VER` is always `v25.2`. Please do not use these two variables to determine whether it is running on KernelSU or not.
|
||||
:::
|
||||
|
||||
#### Functions
|
||||
|
@ -234,28 +236,92 @@ set_perm_recursive <directory> <owner> <group> <dirpermission> <filepermission>
|
|||
|
||||
## Boot scripts
|
||||
|
||||
In KernelSU, scripts are divided into two types based on their running mode: post-fs-data mode and late_start service mode:
|
||||
In KernelSU, scripts are divided into two types based on their running mode: post-fs-data mode and late_start service mode.
|
||||
|
||||
- post-fs-data mode
|
||||
- This stage is BLOCKING. The boot process is paused before execution is done, or 10 seconds have passed.
|
||||
- Scripts run before any modules are mounted. This allows a module developer to dynamically adjust their modules before it gets mounted.
|
||||
- This stage happens before Zygote is started, which pretty much means everything in Android
|
||||
- This stage happens before Zygote is started, which pretty much means everything in Android.
|
||||
- **WARNING:** using `setprop` will deadlock the boot process! Please use `resetprop -n <prop_name> <prop_value>` instead.
|
||||
- **Only run scripts in this mode if necessary.**
|
||||
- late_start service mode
|
||||
- This stage is NON-BLOCKING. Your script runs in parallel with the rest of the booting process.
|
||||
- **This is the recommended stage to run most scripts.**
|
||||
|
||||
In KernelSU, startup scripts are divided into two types based on their storage location: general scripts and module scripts:
|
||||
In KernelSU, startup scripts are divided into two types based on their storage location: general scripts and module scripts.
|
||||
|
||||
- General Scripts
|
||||
- Placed in `/data/adb/post-fs-data.d`, `/data/adb/service.d`, `/data/adb/post-mount.d` or `/data/adb/boot-completed.d`
|
||||
- General scripts
|
||||
- Placed in `/data/adb/post-fs-data.d`, `/data/adb/service.d`, `/data/adb/post-mount.d` or `/data/adb/boot-completed.d.`
|
||||
- Only executed if the script is set as executable (`chmod +x script.sh`)
|
||||
- Scripts in `post-fs-data.d` runs in post-fs-data mode, and scripts in `service.d` runs in late_start service mode.
|
||||
- Modules should **NOT** add general scripts during installation
|
||||
- Module Scripts
|
||||
- Placed in the module's own folder
|
||||
- Only executed if the module is enabled
|
||||
- Modules should **NOT** add general scripts during installation.
|
||||
- Module scripts
|
||||
- Placed in the module's own folder.
|
||||
- Only executed if the module is enabled.
|
||||
- `post-fs-data.sh` runs in post-fs-data mode, `service.sh` runs in late_start service mode, `boot-completed.sh` runs on boot completed, `post-mount.sh` runs on overlayfs mounted.
|
||||
|
||||
All boot scripts will run in KernelSU's BusyBox `ash` shell with "Standalone Mode" enabled.
|
||||
|
||||
### Boot scripts process explanation
|
||||
|
||||
The following is the relevant boot process for Android (some parts are omitted), which includes the operation of KernelSU (with leading asterisks), and can help you better understand the purpose of these module scripts:
|
||||
|
||||
```txt
|
||||
0. Bootloader (nothing on screen)
|
||||
load patched boot.img
|
||||
load kernel:
|
||||
- GKI mode: GKI kernel with KernelSU integrated
|
||||
- LKM mode: stock kernel
|
||||
...
|
||||
|
||||
1. kernel exec init (oem logo on screen):
|
||||
- GKI mode: stock init
|
||||
- LKM mode: exec ksuinit, insmod kernelsu.ko, exec stock init
|
||||
mount /dev, /dev/pts, /proc, /sys, etc.
|
||||
property-init -> read default props
|
||||
read init.rc
|
||||
...
|
||||
early-init -> init -> late_init
|
||||
early-fs
|
||||
start vold
|
||||
fs
|
||||
mount /vendor, /system, /persist, etc.
|
||||
post-fs-data
|
||||
*safe mode check
|
||||
*execute general scripts in post-fs-data.d/
|
||||
*load sepolicy.rule
|
||||
*mount tmpfs
|
||||
*execute module scripts post-fs-data.sh
|
||||
**(Zygisk)./bin/zygisk-ptrace64 monitor
|
||||
*(pre)load system.prop (same as resetprop -n)
|
||||
*remount modules /system
|
||||
*execute general scripts in post-mount.d/
|
||||
*execute module scripts post-mount.sh
|
||||
zygote-start
|
||||
load_all_props_action
|
||||
*execute resetprop (actual set props for resetprop with -n option)
|
||||
... -> boot
|
||||
class_start core
|
||||
start-service logd, console, vold, etc.
|
||||
class_start main
|
||||
start-service adb, netd (iptables), zygote, etc.
|
||||
|
||||
2. kernel2user init (rom animation on screen, start by service bootanim)
|
||||
*execute general scripts in service.d/
|
||||
*execute module scripts service.sh
|
||||
*set props for resetprop without -p option
|
||||
**(Zygisk) hook zygote (start zygiskd)
|
||||
**(Zygisk) mount zygisksu/module.prop
|
||||
start system apps (autostart)
|
||||
...
|
||||
boot complete (broadcast ACTION_BOOT_COMPLETED event)
|
||||
*execute general scripts in boot-completed.d/
|
||||
*execute module scripts boot-completed.sh
|
||||
|
||||
3. User operable (lock screen)
|
||||
input password to decrypt /data/data
|
||||
*actual set props for resetprop with -p option
|
||||
start user apps (autostart)
|
||||
```
|
||||
|
||||
If you are interested in Android Init Language, it is recommended to read its [documentation](https://android.googlesource.com/platform/system/core/+/master/init/README.md).
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Rescue from bootloop
|
||||
|
||||
When flashing a device, we may encounter situations where the device becomes "bricked". In theory, if you only use fastboot to flash the boot partition or install unsuitable modules that cause the device to fail to boot, then this can be restored by appropriate operations. This document aims to provide some emergency methods to help you recover from a "bricked" device.
|
||||
When flashing a device, we may encounter situations when the device becomes "bricked". In theory, if you only use fastboot to flash the boot partition or install incompatible modules that cause the device to fail to boot, then this can be restored by appropriate operations. This document aims to provide some emergency methods to help you recover from a "bricked" state.
|
||||
|
||||
## Brick by flashing boot partition
|
||||
|
||||
|
@ -44,7 +44,7 @@ The built-in safe mode is implemented in the kernel, so there is no possibility
|
|||
|
||||
### Malicious modules
|
||||
|
||||
If the above methods cannot rescue your device, it is highly likely that the module you installed has malicious operations or has damaged your device through other means. In this case, there are only two suggestions:
|
||||
If the above methods cannot rescue your device, it is very likely that the module you installed has malicious operations or has damaged your device through other means. In this case, there are only two suggestions:
|
||||
|
||||
1. Wipe the data and flash the official system.
|
||||
2. Consult the after-sales service.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# What is KernelSU?
|
||||
|
||||
KernelSU is a root solution for Android GKI devices, it works in kernel mode and grant root permission to userspace application directly in kernel space.
|
||||
KernelSU is a root solution for Android GKI devices, it works in kernel mode and grants root permission to userspace applications directly in kernel space.
|
||||
|
||||
## Features
|
||||
|
||||
|
@ -8,13 +8,13 @@ The main feature of KernelSU is it is **Kernel-based**. KernelSU works in kernel
|
|||
|
||||
And also, KernelSU provides a module system via overlayfs, which allows you to load your custom plugin into system. It also provides a mechanism to modify files in `/system` partition.
|
||||
|
||||
## How to use
|
||||
## How to use?
|
||||
|
||||
Please refer: [Installation](installation)
|
||||
|
||||
## How to build
|
||||
## How to build?
|
||||
|
||||
[How to build](how-to-build)
|
||||
Please refer: [How to build](how-to-build)
|
||||
|
||||
## Discussion
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Diferença com Magisk
|
||||
# Diferenças com Magisk
|
||||
|
||||
Embora existam muitas semelhanças entre os módulos KernelSU e os módulos Magisk, existem inevitavelmente algumas diferenças devido aos seus mecanismos de implementação completamente diferentes. Se você deseja que seu módulo seja executado no Magisk e no KernelSU, você deve entender essas diferenças.
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ Achamos que não e esse não é o nosso objetivo. O Magisk é bom o suficiente p
|
|||
|
||||
É possível, o KernelSU é portado para o kernel 4.14 agora, para o kernel mais antigo, você precisa portar manualmente e PRs são sempre bem-vindas!
|
||||
|
||||
## Como integrar o KernelSU para o kernel antigo?
|
||||
## Como integrar o KernelSU para um kernel antigo?
|
||||
|
||||
Por favor, consulte a guia [Como integrar o KernelSU para kernels não GKI](how-to-integrate-for-non-gki).
|
||||
|
||||
|
@ -69,7 +69,7 @@ Claro. Mas o KernelSU não tem suporte a hosts integrados, você pode instalar [
|
|||
|
||||
## Por que existe um enorme arquivo de 1 TB?
|
||||
|
||||
O arquivo `modules.img` de 1 TB é um arquivo de imagem de disco, **não se preocupe com seu tamanho**, é um tipo especial de arquivo conhecido como [arquivo esparso](https://en.wikipedia.org/wiki/Sparse_file), seu tamanho real é apenas o tamanho do módulo que você usa e diminuirá dinamicamente após você excluir o módulo. Na verdade, ele não ocupa 1 TB de espaço em disco (na verdade, seu celular pode não ter tanto espaço).
|
||||
O arquivo `modules.img` de 1 TB é um arquivo de imagem de disco, **não se preocupe com seu tamanho**, é um tipo especial de arquivo conhecido como [arquivo esparso](https://en.wikipedia.org/wiki/Sparse_file), seu tamanho real é apenas o tamanho do módulo que você usa e diminuirá dinamicamente após você excluir o módulo. Na verdade, ele não ocupa 1 TB de espaço em disco (seu celular pode não ter tanto espaço).
|
||||
|
||||
Se você estiver realmente insatisfeito com o tamanho deste arquivo, você pode usar o comando `resize2fs -M` para torná-lo seu tamanho real, mas o módulo pode não funcionar corretamente neste momento e não forneceremos nenhum suporte para isso.
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ O `<kernel_manifest.xml>` é um arquivo de manifesto que pode determinar uma com
|
|||
|
||||
Por favor, verifique [Como criar kernels](https://source.android.com/docs/setup/build/building-kernels) primeiro.
|
||||
|
||||
Por exemplo, precisamos compilar a imagem do kernel `aarch64`:
|
||||
Por exemplo, para compilar uma imagem de kernel `aarch64`:
|
||||
|
||||
```sh
|
||||
LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
|
||||
|
@ -41,7 +41,7 @@ tools/bazel build --config=fast //common:kernel_aarch64_dist
|
|||
```
|
||||
|
||||
:::info INFORMAÇÕES
|
||||
Para alguns kernel do Android 14, para fazer o Wi-Fi/Bluetooth funcionar. Pode ser necessário remover todas as exportações protegidas pelo GKI:
|
||||
Para alguns kernel do Android 14, para fazer o Wi-Fi/Bluetooth funcionar, pode ser necessário remover todas as exportações protegidas pelo GKI:
|
||||
|
||||
```sh
|
||||
rm common/android/abi_gki_protected_exports_*
|
||||
|
@ -50,7 +50,7 @@ rm common/android/abi_gki_protected_exports_*
|
|||
|
||||
## Compilar o kernel com KernelSU
|
||||
|
||||
Se você conseguir compilar o kernel com sucesso, então compilar o KernelSU é muito fácil. Selecione qualquer um executado no diretório raiz de origem do kernel:
|
||||
Se você conseguir compilar o kernel com sucesso, adicionar suporte ao KernelSU a ele será relativamente fácil. Na raiz do diretório de origem do kernel, execute qualquer uma das opções listadas abaixo:
|
||||
|
||||
::: code-group
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
O KernelSU pode ser integrado em kernels não GKI e foi portado para 4.14 e versões anteriores.
|
||||
|
||||
Devido à fragmentação de kernels não GKI, não temos uma maneira uniforme de construí-lo, portanto não podemos fornecer o boot.img não GKI. Mas você mesmo pode compilar o kernel com o KernelSU integrado.
|
||||
Devido à fragmentação de kernels não GKI, não temos uma maneira universal de construí-lo, portanto não podemos fornecer o boot.img não GKI. Mas você mesmo pode compilar o kernel com o KernelSU integrado.
|
||||
|
||||
Primeiro, você deve ser capaz de compilar um kernel inicializável a partir do código-fonte do kernel. Se o kernel não for de código aberto, será difícil executar o KernelSU no seu dispositivo.
|
||||
|
||||
|
@ -18,22 +18,26 @@ O KernelSU usa kprobe para fazer ganchos do kernel, se o kprobe funcionar bem em
|
|||
Primeiro, adicione o KernelSU à árvore de origem do kernel:
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.9.5
|
||||
```
|
||||
|
||||
:::info INFORMAÇÕES
|
||||
[KernelSU 1.0 não oferece mais suporte a kernels não GKI](https://github.com/tiann/KernelSU/issues/1705). A última versão suportada é a `v0.9.5`, por favor, certifique-se de usar o branch correto.
|
||||
:::
|
||||
|
||||
Então, você deve verificar se o kprobe está ativado na configuração do seu kernel, se não estiver, adicione estas configurações a ele:
|
||||
|
||||
```
|
||||
```txt
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_HAVE_KPROBES=y
|
||||
CONFIG_KPROBE_EVENTS=y
|
||||
```
|
||||
|
||||
E construa seu kernel novamente, KernelSU deve funcionar bem.
|
||||
E agora, quando você recompilar seu kernel, o KernelSU deve funcionar bem.
|
||||
|
||||
Se você descobrir que o KPROBES ainda não está ativado, você pode tentar ativar `CONFIG_MODULES`. (Se ainda assim não surtir efeito, use `make menuconfig` para procurar outras dependências do KPROBES)
|
||||
Se você descobrir que o KPROBES ainda não está ativado, você pode tentar ativar `CONFIG_MODULES`. Se ainda assim não surtir efeito, use `make menuconfig` para procurar outras dependências do KPROBES.
|
||||
|
||||
Mas se você entrar em um bootloop quando o KernelSU for integrado, talvez o **kprobe esteja quebrado em seu kernel**. Você deve corrigir o bug do kprobe ou usar o segundo caminho.
|
||||
Mas se você entrar em um bootloop quando o KernelSU for integrado, pode ser porque o **kprobe esteja quebrado em seu kernel**, o que significa que você deve corrigir o bug do kprobe ou usar outra maneira.
|
||||
|
||||
:::tip COMO VERIFICAR SE O KPROBE ESTÁ QUEBRADO?
|
||||
|
||||
|
@ -47,7 +51,7 @@ Se o seu kernel for inferior a 5.9, você deve portar `path_umount` para `fs/nam
|
|||
|
||||
## Modifique manualmente a fonte do kernel
|
||||
|
||||
Se o kprobe não funcionar no seu kernel (pode ser um bug do upstream ou do kernel abaixo de 4.8), então você pode tentar desta forma:
|
||||
Se o kprobe não funcionar no seu kernel (pode ser um bug do upstream ou do kernel abaixo de 4.8), então você pode tentar o seguinte:
|
||||
|
||||
Primeiro, adicione o KernelSU à árvore de origem do kernel:
|
||||
|
||||
|
@ -67,9 +71,9 @@ curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh
|
|||
|
||||
:::
|
||||
|
||||
Tenha em mente que em alguns dispositivos, seu defconfig pode estar em `arch/arm64/configs` ou em outros casos `arch/arm64/configs/vendor/your_defconfig`. Por exemplo, em seu defconfig, habilite `CONFIG_KSU` com **y** para habilitar ou **n** para desabilitar. Seu caminho será algo como:
|
||||
`arch/arm64/configs/...`
|
||||
```
|
||||
Tenha em mente que em alguns dispositivos, seu defconfig pode estar em `arch/arm64/configs` ou em outros casos `arch/arm64/configs/vendor/your_defconfig`. Para qualquer defconfig que você estiver usando, certifique-se de ativar `CONFIG_KSU` com `y` para ativa-lo ou `n` para desativa-lo. Por exemplo, caso você opte por ativa-lo, seu defconfig deverá conter a seguinte string:
|
||||
|
||||
```txt
|
||||
# KernelSU
|
||||
CONFIG_KSU=y
|
||||
```
|
||||
|
@ -200,12 +204,12 @@ index 376543199b5a..82adcef03ecc 100644
|
|||
|
||||
Você deve encontrar as quatro funções no código-fonte do kernel:
|
||||
|
||||
1. do_faccessat, geralmente em `fs/open.c`
|
||||
2. do_execveat_common, geralmente em `fs/exec.c`
|
||||
3. vfs_read, geralmente em `fs/read_write.c`
|
||||
4. vfs_statx, geralmente em `fs/stat.c`
|
||||
1. `do_faccessat`, geralmente em `fs/open.c`
|
||||
2. `do_execveat_common`, geralmente em `fs/exec.c`
|
||||
3. `vfs_read`, geralmente em `fs/read_write.c`
|
||||
4. `vfs_statx`, geralmente em `fs/stat.c`
|
||||
|
||||
Se o seu kernel não tiver `vfs_statx`, use `vfs_fstatat`:
|
||||
Se o seu kernel não tiver a função `vfs_statx`, use `vfs_fstatat`:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/stat.c b/fs/stat.c
|
||||
|
@ -264,7 +268,9 @@ index 2ff887661237..e758d7db7663 100644
|
|||
return -EINVAL;
|
||||
```
|
||||
|
||||
Para ativar o Modo de Segurança integrado do KernelSU, você também deve modificar `input_handle_event` em `drivers/input/input.c`:
|
||||
### Modo de Segurança
|
||||
|
||||
Para ativar o Modo de Segurança integrado do KernelSU, você também deve modificar a função `input_handle_event` em `drivers/input/input.c`:
|
||||
|
||||
:::tip DICA
|
||||
É altamente recomendável ativar este recurso, é muito útil para evitar bootloops!
|
||||
|
@ -297,6 +303,42 @@ index 45306f9ef247..815091ebfca4 100755
|
|||
add_input_randomness(type, code, value);
|
||||
```
|
||||
|
||||
:::info ENTRANDO NO MODO DE SEGURANÇA ACIDENTALMENTE?
|
||||
Se você estiver usando a integração manual e não desabilitar `CONFIG_KPROBES`, o usuário poderá acionar o Modo de Segurança pressionando o botão de diminuir volume após a inicialização! Portanto, se estiver usando a integração manual, você precisa desabilitar `CONFIG_KPROBES`!
|
||||
:::
|
||||
|
||||
### Falha ao executar `pm` no terminal?
|
||||
|
||||
Você deve modificar `fs/devpts/inode.c`. Referência:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
|
||||
index 32f6f1c68..d69d8eca2 100644
|
||||
--- a/fs/devpts/inode.c
|
||||
+++ b/fs/devpts/inode.c
|
||||
@@ -602,6 +602,8 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv)
|
||||
return dentry;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_devpts(struct inode*);
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* devpts_get_priv -- get private data for a slave
|
||||
* @pts_inode: inode of the slave
|
||||
@@ -610,6 +612,7 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv)
|
||||
*/
|
||||
void *devpts_get_priv(struct dentry *dentry)
|
||||
{
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_devpts(dentry->d_inode);
|
||||
+ #ifdef CONFIG_KSU
|
||||
if (dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC)
|
||||
return NULL;
|
||||
return dentry->d_fsdata;
|
||||
```
|
||||
|
||||
### Como portar path_umount
|
||||
|
||||
Você pode fazer com que o recurso "Desmontar módulos" funcione em kernels pré-GKI portando manualmente `path_umount` da versão 5.9. Você pode usar este patch como referência:
|
||||
|
@ -347,7 +389,3 @@ Você pode fazer com que o recurso "Desmontar módulos" funcione em kernels pré
|
|||
```
|
||||
|
||||
Finalmente, construa seu kernel novamente, e então, o KernelSU deve funcionar bem.
|
||||
|
||||
:::info ENTRANDO NO MODO DE SEGURANÇA ACIDENTALMENTE?
|
||||
Se você estiver usando a integração manual e não desabilitar `CONFIG_KPROBES`, o usuário poderá acionar o Modo de Segurança pressionando o botão de diminuir volume após a inicialização! Portanto, se estiver usando a integração manual, você precisa desabilitar `CONFIG_KPROBES`!
|
||||
:::
|
||||
|
|
|
@ -45,15 +45,15 @@ Observe que o SubLevel na versão do kernel não faz parte do KMI! Isso signific
|
|||
|
||||
### Nível do patch de segurança {#security-patch-level}
|
||||
|
||||
Dispositivos Android mais recentes podem ter mecanismos anti-rollback que não permitem flashar um boot.img com um nível do patch de segurança antigo. Por exemplo, se o kernel do seu dispositivo for `5.10.101-android12-9-g30979850fc20`, o patch de segurança será `2023-11`, mesmo se você atualizar o kernel consistente com o KMI do kernel, se o nível do patch de segurança for anterior a `2023-11` (como `2023-06`), então isso pode causar bootloop.
|
||||
Dispositivos Android mais recentes podem ter mecanismos anti-rollback que não permitem flashar um boot.img com um nível do patch de segurança antigo. Por exemplo, se o kernel do seu dispositivo for `5.10.101-android12-9-g30979850fc20`, o patch de segurança será `2023-11`, mesmo se você atualizar o kernel correspondente ao KMI do kernel, se o nível do patch de segurança for anterior a `2023-11` (como `2023-06`), então isso pode causar bootloop.
|
||||
|
||||
Portanto, os kernels com os níveis do patch de segurança mais recentes são preferidos, mantendo a consistência do KMI.
|
||||
Portanto, os kernels com os níveis do patch de segurança mais recentes são preferidos para manter a correspondência com o KMI.
|
||||
|
||||
### Versão do kernel vs Versão do Android
|
||||
|
||||
Por favor, observe: **A versão do kernel e a versão do Android não são necessariamente iguais!**
|
||||
|
||||
Se você descobrir que a versão do seu kernel é `android12-5.10.101`, mas a versão do seu sistema Android é Android 13 ou outra, não se surpreenda, pois o número da versão do sistema Android não é necessariamente igual ao número da versão do kernel Linux. O número da versão do kernel Linux geralmente é consistente com a versão do sistema Android que acompanha o **dispositivo quando ele é enviado**. Se o sistema Android for atualizado posteriormente, a versão do kernel geralmente não será alterada. Se você precisar fazer o flash, **por favor, consulte sempre a versão do kernel!**
|
||||
Se você descobrir que a versão do seu kernel é `android12-5.10.101`, mas a versão do seu sistema Android é Android 13 ou outra, não se surpreenda, pois o número da versão do sistema Android não é necessariamente igual ao número da versão do kernel Linux. O número da versão do kernel Linux geralmente é correspondente à versão do sistema Android que acompanha o **dispositivo quando ele é enviado**. Se o sistema Android for atualizado posteriormente, a versão do kernel geralmente não será alterada. Então, antes de flashar qualquer coisa, **consulte sempre a versão do kernel!**
|
||||
|
||||
## Introdução
|
||||
|
||||
|
@ -76,9 +76,9 @@ No modo GKI, o kernel original do dispositivo será substituído pela imagem gen
|
|||
No modo LKM, o kernel original do dispositivo não será substituído, mas o módulo do kernel carregável será carregado no kernel do dispositivo. As vantagens do modo LKM são:
|
||||
|
||||
1. Não substituirá o kernel original do dispositivo. Se você tiver os requisitos especiais para o kernel original do dispositivo ou quiser usar o KernelSU enquanto usa um kernel de terceiros, poderá usar o modo LKM.
|
||||
2. É mais conveniente atualizar o OTA. Ao atualizar o KernelSU, você pode instalá-lo diretamente no gerenciador sem atualizar manualmente. Após o sistema OTA, você pode instalá-lo diretamente no segundo slot sem flashar manualmente.
|
||||
2. É mais conveniente atualizar o OTA. Ao atualizar o KernelSU, você pode instalá-lo diretamente no gerenciador sem flashar manualmente. Após o sistema OTA, você pode instalá-lo diretamente no segundo slot sem flashar manualmente.
|
||||
3. Adequado para alguns cenários especiais, por exemplo, o LKM também pode ser carregado com privilégios root temporários. Como não é necessário substituir a partição boot, ele não acionará o AVB e não causará o bloqueio do dispositivo.
|
||||
4. O LKM pode ser desinstalado temporariamente. Se você deseja cancelar temporariamente o root, você pode desinstalar o LKM, este processo não requer o flash de partições, nem mesmo a reinicialização do dispositivo. Se quiser fazer root novamente, basta reiniciar o dispositivo.
|
||||
4. O LKM pode ser desinstalado temporariamente. Se você deseja desativar temporariamente o acesso root, você pode desinstalar o LKM, este processo não requer o flash de partições, nem mesmo a reinicialização do dispositivo. Se quiser ativar o root novamente, basta reiniciar o dispositivo.
|
||||
|
||||
:::tip COEXISTÊNCIA DE DOIS MODOS
|
||||
Após abrir o gerenciador, você pode ver o modo atual do dispositivo na página inicial. Observe que a prioridade do modo GKI é maior que a do LKM. Por exemplo, se você usar o kernel GKI para substituir o kernel original e usar LKM para corrigir o kernel GKI, o LKM será ignorado e o dispositivo sempre será executado no modo GKI.
|
||||
|
@ -98,13 +98,13 @@ Existem muitas maneiras de obter o firmware oficial. Se o seu dispositivo suport
|
|||
|
||||
Se o seu dispositivo não suportar `fastboot boot`, pode ser necessário baixar manualmente o pacote de firmware oficial e extrair o boot dele.
|
||||
|
||||
Ao contrário do modo GKI, o modo LKM modificará o `ramdisk`, portanto, em dispositivos com Android 13, ele precisa corrigir a partição `init_boot` em vez da partição `boot`, enquanto o modo GKI sempre opera a partição `boot`.
|
||||
Ao contrário do modo GKI, o modo LKM modificará o `ramdisk`, portanto, em dispositivos com Android 13, ele precisa corrigir a partição `init_boot` em vez da partição `boot`, enquanto isso, o modo GKI sempre opera a partição `boot`.
|
||||
|
||||
### Use o gerenciador
|
||||
|
||||
Abra o gerenciador, clique no ícone de instalação no canto superior direito e diversas opções aparecerão:
|
||||
|
||||
1. Selecione e corrija um arquivo. Se o seu telefone não tiver privilégios root, você pode escolher esta opção e, em seguida, selecionar seu firmware oficial, e o gerenciador irá corrigi-lo automaticamente. Você só precisa flashar este arquivo corrigido para obter privilégios root permanentemente.
|
||||
1. Selecione e corrija um arquivo. Se o seu telefone não tiver privilégios root, você pode escolher esta opção e, em seguida, selecionar seu firmware oficial, o gerenciador irá corrigi-lo automaticamente. Você só precisa flashar este arquivo corrigido para obter privilégios root permanentemente.
|
||||
2. Instale diretamente. Se o seu telefone já estiver rooteado, você pode escolher esta opção, o gerenciador obterá automaticamente as informações do seu dispositivo e, em seguida, corrigirá o firmware oficial e irá fazer o flash automaticamente. Você pode considerar usar `fastboot boot` e o kernel GKI do KernelSU para obter root temporário e instalar o gerenciador, e então usar esta opção. Esta também é a principal forma de atualizar o KernelSU.
|
||||
3. Instale em outra partição. Se o seu dispositivo suportar partição A/B, você pode escolher esta opção, o gerenciador irá corrigir automaticamente o firmware oficial e, em seguida, instalá-lo em outra partição. Este método é adequado para dispositivos após o OTA, você pode instalá-lo diretamente em outra partição após o OTA e, em seguida, reiniciar o dispositivo.
|
||||
|
||||
|
@ -114,7 +114,7 @@ Se não quiser usar o gerenciador, você também pode usar a linha de comando pa
|
|||
|
||||
Esta ferramenta oferece suporte ao macOS, Linux e Windows. Você pode baixar a versão correspondente em [GitHub Release](https://github.com/tiann/KernelSU/releases).
|
||||
|
||||
Uso: `ksud boot-patch` você pode verificar a ajuda da linha de comando para o uso específico.
|
||||
Uso: `ksud boot-patch` você pode verificar a ajuda da linha de comando para opções específicas.
|
||||
|
||||
```sh
|
||||
oriole:/ # ksud boot-patch -h
|
||||
|
@ -168,7 +168,7 @@ Você pode baixar o boot.img em [GitHub Release](https://github.com/tiann/Kernel
|
|||
Normalmente, existem três arquivos de inicialização em formatos diferentes no mesmo KMI e nível do patch de segurança. Eles são todos iguais, exceto pelo formato de compactação do kernel. Por favor, verifique o formato de compactação do kernel de seu boot.img original. Você deve usar o formato correto, como `lz4` ou `gz`. Se você usar um formato de compactação incorreto, poderá encontrar bootloop após flashar o boot.img.
|
||||
|
||||
::: info FORMATO DE COMPACTAÇÃO DO BOOT.IMG
|
||||
1. Você pode usar o magiskboot para obter o formato de compactação de seu boot original; é claro que você também pode perguntar a outras pessoas mais experientes com o mesmo modelo do seu dispositivo. Além disso, o formato de compactação do kernel geralmente não muda, portanto, se você inicializar com êxito com um determinado formato de compactação, poderá tentar esse formato mais tarde.
|
||||
1. Você pode usar o magiskboot para obter o formato de compactação de seu boot original; alternativamente, você também pode solicitá-lo a membros/desenvolvedores da comunidade com o mesmo modelo do seu dispositivo. Além disso, o formato de compactação do kernel geralmente não muda, portanto, se você inicializar com êxito com um determinado formato de compactação, poderá tentar esse formato mais tarde.
|
||||
2. Os dispositivos Xiaomi geralmente usam `gz` ou `uncompressed`.
|
||||
3. Para dispositivos Pixel, siga as instruções abaixo:
|
||||
:::
|
||||
|
@ -203,7 +203,7 @@ Etapa:
|
|||
Dessa forma, é necessário que o app Kernel Flasher tenha privilégios root. Você pode usar os seguintes métodos para conseguir isso:
|
||||
|
||||
1. Seu dispositivo está rooteado. Por exemplo, você instalou o KernelSU e deseja atualizar para a versão mais recente ou fez o root por meio de outros métodos (como Magisk).
|
||||
2. Se o seu telefone não estiver rooteado, mas o telefone suportar o método de inicialização temporária como `fastboot boot boot.img`, você pode usar a imagem GKI fornecida pelo KernelSU para inicializar temporariamente o seu dispositivo, obter privilégios root temporário e, em seguida, usar o Kernel Flasher para obter privilégios root permanente.
|
||||
2. Se o seu dispositivo não estiver rooteado, mas suportar o método de inicialização temporária como `fastboot boot boot.img`, você pode usar a imagem GKI fornecida pelo KernelSU para inicializar temporariamente o seu dispositivo, obter privilégios root temporário e, em seguida, usar o Kernel Flasher para obter privilégios root permanente.
|
||||
|
||||
1. [Kernel Flasher](https://github.com/capntrips/KernelFlasher/releases)
|
||||
2. [Franco Kernel Manager](https://play.google.com/store/apps/details?id=com.franco.kernel)
|
||||
|
@ -213,7 +213,7 @@ Observação: Este método é mais conveniente ao atualizar o KernelSU e pode se
|
|||
|
||||
## Corrigir boot.img manualmente {#patch-boot-image}
|
||||
|
||||
Para alguns dispositivos, o formato boot.img não é tão comum como `lz4`, `gz` e `uncompressed`. O mais típico é o Pixel, seu formato boot.img é `lz4_legacy` compactado, ramdisk pode ser `gz` e também pode ser compactado `lz4_legacy`. Neste momento, se você flashar diretamente o boot.img fornecido pelo KernelSU, o telefone pode não conseguir inicializar. Neste momento, você pode corrigir manualmente o boot.img para conseguir isso.
|
||||
Para alguns dispositivos, o formato boot.img não é tão comum como `lz4`, `gz` e `uncompressed`. O mais típico é o Pixel, seu formato boot.img é `lz4_legacy` compactado, ramdisk pode ser `gz` e também pode ser compactado `lz4_legacy`. Atualmente, se você flashar diretamente o boot.img fornecido pelo KernelSU, o telefone pode não conseguir inicializar. Neste momento, você pode corrigir manualmente o boot.img para conseguir isso.
|
||||
|
||||
É sempre recomendado usar `magiskboot` para corrigir imagens, existem duas maneiras:
|
||||
|
||||
|
@ -223,7 +223,7 @@ Para alguns dispositivos, o formato boot.img não é tão comum como `lz4`, `gz`
|
|||
A versão oficial do `magiskboot` só pode rodar em dispositivos Android, se você quiser rodar no PC, você pode tentar a segunda opção.
|
||||
|
||||
::: tip DICA
|
||||
Android-Image-Kitchen não é recomendado agora, porque ele não lida corretamente com os metadados de inicialização (como o nível do patch de segurança). Portanto, pode não funcionar em alguns dispositivos.
|
||||
Android-Image-Kitchen não é recomendado por enquanto, porque ele não lida corretamente com os metadados de inicialização (como o nível do patch de segurança). Portanto, pode não funcionar em alguns dispositivos.
|
||||
:::
|
||||
|
||||
### Preparação
|
||||
|
@ -240,16 +240,16 @@ Android-Image-Kitchen não é recomendado agora, porque ele não lida corretamen
|
|||
4. Envie o boot.img padrão e Image em AnyKernel3 para o seu dispositivo.
|
||||
5. Entre no ADB shell e no diretório cd `/data/local/tmp/`, em seguida, `chmod +x magiskboot`.
|
||||
6. Entre no ADB shell e no diretório cd `/data/local/tmp/`, execute `./magiskboot unpack boot.img` para descompactar `boot.img`, você obterá um arquivo `kernel`, este é o seu kernel padrão.
|
||||
7. Substitua `kernel` por `Image`: `mv -f Image kernel`.
|
||||
7. Substitua `kernel` por `Image` executando o comando: `mv -f Image kernel`.
|
||||
8. Execute `./magiskboot repack boot.img` para reembalar o boot.img, e você obterá um arquivo `new-boot.img`, faça o flash deste arquivo para o dispositivo por fastboot.
|
||||
|
||||
### Usando o magiskboot no PC Windows/macOS/Linux {#using-magiskboot-on-PC}
|
||||
|
||||
1. Baixe o `magiskboot` adequado para o seu sistema operacional em [magiskboot_build](https://github.com/ookiineko/magiskboot_build/releases/tag/last-ci).
|
||||
2. Prepare o `boot.img` padrão e `Image` em seu PC.
|
||||
3. `chmod +x magiskboot`
|
||||
3. Execute `chmod +x magiskboot`.
|
||||
4. Entre no diretório apropriado, execute `./magiskboot unpack boot.img` para descompactar `boot.img`. Você obterá um arquivo `kernel`, este é o seu kernel padrão.
|
||||
5. Substitua `kernel` por `Image`: `mv -f Image kernel`.
|
||||
5. Substitua `kernel` por `Image` executando o comando: `mv -f Image kernel`.
|
||||
6. Execute `./magiskboot repack boot.img` para reembalar o boot.img, e você obterá um arquivo `new-boot.img`, faça o flash deste arquivo para o dispositivo por fastboot.
|
||||
|
||||
::: info INFORMAÇÕES
|
||||
|
@ -258,13 +258,13 @@ O `magiskboot` oficial pode executar o dispositivo `Linux` normalmente. Se você
|
|||
|
||||
## Instalar com Recovery personalizado {#install-with-custom-recovery}
|
||||
|
||||
Pré-requisito: Seu dispositivo deve ter um Recovery personalizado, como TWRP. Se apenas o Recovery oficial estiver disponível, use outro método.
|
||||
Pré-requisito: Seu dispositivo deve ter um Recovery personalizado, como TWRP. Se não houver Recovery personalizado disponível para o seu dispositivo, use outro método.
|
||||
|
||||
Etapa:
|
||||
Etapas:
|
||||
|
||||
1. Em [GitHub Releases](https://github.com/tiann/KernelSU/releases), baixe o pacote ZIP começando com AnyKernel3 que corresponde à versão do seu telefone. Por exemplo, a versão do kernel do telefone é `android12-5.10. 66`, então você deve baixar o arquivo `AnyKernel3-android12-5.10.66_yyyy-MM.zip` (onde `yyyy` é o ano e `MM` é o mês).
|
||||
1. Em [GitHub Releases](https://github.com/tiann/KernelSU/releases), baixe o pacote ZIP começando com AnyKernel3 que corresponde à versão do seu telefone. Por exemplo, a versão do kernel do dispositivo é `android12-5.10. 66`, então você deve baixar o arquivo `AnyKernel3-android12-5.10.66_yyyy-MM.zip` (onde `yyyy` é o ano e `MM` é o mês).
|
||||
2. Reinicie o telefone no TWRP.
|
||||
3. Use o ADB para colocar AnyKernel3-*.zip no telefone em /sdcard e escolha instalá-lo na interface do TWRP, ou você pode diretamente `adb sideload AnyKernel-*.zip` para instalar.
|
||||
3. Use o ADB para colocar AnyKernel3-*.zip no dispositivo em `/sdcard` e escolha instalá-lo na interface do TWRP, ou você pode diretamente executar `adb sideload AnyKernel-*.zip` para instalar.
|
||||
|
||||
Observação: Este método é adequado para qualquer instalação (não limitado à instalação inicial ou atualizações subsequentes), desde que você use o TWRP.
|
||||
|
||||
|
@ -272,7 +272,7 @@ Observação: Este método é adequado para qualquer instalação (não limitado
|
|||
|
||||
Na verdade, todos esses métodos de instalação têm apenas uma ideia principal, que é **substituir o kernel original pelo fornecido pelo KernelSU**, desde que isso possa ser alcançado, ele pode ser instalado. Por exemplo, a seguir estão outros métodos possíveis.
|
||||
|
||||
1. Primeiro instale o Magisk, obtenha privilégios root através do Magisk e então use o Kernel Flasher para fazer o flash no zip AnyKernel do KernelSU.
|
||||
2. Use algum kit de ferramentas de flash em PCs para flashar no kernel fornecido pelo KernelSU.
|
||||
1. Primeiro instale o Magisk, obtenha privilégios root através do Magisk e então use o Kernel Flasher para fazer o flash no ZIP AnyKernel3 do KernelSU.
|
||||
2. Use algum kit de ferramentas de flash em PC para flashar no kernel fornecido pelo KernelSU.
|
||||
|
||||
Mas se não funcionar, por favor, tente o método `magiskboot`.
|
||||
No entanto, se não funcionar, por favor, tente o método `magiskboot`.
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
O KernelSU fornece um mecanismo de módulo que consegue modificar o diretório do sistema enquanto mantém a integridade da partição do sistema. Este mecanismo é conhecido como "sem sistema".
|
||||
|
||||
O mecanismo de módulos do KernelSU é quase o mesmo do Magisk. Se você está familiarizado com o desenvolvimento de módulos Magisk, o desenvolvimento de módulos KernelSU é muito semelhante. Você pode pular a introdução dos módulos abaixo e só precisa ler [Diferença com Magisk](difference-with-magisk.md).
|
||||
O mecanismo de módulos do KernelSU é quase o mesmo do Magisk. Se você está familiarizado com o desenvolvimento de módulos Magisk, o desenvolvimento de módulos KernelSU é muito semelhante. Você pode pular a introdução dos módulos abaixo e só precisa ler [Diferenças com Magisk](difference-with-magisk.md).
|
||||
|
||||
## WebUI
|
||||
|
||||
Os módulos do KernelSU suportam a exibição de interfaces e a interação com os usuários, consulte a [documentação do WebUI](module-webui.md).
|
||||
Os módulos do KernelSU suportam a exibição de interfaces e a interação com os usuários. Para mais, consulte a [documentação do WebUI](module-webui.md).
|
||||
|
||||
## BusyBox
|
||||
|
||||
|
@ -21,7 +21,7 @@ Para aqueles que desejam usar o recurso Modo Autônomo fora do KernelSU, existem
|
|||
|
||||
Para garantir que todos os shells `sh` subsequentes executados também sejam executados no Modo Autônomo, a opção 1 é o método preferido (e é isso que o KernelSU e o gerenciador do KernelSU usam internamente), pois as variáveis de ambiente são herdadas para os subprocesso.
|
||||
|
||||
::: tip DIFERENÇA COM MAGISK
|
||||
::: tip DIFERENÇAS COM MAGISK
|
||||
|
||||
O BusyBox do KernelSU agora está usando o arquivo binário compilado diretamente do projeto Magisk. **Obrigado ao Magisk!** Portanto, você não precisa se preocupar com problemas de compatibilidade entre scripts BusyBox no Magisk e KernelSU porque eles são exatamente iguais!
|
||||
:::
|
||||
|
@ -82,7 +82,7 @@ Um módulo KernelSU é uma pasta colocada em `/data/adb/modules` com a estrutura
|
|||
├── .
|
||||
```
|
||||
|
||||
::: tip DIFERENÇA COM MAGISK
|
||||
::: tip DIFERENÇAS COM MAGISK
|
||||
O KernelSU não possui suporte integrado para o Zygisk, portanto não há conteúdo relacionado ao Zygisk no módulo. No entanto, você pode usar [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) para suportar módulos Zygisk. Neste caso, o conteúdo do módulo Zygisk é idêntico ao suportado pelo Magisk.
|
||||
:::
|
||||
|
||||
|
@ -112,7 +112,7 @@ Por favor, leia a seção [Scripts de inicialização](#scripts-de-inicializacao
|
|||
|
||||
Em todos os scripts do seu módulo, use `MODDIR=${0%/*}` para obter o caminho do diretório base do seu módulo, **NÃO** codifique o caminho do seu módulo nos scripts.
|
||||
|
||||
::: tip DIFERENÇA COM MAGISK
|
||||
::: tip DIFERENÇAS COM MAGISK
|
||||
Você pode usar a variável de ambiente `KSU` para determinar se um script está sendo executado no KernelSU ou Magisk. Se estiver executando no KernelSU, esse valor será definido como `true`.
|
||||
:::
|
||||
|
||||
|
@ -149,7 +149,7 @@ REPLACE="
|
|||
|
||||
Esta lista criará automaticamente os diretórios `$MODPATH/system/app/YouTube` e `$MODPATH/system/app/Bloatware` e, em seguida, executará `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/YouTube` e `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/Bloatware`. Após o módulo entrar em vigor, `/system/app/YouTube` e `/system/app/Bloatware` serão substituídos por diretórios vazios.
|
||||
|
||||
::: tip DIFERENÇA COM MAGISK
|
||||
::: tip DIFERENÇAS COM MAGISK
|
||||
|
||||
O mecanismo sem sistema do KernelSU é implementado através do OverlayFS do kernel, enquanto o Magisk atualmente usa montagem mágica (montagem de ligação). Os dois métodos de implementação têm diferenças significativas, mas o objetivo final é o mesmo: modificar os arquivos /system sem modificar fisicamente a partição /system.
|
||||
:::
|
||||
|
@ -193,16 +193,16 @@ O script `customize.sh` é executado no shell BusyBox `ash` do KernelSU com o Mo
|
|||
#### Variáveis
|
||||
|
||||
- `KSU` (bool): uma variável para marcar que o script está sendo executado no ambiente KernelSU, e o valor desta variável sempre será `true`. Você pode usá-lo para distinguir entre KernelSU e Magisk.
|
||||
- `KSU_VER` (string): a string da versão do KernelSU atualmente instalado (por exemplo: `v0.4.0`).
|
||||
- `KSU_VER_CODE` (int): o código da versão do KernelSU atualmente instalado no espaço do usuário (por exemplo: `10672`).
|
||||
- `KSU_KERNEL_VER_CODE` (int): o código da versão do KernelSU atualmente instalado no espaço do kernel (por exemplo: `10672`).
|
||||
- `KSU_VER` (string): a string da versão do KernelSU atualmente instalado (ex.: `v0.4.0`).
|
||||
- `KSU_VER_CODE` (int): o código da versão do KernelSU atualmente instalado no espaço do usuário (ex.: `10672`).
|
||||
- `KSU_KERNEL_VER_CODE` (int): o código da versão do KernelSU atualmente instalado no espaço do kernel (ex.: `10672`).
|
||||
- `BOOTMODE` (bool): sempre será `true` no KernelSU.
|
||||
- `MODPATH` (path): o caminho onde os arquivos do seu módulo devem ser instalados.
|
||||
- `TMPDIR` (path): um lugar onde você pode armazenar arquivos temporariamente.
|
||||
- `ZIPFILE` (path): ZIP de instalação do seu módulo.
|
||||
- `ARCH` (string): a arquitetura da CPU do dispositivo. O valor é `arm`, `arm64`, `x86` ou `x64`.
|
||||
- `IS64BIT` (bool): `true` se `$ARCH` for `arm64` ou `x64`.
|
||||
- `API` (int): o nível da API (versão do Android) do dispositivo (por exemplo: `23` para Android 6.0).
|
||||
- `API` (int): o nível da API (versão do Android) do dispositivo (ex.: `23` para Android 6.0).
|
||||
|
||||
::: warning AVISO
|
||||
No KernelSU, `MAGISK_VER_CODE` é sempre `25200` e `MAGISK_VER` é sempre `v25.2`. Por favor, não use essas duas variáveis para determinar se ele está sendo executado no KernelSU ou não.
|
||||
|
@ -236,7 +236,7 @@ set_perm_recursive <directory> <owner> <group> <dirpermission> <filepermission>
|
|||
|
||||
## Scripts de inicialização
|
||||
|
||||
No KernelSU, os scripts são divididos em dois tipos com base em seu modo de execução: modo post-fs-data e modo de serviço late_start:
|
||||
No KernelSU, os scripts são divididos em dois tipos com base em seu modo de execução: modo post-fs-data e modo de serviço late_start.
|
||||
|
||||
- modo post-fs-data
|
||||
- Esta etapa está BLOQUEANDO. O processo de inicialização é pausado antes da execução ser concluída ou 10 segundos se passaram.
|
||||
|
@ -248,7 +248,7 @@ No KernelSU, os scripts são divididos em dois tipos com base em seu modo de exe
|
|||
- Esta etapa é SEM BLOQUEIO. Seu script é executado em paralelo com o restante do processo de inicialização.
|
||||
- **Este é o estágio recomendado para executar a maioria dos scripts**.
|
||||
|
||||
No KernelSU, os scripts de inicialização são divididos em dois tipos com base no local de armazenamento: scripts gerais e scripts de módulo:
|
||||
No KernelSU, os scripts de inicialização são divididos em dois tipos com base no local de armazenamento: scripts gerais e scripts de módulo.
|
||||
|
||||
- Scripts gerais
|
||||
- Colocado em `/data/adb/post-fs-data.d`, `/data/adb/service.d`, `/data/adb/post-mount.d` ou `/data/adb/boot-completed.d`.
|
||||
|
@ -261,3 +261,64 @@ No KernelSU, os scripts de inicialização são divididos em dois tipos com base
|
|||
- `post-fs-data.sh` é executado no modo post-fs-data, `service.sh` é executado no modo de serviço late_start, `boot-completed.sh` é executado na inicialização concluída e `post-mount.sh` é executado no OverlayFS montado.
|
||||
|
||||
Todos os scripts de inicialização serão executados no shell BusyBox `ash` do KernelSU com o Modo Autônomo ativado.
|
||||
|
||||
### Explicação do processo de scripts de inicialização
|
||||
|
||||
A seguir está o processo de inicialização relevante para o Android (algumas partes foram omitidas), que inclui a operação do KernelSU (com asteriscos iniciais) e pode ajudá-lo a entender melhor o propósito desses scripts de módulo:
|
||||
|
||||
```txt
|
||||
0. Bootloader (nada nesta tela)
|
||||
load patched boot.img
|
||||
load kernel:
|
||||
- Modo GKI: kernel GKI com KernelSU integrado
|
||||
- Modo LKM: kernel stock
|
||||
...
|
||||
1. kernel exec init (logotipo oem na tela):
|
||||
- Modo GKI: stock init
|
||||
- Modo LKM: exec ksuinit, insmod kernelsu.ko, exec stock init
|
||||
mount /dev, /dev/pts, /proc, /sys, etc.
|
||||
property-init -> read default props
|
||||
read init.rc
|
||||
...
|
||||
early-init -> init -> late_init
|
||||
early-fs
|
||||
start vold
|
||||
fs
|
||||
montar /vendor, /system, /persist, etc.
|
||||
post-fs-data
|
||||
*verificação do modo de segurança
|
||||
*executar scripts gerais em post-fs-data.d/
|
||||
*carregar sepolicy.rule
|
||||
*montar tmpfs
|
||||
*executar scripts de módulo post-fs-data.sh
|
||||
**(Zygisk)./bin/zygisk-ptrace64 monitor
|
||||
*(pré)carregamento de system.prop (igual a resetprop -n)
|
||||
*remontar módulos em /system
|
||||
*executar scripts gerais em post-mount.d/
|
||||
*executar scripts de módulo post-mount.sh
|
||||
zygote-start
|
||||
load_all_props_action
|
||||
*executar resetprop (defina adereços reais para resetprop com a opção -n)
|
||||
... -> boot
|
||||
class_start core
|
||||
start-service logd, console, vold, etc.
|
||||
class_start main
|
||||
start-service adb, netd (iptables), zygote, etc.
|
||||
2. kernel2user init (animação da rom na tela, inicie pelo serviço bootanim)
|
||||
*executar scripts gerais em service.d/
|
||||
*executar scripts de módulo service.sh
|
||||
*definir adereços para resetprop sem a opção -p
|
||||
**(Zygisk) hook zygote (iniciar o zygiskd)
|
||||
**(Zygisk) montar zygisksu/module.prop
|
||||
iniciar apps do sistema (início automático)
|
||||
...
|
||||
inicialização completa (transmitir evento ACTION_BOOT_COMPLETED)
|
||||
*executar scripts gerais em boot-completed.d/
|
||||
*executar scripts de módulo boot-completed.sh
|
||||
3. Operável pelo usuário (tela de bloqueio)
|
||||
insira a senha para descriptografar /data/data
|
||||
*conjunto real de adereços para resetprop com opção -p
|
||||
iniciar apps de usuário (início automático)
|
||||
```
|
||||
|
||||
Se você estiver interessado na linguagem de inicialização do Android, é recomendável ler sua [documentação](https://android.googlesource.com/platform/system/core/+/master/init/README.md).
|
||||
|
|
|
@ -44,7 +44,7 @@ O Modo de Segurança integrado é implementado no kernel, portanto não há poss
|
|||
|
||||
### Módulos maliciosos
|
||||
|
||||
Se os métodos acima não conseguirem recuperar seu dispositivo, é altamente provável que o módulo que você instalou tenha operações maliciosas ou tenha danificado seu dispositivo por outros meios. Neste caso, existem apenas duas sugestões:
|
||||
Se os métodos acima não conseguirem recuperar seu dispositivo, é muito provável que o módulo que você instalou tenha operações maliciosas ou tenha danificado seu dispositivo por outros meios. Neste caso, existem apenas duas sugestões:
|
||||
|
||||
1. Limpar os dados e instalar o sistema oficial.
|
||||
2. Consultar o serviço pós-venda.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# O que é KernelSU?
|
||||
|
||||
O KernelSU é uma solução root para dispositivos Android GKI, funciona no modo kernel e concede privilégios root ao app do espaço do usuário diretamente no espaço do kernel.
|
||||
O KernelSU é uma solução root para dispositivos Android GKI, funciona no modo kernel e concede privilégios root para apps do espaço do usuário diretamente no espaço do kernel.
|
||||
|
||||
## Características
|
||||
|
||||
|
|
|
@ -48,6 +48,13 @@
|
|||
"kernel_link": "https://github.com/akash07k/nexus_kernel_xiaomi_sm8250/tree/lychee",
|
||||
"devices": "Poco F4: munch"
|
||||
},
|
||||
{
|
||||
"maintainer": "Hadad",
|
||||
"maintainer_link": "https://xdaforums.com/m/hadad.8351572/",
|
||||
"kernel_name": "android_kernel_xiaomi_onc",
|
||||
"kernel_link": "https://github.com/hadadarjt/android_kernel_xiaomi_onc/tree/los21-KSU/local-non-gerrit-review",
|
||||
"devices": "Redmi 7: onclite | Redmi Y3: onc"
|
||||
},
|
||||
{
|
||||
"maintainer": "HMTheBoy154",
|
||||
"maintainer_link": "https://github.com/hmtheboy154",
|
||||
|
@ -111,6 +118,13 @@
|
|||
"kernel_link": "https://github.com/Rohail33/Realking_kernel_sm8250",
|
||||
"devices": "Apollo(Redmi K30S Ultra/Mi 10T/Mi 10T Pro)\uff0cAlioth(Redmi K40/POCO F3/Mi 11X)\uff0cMunch(Redmi K40S/POCO F4), both MIUI and AOSP."
|
||||
},
|
||||
{
|
||||
"maintainer": "Sreeshankar K",
|
||||
"maintainer_link": "https://github.com/sreeshankark",
|
||||
"kernel_name": "NeverSettle Kernel",
|
||||
"kernel_link": "https://github.com/sreeshankark/android_kernel_oneplus_avicii",
|
||||
"devices": "OnePlus Nord (avicii)"
|
||||
},
|
||||
{
|
||||
"maintainer": "PSavarMattas",
|
||||
"maintainer_link": "https://github.com/psavarmattas",
|
||||
|
@ -384,20 +398,6 @@
|
|||
"kernel_link": "https://github.com/tejas101k/Cuh-KerneL",
|
||||
"devices": "Xiaomi Redmi Note 8/8T (ginkgo/willow)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Coconutat",
|
||||
"maintainer_link": "https://github.com/Coconutat",
|
||||
"kernel_name": "android_kernel_xiaomi_ruby_exp",
|
||||
"kernel_link": "https://github.com/Coconutat/android_kernel_xiaomi_ruby_exp",
|
||||
"devices": "Redmi Note 12 Pro / Pro+ For MIUI 14"
|
||||
},
|
||||
{
|
||||
"maintainer": "Coconutat",
|
||||
"maintainer_link": "https://github.com/Coconutat",
|
||||
"kernel_name": "android_kernel_xiaomi_sdm845_byd_exp",
|
||||
"kernel_link": "https://github.com/Coconutat/android_kernel_xiaomi_sdm845_byd_exp",
|
||||
"devices": "Xiaomi Mi 8 Pro(UD)[equuleus]/Explorer Edition[ursa]"
|
||||
},
|
||||
{
|
||||
"maintainer": "Abdul Wahid Khan",
|
||||
"maintainer_link": "https://github.com/Wahid7852",
|
||||
|
@ -594,13 +594,6 @@
|
|||
"kernel_link": "https://github.com/Fede2782/android_kernel_samsung_a34x/",
|
||||
"devices": "Samsung Galaxy A34 5G (a34x)"
|
||||
},
|
||||
{
|
||||
"maintainer": "KJ-Network",
|
||||
"maintainer_link": "https://github.com/KJ-Network",
|
||||
"kernel_name": "K-Nel-M1721",
|
||||
"kernel_link": "https://github.com/KJ-Network/K-Nel-M1721/",
|
||||
"devices": "Meizu M6 Note (M1721)"
|
||||
},
|
||||
{
|
||||
"maintainer": "SnowWolf725 ",
|
||||
"maintainer_link": "https://github.com/snowwolf725",
|
||||
|
|
|
@ -17,20 +17,12 @@ KernelSU 使用 kprobe 机制来做内核的相关 hook,如果 *kprobe* 可以
|
|||
|
||||
首先,把 KernelSU 添加到你的内核源码树,在内核的根目录执行以下命令:
|
||||
|
||||
::: code-group
|
||||
|
||||
```sh[最新tag(稳定版本)]
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
|
||||
```sh[main分支(开发版本)]
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main
|
||||
```
|
||||
|
||||
```sh[指定tag(比如v0.5.2)]
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.5.2
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.9.5
|
||||
```
|
||||
|
||||
:::info
|
||||
[KernelSU 1.0 及更高版本已经不再支持非 GKI 内核](https://github.com/tiann/KernelSU/issues/1705),最后的支持版本为 `v0.9.5`,请注意使用正确的版本。
|
||||
:::
|
||||
|
||||
然后,你需要检查你的内核是否开启了 *kprobe* 相关的配置,如果没有开启,需要添加以下配置:
|
||||
|
|
|
@ -267,3 +267,67 @@ set_perm_recursive <directory> <owner> <group> <dirpermission> <filepermission>
|
|||
- `post-fs-data.sh` 以 post-fs-data 模式运行,`post-mount.sh` 以 post-mount 模式运行,而 `service.sh` 则以 late_start 服务模式运行,`boot-completed` 在 Android 系统启动完毕后以服务模式运行。
|
||||
|
||||
所有启动脚本都将在 KernelSU 的 BusyBox ash shell 中运行,并启用“独立模式”。
|
||||
|
||||
### 启动脚本的流程解疑 {#Boot-scripts-process-explanation}
|
||||
|
||||
以下是 Android 的相关启动流程(部分省略),其中包括了 KernelSU 的操作(带前导星号),应该能帮助你更好地理解这些启动脚本的用途:
|
||||
|
||||
```txt
|
||||
0. Bootloader (nothing on screen)
|
||||
load patched boot.img
|
||||
load kernel:
|
||||
- GKI mode: GKI kernel with KernelSU integrated
|
||||
- LKM mode: stock kernel
|
||||
...
|
||||
|
||||
1. kernel exec init (oem logo on screen):
|
||||
- GKI mode: stock init
|
||||
- LKM mode: exec ksuinit, insmod kernelsu.ko, exec stock init
|
||||
mount /dev, /dev/pts, /proc, /sys, etc.
|
||||
property-init -> read default props
|
||||
read init.rc
|
||||
...
|
||||
early-init -> init -> late_init
|
||||
early-fs
|
||||
start vold
|
||||
fs
|
||||
mount /vendor, /system, /persist, etc.
|
||||
post-fs-data
|
||||
*safe mode check
|
||||
*execute general scripts in post-fs-data.d/
|
||||
*load sepolicy.rule
|
||||
*mount tmpfs
|
||||
*execute module scripts post-fs-data.sh
|
||||
**(Zygisk)./bin/zygisk-ptrace64 monitor
|
||||
*(pre)load system.prop (same as resetprop -n)
|
||||
*remount modules /system
|
||||
*execute general scripts in post-mount.d/
|
||||
*execute module scripts post-mount.sh
|
||||
zygote-start
|
||||
load_all_props_action
|
||||
*execute resetprop (actual set props for resetprop with -n option)
|
||||
... -> boot
|
||||
class_start core
|
||||
start-service logd, console, vold, etc.
|
||||
class_start main
|
||||
start-service adb, netd (iptables), zygote, etc.
|
||||
|
||||
2. kernel2user init (rom animation on screen, start by service bootanim)
|
||||
*execute general scripts in service.d/
|
||||
*execute module scripts service.sh
|
||||
*set props for resetprop without -p option
|
||||
**(Zygisk) hook zygote (start zygiskd)
|
||||
**(Zygisk) mount zygisksu/module.prop
|
||||
start system apps (autostart)
|
||||
...
|
||||
boot complete (broadcast ACTION_BOOT_COMPLETED event)
|
||||
*execute general scripts in boot-completed.d/
|
||||
*execute module scripts boot-completed.sh
|
||||
|
||||
3. User operable (lock screen)
|
||||
input password to decrypt /data/data
|
||||
*actual set props for resetprop with -p option
|
||||
start user apps (autostart)
|
||||
```
|
||||
|
||||
如果你对 Android 的 init 语言感兴趣,推荐阅读[文档](https://android.googlesource.com/platform/system/core/+/master/init/README.md)。
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
"author": "weishu",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"vitepress": "^1.1.3",
|
||||
"vue": "^3.4.25"
|
||||
"vitepress": "^1.2.3",
|
||||
"vue": "^3.4.27"
|
||||
},
|
||||
"scripts": {
|
||||
"docs:dev": "vitepress dev docs",
|
||||
|
@ -16,4 +16,4 @@
|
|||
"docs:preview": "vitepress preview docs"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
}
|
|
@ -151,9 +151,9 @@
|
|||
"@algolia/requester-common" "4.23.3"
|
||||
|
||||
"@babel/parser@^7.24.4":
|
||||
version "7.24.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.4.tgz#234487a110d89ad5a3ed4a8a566c36b9453e8c88"
|
||||
integrity sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==
|
||||
version "7.24.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790"
|
||||
integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==
|
||||
|
||||
"@docsearch/css@3.6.0", "@docsearch/css@^3.6.0":
|
||||
version "3.6.0"
|
||||
|
@ -298,258 +298,263 @@
|
|||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
|
||||
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
|
||||
|
||||
"@rollup/rollup-android-arm-eabi@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.2.tgz#9047b5b1ec19f58c0fdf3a072bd977bcec056576"
|
||||
integrity sha512-ahxSgCkAEk+P/AVO0vYr7DxOD3CwAQrT0Go9BJyGQ9Ef0QxVOfjDZMiF4Y2s3mLyPrjonchIMH/tbWHucJMykQ==
|
||||
"@rollup/rollup-android-arm-eabi@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz#bbd0e616b2078cd2d68afc9824d1fadb2f2ffd27"
|
||||
integrity sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==
|
||||
|
||||
"@rollup/rollup-android-arm64@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.2.tgz#08a2d2705193ebb3054941994e152808beb5254e"
|
||||
integrity sha512-lAarIdxZWbFSHFSDao9+I/F5jDaKyCqAPMq5HqnfpBw8dKDiCaaqM0lq5h1pQTLeIqueeay4PieGR5jGZMWprw==
|
||||
"@rollup/rollup-android-arm64@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz#97255ef6384c5f73f4800c0de91f5f6518e21203"
|
||||
integrity sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==
|
||||
|
||||
"@rollup/rollup-darwin-arm64@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.2.tgz#bf746c610f337b104408ec001549d825a91eca57"
|
||||
integrity sha512-SWsr8zEUk82KSqquIMgZEg2GE5mCSfr9sE/thDROkX6pb3QQWPp8Vw8zOq2GyxZ2t0XoSIUlvHDkrf5Gmf7x3Q==
|
||||
"@rollup/rollup-darwin-arm64@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz#b6dd74e117510dfe94541646067b0545b42ff096"
|
||||
integrity sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==
|
||||
|
||||
"@rollup/rollup-darwin-x64@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.2.tgz#59ebe3b858a44680d5f87546ea2df1c7e3135f6a"
|
||||
integrity sha512-o/HAIrQq0jIxJAhgtIvV5FWviYK4WB0WwV91SLUnsliw1lSAoLsmgEEgRWzDguAFeUEUUoIWXiJrPqU7vGiVkA==
|
||||
"@rollup/rollup-darwin-x64@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz#e07d76de1cec987673e7f3d48ccb8e106d42c05c"
|
||||
integrity sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==
|
||||
|
||||
"@rollup/rollup-linux-arm-gnueabihf@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.2.tgz#44cffc07d04d659cb635aec11bef530d5757ee6a"
|
||||
integrity sha512-nwlJ65UY9eGq91cBi6VyDfArUJSKOYt5dJQBq8xyLhvS23qO+4Nr/RreibFHjP6t+5ap2ohZrUJcHv5zk5ju/g==
|
||||
"@rollup/rollup-linux-arm-gnueabihf@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz#9f1a6d218b560c9d75185af4b8bb42f9f24736b8"
|
||||
integrity sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==
|
||||
|
||||
"@rollup/rollup-linux-arm64-gnu@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.2.tgz#9901e2288fb192b74a2f8428c507d43cc2739ceb"
|
||||
integrity sha512-Pg5TxxO2IVlMj79+c/9G0LREC9SY3HM+pfAwX7zj5/cAuwrbfj2Wv9JbMHIdPCfQpYsI4g9mE+2Bw/3aeSs2rQ==
|
||||
"@rollup/rollup-linux-arm-musleabihf@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz#53618b92e6ffb642c7b620e6e528446511330549"
|
||||
integrity sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==
|
||||
|
||||
"@rollup/rollup-linux-arm64-musl@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.2.tgz#8a2c55a72e0c716a15d830fee3bf5a1a756f13ec"
|
||||
integrity sha512-cAOTjGNm84gc6tS02D1EXtG7tDRsVSDTBVXOLbj31DkwfZwgTPYZ6aafSU7rD/4R2a34JOwlF9fQayuTSkoclA==
|
||||
"@rollup/rollup-linux-arm64-gnu@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz#99a7ba5e719d4f053761a698f7b52291cefba577"
|
||||
integrity sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==
|
||||
|
||||
"@rollup/rollup-linux-powerpc64le-gnu@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.2.tgz#71bf99c8017476ac85b09d21b3fa2eacbad96100"
|
||||
integrity sha512-4RyT6v1kXb7C0fn6zV33rvaX05P0zHoNzaXI/5oFHklfKm602j+N4mn2YvoezQViRLPnxP8M1NaY4s/5kXO5cw==
|
||||
"@rollup/rollup-linux-arm64-musl@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz#f53db99a45d9bc00ce94db8a35efa7c3c144a58c"
|
||||
integrity sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==
|
||||
|
||||
"@rollup/rollup-linux-riscv64-gnu@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.2.tgz#48ee7fe5fee7b6d0028b6dda4fab95238208a0cd"
|
||||
integrity sha512-KNUH6jC/vRGAKSorySTyc/yRYlCwN/5pnMjXylfBniwtJx5O7X17KG/0efj8XM3TZU7raYRXJFFReOzNmL1n1w==
|
||||
"@rollup/rollup-linux-powerpc64le-gnu@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz#cbb0837408fe081ce3435cf3730e090febafc9bf"
|
||||
integrity sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==
|
||||
|
||||
"@rollup/rollup-linux-s390x-gnu@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.2.tgz#65ad6f82729ef9d8634847189214e3205892f42f"
|
||||
integrity sha512-xPV4y73IBEXToNPa3h5lbgXOi/v0NcvKxU0xejiFw6DtIYQqOTMhZ2DN18/HrrP0PmiL3rGtRG9gz1QE8vFKXQ==
|
||||
"@rollup/rollup-linux-riscv64-gnu@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz#8ed09c1d1262ada4c38d791a28ae0fea28b80cc9"
|
||||
integrity sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==
|
||||
|
||||
"@rollup/rollup-linux-x64-gnu@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.2.tgz#2ab802ce25c0d0d44a0ea55b0068f79e462d22cd"
|
||||
integrity sha512-QBhtr07iFGmF9egrPOWyO5wciwgtzKkYPNLVCFZTmr4TWmY0oY2Dm/bmhHjKRwZoGiaKdNcKhFtUMBKvlchH+Q==
|
||||
"@rollup/rollup-linux-s390x-gnu@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz#938138d3c8e0c96f022252a28441dcfb17afd7ec"
|
||||
integrity sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==
|
||||
|
||||
"@rollup/rollup-linux-x64-musl@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.2.tgz#85dcd3f549c2fdbcf1cb1f1b5f501933ed590880"
|
||||
integrity sha512-8zfsQRQGH23O6qazZSFY5jP5gt4cFvRuKTpuBsC1ZnSWxV8ZKQpPqOZIUtdfMOugCcBvFGRa1pDC/tkf19EgBw==
|
||||
"@rollup/rollup-linux-x64-gnu@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz#1a7481137a54740bee1ded4ae5752450f155d942"
|
||||
integrity sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==
|
||||
|
||||
"@rollup/rollup-win32-arm64-msvc@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.2.tgz#10f608dfc1e5bb96aca18c7784cc4a94d890c03c"
|
||||
integrity sha512-H4s8UjgkPnlChl6JF5empNvFHp77Jx+Wfy2EtmYPe9G22XV+PMuCinZVHurNe8ggtwoaohxARJZbaH/3xjB/FA==
|
||||
"@rollup/rollup-linux-x64-musl@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz#f1186afc601ac4f4fc25fac4ca15ecbee3a1874d"
|
||||
integrity sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==
|
||||
|
||||
"@rollup/rollup-win32-ia32-msvc@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.2.tgz#f27f9fb64b7e10b04121e0054d9145ee21589267"
|
||||
integrity sha512-djqpAjm/i8erWYF0K6UY4kRO3X5+T4TypIqw60Q8MTqSBaQNpNXDhxdjpZ3ikgb+wn99svA7jxcXpiyg9MUsdw==
|
||||
"@rollup/rollup-win32-arm64-msvc@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz#ed6603e93636a96203c6915be4117245c1bd2daf"
|
||||
integrity sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==
|
||||
|
||||
"@rollup/rollup-win32-x64-msvc@4.14.2":
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.2.tgz#5d2d9dc96b436469dc74ef93de069b14fb12aace"
|
||||
integrity sha512-teAqzLT0yTYZa8ZP7zhFKEx4cotS8Tkk5XiqNMJhD4CpaWB1BHARE4Qy+RzwnXvSAYv+Q3jAqCVBS+PS+Yee8Q==
|
||||
"@rollup/rollup-win32-ia32-msvc@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz#14e0b404b1c25ebe6157a15edb9c46959ba74c54"
|
||||
integrity sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==
|
||||
|
||||
"@shikijs/core@1.3.0", "@shikijs/core@^1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.3.0.tgz#5b93b51ddb8def1e3a1543107f9b5b0540f716f6"
|
||||
integrity sha512-7fedsBfuILDTBmrYZNFI8B6ATTxhQAasUHllHmjvSZPnoq4bULWoTpHwmuQvZ8Aq03/tAa2IGo6RXqWtHdWaCA==
|
||||
"@rollup/rollup-win32-x64-msvc@4.18.0":
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz#5d694d345ce36b6ecf657349e03eb87297e68da4"
|
||||
integrity sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==
|
||||
|
||||
"@shikijs/transformers@^1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/transformers/-/transformers-1.3.0.tgz#b03c5733ef61e25e4f53666bf11889f8876f34e9"
|
||||
integrity sha512-3mlpg2I9CjhjE96dEWQOGeCWoPcyTov3s4aAsHmgvnTHa8MBknEnCQy8/xivJPSpD+olqOqIEoHnLfbNJK29AA==
|
||||
"@shikijs/core@1.6.2", "@shikijs/core@^1.6.2":
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.6.2.tgz#29be410e33e604c8ccc7d5ab75cade1a52db8ec2"
|
||||
integrity sha512-guW5JeDzZ7uwOjTfCOFZ2VtVXk5tmkMzBYbKGfXsmAH1qYOej49L5jQDcGmwd6/OgvpmWhzO2GNJkQIFnbwLPQ==
|
||||
|
||||
"@shikijs/transformers@^1.6.2":
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/transformers/-/transformers-1.6.2.tgz#dab9f22531f1a16114a59f11e5d681edbd764970"
|
||||
integrity sha512-ndqTWyHnxmsLkowhKWTam26opw8hg5a34y6FAUG/Xf6E49n3MM//nenKxXiWpPYkNPl1KZnYXB1k+Ia46wjOZg==
|
||||
dependencies:
|
||||
shiki "1.3.0"
|
||||
shiki "1.6.2"
|
||||
|
||||
"@types/estree@1.0.5":
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
|
||||
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
|
||||
|
||||
"@types/linkify-it@*":
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.5.tgz#1e78a3ac2428e6d7e6c05c1665c242023a4601d8"
|
||||
integrity sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==
|
||||
"@types/linkify-it@^5":
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-5.0.0.tgz#21413001973106cda1c3a9b91eedd4ccd5469d76"
|
||||
integrity sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==
|
||||
|
||||
"@types/markdown-it@^14.0.1":
|
||||
version "14.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-14.0.1.tgz#3d3fdf9dba83b69edececc070d39ec72b84270a7"
|
||||
integrity sha512-6WfOG3jXR78DW8L5cTYCVVGAsIFZskRHCDo5tbqa+qtKVt4oDRVH7hyIWu1SpDQJlmIoEivNQZ5h+AGAOrgOtQ==
|
||||
"@types/markdown-it@^14.1.1":
|
||||
version "14.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-14.1.1.tgz#06bafb7a4e3f77b62b1f308acf7df76687887e0b"
|
||||
integrity sha512-4NpsnpYl2Gt1ljyBGrKMxFYAYvpqbnnkgP/i/g+NLpjEUa3obn1XJCur9YbEXKDAkaXqsR1LbDnGEJ0MmKFxfg==
|
||||
dependencies:
|
||||
"@types/linkify-it" "*"
|
||||
"@types/mdurl" "*"
|
||||
"@types/linkify-it" "^5"
|
||||
"@types/mdurl" "^2"
|
||||
|
||||
"@types/mdurl@*":
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.5.tgz#3e0d2db570e9fb6ccb2dc8fde0be1d79ac810d39"
|
||||
integrity sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==
|
||||
"@types/mdurl@^2":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-2.0.0.tgz#d43878b5b20222682163ae6f897b20447233bdfd"
|
||||
integrity sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==
|
||||
|
||||
"@types/web-bluetooth@^0.0.20":
|
||||
version "0.0.20"
|
||||
resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597"
|
||||
integrity sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==
|
||||
|
||||
"@vitejs/plugin-vue@^5.0.4":
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz#508d6a0f2440f86945835d903fcc0d95d1bb8a37"
|
||||
integrity sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==
|
||||
"@vitejs/plugin-vue@^5.0.5":
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.0.5.tgz#e3dc11e427d4b818b7e3202766ad156e3d5e2eaa"
|
||||
integrity sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==
|
||||
|
||||
"@vue/compiler-core@3.4.25":
|
||||
version "3.4.25"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.25.tgz#691f59ee5014f6f2a2488fd4465f892e1e82f729"
|
||||
integrity sha512-Y2pLLopaElgWnMNolgG8w3C5nNUVev80L7hdQ5iIKPtMJvhVpG0zhnBG/g3UajJmZdvW0fktyZTotEHD1Srhbg==
|
||||
"@vue/compiler-core@3.4.27":
|
||||
version "3.4.27"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.27.tgz#e69060f4b61429fe57976aa5872cfa21389e4d91"
|
||||
integrity sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.24.4"
|
||||
"@vue/shared" "3.4.25"
|
||||
"@vue/shared" "3.4.27"
|
||||
entities "^4.5.0"
|
||||
estree-walker "^2.0.2"
|
||||
source-map-js "^1.2.0"
|
||||
|
||||
"@vue/compiler-dom@3.4.25":
|
||||
version "3.4.25"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.25.tgz#b367e0c84e11d9e9f70beabdd6f6b2277fde375f"
|
||||
integrity sha512-Ugz5DusW57+HjllAugLci19NsDK+VyjGvmbB2TXaTcSlQxwL++2PETHx/+Qv6qFwNLzSt7HKepPe4DcTE3pBWg==
|
||||
"@vue/compiler-dom@3.4.27":
|
||||
version "3.4.27"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz#d51d35f40d00ce235d7afc6ad8b09dfd92b1cc1c"
|
||||
integrity sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==
|
||||
dependencies:
|
||||
"@vue/compiler-core" "3.4.25"
|
||||
"@vue/shared" "3.4.25"
|
||||
"@vue/compiler-core" "3.4.27"
|
||||
"@vue/shared" "3.4.27"
|
||||
|
||||
"@vue/compiler-sfc@3.4.25":
|
||||
version "3.4.25"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.25.tgz#ceab148f81571c8b251e8a8b75a9972addf1db8b"
|
||||
integrity sha512-m7rryuqzIoQpOBZ18wKyq05IwL6qEpZxFZfRxlNYuIPDqywrXQxgUwLXIvoU72gs6cRdY6wHD0WVZIFE4OEaAQ==
|
||||
"@vue/compiler-sfc@3.4.27":
|
||||
version "3.4.27"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz#399cac1b75c6737bf5440dc9cf3c385bb2959701"
|
||||
integrity sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.24.4"
|
||||
"@vue/compiler-core" "3.4.25"
|
||||
"@vue/compiler-dom" "3.4.25"
|
||||
"@vue/compiler-ssr" "3.4.25"
|
||||
"@vue/shared" "3.4.25"
|
||||
"@vue/compiler-core" "3.4.27"
|
||||
"@vue/compiler-dom" "3.4.27"
|
||||
"@vue/compiler-ssr" "3.4.27"
|
||||
"@vue/shared" "3.4.27"
|
||||
estree-walker "^2.0.2"
|
||||
magic-string "^0.30.10"
|
||||
postcss "^8.4.38"
|
||||
source-map-js "^1.2.0"
|
||||
|
||||
"@vue/compiler-ssr@3.4.25":
|
||||
version "3.4.25"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.25.tgz#7fdd540bfdf2d4a3d6cb107b7ba4c77228d36331"
|
||||
integrity sha512-H2ohvM/Pf6LelGxDBnfbbXFPyM4NE3hrw0e/EpwuSiYu8c819wx+SVGdJ65p/sFrYDd6OnSDxN1MB2mN07hRSQ==
|
||||
"@vue/compiler-ssr@3.4.27":
|
||||
version "3.4.27"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz#2a8ecfef1cf448b09be633901a9c020360472e3d"
|
||||
integrity sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.4.25"
|
||||
"@vue/shared" "3.4.25"
|
||||
"@vue/compiler-dom" "3.4.27"
|
||||
"@vue/shared" "3.4.27"
|
||||
|
||||
"@vue/devtools-api@^7.0.27":
|
||||
version "7.0.27"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-7.0.27.tgz#bfbbfb1d632bdb71b7a9b5e3ed4314dab26a5440"
|
||||
integrity sha512-BFCFCusSDcw2UcOFD/QeK7OxD1x2C/m+uAN30Q7jLKECSW53hmz0urzJmX834GuWDZX/hIxkyUKnLLfEIP1c/w==
|
||||
"@vue/devtools-api@^7.2.1":
|
||||
version "7.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-7.2.1.tgz#1eb3d33c85b76306106d5804bafa0d13178e9224"
|
||||
integrity sha512-6oNCtyFOrNdqm6GUkFujsCgFlpbsHLnZqq7edeM/+cxAbMyCWvsaCsIMUaz7AiluKLccCGEM8fhOsjaKgBvb7g==
|
||||
dependencies:
|
||||
"@vue/devtools-kit" "^7.0.27"
|
||||
"@vue/devtools-kit" "^7.2.1"
|
||||
|
||||
"@vue/devtools-kit@^7.0.27":
|
||||
version "7.0.27"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-kit/-/devtools-kit-7.0.27.tgz#23dfcc70da74291f5ec5456cc8a4644093b6045f"
|
||||
integrity sha512-/A5xM38pPCFX5Yhl/lRFAzjyK6VNsH670nww2WbjFKWqlu3I+lMxWKzQkCW6A1V8bduITgl2kHORfg2gTw6QaA==
|
||||
"@vue/devtools-kit@^7.2.1":
|
||||
version "7.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-kit/-/devtools-kit-7.2.1.tgz#eb4e6726f0f71aa0b9405c847799f75cc86d3d81"
|
||||
integrity sha512-Wak/fin1X0Q8LLIfCAHBrdaaB+R6IdpSXsDByPHbQ3BmkCP0/cIo/oEGp9i0U2+gEqD4L3V9RDjNf1S34DTzQQ==
|
||||
dependencies:
|
||||
"@vue/devtools-shared" "^7.0.27"
|
||||
"@vue/devtools-shared" "^7.2.1"
|
||||
hookable "^5.5.3"
|
||||
mitt "^3.0.1"
|
||||
perfect-debounce "^1.0.0"
|
||||
speakingurl "^14.0.1"
|
||||
|
||||
"@vue/devtools-shared@^7.0.27":
|
||||
version "7.0.27"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-7.0.27.tgz#99d6d64f502110bb4b20a4029029a16ea62ed837"
|
||||
integrity sha512-4VxtmZ6yjhiSloqZZq2UYU0TBGxOJ8GxWvp5OlAH70zYqi0FIAyWGPkOhvfoZ7DKQyv2UU0mmKzFHjsEkelGyQ==
|
||||
"@vue/devtools-shared@^7.2.1":
|
||||
version "7.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-7.2.1.tgz#576c048375ba3c63e555017abbc0b1019a7d4cbe"
|
||||
integrity sha512-PCJF4UknJmOal68+X9XHyVeQ+idv0LFujkTOIW30+GaMJqwFVN9LkQKX4gLqn61KkGMdJTzQ1bt7EJag3TI6AA==
|
||||
dependencies:
|
||||
rfdc "^1.3.1"
|
||||
|
||||
"@vue/reactivity@3.4.25":
|
||||
version "3.4.25"
|
||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.25.tgz#74983b146e06ce3341d15382669350125375d36f"
|
||||
integrity sha512-mKbEtKr1iTxZkAG3vm3BtKHAOhuI4zzsVcN0epDldU/THsrvfXRKzq+lZnjczZGnTdh3ojd86/WrP+u9M51pWQ==
|
||||
"@vue/reactivity@3.4.27":
|
||||
version "3.4.27"
|
||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.27.tgz#6ece72331bf719953f5eaa95ec60b2b8d49e3791"
|
||||
integrity sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==
|
||||
dependencies:
|
||||
"@vue/shared" "3.4.25"
|
||||
"@vue/shared" "3.4.27"
|
||||
|
||||
"@vue/runtime-core@3.4.25":
|
||||
version "3.4.25"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.25.tgz#c5545d469ae0827dc471a1376f97c6ace41081ec"
|
||||
integrity sha512-3qhsTqbEh8BMH3pXf009epCI5E7bKu28fJLi9O6W+ZGt/6xgSfMuGPqa5HRbUxLoehTNp5uWvzCr60KuiRIL0Q==
|
||||
"@vue/runtime-core@3.4.27":
|
||||
version "3.4.27"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.27.tgz#1b6e1d71e4604ba7442dd25ed22e4a1fc6adbbda"
|
||||
integrity sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==
|
||||
dependencies:
|
||||
"@vue/reactivity" "3.4.25"
|
||||
"@vue/shared" "3.4.25"
|
||||
"@vue/reactivity" "3.4.27"
|
||||
"@vue/shared" "3.4.27"
|
||||
|
||||
"@vue/runtime-dom@3.4.25":
|
||||
version "3.4.25"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.25.tgz#9bc195e4860edcd0db4303cbba5a160922b963fd"
|
||||
integrity sha512-ode0sj77kuwXwSc+2Yhk8JMHZh1sZp9F/51wdBiz3KGaWltbKtdihlJFhQG4H6AY+A06zzeMLkq6qu8uDSsaoA==
|
||||
"@vue/runtime-dom@3.4.27":
|
||||
version "3.4.27"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz#fe8d1ce9bbe8921d5dd0ad5c10df0e04ef7a5ee7"
|
||||
integrity sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==
|
||||
dependencies:
|
||||
"@vue/runtime-core" "3.4.25"
|
||||
"@vue/shared" "3.4.25"
|
||||
"@vue/runtime-core" "3.4.27"
|
||||
"@vue/shared" "3.4.27"
|
||||
csstype "^3.1.3"
|
||||
|
||||
"@vue/server-renderer@3.4.25":
|
||||
version "3.4.25"
|
||||
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.25.tgz#6cfc96ee631104951d5d6c09a8f1e7cef3ef3972"
|
||||
integrity sha512-8VTwq0Zcu3K4dWV0jOwIVINESE/gha3ifYCOKEhxOj6MEl5K5y8J8clQncTcDhKF+9U765nRw4UdUEXvrGhyVQ==
|
||||
"@vue/server-renderer@3.4.27":
|
||||
version "3.4.27"
|
||||
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.27.tgz#3306176f37e648ba665f97dda3ce705687be63d2"
|
||||
integrity sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==
|
||||
dependencies:
|
||||
"@vue/compiler-ssr" "3.4.25"
|
||||
"@vue/shared" "3.4.25"
|
||||
"@vue/compiler-ssr" "3.4.27"
|
||||
"@vue/shared" "3.4.27"
|
||||
|
||||
"@vue/shared@3.4.25":
|
||||
version "3.4.25"
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.25.tgz#243ba8543e7401751e0ca319f75a80f153edd273"
|
||||
integrity sha512-k0yappJ77g2+KNrIaF0FFnzwLvUBLUYr8VOwz+/6vLsmItFp51AcxLL7Ey3iPd7BIRyWPOcqUjMnm7OkahXllA==
|
||||
"@vue/shared@3.4.27", "@vue/shared@^3.4.27":
|
||||
version "3.4.27"
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.27.tgz#f05e3cd107d157354bb4ae7a7b5fc9cf73c63b50"
|
||||
integrity sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==
|
||||
|
||||
"@vueuse/core@10.9.0", "@vueuse/core@^10.9.0":
|
||||
version "10.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.9.0.tgz#7d779a95cf0189de176fee63cee4ba44b3c85d64"
|
||||
integrity sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==
|
||||
"@vueuse/core@10.10.0", "@vueuse/core@^10.10.0":
|
||||
version "10.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.10.0.tgz#05a98d3c5674762455a2c552c915d461d83e6490"
|
||||
integrity sha512-vexJ/YXYs2S42B783rI95lMt3GzEwkxzC8Hb0Ndpd8rD+p+Lk/Za4bd797Ym7yq4jXqdSyj3JLChunF/vyYjUw==
|
||||
dependencies:
|
||||
"@types/web-bluetooth" "^0.0.20"
|
||||
"@vueuse/metadata" "10.9.0"
|
||||
"@vueuse/shared" "10.9.0"
|
||||
"@vueuse/metadata" "10.10.0"
|
||||
"@vueuse/shared" "10.10.0"
|
||||
vue-demi ">=0.14.7"
|
||||
|
||||
"@vueuse/integrations@^10.9.0":
|
||||
version "10.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-10.9.0.tgz#2b1a9556215ad3c1f96d39cbfbef102cf6e0ec05"
|
||||
integrity sha512-acK+A01AYdWSvL4BZmCoJAcyHJ6EqhmkQEXbQLwev1MY7NBnS+hcEMx/BzVoR9zKI+UqEPMD9u6PsyAuiTRT4Q==
|
||||
"@vueuse/integrations@^10.10.0":
|
||||
version "10.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-10.10.0.tgz#31f413b88d7ed24213958eba6824d46b2bf71b5f"
|
||||
integrity sha512-vHGeK7X6mkdkpcm1eE9t3Cpm21pNVfZRwrjwwbrEs9XftnSgszF4831G2rei8Dt9cIYJIfFV+iyx/29muimJPQ==
|
||||
dependencies:
|
||||
"@vueuse/core" "10.9.0"
|
||||
"@vueuse/shared" "10.9.0"
|
||||
"@vueuse/core" "10.10.0"
|
||||
"@vueuse/shared" "10.10.0"
|
||||
vue-demi ">=0.14.7"
|
||||
|
||||
"@vueuse/metadata@10.9.0":
|
||||
version "10.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.9.0.tgz#769a1a9db65daac15cf98084cbf7819ed3758620"
|
||||
integrity sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==
|
||||
"@vueuse/metadata@10.10.0":
|
||||
version "10.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.10.0.tgz#53e61e9380670e342cbe6e03d852f3319308cb5b"
|
||||
integrity sha512-UNAo2sTCAW5ge6OErPEHb5z7NEAg3XcO9Cj7OK45aZXfLLH1QkexDcZD77HBi5zvEiLOm1An+p/4b5K3Worpug==
|
||||
|
||||
"@vueuse/shared@10.9.0":
|
||||
version "10.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.9.0.tgz#13af2a348de15d07b7be2fd0c7fc9853a69d8fe0"
|
||||
integrity sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==
|
||||
"@vueuse/shared@10.10.0":
|
||||
version "10.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.10.0.tgz#93f7c2210151ff43c2c7677963f7aa3aef5d9896"
|
||||
integrity sha512-2aW33Ac0Uk0U+9yo3Ypg9s5KcR42cuehRWl7vnUHadQyFvCktseyxxEPBi1Eiq4D2yBGACOnqLZpx1eMc7g5Og==
|
||||
dependencies:
|
||||
vue-demi ">=0.14.7"
|
||||
|
||||
|
@ -668,9 +673,9 @@ perfect-debounce@^1.0.0:
|
|||
integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==
|
||||
|
||||
picocolors@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1"
|
||||
integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==
|
||||
|
||||
postcss@^8.4.38:
|
||||
version "8.4.38"
|
||||
|
@ -682,9 +687,9 @@ postcss@^8.4.38:
|
|||
source-map-js "^1.2.0"
|
||||
|
||||
preact@^10.0.0:
|
||||
version "10.20.2"
|
||||
resolved "https://registry.yarnpkg.com/preact/-/preact-10.20.2.tgz#0b343299a8c020562311cc25db93b3d832ec5e71"
|
||||
integrity sha512-S1d1ernz3KQ+Y2awUxKakpfOg2CEmJmwOP+6igPx6dgr6pgDvenqYviyokWso2rhHvGtTlWWnJDa7RaPbQerTg==
|
||||
version "10.22.0"
|
||||
resolved "https://registry.yarnpkg.com/preact/-/preact-10.22.0.tgz#a50f38006ae438d255e2631cbdaf7488e6dd4e16"
|
||||
integrity sha512-RRurnSjJPj4rp5K6XoP45Ui33ncb7e4H7WiOHVpjbkvqvA3U+N8Z6Qbo0AE6leGYBV66n8EhEaFixvIu3SkxFw==
|
||||
|
||||
rfdc@^1.3.1:
|
||||
version "1.3.1"
|
||||
|
@ -692,35 +697,36 @@ rfdc@^1.3.1:
|
|||
integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==
|
||||
|
||||
rollup@^4.13.0:
|
||||
version "4.14.2"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.14.2.tgz#992df3c3bb4ca84ce6b00d51aacb1e5a62d0a14c"
|
||||
integrity sha512-WkeoTWvuBoFjFAhsEOHKRoZ3r9GfTyhh7Vff1zwebEFLEFjT1lG3784xEgKiTa7E+e70vsC81roVL2MP4tgEEQ==
|
||||
version "4.18.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.18.0.tgz#497f60f0c5308e4602cf41136339fbf87d5f5dda"
|
||||
integrity sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==
|
||||
dependencies:
|
||||
"@types/estree" "1.0.5"
|
||||
optionalDependencies:
|
||||
"@rollup/rollup-android-arm-eabi" "4.14.2"
|
||||
"@rollup/rollup-android-arm64" "4.14.2"
|
||||
"@rollup/rollup-darwin-arm64" "4.14.2"
|
||||
"@rollup/rollup-darwin-x64" "4.14.2"
|
||||
"@rollup/rollup-linux-arm-gnueabihf" "4.14.2"
|
||||
"@rollup/rollup-linux-arm64-gnu" "4.14.2"
|
||||
"@rollup/rollup-linux-arm64-musl" "4.14.2"
|
||||
"@rollup/rollup-linux-powerpc64le-gnu" "4.14.2"
|
||||
"@rollup/rollup-linux-riscv64-gnu" "4.14.2"
|
||||
"@rollup/rollup-linux-s390x-gnu" "4.14.2"
|
||||
"@rollup/rollup-linux-x64-gnu" "4.14.2"
|
||||
"@rollup/rollup-linux-x64-musl" "4.14.2"
|
||||
"@rollup/rollup-win32-arm64-msvc" "4.14.2"
|
||||
"@rollup/rollup-win32-ia32-msvc" "4.14.2"
|
||||
"@rollup/rollup-win32-x64-msvc" "4.14.2"
|
||||
"@rollup/rollup-android-arm-eabi" "4.18.0"
|
||||
"@rollup/rollup-android-arm64" "4.18.0"
|
||||
"@rollup/rollup-darwin-arm64" "4.18.0"
|
||||
"@rollup/rollup-darwin-x64" "4.18.0"
|
||||
"@rollup/rollup-linux-arm-gnueabihf" "4.18.0"
|
||||
"@rollup/rollup-linux-arm-musleabihf" "4.18.0"
|
||||
"@rollup/rollup-linux-arm64-gnu" "4.18.0"
|
||||
"@rollup/rollup-linux-arm64-musl" "4.18.0"
|
||||
"@rollup/rollup-linux-powerpc64le-gnu" "4.18.0"
|
||||
"@rollup/rollup-linux-riscv64-gnu" "4.18.0"
|
||||
"@rollup/rollup-linux-s390x-gnu" "4.18.0"
|
||||
"@rollup/rollup-linux-x64-gnu" "4.18.0"
|
||||
"@rollup/rollup-linux-x64-musl" "4.18.0"
|
||||
"@rollup/rollup-win32-arm64-msvc" "4.18.0"
|
||||
"@rollup/rollup-win32-ia32-msvc" "4.18.0"
|
||||
"@rollup/rollup-win32-x64-msvc" "4.18.0"
|
||||
fsevents "~2.3.2"
|
||||
|
||||
shiki@1.3.0, shiki@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/shiki/-/shiki-1.3.0.tgz#3eda35cb49f6f0a98525e9da48fc072e6c655a3f"
|
||||
integrity sha512-9aNdQy/etMXctnPzsje1h1XIGm9YfRcSksKOGqZWXA/qP9G18/8fpz5Bjpma8bOgz3tqIpjERAd6/lLjFyzoww==
|
||||
shiki@1.6.2, shiki@^1.6.2:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/shiki/-/shiki-1.6.2.tgz#082db563387a94c10e4002e0c62c61bc78e9cae7"
|
||||
integrity sha512-X3hSm5GzzBd/BmPmGfkueOUADLyBoZo1ojYQXhd+NU2VJn458yt4duaS0rVzC+WtqftSV7mTVvDw+OB9AHi3Eg==
|
||||
dependencies:
|
||||
"@shikijs/core" "1.3.0"
|
||||
"@shikijs/core" "1.6.2"
|
||||
|
||||
source-map-js@^1.2.0:
|
||||
version "1.2.0"
|
||||
|
@ -737,10 +743,10 @@ tabbable@^6.2.0:
|
|||
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97"
|
||||
integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
|
||||
|
||||
vite@^5.2.9:
|
||||
version "5.2.9"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.9.tgz#cd9a356c6ff5f7456c09c5ce74068ffa8df743d9"
|
||||
integrity sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==
|
||||
vite@^5.2.12:
|
||||
version "5.2.12"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.12.tgz#3536c93c58ba18edea4915a2ac573e6537409d97"
|
||||
integrity sha512-/gC8GxzxMK5ntBwb48pR32GGhENnjtY30G4A0jemunsBkiEZFw60s8InGpN8gkhHEkjnRK1aSAxeQgwvFhUHAA==
|
||||
dependencies:
|
||||
esbuild "^0.20.1"
|
||||
postcss "^8.4.38"
|
||||
|
@ -748,39 +754,40 @@ vite@^5.2.9:
|
|||
optionalDependencies:
|
||||
fsevents "~2.3.3"
|
||||
|
||||
vitepress@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-1.1.3.tgz#ded22392f5274680aaba8bb81dd4fb1c4741c02e"
|
||||
integrity sha512-hGrIYN0w9IHWs0NQSnlMjKV/v/HLfD+Ywv5QdvCSkiT32mpNOOwUrZjnqZv/JL/WBPpUc94eghTUvmipxw0xrA==
|
||||
vitepress@^1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-1.2.3.tgz#a507d2f5e86c1fbcdb5ec2212f1db4828504df34"
|
||||
integrity sha512-GvEsrEeNLiDE1+fuwDAYJCYLNZDAna+EtnXlPajhv/MYeTjbNK6Bvyg6NoTdO1sbwuQJ0vuJR99bOlH53bo6lg==
|
||||
dependencies:
|
||||
"@docsearch/css" "^3.6.0"
|
||||
"@docsearch/js" "^3.6.0"
|
||||
"@shikijs/core" "^1.3.0"
|
||||
"@shikijs/transformers" "^1.3.0"
|
||||
"@types/markdown-it" "^14.0.1"
|
||||
"@vitejs/plugin-vue" "^5.0.4"
|
||||
"@vue/devtools-api" "^7.0.27"
|
||||
"@vueuse/core" "^10.9.0"
|
||||
"@vueuse/integrations" "^10.9.0"
|
||||
"@shikijs/core" "^1.6.2"
|
||||
"@shikijs/transformers" "^1.6.2"
|
||||
"@types/markdown-it" "^14.1.1"
|
||||
"@vitejs/plugin-vue" "^5.0.5"
|
||||
"@vue/devtools-api" "^7.2.1"
|
||||
"@vue/shared" "^3.4.27"
|
||||
"@vueuse/core" "^10.10.0"
|
||||
"@vueuse/integrations" "^10.10.0"
|
||||
focus-trap "^7.5.4"
|
||||
mark.js "8.11.1"
|
||||
minisearch "^6.3.0"
|
||||
shiki "^1.3.0"
|
||||
vite "^5.2.9"
|
||||
vue "^3.4.23"
|
||||
shiki "^1.6.2"
|
||||
vite "^5.2.12"
|
||||
vue "^3.4.27"
|
||||
|
||||
vue-demi@>=0.14.7:
|
||||
version "0.14.7"
|
||||
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.7.tgz#8317536b3ef74c5b09f268f7782e70194567d8f2"
|
||||
integrity sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==
|
||||
|
||||
vue@^3.4.23, vue@^3.4.25:
|
||||
version "3.4.25"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.25.tgz#e59d4ed36389647b52ff2fd7aa84bb6691f4205b"
|
||||
integrity sha512-HWyDqoBHMgav/OKiYA2ZQg+kjfMgLt/T0vg4cbIF7JbXAjDexRf5JRg+PWAfrAkSmTd2I8aPSXtooBFWHB98cg==
|
||||
vue@^3.4.27:
|
||||
version "3.4.27"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.27.tgz#40b7d929d3e53f427f7f5945386234d2854cc2a1"
|
||||
integrity sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.4.25"
|
||||
"@vue/compiler-sfc" "3.4.25"
|
||||
"@vue/runtime-dom" "3.4.25"
|
||||
"@vue/server-renderer" "3.4.25"
|
||||
"@vue/shared" "3.4.25"
|
||||
"@vue/compiler-dom" "3.4.27"
|
||||
"@vue/compiler-sfc" "3.4.27"
|
||||
"@vue/runtime-dom" "3.4.27"
|
||||
"@vue/server-renderer" "3.4.27"
|
||||
"@vue/shared" "3.4.27"
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
home-key {
|
||||
label = "home";
|
||||
linux,code = <BTN_MODE>;
|
||||
linux,code = <KEY_HOMEPAGE>;
|
||||
press-threshold-microvolt = <890000>;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue