188 Commits

Author SHA1 Message Date
YC酱luyancib
4301d1dc5d kernel(lsm_hooks):fix misding __init (#641) 2025-11-30 10:21:58 +08:00
AlexLiuDev233
36d803a92a kernel: fix build (#633) 2025-11-28 18:02:24 +08:00
AlexLiuDev233
3a12bdead1 kernel: Add nuke_ext4_sysfs interface (#632)
Co-authored-by: weishu <twsxtd@gmail.com>
2025-11-27 18:44:01 +05:30
F640
57e3c095be include objsec.h unconditonally (#618) 2025-11-26 20:33:30 +08:00
backslashxx
3510203fa6 kernel: expose umount list to ioctl interface (#2950)
This idea is borrowed from simonpunk's susfs4ksu.
What we see here is that, yeah well, lets just have userspace send us
what it
wants unmounted, this is better than hardcoding everything.

This also solves that issue where MNT_DETACH fails, as long as we send
unmountables in proper order.

A small anti-duplicate mechanism is also added.

While in-kernel umount is a bit worse than zygisk-provider-based ones,
this can still
serve as a healthy alternative.

---------

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-authored-by: weishu <twsxtd@gmail.com>
Signed-off-by: fc5b87cf <rissu.ntk@gmail.com>
2025-11-18 23:13:27 +08:00
F640
2aa0034695 fix compile on nongki branch (#602)
* fix compile

* revert some edits
2025-11-18 23:07:00 +08:00
fc5b87cf
7782c00275 kernel: handle seccomp_filter_release compat (#203)
* It's actually very excessive that we provide this thing
- Stale: https://github.com/rsuntk/KernelSU/pull/199

Signed-off-by: TwinbornPlate75 <3342733415@qq.com>
Signed-off-by: fc5b87cf <rissu.ntk@gmail.com>
Co-authored-by: TwinbornPlate75 <3342733415@qq.com>
2025-11-18 15:21:50 +08:00
fc5b87cf
dc3de58aa6 kernel: fix compatibility with 5.10
Signed-off-by: fc5b87cf <rissu.ntk@gmail.com>
2025-11-18 15:20:43 +08:00
fc5b87cf
83db28b262 kernel: add close_fd helper, debloat dmesg log
Signed-off-by: fc5b87cf <rissu.ntk@gmail.com>
2025-11-18 15:20:35 +08:00
backslashxx
6e44090e57 RELAND: kernel: throne_tracker: always cleanup
sometimes crowning fails especially when you replace managers.
it is likely due to using different manager hashes. this will
initialize this dynamically and then clear out unconditionally,
manager or not, to try avoid stale data.

while that is a good thing, this will cause a lot of repetetive
work, especially when nothing is crowned.

but ehh, I'd take the reliability and simplicity.

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: fc5b87cf <rissu.ntk@gmail.com>
2025-11-18 15:19:13 +08:00
fc5b87cf
c93cf58f48 kernel: Syncronize upstream changes (#198)
* Cherry-picked range: (kernel)
ebea31daa8..6915b62b9a

* Also merged unmerged pr:
https://github.com/tiann/KernelSU/pull/ 2909

Co-authored-by: Ylarod <me@ylarod.cn>
Co-authored-by: 5ec1cff <56485584+5ec1cff@users.noreply.github.com>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-authored-by: u9521 <63995396+u9521@users.noreply.github.com>
Co-authored-by: Wang Han <416810799@qq.com>
2025-11-17 20:57:05 +08:00
ShirkNeko
edeff936ce kernel: fix build 2025-11-11 18:25:21 +08:00
AlexLiuDev233
d918e016bc fix: fix 5.0- users can't build (#551)
my mistake, forget old kernel's access_ok has 3 params,
so i switch to ksu_access_ok
2025-11-11 15:49:37 +08:00
Faris
a4d642bf50 kernel: fix log typo
Signed-off-by: Faris <rissu.ntk@gmail.com>
2025-11-11 15:39:22 +08:00
Wang Han
d36371580b kernel: add missing kfree, use proper return code
* This is half picked from 559be41482
* We haven't sync latest upstream changes yet

Signed-off-by: Faris <rissu.ntk@gmail.com>
2025-11-11 15:39:15 +08:00
Faris
a2211e2909 kernel, manager: Track upstream changes (#195)
* These commits are carefully picked from upstream (tiann/KernelSU)

- Picked range:
8c5f485f27..e5f43a3427

Signed-off-by: Faris <rissu.ntk@gmail.com>
Co-authored-by: Wang Han <416810799@qq.com>
Co-authored-by: TwinbornPlate75 <3342733415@qq.com>
Co-authored-by: KOWX712 <leecc0503@gmail.com>
Co-authored-by: Ylarod <me@ylarod.cn>
Co-authored-by: YuKongA <70465933+YuKongA@users.noreply.github.com>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-authored-by: 5ec1cff <56485584+5ec1cff@users.noreply.github.com>
Co-authored-by: weishu <twsxtd@gmail.com>
2025-11-11 15:38:53 +08:00
ShirkNeko
00ea078da7 kernel: Remove redundant #if __SULOG_GATE 2025-11-11 15:21:21 +08:00
ShirkNeko
25e5c0aacb kernel & ksud: Syncronize changes from upstreams 2025-11-08 21:56:32 +08:00
Faris
d22f1bdcc4 kernel: add missing goto
Signed-off-by: Faris <rissu.ntk@gmail.com>
2025-11-08 21:53:31 +08:00
Faris
a473707c10 kernel: fix anon_get_inode_* compat
* Yes, we don't have fancy secure fd thing on older kernels.

Signed-off-by: Faris <rissu.ntk@gmail.com>
2025-11-08 21:53:21 +08:00
5ec1cff
cc0dfc44ac kernel: fdwrapper: use anon_inode_getfd_secure to make new inode
Signed-off-by: Faris <rissu.ntk@gmail.com>
2025-11-08 21:53:09 +08:00
Faris
f87c4e077a kernel: pass arg variable
Signed-off-by: Faris <rissu.ntk@gmail.com>
2025-11-08 21:50:03 +08:00
Faris
76ca0050a7 kernel: Add header guard and support Official KernelSU fd wrapper
* Based on unmerged pull-request
https://github.com/tiann/KernelSU/pull/ 2285

Co-authored-by: Ylarod <me@ylarod.cn>
Signed-off-by: Faris <rissu.ntk@gmail.com>
2025-11-08 21:49:47 +08:00
ShirkNeko
2f2d6aeecf kernel: bump KPM version
Co-authored-by: AlexLiuDev233 <wzylin11@outlook.com>
Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
2025-11-08 18:33:36 +08:00
ShirkNeko
f6657fdbfd clean 2025-11-08 12:54:13 +08:00
Azyr Ruthless
5782afe481 kernel: add __poll_t compat for pre-4.16 and backported kernels (#194)
__poll_t was introduced in v4.16-rc1. Add Makefile header check to detect and provide fallback for older kernels and those with backports.

Signed-off-by: AzyrRuthless <azyrruthless@tutamail.com>
2025-11-08 12:11:35 +08:00
Faris
2ab373d146 kernel: Clean up mess
Signed-off-by: Faris <rissu.ntk@gmail.com>
2025-11-08 12:11:29 +08:00
Faris
eba286ef7e kernel: fix redeclared __poll_t
* Probably useful in Ultra-Legacy kernel.

Signed-off-by: Faris <rissu.ntk@gmail.com>
2025-11-08 12:10:54 +08:00
ShirkNeko
2a89159a3d fix build 2025-11-08 12:10:12 +08:00
Faris
29c6e2dbcc kernel, ksud: clean headers and add fd wrapper for devpts (#193)
* Now Official KernelSU devpts compat is questionable
Squashed commits:
4893fad235
e7c3d4a6a6
4bb2dae3f5

Signed-off-by: Faris <rissu.ntk@gmail.com>
Co-authored-by: 5ec1cff <56485584+5ec1cff@users.noreply.github.com>
Co-authored-by: weishu <twsxtd@gmail.com>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-11-08 12:08:54 +08:00
Faris
968c3f7d57 kernel: sepolicy: fix incompatible pointer type
Signed-off-by: Faris <rissu.ntk@gmail.com>
2025-11-08 11:54:22 +08:00
Faris
a8cdd014dc kernel: fix wrong non-kprobe sucompat handler
* Oops, i should read the code correctly..

Signed-off-by: Faris <rissu.ntk@gmail.com>
2025-11-08 11:54:05 +08:00
Faris
4d7dd32b11 kernel: selinux: Use switch-case instead of if-else
Signed-off-by: Faris <rissu.ntk@gmail.com>
2025-11-08 11:51:45 +08:00
Fanuel Berhanu
97b57de3d0 Update sucompat.c (#535) 2025-11-08 01:42:43 +08:00
ShirkNeko
c53cb0afb1 fix 2025-11-08 01:22:31 +08:00
Ylarod
699852009c ksud, kernel: fix sepolicy patch hint (#2872) 2025-11-07 17:30:08 +08:00
ShirkNeko
a8302120c4 fix 2025-11-07 17:28:13 +08:00
ShirkNeko
8d535fa03a kernel: Resolve compilation errors 2025-11-06 04:07:43 +08:00
ShirkNeko
2b97c77a6d Use a more appropriate minor version number 2025-11-06 03:56:52 +08:00
ShirkNeko
68f3be2cbe kernel, ksud, manager: New supercalls implementations
* This commit squashes new supercall impl:
3138651a38..562a3b9be7

Thanks to these people below:

Official KernelSU:
Co-authored-by: Wang Han <416810799@qq.com>
Co-authored-by: weishu <twsxtd@gmail.com>
Co-authored-by: Ylarod <me@ylarod.cn>
Co-authored-by: YuKongA <70465933+YuKongA@users.noreply.github.com>

xxKSU maintainer:
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
MMRL maintainer:
Co-authored-by: Der_Googler <54764558+dergoogler@users.noreply.github.com>
KSUN maintainer:
Co-authored-by: Rifat Azad <33044977+rifsxd@users.noreply.github.com>
KOWSU maintainer:
Co-authored-by: KOWX712 <leecc0503@gmail.com>
2025-11-06 03:54:44 +08:00
ShirkNeko
c55a918957 Kernel(Makefile): Add KSU_SRC to set path correctly #483
try Fix version define for 6.12 Kernel

Co-authored-by: YC酱luyancib <luyancib@qq.com>
2025-10-21 16:38:59 +08:00
Sultan Alsawaf
3cdb8fd057 kernel: Fix kernel panics caused by thread info flag corruption
Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com>
2025-10-21 16:38:53 +08:00
ShirkNeko
2fdb933acc Kernel: Add support for 6.12
Filtered from tiann/KernelSU #2793

Co-authored-by: libingxuan <84086386+aaaaaaaa-815@users.noreply.github.com>
2025-10-08 15:00:44 +08:00
ShirkNeko
cd05d49a7a kernel: Simplified Logic 2025-10-08 14:37:25 +08:00
unknow-tech
bcb38274f9 Add support for 6.13 (#454)
Fiz issue https://github.com/SukiSU-Ultra/SukiSU-Ultra/issues/364

cdd30ebb1b
2025-10-08 14:34:59 +08:00
backslashxx
1f468f35f4 kernel: align prctl harden commit from backslashxx/KernelSU
SQUASHED:
* kernel: harden barriers for arm/arm64
* kernel: core_hook: harden prctl handler

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-10-07 16:50:37 +08:00
rsuntk
1d4d23d2c9 kernel: add guard for avoiding LKM being builded on Linux 6.8+
* Due to numerous changes on LSM (Linux Security Module) in Linux 6.8+
* This is temporary guard until a working solution exist.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-10-07 16:50:01 +08:00
rsuntk
994999c8ce kernel: refine prctl harden
* I am not sure if this gonna defeats the main purpose or not,
but it fix prctl issue.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-10-07 16:49:52 +08:00
Faris
f05b20dbce [skip ci] kernel: restore original from_root logic 2025-10-07 16:48:56 +08:00
backslashxx
6af2da13ae kernel: migrate barriers to spec barriers and code style thing
overkill, but yeah, might as well move on to the real deal.

[ rsuntk: Rename original variable name ]
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-10-07 16:48:38 +08:00
Huy Minh
fd8e3c35bb kernel: add initial 6.8+/6.14 kernel support
* This is a squashed of un-merged pull requests of Official KernelSU
* LKM support are not available.
* Require this additional patch to avoid kernel panic because of "Too many LSMs registered":
7042991a5c

* Un-merged pull requests of Official KernelSU:
https://github.com/tiann/KernelSU/pull/1785
https://github.com/tiann/KernelSU/pull/2662

* This commit probably not 100% completed.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-10-07 16:47:46 +08:00
rsuntk
04586ccb96 kernel: make apk_sign_key as a typedef instead
Style preference.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-10-07 16:47:34 +08:00
backslashxx
b537b957bd kernel: harden prctl check
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-10-07 16:46:04 +08:00
rifsxd
c02b42d7de kernel: handle throned UID change if manager is reinstall or changed
drop old UID and throne the new one when the manager is reinstalled or changed

- Add dynamic manager lock

Co-authored-by: rifsxd <rifat.44.azad.rifs@gmail.com>
Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
2025-10-07 00:06:47 +08:00
Natsume324
3f4293e69a Fixed an error in the SukiSU integration of the Kirin 970 HarmonyOS2 kernel source code:
- Error: In the Kirin 970 HarmonyOS2 kernel source code, integrating SukiSU requires disabling the CONFIG_HKIP_SELINUX_PROT configuration option. Disabling this option will enable the use of flex_array. However, in the add_type and add_typeattribute_raw functions in kernel/selinux/sepolicy.c, if a Huawei HISI device is detected, ebitmap not flex_array is used, causing an error.

- Fix: Added conditional checks to the add_type and add_typeattribute_raw functions in kernel/selinux/sepolicy.c. Because the Kirin 970 EMUI10 kernel source code does not use flex_array, an option defined only in the EMUI10 kernel configuration is added to determine the kernel source code version.
2025-10-02 01:18:57 +08:00
ShirkNeko
8943bab810 kernel: Revert partial changes 2025-09-27 23:02:40 +08:00
ShirkNeko
99898203a3 kernel: fmt ,optimization Log 2025-09-27 21:11:05 +08:00
ShirkNeko
27fba0d48b kernel: Use the prctl command to provide switches for scanning functionality in user space 2025-09-27 19:41:31 +08:00
ShirkNeko
07320d9e11 bump KSU_VERSION_API to 3.2.0 2025-09-24 22:35:59 +08:00
ShirkNeko
90611232ed kernel: Bump tracepoint_hooks to version v1.1
Remove `devpts_hook` and `execveat_hook` from `tracepoint_hooks`
2025-09-24 22:03:22 +08:00
ShirkNeko
868b1e655f Revert "kernel: throne_tracker: offload to kthread tiann #2632"
This reverts commit 86ccca18eb.
2025-09-24 16:26:08 +08:00
backslashxx
f7d055c9e1 pullout envp 2025-09-24 16:22:02 +08:00
backslashxx
c63186cad2 move debug back up 2025-09-24 16:21:52 +08:00
ShirkNeko
86ccca18eb kernel: throne_tracker: offload to kthread tiann #2632
Run throne_tracker() in kthread instead of blocking the caller.
Prevents full lockup during installation and removing the manager.

By default, first run remains synchronous for compatibility purposes
(FDE, FBEv1, FBEv2)

Features:
- looks and waits for manager UID in /data/system/packages.list
- run track_throne() in a kthread after the first synchronous run
- prevent duplicate thread creation with a single-instance check
- spinlock-on-d_lock based polling adressing possible race conditions.

Race conditions adressed
- single instance kthread lock, smp_mb()
- track_throne_function, packages.list, spinlock-on-d_lock based polling
- is_manager_apk, apk, spinlock-on-d_lock based polling

This is a squash of:
https://github.com/tiann/KernelSU/pull/2632

Original skeleton based on:
`kernelsu: move throne_tracker() to kthread`
`kernelsu: check locking before accessing files and dirs during searching manager`
`kernelsu: look for manager UID in /data/system/packages.list, not /data/system/packages.list.tmp`
0b05e927...8783badd

Co-Authored-By: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-Authored-By: Yaroslav Zviezda <10716792+acroreiser@users.noreply.github.com>
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-09-24 01:50:49 +08:00
ShirkNeko
23dde3f863 kernel: sys_execve bprm simplified
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-09-23 23:53:48 +08:00
ShirkNeko
4a5119a80c kernel ksud: Attempt registration with bprm_check_kp first. If it fails, fall back to sys_execve_kp.
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
2025-09-23 17:26:24 +08:00
ShirkNeko
f0fec48050 kernel: Add the missing endif 2025-09-23 00:08:00 +08:00
ShirkNeko
b4bdd17e4e kernel: core_hook: intercept devpts via security_inode_permission LSM
`ksu handles devpts with selinux lsm hook` - aviraxp

- no, not yet, but yes we can, thats a good idea.

This change tries to do that, so instead of hooking pts_unix98_lookup or
devpts_get_priv, we just watch security_inode_permission, if its devpts,
pass it along to the original handler.

EDIT: define devpts super magic if its undefined
- yeah I aint gonna include a conditional include of a header just for this
- while we can just fully remove the macro and inline, readability loss is bad

Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-09-22 23:54:51 +08:00
ShirkNeko
de92cc4bad kernel: selinux: fix pointer mismatch with 32-bit ksud on 64-bit kernels
Since KernelSU Manager can now be built for 32-bit, theres this problematic
setup where userspace is 32-bit (armeabi-v7a) and kernel is 64bit (aarch64).

On 64-bit kernels with CONFIG_COMPAT=y, 32-bit userspace passes 32-bit pointers.
These values are interpreted as 64-bit pointers without proper casting and that
results in invalid or near-null memory access.

This patch adds proper compat-mode handling with the ff changes:
- introduce a dedicated struct (`sepol_compat_data`) using u32 fields
- use `compat_ptr()` to safely convert 32-bit user pointers to kernel pointers
- adding a runtime `ksu_is_compat` flag to dynamically select between struct layouts

This prevents a near-null pointer dereference when handling SELinux
policy updates from 32-bit ksud in a 64-bit kernel.

Truth table:

kernel 32 + ksud 32, struct is u32, no compat_ptr
kernel 64 + ksud 32, struct is u32, yes compat_ptr
kernel 64 + ksud 64, struct is u64, no compat_ptr

Preprocessor check

64BIT=y COMPAT=y: define both structs, select dynamically
64BIT=y COMPAT=n: struct u64
64BIT=n: struct u32

Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-09-22 23:34:19 +08:00
backslashxx
d288b8f24f ksud: migrate ksud execution to security_bprm_check (tiann#2653)
This migrates ksud execution decision-making to bprm_check_security.
This requires passing proper argv and envp to a modified _ksud handler
aptly named 'ksu_handle_bprm_ksud'.

Introduces:
int ksu_handle_bprm_ksud(const char *filename, const char *argv1,
const char *envp, size_t envp_len)

which is adapted from:
int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
struct user_arg_ptr *argv,
struct user_arg_ptr *envp,
int *flags)

ksu_handle_bprm_ksud handles all the decision making, it decides when it is
time to apply_kernelsu_rules depending if it sees "second_stage".

For LSM hook, turns out we can pull out argv and envp from mm_struct.
The code in here explains itself on how to do it.

whole blob exists on arg_start to arg_end, so we just pull it out and grab next
array after the first null terminator.

as for envp, we pass the pointer then hunt for it when needed

My reasoning on adding a fallback on usercopy is that on some devices a fault
happens, and it copies garbled data. On my creation of this, I actually had to lock
that _nofault copy on a spinlock as a way to mimic preempt_disable/enable without
actually doing it. As per user reports, no failed _nofault copies anyway but we
have-to-have a fallback for resilience.

References:
- old version1 6efcd8193e
- old version2 37d5938e66
- bad usercopy #21

This now provides a small helper function, ksu_copy_from_user_retry, which explains
itself. First we attempt a _nofault copy, if that fails, we try plain.

With that, It also provides an inlined copy_from_user_nofault for < 5.8.

While using strncpy_from_user_nofault was considered, this wont do, this will
only copy up to the first \0.

devlog:
16e5dce9e7...16c1f5f521
28642e60d7...728de0c571

References:
https://elixir.bootlin.com/linux/v4.14.1/source/include/linux/mm_types.h#L429
https://elixir.bootlin.com/linux/v4.14.1/source/include/linux/lsm_hooks.h

Stale: https://github.com/tiann/KernelSU/pull/2653

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-09-22 23:21:47 +08:00
ShirkNeko
1b732f62e8 kernel: Added legacy throne tracker support, using packages.list to scan application UIDs 2025-09-21 17:37:43 +08:00
JackAltman
36742cc17e feat: detect proc_ops support via header parsing instead of version check. (#411)
Some kernels (e.g. 5.4 with backports) include proc_ops despite being
older than 5.6.0. Replace hardcoded version check with runtime header
detection to handle these cases.

- Check for "struct proc_ops" in include/linux/proc_fs.h
- Use KSU_COMPAT_HAS_PROC_OPS macro for conditional compilation
- Fixes build failures on kernels with backported proc_ops

Signed-off-by: JackAltman
2025-09-20 13:31:18 +08:00
ShirkNeko
3a61da7f45 Add vfs_getattr compatibility for kernels < 4.14
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
2025-09-20 13:24:29 +08:00
ShirkNeko
fb7901b7fe kernel: Use /data/user_de/ for rollback instead of packages.list 2025-09-19 21:05:18 +08:00
ShirkNeko
9b96f853e9 Kernel: Improved throne communication module for user space UID rescan 2025-09-18 22:58:01 +08:00
TwinbornPlate75
bcdbb1e877 kernel/throne_tracker: Fix mismerge in commit d0c3c2a (#405) 2025-09-18 17:31:26 +08:00
rsuntk
cc8cf28cbc kernel: handle optional backport for selinux_inode
* For supporting kernel 4.19 with 5.10 bpf backports.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-09-12 14:41:31 +08:00
ShirkNeko
d0c3c2ada2 kernel: Add the real UID by parsing the UID from the /data/user_de/0/[app] directory
Prioritize retrieving the application UID from /data/user_de. If this fails, fall back to retrieving it from packages.list.

Fix unstable application UID acquisition

Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
2025-09-12 14:02:35 +08:00
ShirkNeko
ed3536d5fd kernel: Reworking Dynamic Manager Index Configuration 2025-09-06 15:21:21 +08:00
rsuntk
a7efaf6b93 kernel: remove unused ifdef
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-09-04 16:08:43 +08:00
rsuntk
856bbf79d0 kernel: stop intercepting devpts inode permission via LSM
* Somehow, it just does not work properly. (sometimes)

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-09-04 16:07:06 +08:00
rsuntk
c19b025767 kernel: return the value of ksu_sys_umount
* Potentially causing compilation error?

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-09-02 14:53:29 +08:00
rsuntk
1294bbe853 kernel: fix -Wstrict-prototypes warnings/errors
* On newer kernel for some reason -Wno-strict-prototypes still does not fix the errors or warnings.
* To fix it, we just need to add void type.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-09-02 14:51:06 +08:00
dabao1955
a670b82bb6 kernel: Removs extra strip for hook choice (#361)
* kernel: Removs extra strip for hook choice

extra changes for #353

* kernel: Fix Makefile
2025-08-28 10:20:09 +08:00
Prslc
d17960d9ec kernel: define ksu_core_exit() for <4.1 devices without LSM hooks (#360)
* kernel: define ksu_core_exit() for <4.1 devices without LSM hooks

Ensure ksu_core_exit() is defined even if CONFIG_KSU_LSM_SECURITY_HOOKS
is disabled, which is mostly relevant for kernels 4.1 and older, preventing
build failures due to missing exit function.

Signed-off-by: Prslc <prslc113@gmail.com>

* kernel: consolidate ksu_core_exit() definition

Move ksu_core_exit() out of the CONFIG_KSU_LSM_SECURITY_HOOKS
conditional branches to remove redundant empty definitions
and ensure the exit function is always available.

Signed-off-by: Prslc <prslc113@gmail.com>

---------

Signed-off-by: Prslc <prslc113@gmail.com>
2025-08-28 10:16:41 +08:00
ShirkNeko
7177a48678 Remove references to ksu_creds.h 2025-08-27 15:22:27 +08:00
backslashxx
06bf44de11 kernel: micro-opt escape_to_root
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-27 15:16:06 +08:00
rsuntk
98d543e989 kernel: nuke creds wrapper
* Little bit complicated, so let's remove it.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-27 15:15:17 +08:00
ShirkNeko
8ca2a25535 kernel: Remove the ksu_ prefix from the dynamic manager signature. 2025-08-25 20:14:22 +08:00
ShirkNeko
77c2ae72d6 kernel: Rename dynamic_sign_user_config to dynamic_manager_user_config 2025-08-24 11:57:45 +08:00
ShirkNeko
e24c09acbd kernel: Bump KSU_VERSION_API to 3.1.9 2025-08-24 11:46:20 +08:00
dabao1955
2ab242a209 kernel: Remove unnecessary strip in CONFIG_KSU_TRACEPOINT_HOOK check (#353)
The 'strip' function is redundant when checking Kconfig variables, as
values from CONFIG options (like CONFIG_KSU_TRACEPOINT_HOOK) are already
trimmed and do not contain leading/trailing whitespace.

Simplify the condition for better readability and maintainability:
  - Remove unnecessary $(strip ...)
  - Add consistent spacing around the comma

This change aligns with kernel Makefile conventions and improves code clarity
without altering behavior.

Signed-off-by: dabao1955 <dabao1955@163.com>
2025-08-24 11:42:43 +08:00
ShirkNeko
605ef68b3a kernel: Modified dynamic signature All files have been renamed to the correct names: Dynamic Manager 2025-08-24 11:22:54 +08:00
rsuntk
a184dcf165 kernel: address -Wunused-but-set-variable
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-23 16:55:28 +08:00
Helium_Studio
ce58519e66 kernel: Reformat code using clang-format (#347)
* The coding format is too messy, reformat to improve readability
  and get closer to Linux kernel coding style.

* While at it, update .clang-format file to linux-mainline state.
2025-08-22 14:02:20 +08:00
rsuntk
fe472057b1 kernel: guard path_umount logging
* path_umount pretty much guaranteed to work as is, so it would not need
  much logging.

Unlike sys_umount which is an alternative to path_umount for older kernel, so, sys_umount need constant logging.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-22 11:40:33 +08:00
rsuntk
a17cd29e7a kernel: handle spinlock from escape_to_root
* Likely fix the freeze in a few kernel version.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-21 13:04:55 +08:00
backslashxx
210f61949f kernel: apk_sign: fix return check for ksu_sha256
upstream used IS_ERR to check for negative return and that is int,
so correct it.

This is one headache for old compilers.

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-08-21 13:04:34 +08:00
rsuntk
5c7241da31 kernel: remove unnecessary logging in disable_seccomp
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-21 13:03:50 +08:00
ShirkNeko
2fb7bde2d9 Kernel: Improved permission tracking logic when dynamic signature manager existence checks are enabled
- Fixed a panic issue caused by repeated scans in certain cases where dynamic signatures were not enabled
2025-08-19 18:11:34 +08:00
ShirkNeko
14b3449af2 kernel: refactor APK signature verification functions for clarity and efficiency 2025-08-17 23:11:22 +08:00
ShirkNeko
351dc15d08 Fix lld link ksu_current_uid problem 2025-08-16 14:34:51 +08:00
M. Faris
ff6a68221f kernel: add wrapper for creds, refine disable_seccomp, revert some changes (#131)
1. Wrapper for creds:
* Some older kernel does not have {.val}, so, for nicer compatibility support and clean code,
make some wrapper for credential use.
* After this change, do not use current_uid().val, instead, use ksu_current_uid(). For more
info, check kernel/include/ksu_creds.h.

2. Refine disable_seccomp (need to add k6.11+ support)
https://github.com/tiann/KernelSU/pull/2708
https://github.com/tiann/KernelSU/issues/2706

3. Revert "Handle unmount for isolated process correctly"
Reason: https://github.com/tiann/KernelSU/pull/2696#issuecomment-3181866301

4. consolidate most of the gaps

Co-authored-by: Wang Han <416810799@qq.com>
2025-08-16 13:11:58 +08:00
rsuntk
665091f37d kernel: selinux: dontaudit untrusted_app su dir { getattr }
* Following the advice that was given by member in rksu group, by replacing ALL to untrusted_app.

$ /system/bin/stat /proc/1
Result:
08-15 14:57:54.370 20062 20062 W stat    : type=1400 audit(0.0:9564): avc:  denied  { getattr } for  path="/proc/1" dev="proc" ino=12308 scontext=u:r:untrusted_app_27:s0:c27,c258,c512,c768 tcontext=u:r:init:s0 tclass=dir permissive=0 app=com.termux
(issue
438bd5fd6d (commitcomment-163785768))

Test: Checker pass.

* Any issue? Let me know.

Tested-by: rsuntk <rsuntk@yukiprjkt.my.id>
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-16 12:45:04 +08:00
rsuntk
963717e000 Revert "kernel: selinux: dontaudit * su dir getattr"
* Maybe there's much better solution than this.

This reverts commit 438bd5fd6dac74ba63ef627124f0d2f552b1cb31.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-16 12:44:55 +08:00
rsuntk
deed7a7903 kernel: move some defs to single file
* Much cleaner code, although setenforce is not used anymore
* Guard is_ksu_transition only for 4.19 and under.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-16 12:44:41 +08:00
ShirkNeko
68f2f5a0ae kernel: Introducing Tracepoint Hook Type Support
Tracepoint is a predefined hook point in the kernel, compared to Kprobe,
it is more stable and has lower performance overhead, although compatibility
is relatively poor, it is still worth trying

By the way, we have also included the config definitions related to hook types
in Kconfig, to enhance cleanliness

Improve and merge types that do not require hooks

Introducing the hook type prctl

These patches is based on backslashxx/KernelSU#5

Co-authored-by: Cloud_Yun <1770669041@qq.com>
Co-authored-by: Prslc <prslc113@gmail.com>
Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>

Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
2025-08-14 22:19:07 +08:00
rsuntk
3a5bcb0e09 kernel: selinux: dontaudit * su dir getattr
* Likely a detection point for newer android.

* I am not sure about this, but a module try to address this: https://github.com/aviraxp/ZN-AuditPatch

* Need more testing.

Suggested-by: fatalcoder524 <11532648+fatalcoder524@users.noreply.github.com>
Tested-by: rsuntk <rsuntk@yukiprjkt.my.id>
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-10 18:03:02 +08:00
rsuntk
441d06b065 kernel: fix mismerge
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-10 18:02:52 +08:00
Wang Han
347ffa389e kernel: Handle unmount for isolated process correctly
Isolated processes can be directly forked from zygote, but current code doesn't handle it well. Fix it by unmounting unconditionally if isolated process is forked from zygote.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-10 18:02:41 +08:00
Tashfin Shakeer Rhythm
157df04c8b kernel: selinux: rules: Remove unnecessary RCU dereference in get_policydb()
get_policydb() uses rcu_dereference() to read pointers to selinux_state.policy.
But in the SELinux implementation, these pointers are assigned once during
initialization and never changed with rcu_assign_pointer(), rendering the
rcu_dereference() call in get_policydb() completely useless. This just adds
unwanted overhead and implies concurrency pattern that is not even present in
the kernel.

Therefore, read the pointers directly since it's safe.

* selinux_state.ss needs more context.

Signed-off-by: Tashfin Shakeer Rhythm <tashfinshakeerrhythm@gmail.com>
2025-08-10 18:02:29 +08:00
Tashfin Shakeer Rhythm
8eb2c79471 kernel: selinux: rules: Fix illegal RCU lock usage in handle_sepolicy()
Currently, handle_sepolicy() holds an RCU read lock across the entire
function including calls to strncpy_from_user() which can sleep, which
is illegal in RCU semantics.

This triggers the following warning when the kernel is compiled with
CONFIG_DEBUG_ATOMIC_SLEEP enabled:

[    8.526345] BUG: sleeping function called from invalid context at lib/strncpy_from_user.c:40
[    8.526349] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 683, name: ksud
[    8.526351] preempt_count: 0, expected: 0
[    8.526352] RCU nest depth: 1, expected: 0
[    8.526354] 1 lock held by ksud/683:
[    8.526355] #0: ffffffe013e1b970 (rcu_read_lock){....}, at: handle_sepolicy+0xe4/0xaa0
[    8.526365] CPU: 6 PID: 683 Comm: ksud Tainted: G        W         5.4.289-Scarlet-v2.2-beta2 #1
[    8.526366] Hardware name: redwood based Qualcomm Technologies, Inc. SM7325 (DT)
[    8.526367] Call trace:
[    8.526371] dump_backtrace+0x0/0x1c0
[    8.526374] dump_stack+0x90/0xcc
[    8.526376] __might_sleep+0x1a0/0x200
[    8.526378] __might_fault+0x28/0x40
[    8.526381] strncpy_from_user+0xac/0x300
[    8.526383] handle_sepolicy+0x588/0xaa0
[    8.526385] ksu_handle_prctl+0x368/0xd60
[    8.526386] ksu_task_prctl+0xc/0x20
[    8.526389] security_task_prctl+0x5c/0xa0
[    8.526391] __arm64_sys_prctl+0x58/0x7e0
[    8.526393] do_el0_svc+0x68/0x120
[    8.526394] el0_sync_handler+0x11c/0x1c0
[    8.526395] el0_sync+0x140/0x180

To fix this, replace the rcu_read_lock() with the `ksu_rules` mutex_lock()
introduced with commit 9014c663d1eb4 ("kernel: selinux: rules: Fix illegal RCU
lock usage in apply_kernelsu_rules()") which allows sleeping.

This mutex_lock() ensures mutual exclusion between threads invoking dynamic
policy modifications via handle_sepolicy() and those applying KernelSU rules
via apply_kernelsu_rules(), both of which access the policydb structure through
get_policydb().

Signed-off-by: Tashfin Shakeer Rhythm <tashfinshakeerrhythm@gmail.com>
2025-08-10 18:02:12 +08:00
rsuntk
78a95ae82b kernel: selinux: replace rcu_read_{lock, unlock} to mutex_{lock, unlock}
* We got a splat related to atomic sleep.
* The trace is from strncpy_from_user and might_fault

Same case:
e47115e009

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-10 18:01:58 +08:00
Prslc
a7b9b4c390 kernel(kpm): Fix typo in printk logs (#311)
Signed-off-by: Prslc <prslc113@gmail.com>
2025-08-10 17:59:58 +08:00
rsuntk
f63dbca3fa kernel: rename sh to ksud_path
* Questionable naming.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-03 23:01:15 +08:00
rsuntk
672041b4d6 kernel: Replace ksu_access_ok with macro
Signed-off-by: rsuntk <rissu.ntk@gmail.com>
2025-08-03 23:01:04 +08:00
rsuntk
0c87765958 kernel: increase reliability, add ksu_access_ok to simplify
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-03 23:00:42 +08:00
rsuntk
39811e311f kernel: fixup sucompat
* For whatever reason, sh is ksud.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-03 23:00:17 +08:00
rsuntk
cf50966952 kernel: rename ksu_common_ksud_execve to ksu_ksud_execve_common
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-03 23:00:08 +08:00
rsuntk
da477fd588 kernel: fixup! su_path->su, make it as an array
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-03 22:59:55 +08:00
rsuntk
fc85270a35 kernel: code clean up and some inlining
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-08-03 22:58:46 +08:00
ShirkNeko
a9e3c1cc8f kermel: Refactoring and separating dynamic signature-related structures and functions and implement hot-signature updates 2025-08-03 22:51:38 +08:00
ShirkNeko
dd4cf956dd kernel: bump KSU_VERSION_API to 3.1.8 2025-07-21 21:24:32 +08:00
ShirkNeko
ac9acf6c0a kernel: simplified signature verification 2025-07-09 12:07:33 +08:00
TwinbornPlate75
340a94ef30 kernel/throne_tracker: Fix missing variable in function my_actor (#266) 2025-07-08 22:34:01 +08:00
ShirkNeko
6e0fb0b388 kernel: Add the ability to get active managers for multi-manager APKs 2025-07-06 00:53:47 +08:00
ShirkNeko
ed95981d09 kernel: add multi-manager support 2025-07-05 22:30:16 +08:00
ShirkNeko
942210459f Add dynamic signature support 2025-07-05 16:29:40 +08:00
WenHao2130
828290059d kernel: Drop Elysia key
The key owner has lost it

Change-Id: Id9e0037a490a545dc35b90312fc110b54465e153
Signed-off-by: WenHao2130 <wenhao2130@outlook.com>
2025-07-04 18:51:42 +08:00
ShirkNeko
6af65779d1 kernel: Update CMD_GET_FULL_VERSION to a new value 2025-07-03 00:10:06 +08:00
ShirkNeko
6bbb47bad4 kernel: bump KSU_VERSION to 3.1.7 2025-06-30 17:05:44 +08:00
YC酱luyancib
b44dd7d020 Update Kconfig (#224)
make sure kpm config requrement was enabled
2025-06-30 16:33:09 +08:00
WenHao2130
67c4111bbd kernel: fmt
Change-Id: Ie84bde7b2944152eb08f5e8f12df1c3aa86f8ca5
Signed-off-by: WenHao2130 <wenhao2130@outlook.com>
2025-06-28 21:26:56 +08:00
愛莉希雅
4908e3b633 愛莉希雅小姐嘅惠禮 (#226) 2025-06-28 14:43:59 +08:00
Tashfin Shakeer Rhythm
0c3049ec03 kernel: selinux: rules: Fix illegal RCU lock usage in apply_kernelsu_rules()
When kernel is compiled with CONFIG_DEBUG_ATOMIC_SLEEP enabled, it prints
the following splat in dmesg during post boot:

[ 6.739169] init: Opening SELinux policy
[ 6.751520] init: Loading SELinux policy
[ 6.894684] SELinux: policy capability network_peer_controls=1
[ 6.894688] SELinux: policy capability open_perms=1
[ 6.894690] SELinux: policy capability extended_socket_class=1
[ 6.894691] SELinux: policy capability always_check_network=0
[ 6.894693] SELinux: policy capability cgroup_seclabel=0
[ 6.894695] SELinux: policy capability nnp_nosuid_transition=1
[ 7.214323] selinux: SELinux: Loaded file context from:
[ 7.214332] selinux: /system/etc/selinux/plat_file_contexts
[ 7.214339] selinux: /system_ext/etc/selinux/system_ext_file_contexts
[ 7.214345] selinux: /product/etc/selinux/product_file_contexts
[ 7.214350] selinux: /vendor/etc/selinux/vendor_file_contexts
[ 7.214356] selinux: /odm/etc/selinux/odm_file_contexts
[ 7.216398] KernelSU: /system/bin/init argc: 2
[ 7.216401] KernelSU: /system/bin/init first arg: second_stage
[ 7.216403] KernelSU: /system/bin/init second_stage executed
[ 7.216506] BUG: sleeping function called from invalid context at security/selinux/ss/hashtab.c:47
[ 7.216512] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 1, name: init
[ 7.216516] preempt_count: 0, expected: 0
[ 7.216518] RCU nest depth: 1, expected: 0
[ 7.216524] CPU: 6 PID: 1 Comm: init Not tainted 5.4.289-Scarlet-v2.0-beta3 #1
[ 7.216526] Hardware name: redwood based Qualcomm Technologies, Inc. SM7325 (DT)
[ 7.216528] Call trace:
[ 7.216536] dump_backtrace+0x0/0x210
[ 7.216539] show_stack+0x14/0x20
[ 7.216544] dump_stack+0x9c/0xec
[ 7.216548] __might_resched+0x1f0/0x210
[ 7.216552] hashtab_insert+0x38/0x230
[ 7.216557] add_type+0xd4/0x2e0
[ 7.216559] ksu_type+0x24/0x60
[ 7.216562] apply_kernelsu_rules+0xa8/0x650
[ 7.216565] ksu_handle_execveat_ksud+0x2a8/0x460
[ 7.216568] ksu_handle_execveat+0x2c/0x60
[ 7.216571] __arm64_sys_execve+0xe8/0xf0
[ 7.216574] el0_svc_common+0xf4/0x1a0
[ 7.216577] do_el0_svc+0x2c/0x40
[ 7.216579] el0_sync_handler+0x18c/0x200
[ 7.216582] el0_sync+0x140/0x180

This is because apply_kernelsu_rules() uses rcu_read_lock() to protect
SELinux policy modifications. However, cond_resched() from
hashtab_insert() at security/selinux/ss/hashtab.c is internally called
and it sleeps which is illegal under an RCU read-side critical section.

While replacing it with a spinlock would suppress the warning, this is
fundamentally incorrect because sleeping is illegal while holding a
spinlock and spinlock would turn off preemption which isn't an ideal
solution since it intentionally turns off rescheduling, and can lead
to deadlocks.

Instead, replace the RCU lock with a mutex lock. Mutex lock allows
sleeping when necessary, which is appropriate here because
apply_kernelsu_rules() runs in process context, not in atomic or
interrupt context. As apply_kernelsu_rules() is invoked only once during
post boot (SYSTEM_RUNNING), the mutex lock does not introduce any major
runtime performance regression and provides correct synchronization.

Fixes: tiann#2637
Signed-off-by: Tashfin Shakeer Rhythm <tashfinshakeerrhythm@gmail.com>
2025-06-27 12:27:45 +08:00
rsuntk
f820b9aaa8 kernel: phase out devpts_hook
* Since it's interceptable from LSM Hook,
then we just need to remove ksu_handle_devpts and
make a decoy for it.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-06-27 12:26:55 +08:00
古塵
f1ba7127b8 kernel: refactor CMD_GET_FULL_VERSION to safely initialize version string (#220)
Use strscpy()/strlcpy() to populate the version buffer in CMD_GET_FULL_VERSION
instead of relying on uninitialized memory. This ensures the returned string
is null-terminated and avoids exposing garbage data to user space.

Signed-off-by: schqiushui <orochi9999@gmail.com>
2025-06-27 00:26:17 +08:00
ShirkNeko
2564dce9ed kernel/core_hook: fix error handling in ksu_handle_prctl for CMD_GET_FULL_VERSION 2025-06-25 21:21:16 +08:00
ShirkNeko
1a43244288 kernel/Makefile: enhance version retrieval logic with GitHub commit count 2025-06-24 23:12:42 +08:00
ShirkNeko
8752b82fdc kernel: Rewrite kernle version code management
Co-authored-by: lamadaemon <i@lama.icu>
Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
2025-06-24 20:12:36 +08:00
Prslc
ddea10e0d8 Kernel: use main branch commit count for consistent versioning (#209) 2025-06-23 20:04:50 +08:00
ShirkNeko
4c4dce98f4 kernel/Makefile: check kernelsu driver version from online git repo first, if fails then check local .git and if that also fails then use hardcoded fallback
Co-authored-by: rifsxd <rifat.44.azad.rifs@gmail.com>
2025-06-21 17:13:42 +08:00
ShirkNeko
aef862e91a kernel: clean up ksu_inode_permission by removing unused code 2025-06-21 14:59:42 +08:00
ShirkNeko
a437f69586 kernel: change ksu_key_permission to public for broader access 2025-06-20 00:38:31 +08:00
rsuntk
ea7e2f4db6 kernel: allow GKI kprobes to use LSM hook for ksu_handle_devpts
* Also minor changes on comments

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-06-20 00:28:20 +08:00
rsuntk
ae475cba67 kernel: selinux: expose is_ksu_transition to all linux version
* Allow newer kernel to use is_ksu_transition function.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-06-20 00:27:17 +08:00
rsuntk
8987312fc1 [skip ci] kernel: just search for ksu_handle_devpts
* only to make 100% sure?

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-06-19 18:23:17 +08:00
backslashxx
2394fc67fc kernel: intercept devpts via security_inode_permission LSM
* This changes:
  + Avoid conflicts with other devpts hooks.
  + We keep pts_unix98_pre for KPROBES for simplifying things.

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-06-19 18:23:03 +08:00
rsuntk
d13233f566 [skip ci] kernel: remove and fmt
* People who understands kernel, likely the didn't need this.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-06-19 18:22:05 +08:00
backslashxx
d582e619f0 kernel: minor optimization on throne tracker
* Picked from https://github.com/tiann/KernelSU/pull/2633
* Add missed filp_close and don't make data_app_magic static + __read_mostly

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-06-12 17:35:19 +08:00
rsuntk
722b5ab944 [skip ci] kernel: core_hook: add missing path_put
[  101.572296] CPU: 0 PID: 8674 Comm: main Tainted: G        WC OE     5.15.148-Ghost@NVG-064-gce02b349fb2b #1
[  101.572305] Hardware name: Qualcomm Technologies, Inc. KHAJE IDP nopmi topaz (DT)
[  101.572309] pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[  101.572315] pc : mntput_no_expire+0x25c/0x300
[  101.572328] lr : mntput_no_expire+0x134/0x300
[  101.572334] sp : ffffffc01d163c10
[  101.572336] x29: ffffffc01d163c30 x28: ffffffdb2c74bff0 x27: 0000000000000000
[  101.572345] x26: ffffff806cf11200 x25: ffffff806cf11200 x24: ffffffdb2db93000
[  101.572353] x23: ffffff807df66da0 x22: ffffff807df66d80 x21: ffffff807df66d80
[  101.572361] x20: ffffffdb2db89380 x19: ffffff806cf11200 x18: ffffffc013aad068
[  101.572369] x17: 0000000000000001 x16: ffffffa6c928b000 x15: 0000000000000000
[  101.572378] x14: 0000000000000020 x13: ffffffdb2db9f860 x12: 0000000000000020
[  101.572385] x11: ffffffffffffffff x10: 00000000000000ff x9 : 0000000000000008
[  101.572393] x8 : ffffff807df66d80 x7 : 61705f75736b203a x6 : 55536c656e72654b
[  101.572401] x5 : ffffffdb2de14332 x4 : ffffff81f6c435c1 x3 : 0000000000000000
[  101.572409] x2 : 0000000200000000 x1 : 0000000000000000 x0 : 00000000ffffffff
[  101.572418] Call trace:
[  101.572422] mntput_no_expire+0x25c/0x300
[  101.572431] path_put+0x3c/0x58
[  101.572438] ksu_try_umount+0x14c/0x174
[  101.572445] susfs_try_umount_all+0x6c/0x190
[  101.572450] ksu_handle_setuid+0x20c/0x320
[  101.572454] ksu_task_fix_setuid+0x18/0x2c
[  101.572459] __sys_setresuid+0x1e0/0x3dc
[  101.572466] __arm64_sys_setresuid+0x28/0x38
[  101.572472] invoke_syscall+0x64/0x154
[  101.572479] el0_svc_common+0x90/0xf4
[  101.572484] do_el0_svc+0x2c/0x9c
[  101.572489] el0_svc+0x28/0x60
[  101.572496] el0t_64_sync_handler+0xd4/0xf0
[  101.572501] el0t_64_sync+0x1b8/0x1bc
[  101.572508] ---[ end trace b57c69edb246930f ]---
[  101.572626] ------------[ cut here ]------------

Suggested-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-06-12 17:34:32 +08:00
ShirkNeko
c1aa0690c5 Revert "kernel: add package whitelist check for manager APKs" 2025-06-12 15:14:37 +08:00
rsuntk
8331ed2d74 kernel: Remove NULL-ing after commit_creds
* Although it works, but i suspect it causing reboot
* issue in some device, so i'll drop it

Signed-off-by: rsuntk <rissu.ntk@gmail.com>
2025-06-12 14:12:54 +08:00
rsuntk
a0fd27dc33 kernel: ksud: commonize handle_execve_ksud and add support for compat_execve_ksud (#109)
* This is only for 32bit userspace, 64bit kernel
* Adapt from backslashxx KernelSU repository (our fork still using struct)
* Sync-up with baskslashxx's scope minimized hook.

Signed-off-by: rsuntk <90097027+rsuntk@users.noreply.github.com>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-06-12 14:12:22 +08:00
rsuntk
8359bc5890 [skip ci] kernel: move is_ksu_transition to selinux.c
* SELinux stuff on ksud? Does something like this is offtopic?

Signed-off-by: rsuntk <90097027+rsuntk@users.noreply.github.com>
2025-06-12 14:12:06 +08:00
rsuntk
02629db24b kernel: Remove ksu_execveat_hook from is_ksu_transition
* Doesn't work well

Ref: c40e3512b5

Reported-by: edenadversary <143865198+edenadversary@users.noreply.github.com>
2025-06-11 17:40:55 +08:00
ShirkNeko
430a3504d4 Fix line breaks in code and clean up unnecessary includes 2025-06-11 15:08:43 +08:00
rsuntk
71bb5a3d3b kernel: kernel_compat: Remove inline get_cred_rcu
Since commit:
kernel: core_hook: switch to prepare_creds (c58e102)

get_cred_rcu is no longer needed.

Signed-off-by: rsuntk <90097027+rsuntk@users.noreply.github.com>
2025-06-11 14:50:52 +08:00
Wang Han
3e7cae8134 kernel: core_hook: switch to prepare_creds
- Picked from https://github.com/tiann/KernelSU/pull/2631
- Minor changes: NULL-ing creds after committing

Signed-off-by: rsuntk <90097027+rsuntk@users.noreply.github.com>
2025-06-11 14:49:48 +08:00
backslashxx
29de74c941 kernel: core_hook: fix missed path_put
make sure to path_put() on all codepaths after kern_path() success

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: rsuntk <90097027+rsuntk@users.noreply.github.com>
2025-06-11 14:46:24 +08:00
backslashxx
e4285fcb25 kernel: core_hook: refactor escape_to_root
- Remove BUG_ON, bail out when failed
- Add put_cred

Signed-off-by: rsuntk <rissu.ntk@gmail.com>
2025-06-11 14:45:25 +08:00
backslashxx
0144a888da kernel: throne_tracker: avoid cross-fs traversal using s_magic check
Skip directories that does NOT have the same magic as /data/app.
This is to avoid scanning incfs and any other stacked filesystems.

While this is way dumber, it's way cheaper.
no kern_path(), no missable path_put(), no ref handling.

This is a workaround for Ultra-Legacy kernels where upstream's
method fails.

Seems doing 50+ kern_path() calls is a bad meme.

This supercedes `throne_tracker: avoid cross fs access (tiann#2626)`
- upstream 0b6998b474

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-06-11 14:44:49 +08:00
rsuntk
99becea3a1 Revert "kernel: throne_tracker: avoid cross fs access"
Use better alternative

This reverts commit e9b91c7faa4a5076c83dec9766c5c464d9297e2f.

Signed-off-by: rsuntk <rissu.ntk@gmail.com>
2025-06-11 14:44:39 +08:00
rsuntk
58c31cb726 [skip ci] kernel: minor changes on ksu_sys_umount
* Simplify value for 'ret', adding some comments

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-06-11 14:44:28 +08:00
rsuntk
43590fc350 kernel: mark is_ksu_transition as maybe_unused
* Probably this hook is not needed much

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-06-11 14:44:15 +08:00
F-19-F
1d1e0f1e7f kernel: provide is_ksu_transition check
context: this is known by many as `selinux hook`, `4.9 hook`

add is_ksu_transition check which allows ksud execution under nosuid.
it also eases up integration on 3.X kernels that does not have check_nnp_nosuid.

this also adds a `ksu_execveat_hook` check since this transition is NOT needed
anymore once ksud ran.

Usage:
	if (check_ksu_transition(old_tsec, new_tsec))
		return 0;

on either check_nnp_nosuid or selinux_bprm_set_creds (after execve sid reset)

reference: dfe003c9fd

taken from:
`allow init exec ksud under nosuid`
- 3df9df42a6
- https://github.com/tiann/KernelSU/pull/166#issue-1565872173

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-06-11 14:44:06 +08:00
ShirkNeko
aec76a388f kernel: add package whitelist check for manager APKs
Co-authored-by: lamadaemon <i@lama.icu>
Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
2025-06-07 00:48:06 +08:00
rsuntk
3b8445cdaa kernel: Remove more stray backslash in grep regex and move path_umount as optional backport 2025-06-07 00:35:23 +08:00
Tashfin Shakeer Rhythm
6225985f6f kernel: Makefile: Remove stray backslash from path_umount grep regex (#103)
Signed-off-by: Tashfin Shakeer Rhythm <tashfinshakeerrhythm@gmail.com>
2025-06-07 00:35:14 +08:00
Paul
d52fc57fc4 kernel: core_hook: intercept devpts via security_inode_permission LSM (#137)
`ksu handles devpts with selinux lsm hook` - aviraxp

- no, not yet, but yes we can, thats a good idea.

This change tries to do that, so instead of hooking pts_unix98_lookup or
devpts_get_priv, we just watch security_inode_permission, if its devpts,
pass it along to the original handler.

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-06-04 20:24:10 +08:00
5ec1cff
79c298cae1 throne_tracker: avoid cross fs access 2025-06-03 00:03:44 +08:00
ShirkNeko
ab3aa84173 kernel: remove SELinux Makefile and add manager to .gitignore 2025-05-28 14:18:08 +08:00
ShirkNeko
b337fc869c kernel: remove unused ksu_task_prctl function 2025-05-27 15:34:19 +08:00
ShirkNeko
08d0b2b048 kernel: include KPM header in core_hook.c 2025-05-27 15:13:32 +08:00
ShirkNeko
622c681ffc kernel: update comments and picked some from upstream
Signed-off-by: rsuntk <90097027+rsuntk@users.noreply.github.com>
2025-05-27 15:12:32 +08:00
rsuntk
98d25694dc kernel: make path_umount backporting as optional
Since https://github.com/backslashxx/KernelSU/commit/4f8943a, path_umount is no longer needed.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
2025-05-24 14:33:05 +08:00
ShirkNeko
d9f54a8e42 Refactoring KPM support to check KPM status using CMD_ENABLE_KPM 2025-05-24 14:32:46 +08:00
backslashxx
a3a847a885 kernel: core_hook: screw path_umount backport, call sys_umount directly
I am repasting here what I posted on the source code originally:

/*
 * turns out path_umount backport is completely unneeded
 * we copy the trick used on strncpy_from_unsafe_user / strncpy_from_user_nofault
 * https://elixir.bootlin.com/linux/v4.4.302/source/mm/maccess.c#L184
 * basically
 *
 *     mm_segment_t old_fs = get_fs();     // remember original fs segment
 *     set_fs(USER_DS);                    // or KERNEL_DS *
 *     do_whatever_in_userspace();
 *     set_fs(old_fs);                     // restore fs segment
 *
 *  * kernel -> user, KERNEL_DS, user -> kernel, USER_DS
 *
 * so yes, we can try to straight up call a syscall from kernel space
 *
 * NOTE: on newer kernels you can use force_uaccess_begin + force_uaccess_end
 * ref: https://elixir.bootlin.com/linux/v5.10.237/source/mm/maccess.c#L250
 *
 */

path_umount backport now optional — neat trick, werks, what can I say.

Backports? Nah, we’re good.

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-05-24 14:27:00 +08:00
backslashxx
bf06b92850 kernel: sucompat: increase reliability of execve_sucompat
On plain ARMv8.0 devices (A53,A57,A73), strncpy_from_user_nofault() sometimes
fails to copy `filename_user` string correctly. This breaks su ofc, breaking
some apps like Termux (Play Store ver), ZArchiver and Root Explorer.

This does NOT seem to affect newer ARMv8.2+ CPUs (A75/A76 and newer)

My speculation? ARMv8.0 has weak speculation :)

here we replace `strncpy_from_user_nofault()` with another routine:
 - access_ok() to validate the pointer
 - strncpy_from_user() to copy and validate string
 - manual null-termination just in case, as strncpy_from_user_nofault also does it
 - remove that memset, seems useless as it is an strncpy, not strncat

Kind of mimicking _nofault, but yes with this one we allow pagefaults.

Tested on:
- ARMv8.0 A73.a53, A57.a53, A53.a53
- ARMv8.2 A76.a55

Tested-by: iDead XD <rafifirdaus12bb@gmail.com>
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-05-24 14:26:31 +08:00
ShirkNeko
80e3c736d1 kernel: fix repository URL for KernelSU cloning 2025-05-20 12:53:05 +08:00
ShirkNeko
a16f150269 Updating the KPM configuration
- We don't know if KPM can run on arm32-bit devices, so to avoid some problems, add a dependency on 64-bit architectures

kernel/throne_tracker: we just uninstalled the manager, stop looking for it
When the manager UID disappears from packages.list, we correctly
invalidate it — good. But, in the very next breath, we start scanning
/data/app hoping to find it again?

Skip the scan — we’ll catch the reinstall next time packages.list updates.

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
2025-05-17 18:45:01 +08:00
backslashxx
8d066b9ec5 kernel: expose KSU_LSM_SECURITY_HOOKS on Kconfig (#77)
disabling this removes the need for LSM_HOOK_INIT, security_add_hooks and such,.
furthermore, this will also allow easier integration on pre-4.1 kernels.
Expose this and make it a configurable option.

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-05-15 20:28:44 +08:00
sidex15
db547eecf1 kernel: kpm: add compatibility for kernel 4.14 and lower (#76)
`thread_pid` is not defined in kernel 4.14 and lower, leading to compilation issue.
To fix this, use `pids[PIDTYPE_PID].pid` for kernel versions 4.14 and lower.
Else use `thread_pid` for kernel versions 4.19 and higher.

Reference: 107717913b/tracee/tracee.bpf.c (L354)
2025-05-15 17:38:34 +08:00
ShirkNeko
0973cd1ae0 kernel: handle samsung selinux driver
* Some samsung kernel source have SEC_SELINUX_PORTING_COMMON
* This commit mayfix false warning to sepolicy.

Mayfix: I haven't test it yet

Signed-off-by: rsuntk <90097027+rsuntk@users.noreply.github.com>
2025-05-12 19:29:25 +08:00
ShirkNeko
8c6f50815a Clean up the project structure and keep only the kernel 2025-05-12 19:26:18 +08:00
ShirkNeko
c98cf121dc Optimized SELinux compatibility support, adapted data structures to support 32-bit and 64-bit kernels
Co-authored-by: rsuntk <rsuntk@yukiprjkt.my.id>
Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
2025-05-12 19:24:40 +08:00
ShirkNeko
037c5b6c73 kernel: rename KernelSU to SukiSU and update versioning logic 2025-05-10 14:12:48 +08:00
ShirkNeko
9d920e7cc5 kernel: added compatibility for non-GKI devices
Co-authored-by: rsuntk <rsuntk@yukiprjkt.my.id>
Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
2025-05-10 13:19:30 +08:00
402 changed files with 5732 additions and 68529 deletions

1
.gitattributes vendored
View File

@@ -1 +0,0 @@
*.bat eol=crlf

4
.github/FUNDING.yml vendored
View File

@@ -1,4 +0,0 @@
github: tiann
patreon: weishu
open_collective: sukisu-ultra

View File

@@ -1,33 +0,0 @@
name: Contribute to Unofficially Supported Device
description: Add your device kernel source to KernelSU's Unofficially Supported Device List
title: "[Add Device]: "
labels: ["add-device"]
body:
- type: markdown
attributes:
value: |
Thanks for supporting KernelSU!
- type: input
id: repo-url
attributes:
label: Repository URL
description: Your repository URL
placeholder: https://github.com/tiann/KernelSU
validations:
required: true
- type: input
id: device
attributes:
label: Device
description: Please describe the device maintained by you.
placeholder: GKI 2.0 Device
validations:
required: true
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you should be the maintainer of the repository.
options:
- label: I'm the maintainer of this repository
required: true

View File

@@ -1,72 +0,0 @@
name: Bug report
description: Create a report to help us improve KernelSU
labels: [Bug]
body:
- type: checkboxes
attributes:
label: Please check before submitting an issue
options:
- label: I have searched the issues and haven't found anything relevant
required: true
- label: I will upload bugreport file in KernelSU Manager - Settings - Report log
required: true
- label: I know how to reproduce the issue which may not be specific to my device
required: false
- type: textarea
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is
validations:
required: true
- type: textarea
attributes:
label: To Reproduce
description: Steps to reproduce the behaviour
placeholder: |
- 1. Go to '...'
- 2. Click on '....'
- 3. Scroll down to '....'
- 4. See error
- type: textarea
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
- type: textarea
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain your problem.
- type: textarea
attributes:
label: Logs
description: If applicable, add crash or any other logs to help us figure out the problem.
- type: textarea
attributes:
label: Device info
value: |
- Device:
- OS Version:
- KernelSU Version:
- Kernel Version:
validations:
required: true
- type: textarea
attributes:
label: Additional context
description: Add any other context about the problem here.

View File

@@ -1,11 +0,0 @@
name: Custom issue template
description: WARNING! If you are reporting a bug but use this template, the issue will be closed directly.
title: '[Custom]'
body:
- type: textarea
id: description
attributes:
label: "Describe your problem."
validations:
required: true

View File

@@ -1,39 +0,0 @@
name: Feature Request
description: "Suggest an idea for this project"
title: "[Feature]"
labels: "feature"
body:
- type: markdown
id: feature-info
attributes:
value: "## Feature Infomation"
- type: textarea
id: feature-main
validations:
required: true
attributes:
label: "Is your feature request related to a problem? Please describe."
description: "A clear and concise description of what the problem is."
placeholder: "I'm always frustrated when [...]"
- type: textarea
id: feature-solution
validations:
required: true
attributes:
label: "Describe the solution you'd like."
description: "A clear and concise description of what you want to happen."
- type: textarea
id: feature-describe
validations:
required: true
attributes:
label: "Describe alternatives you've considered."
description: "A clear and concise description of any alternative solutions or features you've considered."
- type: textarea
id: feature-extra
validations:
required: false
attributes:
label: "Additional context"
description: "Add any other context or screenshots about the feature request here."

View File

@@ -1,64 +0,0 @@
#!/bin/bash
set -euo pipefail
build_from_image() {
export TITLE
TITLE=kernel-aarch64-${1//Image-/}
echo "[+] title: $TITLE"
export PATCH_LEVEL
PATCH_LEVEL=$(echo "$1" | awk -F_ '{ print $2}')
echo "[+] patch level: $PATCH_LEVEL"
echo '[+] Download prebuilt ramdisk'
GKI_URL=https://dl.google.com/android/gki/gki-certified-boot-android12-5.10-"${PATCH_LEVEL}"_r1.zip
FALLBACK_URL=https://dl.google.com/android/gki/gki-certified-boot-android12-5.10-2023-01_r1.zip
status=$(curl -sL -w "%{http_code}" "$GKI_URL" -o /dev/null)
if [ "$status" = "200" ]; then
curl -Lo gki-kernel.zip "$GKI_URL"
else
echo "[+] $GKI_URL not found, using $FALLBACK_URL"
curl -Lo gki-kernel.zip "$FALLBACK_URL"
fi
unzip gki-kernel.zip && rm gki-kernel.zip
echo '[+] Unpack prebuilt boot.img'
BOOT_IMG=$(find . -maxdepth 1 -name "boot*.img")
$UNPACK_BOOTIMG --boot_img="$BOOT_IMG"
rm "$BOOT_IMG"
echo '[+] Building Image.gz'
$GZIP -n -k -f -9 Image >Image.gz
echo '[+] Building boot.img'
$MKBOOTIMG --header_version 4 --kernel Image --output boot.img --ramdisk out/ramdisk --os_version 12.0.0 --os_patch_level "${PATCH_LEVEL}"
$AVBTOOL add_hash_footer --partition_name boot --partition_size $((64 * 1024 * 1024)) --image boot.img --algorithm SHA256_RSA2048 --key ../kernel-build-tools/linux-x86/share/avb/testkey_rsa2048.pem
echo '[+] Building boot-gz.img'
$MKBOOTIMG --header_version 4 --kernel Image.gz --output boot-gz.img --ramdisk out/ramdisk --os_version 12.0.0 --os_patch_level "${PATCH_LEVEL}"
$AVBTOOL add_hash_footer --partition_name boot --partition_size $((64 * 1024 * 1024)) --image boot-gz.img --algorithm SHA256_RSA2048 --key ../kernel-build-tools/linux-x86/share/avb/testkey_rsa2048.pem
echo '[+] Building boot-lz4.img'
$MKBOOTIMG --header_version 4 --kernel Image.lz4 --output boot-lz4.img --ramdisk out/ramdisk --os_version 12.0.0 --os_patch_level "${PATCH_LEVEL}"
$AVBTOOL add_hash_footer --partition_name boot --partition_size $((64 * 1024 * 1024)) --image boot-lz4.img --algorithm SHA256_RSA2048 --key ../kernel-build-tools/linux-x86/share/avb/testkey_rsa2048.pem
echo '[+] Compress images'
for image in boot*.img; do
$GZIP -n -f -9 "$image"
mv "$image".gz "${1//Image-/}"-"$image".gz
done
echo "[+] Images to upload"
find . -type f -name "*.gz"
# find . -type f -name "*.gz" -exec python3 "$GITHUB_WORKSPACE"/KernelSU/scripts/ksubot.py {} +
}
for dir in Image*; do
if [ -d "$dir" ]; then
echo "----- Building $dir -----"
cd "$dir"
build_from_image "$dir"
cd ..
fi
done

View File

@@ -1,43 +0,0 @@
#!/bin/bash
set -euo pipefail
build_from_image() {
export TITLE
TITLE=kernel-aarch64-${1//Image-/}
echo "[+] title: $TITLE"
echo '[+] Building Image.gz'
$GZIP -n -k -f -9 Image >Image.gz
echo '[+] Building boot.img'
$MKBOOTIMG --header_version 4 --kernel Image --output boot.img
$AVBTOOL add_hash_footer --partition_name boot --partition_size $((64 * 1024 * 1024)) --image boot.img --algorithm SHA256_RSA2048 --key ../kernel-build-tools/linux-x86/share/avb/testkey_rsa2048.pem
echo '[+] Building boot-gz.img'
$MKBOOTIMG --header_version 4 --kernel Image.gz --output boot-gz.img
$AVBTOOL add_hash_footer --partition_name boot --partition_size $((64 * 1024 * 1024)) --image boot-gz.img --algorithm SHA256_RSA2048 --key ../kernel-build-tools/linux-x86/share/avb/testkey_rsa2048.pem
echo '[+] Building boot-lz4.img'
$MKBOOTIMG --header_version 4 --kernel Image.lz4 --output boot-lz4.img
$AVBTOOL add_hash_footer --partition_name boot --partition_size $((64 * 1024 * 1024)) --image boot-lz4.img --algorithm SHA256_RSA2048 --key ../kernel-build-tools/linux-x86/share/avb/testkey_rsa2048.pem
echo '[+] Compress images'
for image in boot*.img; do
$GZIP -n -f -9 "$image"
mv "$image".gz "${1//Image-/}"-"$image".gz
done
echo '[+] Images to upload'
find . -type f -name "*.gz"
# find . -type f -name "*.gz" -exec python3 "$GITHUB_WORKSPACE"/KernelSU/scripts/ksubot.py {} +
}
for dir in Image*; do
if [ -d "$dir" ]; then
echo "----- Building $dir -----"
cd "$dir"
build_from_image "$dir"
cd ..
fi
done

View File

@@ -1,60 +0,0 @@
name: handle-add-device-issue
on:
issues:
types: [labeled]
jobs:
handle-add-device:
if: github.event.label.name == 'add-device'
runs-on: ubuntu-latest
env:
ISSUE_CONTENT: ${{ github.event.issue.body }}
steps:
- uses: actions/checkout@v4
- name: Parse issue body
id: handle-add-device
run: |
python3 scripts/add_device_handler.py website/docs/repos.json || true
- name: Commit
if: steps.handle-add-device.outputs.success == 'true'
run: |
git config --local user.name "GitHub Actions"
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add website/docs/repos.json
git commit -m "add device: ${{ steps.handle-add-device.outputs.device }}"
- name: Make pull request
if: steps.handle-add-device.outputs.success == 'true'
id: cpr
uses: peter-evans/create-pull-request@v7
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "[add device]: ${{ steps.handle-add-device.outputs.device }}"
title: "[add device]: ${{ steps.handle-add-device.outputs.device }}"
body: |
${{ steps.handle-add-device.outputs.device }} has been added to the website.
Related issue: ${{ github.event.issue.html_url }}
branch: "add-device-${{ github.event.issue.number }}"
labels: add-device
delete-branch: true
sign-commits: true
- name: Check outputs
if: ${{ steps.cpr.outputs.pull-request-number }}
run: |
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
- uses: Kernel-SU/actions-comment-on-issue@master
if: ${{ steps.cpr.outputs.pull-request-number }}
with:
message: "Automatically created pull request: ${{ steps.cpr.outputs.pull-request-url }}"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: Kernel-SU/actions-comment-on-issue@master
if: steps.handle-add-device.outputs.success != 'true'
with:
message: "Cannot create pull request. Please check the issue content. Or you can create a pull request manually."
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: close issue
uses: peter-evans/close-issue@v3
with:
issue-number: ${{ github.event.issue.number }}
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,137 +0,0 @@
name: GKI Kernel Build
on:
workflow_call:
inputs:
version_name:
required: true
type: string
description: >
With SUBLEVEL of kernel,
for example: android12-5.10.66
arch:
required: true
type: string
description: >
Build arch: aarch64/x86_64
debug:
required: false
type: boolean
default: true
manifest_name:
required: false
type: string
description: >
Local repo manifest xml path,
typically for AVD kernel build.
secrets:
BOOT_SIGN_KEY:
required: false
CHAT_ID:
required: false
BOT_TOKEN:
required: false
MESSAGE_THREAD_ID:
required: false
jobs:
build:
name: Build ${{ inputs.version_name }}
runs-on: ubuntu-22.04
steps:
- name: Maximize build space
uses: easimon/maximize-build-space@master
with:
root-reserve-mb: 8192
temp-reserve-mb: 2048
remove-dotnet: 'true'
remove-android: 'true'
remove-haskell: 'true'
remove-codeql: 'true'
- uses: actions/checkout@v4
with:
path: KernelSU
fetch-depth: 0
- name: Setup need_upload
id: need_upload
run: |
if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then
echo "UPLOAD=true" >> $GITHUB_OUTPUT
else
echo "UPLOAD=false" >> $GITHUB_OUTPUT
fi
- name: Setup kernel source
run: |
echo "Free space:"
df -h
cd $GITHUB_WORKSPACE
sudo apt-get install repo -y
mkdir android-kernel && cd android-kernel
repo init --depth=1 -u https://android.googlesource.com/kernel/manifest -m "$GITHUB_WORKSPACE/KernelSU/.github/manifests/${{ inputs.manifest_name }}" --repo-rev=v2.16
repo --version
repo --trace sync -c -j$(nproc --all) --no-tags
df -h
- name: Setup KernelSU
env:
PATCH_PATH: ${{ inputs.patch_path }}
IS_DEBUG_KERNEL: ${{ inputs.debug }}
run: |
cd $GITHUB_WORKSPACE/android-kernel
echo "[+] KernelSU setup"
GKI_ROOT=$(pwd)
echo "[+] GKI_ROOT: $GKI_ROOT"
echo "[+] Copy KernelSU driver to $GKI_ROOT/common/drivers"
ln -sf $GITHUB_WORKSPACE/KernelSU/kernel $GKI_ROOT/common/drivers/kernelsu
echo "[+] Add KernelSU driver to Makefile"
DRIVER_MAKEFILE=$GKI_ROOT/common/drivers/Makefile
DRIVER_KCONFIG=$GKI_ROOT/common/drivers/Kconfig
grep -q "kernelsu" "$DRIVER_MAKEFILE" || printf "\nobj-\$(CONFIG_KSU) += kernelsu/\n" >> "$DRIVER_MAKEFILE"
grep -q "kernelsu" "$DRIVER_KCONFIG" || sed -i "/endmenu/i\\source \"drivers/kernelsu/Kconfig\"" "$DRIVER_KCONFIG"
echo "[+] Apply KernelSU patches"
cd $GKI_ROOT/common/ && git apply $GITHUB_WORKSPACE/KernelSU/.github/patches/$PATCH_PATH/*.patch || echo "[-] No patch found"
if [ "$IS_DEBUG_KERNEL" = "true" ]; then
echo "[+] Enable debug features for kernel"
printf "\nccflags-y += -DCONFIG_KSU_DEBUG\n" >> $GITHUB_WORKSPACE/KernelSU/kernel/Makefile
fi
repo status
echo "[+] KernelSU setup done."
cd $GITHUB_WORKSPACE/KernelSU
VERSION=$(($(git rev-list --count HEAD) + 10200))
echo "VERSION: $VERSION"
echo "kernelsu_version=$VERSION" >> $GITHUB_ENV
- name: Make working directory clean to avoid dirty
working-directory: android-kernel
run: |
rm common/android/abi_gki_protected_exports_* || echo "No protected exports!"
git config --global user.email "bot@kernelsu.org"
git config --global user.name "KernelSUBot"
cd common/ && git add -A && git commit -a -m "Add KernelSU"
repo status
- name: Build kernel
working-directory: android-kernel
run: |
if [ ! -z ${{ vars.EXPECTED_SIZE }} ] && [ ! -z ${{ vars.EXPECTED_HASH }} ]; then
export KSU_EXPECTED_SIZE=${{ vars.EXPECTED_SIZE }}
export KSU_EXPECTED_HASH=${{ vars.EXPECTED_HASH }}
fi
tools/bazel run --config=fast --config=stamp --lto=thin //common-modules/virtual-device:virtual_device_${{ inputs.arch }}_dist -- --dist_dir=dist
NAME=kernel-${{ inputs.arch }}-avd-${{ inputs.version_name }}-${{ env.kernelsu_version }}
TARGET_IMAGE=dist/bzImage
if [ ! -e $TARGET_IMAGE ]; then
TARGET_IMAGE=dist/Image
fi
mv $TARGET_IMAGE $NAME
echo "file_path=android-kernel/$NAME" >> $GITHUB_ENV
- name: Upload Kernel
uses: actions/upload-artifact@v4
with:
name: kernel-${{ inputs.arch }}-avd-${{ inputs.version_name }}-${{ env.kernelsu_version }}
path: "${{ env.file_path }}"

View File

@@ -1,74 +0,0 @@
name: Build LKM for KernelSU Local
on:
workflow_call:
inputs:
upload:
required: true
type: boolean
default: true
description: "Whether to upload to branch"
secrets:
# username:github_pat
TOKEN:
required: true
workflow_dispatch:
inputs:
upload:
required: true
type: boolean
default: true
description: "Whether to upload to branch"
jobs:
build-lkm:
strategy:
matrix:
include:
- version: "android12-5.10"
sub_level: 236
os_patch_level: 2025-05
- version: "android13-5.10"
sub_level: 234
os_patch_level: 2025-03
- version: "android13-5.15"
sub_level: 178
os_patch_level: 2025-03
- version: "android14-5.15"
sub_level: 178
os_patch_level: 2025-03
- version: "android14-6.1"
sub_level: 134
os_patch_level: 2025-05
- version: "android15-6.6"
sub_level: 87
os_patch_level: 2025-05
# uses: ./.github/workflows/gki-kernel-mock.yml when debugging
uses: ./.github/workflows/gki-kernel-local.yml
with:
version: ${{ matrix.version }}
version_name: ${{ matrix.version }}.${{ matrix.sub_level }}
tag: ${{ matrix.version }}-${{ matrix.os_patch_level }}
os_patch_level: ${{ matrix.os_patch_level }}
build_lkm: true
push-to-branch:
needs: [build-lkm]
runs-on: self-hosted
if: ${{ inputs.upload }}
steps:
- name: Download all workflow run artifacts
uses: actions/download-artifact@v4
with:
path: bin/
merge-multiple: true
- name: Push to branch LKM
run: |
cd bin
git config --global init.defaultBranch lkm
git init
git remote add origin https://${{ secrets.TOKEN }}@github.com/${{ github.repository }}
git config --local user.name "github-actions[bot]"
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
find . -type f
git add .
git commit -m "Upload LKM from ${{ github.sha }}" -m "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
git push --force --set-upstream origin lkm

View File

@@ -1,74 +0,0 @@
name: Build LKM for KernelSU
on:
workflow_call:
inputs:
upload:
required: true
type: boolean
default: true
description: "Whether to upload to branch"
secrets:
# username:github_pat
TOKEN:
required: true
workflow_dispatch:
inputs:
upload:
required: true
type: boolean
default: true
description: "Whether to upload to branch"
jobs:
build-lkm:
strategy:
matrix:
include:
- version: "android12-5.10"
sub_level: 240
os_patch_level: 2025-09
- version: "android13-5.10"
sub_level: 238
os_patch_level: 2025-07
- version: "android13-5.15"
sub_level: 189
os_patch_level: 2025-09
- version: "android14-5.15"
sub_level: 185
os_patch_level: 2025-07
- version: "android14-6.1"
sub_level: 145
os_patch_level: 2025-09
- version: "android15-6.6"
sub_level: 98
os_patch_level: 2025-09
# uses: ./.github/workflows/gki-kernel-mock.yml when debugging
uses: ./.github/workflows/gki-kernel.yml
with:
version: ${{ matrix.version }}
version_name: ${{ matrix.version }}.${{ matrix.sub_level }}
tag: ${{ matrix.version }}-${{ matrix.os_patch_level }}
os_patch_level: ${{ matrix.os_patch_level }}
build_lkm: true
push-to-branch:
needs: [build-lkm]
runs-on: ubuntu-latest
if: ${{ inputs.upload }}
steps:
- name: Download all workflow run artifacts
uses: actions/download-artifact@v4
with:
path: bin/
merge-multiple: true
- name: Push to branch LKM
run: |
cd bin
git config --global init.defaultBranch lkm
git init
git remote add origin https://${{ secrets.TOKEN }}@github.com/${{ github.repository }}
git config --local user.name "github-actions[bot]"
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
find . -type f
git add .
git commit -m "Upload LKM from ${{ github.sha }}" -m "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
git push --force --set-upstream origin lkm

View File

@@ -1,245 +0,0 @@
name: Build Manager Manual
on:
workflow_dispatch:
inputs:
build_lkm:
required: true
type: choice
default: "auto"
options:
- "true"
- "false"
- "auto"
description: "Whether to build lkm"
upload_lkm:
required: true
type: boolean
default: true
description: "Whether to upload lkm"
jobs:
check-build-lkm:
runs-on: self-hosted
outputs:
build_lkm: ${{ steps.check-build.outputs.build_lkm }}
upload_lkm: ${{ steps.check-build.outputs.upload_lkm }}
steps:
- name: check build
id: check-build
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ "${{ inputs.build_lkm }}" != "auto" ]; then
kernel_changed="${{ inputs.build_lkm }}"
else
kernel_changed=true
mkdir tmp
cd tmp
git config --global init.defaultBranch bot
git config --global user.name 'Bot'
git config --global user.email 'bot@github.shirkneko.io'
git init .
git remote add origin https://github.com/${{ github.repository }}
CURRENT_COMMIT="${{ github.event.head_commit.id }}"
git fetch origin $CURRENT_COMMIT --depth=1
git fetch origin lkm --depth=1
LKM_COMMIT="$(git log --format=%B -n 1 origin/lkm | head -n 1)"
LKM_COMMIT="${LKM_COMMIT#Upload LKM from }"
LKM_COMMIT=$(echo "$LKM_COMMIT" | tr -d '[:space:]')
echo "LKM_COMMIT=$LKM_COMMIT"
git fetch origin "$LKM_COMMIT" --depth=1
git diff --quiet "$LKM_COMMIT" "$CURRENT_COMMIT" -- kernel :!kernel/setup.sh .github/workflows/build-lkm-local.yml .github/workflows/build-kernel-*.yml && kernel_changed=false
cd ..
rm -rf tmp
fi
if [ "${{ github.event_name }}" == "push" ] && [ "${{ github.ref }}" == 'refs/heads/main' ]; then
need_upload=true
elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
need_upload="${{ inputs.upload_lkm }}"
else
need_upload=false
fi
echo "kernel changed: $kernel_changed"
echo "need upload: $need_upload"
echo "build_lkm=$kernel_changed" >> "$GITHUB_OUTPUT"
echo "upload_lkm=$need_upload" >> "$GITHUB_OUTPUT"
build-lkm:
needs: check-build-lkm
uses: ./.github/workflows/build-lkm-local.yml
if: ${{ needs.check-build-lkm.outputs.build_lkm == 'true' }}
with:
upload: ${{ needs.check-build-lkm.outputs.upload_lkm == 'true' }}
secrets: inherit
build-susfs:
if: ${{ always() }}
needs: [ check-build-lkm, build-lkm ]
strategy:
matrix:
include:
- target: aarch64-linux-android
os: ubuntu-latest
uses: ./.github/workflows/susfs.yml
with:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
build-kpmmgr:
if: ${{ always() }}
needs: [ check-build-lkm, build-lkm ]
strategy:
matrix:
include:
- target: aarch64-linux-android
os: ubuntu-latest
uses: ./.github/workflows/kpmmgr.yml
with:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
build-ksud:
if: ${{ always() }}
needs: [ check-build-lkm, build-lkm ]
strategy:
matrix:
include:
- target: aarch64-linux-android
os: ubuntu-latest
- target: x86_64-linux-android
os: ubuntu-latest
- target: armv7-linux-androideabi
os: ubuntu-latest
uses: ./.github/workflows/ksud.yml
with:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
pack_lkm: true
pull_lkm: ${{ needs.check-build-lkm.outputs.build_lkm != 'true' }}
build-manager:
if: ${{ always() }}
needs: build-ksud
runs-on: self-hosted
defaults:
run:
working-directory: ./manager
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup need_upload
id: need_upload
run: |
if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then
echo "UPLOAD=true" >> $GITHUB_OUTPUT
else
echo "UPLOAD=false" >> $GITHUB_OUTPUT
fi
- name: Write key
if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref == 'refs/heads/susfs' || github.ref_type == 'tag' }}
run: |
if [ ! -z "${{ secrets.KEYSTORE }}" ]; then
{
echo KEYSTORE_PASSWORD='${{ secrets.KEYSTORE_PASSWORD }}'
echo KEY_ALIAS='${{ secrets.KEY_ALIAS }}'
echo KEY_PASSWORD='${{ secrets.KEY_PASSWORD }}'
echo KEYSTORE_FILE='key.jks'
} >> gradle.properties
echo "${{ secrets.KEYSTORE }}" | base64 -d > key.jks
fi
- name: Download arm64 susfs
uses: actions/download-artifact@v4
with:
name: susfs-aarch64-linux-android
path: .
- name: Download arm64 kpmmgr
uses: actions/download-artifact@v4
with:
name: kpmmgr-aarch64-linux-android
path: .
- name: Download arm64 ksud
uses: actions/download-artifact@v4
with:
name: ksud-aarch64-linux-android
path: .
- name: Download x86_64 ksud
uses: actions/download-artifact@v4
with:
name: ksud-x86_64-linux-android
path: .
- name: Download arm ksud
uses: actions/download-artifact@v4
with:
name: ksud-armv7-linux-androideabi
path: .
- name: Copy ksud to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/x86_64
mkdir -p app/src/main/jniLibs/armeabi-v7a
cp -f ../aarch64-linux-android/release/zakozako ../manager/app/src/main/jniLibs/arm64-v8a/libzakozako.so
cp -f ../x86_64-linux-android/release/zakozako ../manager/app/src/main/jniLibs/x86_64/libzakozako.so
cp -f ../armv7-linux-androideabi/release/zakozako ../manager/app/src/main/jniLibs/armeabi-v7a/libzakozako.so
- name: Copy kpmmgr to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
cp -f ../arm64-v8a/kpmmgr ../manager/app/src/main/jniLibs/arm64-v8a/libkpmmgr.so
- name: Copy susfs to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
cp -f ../arm64-v8a/zakozakozako ../manager/app/src/main/jniLibs/arm64-v8a/libzakozakozako.so
- name: Build with Gradle
run: |
export ANDROID_HOME=/root/.android/sdk
export PATH=$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$PATH
./gradlew clean assembleRelease
- name: Upload build artifact
uses: actions/upload-artifact@v4
if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' }}
with:
name: manager
path: manager/app/build/outputs/apk/release/*.apk
- name: Upload mappings
uses: actions/upload-artifact@v4
if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' }}
with:
name: "mappings"
path: "manager/app/build/outputs/mapping/release/"
- name: Bot session cache
if: github.event_name != 'pull_request' && steps.need_upload.outputs.UPLOAD == 'true'
id: bot_session_cache
uses: actions/cache@v4
with:
path: scripts/ksubot.session
key: ${{ runner.os }}-bot-session
- name: Upload to telegram
if: github.event_name != 'pull_request' && steps.need_upload.outputs.UPLOAD == 'true'
env:
CHAT_ID: ${{ vars.CHAT_ID }}
BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
MESSAGE_THREAD_ID: ${{ vars.MESSAGE_THREAD_ID }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
COMMIT_URL: ${{ github.event.head_commit.url }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
TITLE: Manager
run: |
if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then
export VERSION=$(git rev-list --count HEAD)
APK=$(find ./app/build/outputs/apk/release -name "*.apk")
python3 $GITHUB_WORKSPACE/scripts/ksubot.py $APK
fi

View File

@@ -1,298 +0,0 @@
name: Build Manager
on:
push:
branches: [ "main", "ci" ]
paths:
- '.github/workflows/build-manager.yml'
- 'manager/**'
- 'kernel/**'
- 'userspace/ksud/**'
- 'userspace/susfs/**'
- 'userspace/kpmmgr/**'
- 'userspace/user_scanner/**'
pull_request:
branches: [ "main" ]
paths:
- 'manager/**'
workflow_call:
workflow_dispatch:
inputs:
build_lkm:
required: true
type: choice
default: "auto"
options:
- "true"
- "false"
- "auto"
description: "Whether to build lkm"
upload_lkm:
required: true
type: boolean
default: true
description: "Whether to upload lkm"
jobs:
check-build-lkm:
runs-on: ubuntu-latest
outputs:
build_lkm: ${{ steps.check-build.outputs.build_lkm }}
upload_lkm: ${{ steps.check-build.outputs.upload_lkm }}
steps:
- name: check build
id: check-build
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ "${{ inputs.build_lkm }}" != "auto" ]; then
kernel_changed="${{ inputs.build_lkm }}"
else
kernel_changed=true
mkdir tmp
cd tmp
git config --global init.defaultBranch bot
git config --global user.name 'Bot'
git config --global user.email 'bot@github.shirkneko.io'
git init .
git remote add origin https://github.com/${{ github.repository }}
CURRENT_COMMIT="${{ github.event.head_commit.id }}"
git fetch origin $CURRENT_COMMIT --depth=1
git fetch origin lkm --depth=1
LKM_COMMIT="$(git log --format=%B -n 1 origin/lkm | head -n 1)"
LKM_COMMIT="${LKM_COMMIT#Upload LKM from }"
LKM_COMMIT=$(echo "$LKM_COMMIT" | tr -d '[:space:]')
echo "LKM_COMMIT=$LKM_COMMIT"
git fetch origin "$LKM_COMMIT" --depth=1
git diff --quiet "$LKM_COMMIT" "$CURRENT_COMMIT" -- kernel :!kernel/setup.sh .github/workflows/build-lkm.yml .github/workflows/build-kernel-*.yml && kernel_changed=false
cd ..
rm -rf tmp
fi
if [ "${{ github.event_name }}" == "push" ] && [ "${{ github.ref }}" == 'refs/heads/main' ]; then
need_upload=true
elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
need_upload="${{ inputs.upload_lkm }}"
else
need_upload=false
fi
echo "kernel changed: $kernel_changed"
echo "need upload: $need_upload"
echo "build_lkm=$kernel_changed" >> "$GITHUB_OUTPUT"
echo "upload_lkm=$need_upload" >> "$GITHUB_OUTPUT"
build-lkm:
needs: check-build-lkm
uses: ./.github/workflows/build-lkm.yml
if: ${{ needs.check-build-lkm.outputs.build_lkm == 'true' }}
with:
upload: ${{ needs.check-build-lkm.outputs.upload_lkm == 'true' }}
secrets: inherit
build-susfs:
if: ${{ always() }}
needs: [ check-build-lkm, build-lkm ]
strategy:
matrix:
include:
- target: aarch64-linux-android
os: ubuntu-latest
uses: ./.github/workflows/susfs.yml
with:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
build-kpmmgr:
if: ${{ always() }}
needs: [ check-build-lkm, build-lkm ]
strategy:
matrix:
include:
- target: aarch64-linux-android
os: ubuntu-latest
uses: ./.github/workflows/kpmmgr.yml
with:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
build-user_scanner:
if: ${{ always() }}
needs: [ check-build-lkm, build-lkm ]
strategy:
matrix:
include:
- target: All-linux-android
os: ubuntu-latest
uses: ./.github/workflows/user_scanner.yml
with:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
build-ksud:
if: ${{ always() }}
needs: [ check-build-lkm, build-lkm ]
strategy:
matrix:
include:
- target: aarch64-linux-android
os: ubuntu-latest
- target: x86_64-linux-android
os: ubuntu-latest
- target: armv7-linux-androideabi
os: ubuntu-latest
uses: ./.github/workflows/ksud.yml
with:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
pack_lkm: true
pull_lkm: ${{ needs.check-build-lkm.outputs.build_lkm != 'true' }}
build-manager:
if: ${{ always() }}
needs: build-ksud
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./manager
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup need_upload
id: need_upload
run: |
if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then
echo "UPLOAD=true" >> $GITHUB_OUTPUT
else
echo "UPLOAD=false" >> $GITHUB_OUTPUT
fi
- name: Write key
if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref == 'refs/heads/susfs' || github.ref_type == 'tag' }}
run: |
if [ ! -z "${{ secrets.KEYSTORE }}" ]; then
{
echo KEYSTORE_PASSWORD='${{ secrets.KEYSTORE_PASSWORD }}'
echo KEY_ALIAS='${{ secrets.KEY_ALIAS }}'
echo KEY_PASSWORD='${{ secrets.KEY_PASSWORD }}'
echo KEYSTORE_FILE='key.jks'
} >> gradle.properties
echo "${{ secrets.KEYSTORE }}" | base64 -d > key.jks
fi
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Download all userscanner artifacts
uses: actions/download-artifact@v4
with:
name: userscanner-all-linux-android
path: .
- name: Download arm64 susfs
uses: actions/download-artifact@v4
with:
name: susfs-aarch64-linux-android
path: .
- name: Download arm64 kpmmgr
uses: actions/download-artifact@v4
with:
name: kpmmgr-aarch64-linux-android
path: .
- name: Download arm64 ksud
uses: actions/download-artifact@v4
with:
name: ksud-aarch64-linux-android
path: .
- name: Download x86_64 ksud
uses: actions/download-artifact@v4
with:
name: ksud-x86_64-linux-android
path: .
- name: Download arm ksud
uses: actions/download-artifact@v4
with:
name: ksud-armv7-linux-androideabi
path: .
- name: Copy ksud to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/x86_64
mkdir -p app/src/main/jniLibs/armeabi-v7a
cp -f ../aarch64-linux-android/release/zakozako ../manager/app/src/main/jniLibs/arm64-v8a/libzakozako.so
cp -f ../x86_64-linux-android/release/zakozako ../manager/app/src/main/jniLibs/x86_64/libzakozako.so
cp -f ../armv7-linux-androideabi/release/zakozako ../manager/app/src/main/jniLibs/armeabi-v7a/libzakozako.so
- name: Copy kpmmgr to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
cp -f ../arm64-v8a/kpmmgr ../manager/app/src/main/jniLibs/arm64-v8a/libkpmmgr.so
- name: Copy susfs to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
cp -f ../arm64-v8a/zakozakozako ../manager/app/src/main/jniLibs/arm64-v8a/libzakozakozako.so
- name: Copy user_scanner to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/x86_64
mkdir -p app/src/main/jniLibs/armeabi-v7a
cp -f ../arm64-v8a/uid_scanner ../manager/app/src/main/jniLibs/arm64-v8a/libuid_scanner.so
cp -f ../x86_64/uid_scanner ../manager/app/src/main/jniLibs/x86_64/libuid_scanner.so
cp -f ../armeabi-v7a/uid_scanner ../manager/app/src/main/jniLibs/armeabi-v7a/libuid_scanner.so
- name: Build with Gradle
run: ./gradlew clean assembleRelease
- name: Upload build artifact
uses: actions/upload-artifact@v4
if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' }}
with:
name: manager
path: manager/app/build/outputs/apk/release/*.apk
- name: Upload mappings
uses: actions/upload-artifact@v4
if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' }}
with:
name: "mappings"
path: "manager/app/build/outputs/mapping/release/"
- name: Bot session cache
if: github.event_name != 'pull_request' && steps.need_upload.outputs.UPLOAD == 'true'
id: bot_session_cache
uses: actions/cache@v4
with:
path: scripts/ksubot.session
key: ${{ runner.os }}-bot-session
- name: Upload to telegram
if: github.event_name != 'pull_request' && steps.need_upload.outputs.UPLOAD == 'true'
env:
CHAT_ID: ${{ vars.CHAT_ID }}
BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
MESSAGE_THREAD_ID: ${{ vars.MESSAGE_THREAD_ID }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
COMMIT_URL: ${{ github.event.head_commit.url }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
TITLE: Manager
run: |
if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then
export VERSION=$(git rev-list --count HEAD)
APK=$(find ./app/build/outputs/apk/release -name "*.apk")
pip3 install telethon
python3 $GITHUB_WORKSPACE/scripts/ksubot.py $APK
fi

View File

@@ -1,36 +0,0 @@
name: Build SU
on:
push:
branches: [ "main", "ci" ]
paths:
- '.github/workflows/build-su.yml'
- 'userspace/su/**'
- 'scripts/ksubot.py'
pull_request:
branches: [ "main" ]
paths:
- 'userspace/su/**'
jobs:
build-su:
name: Build userspace su
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup need_upload
id: need_upload
run: |
if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then
echo "UPLOAD=true" >> $GITHUB_OUTPUT
else
echo "UPLOAD=false" >> $GITHUB_OUTPUT
fi
- name: Build su
working-directory: ./userspace/su
run: $ANDROID_NDK/ndk-build
- name: Upload a Build Artifact
uses: actions/upload-artifact@v4
with:
name: su
path: ./userspace/su/libs

View File

@@ -1,37 +0,0 @@
name: Clippy check
on:
push:
branches:
- main
paths:
- '.github/workflows/clippy.yml'
- 'userspace/ksud/**'
pull_request:
branches:
- main
paths:
- '.github/workflows/clippy.yml'
- 'userspace/ksud/**'
env:
RUSTFLAGS: '-Dwarnings'
jobs:
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: rustup update stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: userspace/ksud
- name: Install cross
run: |
RUSTFLAGS="" cargo install cross --git https://github.com/cross-rs/cross --rev 66845c1
- name: Run clippy
run: |
cross clippy --manifest-path userspace/ksud/Cargo.toml --target aarch64-linux-android --release
cross clippy --manifest-path userspace/ksud/Cargo.toml --target x86_64-linux-android --release

View File

@@ -1,40 +0,0 @@
name: Crowdin Action
on:
push:
branches: [ main ]
paths:
- 'manager/app/src/main/res/values/strings.xml'
- 'manager/app/src/main/res/values-*/strings.xml'
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
jobs:
synchronize-with-crowdin:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Crowdin Action
uses: crowdin/github-action@v2
with:
upload_sources: true
upload_translations: true
auto_approve_imported: true
download_translations: true
skip_untranslated_files: false
skip_untranslated_strings: true
create_pull_request: true
localization_branch_name: "Crowdin"
pull_request_labels: 'enhancement, translation'
pull_request_title: 'opt: sync translation from Crowdin'
config: 'crowdin.yml'
crowdin_branch_name: "main"
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_API_TOKEN: ${{ secrets.CROWDIN_API_TOKEN }}

View File

@@ -1,252 +0,0 @@
name: GKI Kernel Build Local
on:
workflow_call:
inputs:
version:
required: true
type: string
description: >
Output directory of gki,
for example: android12-5.10
version_name:
required: true
type: string
description: >
With SUBLEVEL of kernel,
for example: android12-5.10.66
tag:
required: true
type: string
description: >
Part of branch name of common kernel manifest,
for example: android12-5.10-2021-11
os_patch_level:
required: false
type: string
description: >
Patch level of common kernel manifest,
for example: 2021-11
default: 2022-05
patch_path:
required: false
type: string
description: >
Directory name of .github/patches/<patch_path>
for example: 5.10
use_cache:
required: false
type: boolean
default: true
embed_ksud:
required: false
type: string
default: ksud-aarch64-linux-android
description: >
Artifact name of prebuilt ksud to be embedded
for example: ksud-aarch64-linux-android
debug:
required: false
type: boolean
default: false
build_lkm:
required: false
type: boolean
default: false
secrets:
BOOT_SIGN_KEY:
required: false
CHAT_ID:
required: false
BOT_TOKEN:
required: false
MESSAGE_THREAD_ID:
required: false
jobs:
build:
name: Build ${{ inputs.version_name }}
runs-on: self-hosted
env:
CCACHE_COMPILERCHECK: "%compiler% -dumpmachine; %compiler% -dumpversion"
CCACHE_NOHASHDIR: "true"
CCACHE_HARDLINK: "true"
steps:
- uses: actions/checkout@v4
with:
path: KernelSU
fetch-depth: 0
- name: Setup need_upload
id: need_upload
run: |
if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then
echo "UPLOAD=true" >> $GITHUB_OUTPUT
else
echo "UPLOAD=false" >> $GITHUB_OUTPUT
fi
- name: Setup kernel source
run: |
echo "Free space:"
df -h
cd $GITHUB_WORKSPACE
sudo apt-get install repo -y
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
mkdir android-kernel && cd android-kernel
repo init --depth=1 --u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/kernel/manifest -b common-${{ inputs.tag }} --repo-rev=v2.35
REMOTE_BRANCH=$(git ls-remote https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/kernel/common ${{ inputs.tag }})
DEFAULT_MANIFEST_PATH=.repo/manifests/default.xml
if grep -q deprecated <<< $REMOTE_BRANCH; then
echo "Found deprecated branch: ${{ inputs.tag }}"
sed -i 's/"${{ inputs.tag }}"/"deprecated\/${{ inputs.tag }}"/g' $DEFAULT_MANIFEST_PATH
cat $DEFAULT_MANIFEST_PATH
fi
repo --version
repo --trace sync -c -j$(nproc --all) --no-tags
df -h
- name: Setup KernelSU
env:
PATCH_PATH: ${{ inputs.patch_path }}
IS_DEBUG_KERNEL: ${{ inputs.debug }}
run: |
cd $GITHUB_WORKSPACE/android-kernel
echo "[+] KernelSU setup"
GKI_ROOT=$(pwd)
echo "[+] GKI_ROOT: $GKI_ROOT"
echo "[+] Copy KernelSU driver to $GKI_ROOT/common/drivers"
ln -sf $GITHUB_WORKSPACE/KernelSU/kernel $GKI_ROOT/common/drivers/kernelsu
echo "[+] Add KernelSU driver to Makefile"
DRIVER_MAKEFILE=$GKI_ROOT/common/drivers/Makefile
DRIVER_KCONFIG=$GKI_ROOT/common/drivers/Kconfig
grep -q "kernelsu" "$DRIVER_MAKEFILE" || printf "\nobj-\$(CONFIG_KSU) += kernelsu/\n" >> "$DRIVER_MAKEFILE"
grep -q "kernelsu" "$DRIVER_KCONFIG" || sed -i "/endmenu/i\\source \"drivers/kernelsu/Kconfig\"" "$DRIVER_KCONFIG"
echo "[+] Apply Compilation Patches"
if [ ! -e build/build.sh ]; then
GLIBC_VERSION=$(ldd --version 2>/dev/null | head -n 1 | awk '{print $NF}')
echo "GLIBC_VERSION: $GLIBC_VERSION"
if [ "$(printf '%s\n' "2.38" "$GLIBC_VERSION" | sort -V | head -n1)" = "2.38" ]; then
echo "Patching resolve_btfids/Makefile"
cd $GKI_ROOT/common/ && sed -i '/\$(Q)\$(MAKE) -C \$(SUBCMD_SRC) OUTPUT=\$(abspath \$(dir \$@))\/ \$(abspath \$@)/s//$(Q)$(MAKE) -C $(SUBCMD_SRC) EXTRA_CFLAGS="$(CFLAGS)" OUTPUT=$(abspath $(dir $@))\/ $(abspath $@)/' tools/bpf/resolve_btfids/Makefile || echo "No patch needed."
fi
fi
if [ "$IS_DEBUG_KERNEL" = "true" ]; then
echo "[+] Enable debug features for kernel"
printf "\nccflags-y += -DCONFIG_KSU_DEBUG\n" >> $GITHUB_WORKSPACE/KernelSU/kernel/Makefile
fi
repo status
echo "[+] KernelSU setup done."
- name: Symbol magic
run: |
echo "[+] Export all symbol from abi_gki_aarch64.xml"
COMMON_ROOT=$GITHUB_WORKSPACE/android-kernel/common
KSU_ROOT=$GITHUB_WORKSPACE/KernelSU
ABI_XML=$COMMON_ROOT/android/abi_gki_aarch64.xml
SYMBOL_LIST=$COMMON_ROOT/android/abi_gki_aarch64
# python3 $KSU_ROOT/scripts/abi_gki_all.py $ABI_XML > $SYMBOL_LIST
echo "[+] Add KernelSU symbols"
cat $KSU_ROOT/kernel/export_symbol.txt | awk '{sub("[ \t]+","");print " "$0}' >> $SYMBOL_LIST
- name: Setup ccache
if: inputs.use_cache == true
uses: hendrikmuhs/ccache-action@v1
with:
key: gki-kernel-aarch64-${{ inputs.version_name }}
max-size: 2G
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
- name: Setup for LKM
if: ${{ inputs.build_lkm == true }}
working-directory: android-kernel
run: |
pip install ast-grep-cli
sudo apt-get install llvm-15 -y
ast-grep -U -p '$$$ check_exports($$$) {$$$}' -r '' common/scripts/mod/modpost.c
ast-grep -U -p 'check_exports($$$);' -r '' common/scripts/mod/modpost.c
sed -i '/config KSU/,/help/{s/default y/default m/}' common/drivers/kernelsu/Kconfig
echo "drivers/kernelsu/kernelsu.ko" >> common/android/gki_aarch64_modules
# bazel build, android14-5.15, android14-6.1 use bazel
if [ ! -e build/build.sh ]; then
sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' build/kernel/*.sh || echo "No unknown symbol scripts found"
if [ -e common/modules.bzl ]; then
sed -i 's/_COMMON_GKI_MODULES_LIST = \[/_COMMON_GKI_MODULES_LIST = \[ "drivers\/kernelsu\/kernelsu.ko",/g' common/modules.bzl
fi
else
TARGET_FILE="build/kernel/build.sh"
if [ ! -e "$TARGET_FILE" ]; then
TARGET_FILE="build/build.sh"
fi
sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' $TARGET_FILE || echo "No unknown symbol in $TARGET_FILE"
sed -i 's/if ! diff -u "\${KERNEL_DIR}\/\${MODULES_ORDER}" "\${OUT_DIR}\/modules\.order"; then/if false; then/g' $TARGET_FILE
sed -i 's@${ROOT_DIR}/build/abi/compare_to_symbol_list@echo@g' $TARGET_FILE
sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' build/kernel/*.sh || echo "No unknown symbol scripts found"
fi
- name: Make working directory clean to avoid dirty
working-directory: android-kernel
run: |
if [ -e common/BUILD.bazel ]; then
sed -i '/^[[:space:]]*"protected_exports_list"[[:space:]]*:[[:space:]]*"android\/abi_gki_protected_exports_aarch64",$/d' common/BUILD.bazel
fi
rm common/android/abi_gki_protected_exports_* || echo "No protected exports!"
git config --global user.email "bot@kernelsu.org"
git config --global user.name "KernelSUBot"
cd common/ && git add -A && git commit -a -m "Add KernelSU"
repo status
- name: Build Kernel/LKM
working-directory: android-kernel
run: |
if [ ! -z ${{ vars.EXPECTED_SIZE }} ] && [ ! -z ${{ vars.EXPECTED_HASH }} ]; then
export KSU_EXPECTED_SIZE=${{ vars.EXPECTED_SIZE }}
export KSU_EXPECTED_HASH=${{ vars.EXPECTED_HASH }}
fi
if [ -e build/build.sh ]; then
LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh CC="/usr/bin/ccache clang"
else
tools/bazel run --disk_cache=/home/runner/.cache/bazel --config=fast --config=stamp --lto=thin //common:kernel_aarch64_dist -- --dist_dir=dist
fi
- name: Prepare artifacts
id: prepareArtifacts
run: |
OUTDIR=android-kernel/out/${{ inputs.version }}/dist
if [ ! -e $OUTDIR ]; then
OUTDIR=android-kernel/dist
fi
mkdir output
if [ "${{ inputs.build_lkm}}" = "true" ]; then
llvm-strip-15 -d $OUTDIR/kernelsu.ko
mv $OUTDIR/kernelsu.ko ./output/${{ inputs.version }}_kernelsu.ko
else
cp $OUTDIR/Image ./output/
cp $OUTDIR/Image.lz4 ./output/
git clone https://github.com/Kernel-SU/AnyKernel3
rm -rf ./AnyKernel3/.git
cp $OUTDIR/Image ./AnyKernel3/
fi
- name: Upload Image and Image.gz
uses: actions/upload-artifact@v4
if: ${{ inputs.build_lkm == false }}
with:
name: Image-${{ inputs.version_name }}_${{ inputs.os_patch_level }}
path: ./output/*
- name: Upload AnyKernel3
if: ${{ inputs.build_lkm == false }}
uses: actions/upload-artifact@v4
with:
name: AnyKernel3-${{ inputs.version_name }}_${{ inputs.os_patch_level }}
path: ./AnyKernel3/*
- name: Upload LKM
uses: actions/upload-artifact@v4
if: ${{ inputs.build_lkm == true }}
with:
name: ${{ inputs.version }}-lkm
path: ./output/*_kernelsu.ko

View File

@@ -1,79 +0,0 @@
name: GKI Kernel Build
on:
workflow_call:
inputs:
version:
required: true
type: string
description: >
Output directory of gki,
for example: android12-5.10
version_name:
required: true
type: string
description: >
With SUBLEVEL of kernel,
for example: android12-5.10.66
tag:
required: true
type: string
description: >
Part of branch name of common kernel manifest,
for example: android12-5.10-2021-11
os_patch_level:
required: false
type: string
description: >
Patch level of common kernel manifest,
for example: 2021-11
default: 2022-05
patch_path:
required: false
type: string
description: >
Directory name of .github/patches/<patch_path>
for example: 5.10
use_cache:
required: false
type: boolean
default: true
embed_ksud:
required: false
type: string
default: ksud-aarch64-linux-android
description: >
Artifact name of prebuilt ksud to be embedded
for example: ksud-aarch64-linux-android
debug:
required: false
type: boolean
default: false
build_lkm:
required: false
type: boolean
default: false
secrets:
BOOT_SIGN_KEY:
required: false
CHAT_ID:
required: false
BOT_TOKEN:
required: false
MESSAGE_THREAD_ID:
required: false
jobs:
mock_build:
name: Mock build ${{ inputs.version_name }}
runs-on: ubuntu-latest
steps:
- name: Create mocking ko
run: |
echo "${{ inputs.version }}_kernelsu.ko" > ${{ inputs.version }}_kernelsu.ko
- name: Upload LKM
uses: actions/upload-artifact@v4
if: ${{ inputs.build_lkm == true }}
with:
name: ${{ inputs.version }}-lkm
path: ./*_kernelsu.ko

View File

@@ -1,261 +0,0 @@
name: GKI Kernel Build
on:
workflow_call:
inputs:
version:
required: true
type: string
description: >
Output directory of gki,
for example: android12-5.10
version_name:
required: true
type: string
description: >
With SUBLEVEL of kernel,
for example: android12-5.10.66
tag:
required: true
type: string
description: >
Part of branch name of common kernel manifest,
for example: android12-5.10-2021-11
os_patch_level:
required: false
type: string
description: >
Patch level of common kernel manifest,
for example: 2021-11
default: 2022-05
patch_path:
required: false
type: string
description: >
Directory name of .github/patches/<patch_path>
for example: 5.10
use_cache:
required: false
type: boolean
default: true
embed_ksud:
required: false
type: string
default: ksud-aarch64-linux-android
description: >
Artifact name of prebuilt ksud to be embedded
for example: ksud-aarch64-linux-android
debug:
required: false
type: boolean
default: false
build_lkm:
required: false
type: boolean
default: false
secrets:
BOOT_SIGN_KEY:
required: false
CHAT_ID:
required: false
BOT_TOKEN:
required: false
MESSAGE_THREAD_ID:
required: false
jobs:
build:
name: Build ${{ inputs.version_name }}
runs-on: ubuntu-latest
env:
CCACHE_COMPILERCHECK: "%compiler% -dumpmachine; %compiler% -dumpversion"
CCACHE_NOHASHDIR: "true"
CCACHE_HARDLINK: "true"
steps:
- name: Maximize build space
uses: easimon/maximize-build-space@master
with:
root-reserve-mb: 8192
temp-reserve-mb: 2048
remove-dotnet: 'true'
remove-android: 'true'
remove-haskell: 'true'
remove-codeql: 'true'
- uses: actions/checkout@v4
with:
path: KernelSU
fetch-depth: 0
- name: Setup need_upload
id: need_upload
run: |
if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then
echo "UPLOAD=true" >> $GITHUB_OUTPUT
else
echo "UPLOAD=false" >> $GITHUB_OUTPUT
fi
- name: Setup kernel source
run: |
echo "Free space:"
df -h
cd $GITHUB_WORKSPACE
sudo apt-get install repo -y
mkdir android-kernel && cd android-kernel
repo init --depth=1 --u https://android.googlesource.com/kernel/manifest -b common-${{ inputs.tag }} --repo-rev=v2.35
REMOTE_BRANCH=$(git ls-remote https://android.googlesource.com/kernel/common ${{ inputs.tag }})
DEFAULT_MANIFEST_PATH=.repo/manifests/default.xml
if grep -q deprecated <<< $REMOTE_BRANCH; then
echo "Found deprecated branch: ${{ inputs.tag }}"
sed -i 's/"${{ inputs.tag }}"/"deprecated\/${{ inputs.tag }}"/g' $DEFAULT_MANIFEST_PATH
cat $DEFAULT_MANIFEST_PATH
fi
repo --version
repo --trace sync -c -j$(nproc --all) --no-tags
df -h
- name: Setup KernelSU
env:
PATCH_PATH: ${{ inputs.patch_path }}
IS_DEBUG_KERNEL: ${{ inputs.debug }}
run: |
cd $GITHUB_WORKSPACE/android-kernel
echo "[+] KernelSU setup"
GKI_ROOT=$(pwd)
echo "[+] GKI_ROOT: $GKI_ROOT"
echo "[+] Copy KernelSU driver to $GKI_ROOT/common/drivers"
ln -sf $GITHUB_WORKSPACE/KernelSU/kernel $GKI_ROOT/common/drivers/kernelsu
echo "[+] Add KernelSU driver to Makefile"
DRIVER_MAKEFILE=$GKI_ROOT/common/drivers/Makefile
DRIVER_KCONFIG=$GKI_ROOT/common/drivers/Kconfig
grep -q "kernelsu" "$DRIVER_MAKEFILE" || printf "\nobj-\$(CONFIG_KSU) += kernelsu/\n" >> "$DRIVER_MAKEFILE"
grep -q "kernelsu" "$DRIVER_KCONFIG" || sed -i "/endmenu/i\\source \"drivers/kernelsu/Kconfig\"" "$DRIVER_KCONFIG"
echo "[+] Apply Compilation Patches"
if [ ! -e build/build.sh ]; then
GLIBC_VERSION=$(ldd --version 2>/dev/null | head -n 1 | awk '{print $NF}')
echo "GLIBC_VERSION: $GLIBC_VERSION"
if [ "$(printf '%s\n' "2.38" "$GLIBC_VERSION" | sort -V | head -n1)" = "2.38" ]; then
echo "Patching resolve_btfids/Makefile"
cd $GKI_ROOT/common/ && sed -i '/\$(Q)\$(MAKE) -C \$(SUBCMD_SRC) OUTPUT=\$(abspath \$(dir \$@))\/ \$(abspath \$@)/s//$(Q)$(MAKE) -C $(SUBCMD_SRC) EXTRA_CFLAGS="$(CFLAGS)" OUTPUT=$(abspath $(dir $@))\/ $(abspath $@)/' tools/bpf/resolve_btfids/Makefile || echo "No patch needed."
fi
fi
if [ "$IS_DEBUG_KERNEL" = "true" ]; then
echo "[+] Enable debug features for kernel"
printf "\nccflags-y += -DCONFIG_KSU_DEBUG\n" >> $GITHUB_WORKSPACE/KernelSU/kernel/Makefile
fi
repo status
echo "[+] KernelSU setup done."
- name: Symbol magic
run: |
echo "[+] Export all symbol from abi_gki_aarch64.xml"
COMMON_ROOT=$GITHUB_WORKSPACE/android-kernel/common
KSU_ROOT=$GITHUB_WORKSPACE/KernelSU
ABI_XML=$COMMON_ROOT/android/abi_gki_aarch64.xml
SYMBOL_LIST=$COMMON_ROOT/android/abi_gki_aarch64
# python3 $KSU_ROOT/scripts/abi_gki_all.py $ABI_XML > $SYMBOL_LIST
echo "[+] Add KernelSU symbols"
cat $KSU_ROOT/kernel/export_symbol.txt | awk '{sub("[ \t]+","");print " "$0}' >> $SYMBOL_LIST
- name: Setup ccache
if: inputs.use_cache == true
uses: hendrikmuhs/ccache-action@v1
with:
key: gki-kernel-aarch64-${{ inputs.version_name }}
max-size: 2G
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
- name: Setup for LKM
if: ${{ inputs.build_lkm == true }}
working-directory: android-kernel
run: |
pip install ast-grep-cli
sudo apt-get install llvm-15 -y
ast-grep -U -p '$$$ check_exports($$$) {$$$}' -r '' common/scripts/mod/modpost.c
ast-grep -U -p 'check_exports($$$);' -r '' common/scripts/mod/modpost.c
sed -i '/config KSU/,/help/{s/default y/default m/}' common/drivers/kernelsu/Kconfig
echo "drivers/kernelsu/kernelsu.ko" >> common/android/gki_aarch64_modules
# bazel build, android14-5.15, android14-6.1 use bazel
if [ ! -e build/build.sh ]; then
sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' build/kernel/*.sh || echo "No unknown symbol scripts found"
if [ -e common/modules.bzl ]; then
sed -i 's/_COMMON_GKI_MODULES_LIST = \[/_COMMON_GKI_MODULES_LIST = \[ "drivers\/kernelsu\/kernelsu.ko",/g' common/modules.bzl
fi
else
TARGET_FILE="build/kernel/build.sh"
if [ ! -e "$TARGET_FILE" ]; then
TARGET_FILE="build/build.sh"
fi
sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' $TARGET_FILE || echo "No unknown symbol in $TARGET_FILE"
sed -i 's/if ! diff -u "\${KERNEL_DIR}\/\${MODULES_ORDER}" "\${OUT_DIR}\/modules\.order"; then/if false; then/g' $TARGET_FILE
sed -i 's@${ROOT_DIR}/build/abi/compare_to_symbol_list@echo@g' $TARGET_FILE
sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' build/kernel/*.sh || echo "No unknown symbol scripts found"
fi
- name: Make working directory clean to avoid dirty
working-directory: android-kernel
run: |
if [ -e common/BUILD.bazel ]; then
sed -i '/^[[:space:]]*"protected_exports_list"[[:space:]]*:[[:space:]]*"android\/abi_gki_protected_exports_aarch64",$/d' common/BUILD.bazel
fi
rm common/android/abi_gki_protected_exports_* || echo "No protected exports!"
git config --global user.email "bot@kernelsu.org"
git config --global user.name "KernelSUBot"
cd common/ && git add -A && git commit -a -m "Add KernelSU"
repo status
- name: Build Kernel/LKM
working-directory: android-kernel
run: |
if [ ! -z ${{ vars.EXPECTED_SIZE }} ] && [ ! -z ${{ vars.EXPECTED_HASH }} ]; then
export KSU_EXPECTED_SIZE=${{ vars.EXPECTED_SIZE }}
export KSU_EXPECTED_HASH=${{ vars.EXPECTED_HASH }}
fi
if [ -e build/build.sh ]; then
LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh CC="/usr/bin/ccache clang"
else
tools/bazel run --disk_cache=/home/runner/.cache/bazel --config=fast --config=stamp --lto=thin //common:kernel_aarch64_dist -- --dist_dir=dist
fi
- name: Prepare artifacts
id: prepareArtifacts
run: |
OUTDIR=android-kernel/out/${{ inputs.version }}/dist
if [ ! -e $OUTDIR ]; then
OUTDIR=android-kernel/dist
fi
mkdir output
if [ "${{ inputs.build_lkm}}" = "true" ]; then
llvm-strip-15 -d $OUTDIR/kernelsu.ko
mv $OUTDIR/kernelsu.ko ./output/${{ inputs.version }}_kernelsu.ko
else
cp $OUTDIR/Image ./output/
cp $OUTDIR/Image.lz4 ./output/
git clone https://github.com/Kernel-SU/AnyKernel3
rm -rf ./AnyKernel3/.git
cp $OUTDIR/Image ./AnyKernel3/
fi
- name: Upload Image and Image.gz
uses: actions/upload-artifact@v4
if: ${{ inputs.build_lkm == false }}
with:
name: Image-${{ inputs.version_name }}_${{ inputs.os_patch_level }}
path: ./output/*
- name: Upload AnyKernel3
if: ${{ inputs.build_lkm == false }}
uses: actions/upload-artifact@v4
with:
name: AnyKernel3-${{ inputs.version_name }}_${{ inputs.os_patch_level }}
path: ./AnyKernel3/*
- name: Upload LKM
uses: actions/upload-artifact@v4
if: ${{ inputs.build_lkm == true }}
with:
name: ${{ inputs.version }}-lkm
path: ./output/*_kernelsu.ko

View File

@@ -1,40 +0,0 @@
name: Build kpmmgr
on:
push:
branches: [ "mian" ]
paths:
- '.github/workflows/kpmmgr.yml'
- 'userspace/kpmmgr/**'
workflow_dispatch:
workflow_call:
inputs:
target:
required: true
type: string
os:
required: false
type: string
default: self-hosted
jobs:
build-susfs:
name: Build userspace kpmmgr
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Build kpmmgr
working-directory: ./userspace/kpmmgr
run: |
$ANDROID_NDK_HOME/ndk-build
- name: Upload a Build Artifact
uses: actions/upload-artifact@v4
with:
name: kpmmgr-aarch64-linux-android
path: ./userspace/kpmmgr/libs

View File

@@ -1,74 +0,0 @@
name: Build ksud
on:
workflow_call:
inputs:
target:
required: true
type: string
os:
required: false
type: string
default: ubuntu-latest
pull_lkm:
required: false
type: boolean
default: true
pack_lkm:
required: false
type: boolean
default: true
use_cache:
required: false
type: boolean
default: true
jobs:
build:
runs-on: ${{ inputs.os }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Pull lkms from branch
if: ${{ inputs.pack_lkm && inputs.pull_lkm }}
uses: actions/checkout@v4
with:
ref: lkm
path: lkm
- name: Download lkms from artifacts
if: ${{ inputs.pack_lkm && !inputs.pull_lkm }}
uses: actions/download-artifact@v4
- name: Prepare LKM files
if: ${{ inputs.pack_lkm && inputs.pull_lkm }}
run: |
cp lkm/*_kernelsu.ko ./userspace/ksud/bin/aarch64/
- name: Prepare LKM files
if: ${{ inputs.pack_lkm && !inputs.pull_lkm }}
run: |
cp android*-lkm/*_kernelsu.ko ./userspace/ksud/bin/aarch64/
- name: Setup rustup
run: |
rustup update stable
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin
- uses: Swatinem/rust-cache@v2
with:
workspaces: userspace/ksud
cache-targets: false
- name: Install cross
run: |
RUSTFLAGS="" cargo install cross --git https://github.com/cross-rs/cross --rev 66845c1
- name: Build ksud
run: CROSS_NO_WARNINGS=0 cross build --target ${{ inputs.target }} --release --manifest-path ./userspace/ksud/Cargo.toml
- name: Upload ksud artifact
uses: actions/upload-artifact@v4
with:
name: ksud-${{ inputs.target }}
path: userspace/ksud/target/**/release/zakozako*

View File

@@ -1,33 +0,0 @@
name: Rustfmt check
on:
push:
branches:
- 'main'
paths:
- '.github/workflows/rustfmt.yml'
- 'userspace/ksud/**'
pull_request:
branches:
- 'main'
paths:
- '.github/workflows/rustfmt.yml'
- 'userspace/ksud/**'
permissions:
checks: write
jobs:
format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
components: rustfmt
- uses: LoliGothick/rustfmt-check@master
with:
token: ${{ github.token }}
working-directory: userspace/ksud

View File

@@ -1,27 +0,0 @@
name: ShellCheck
on:
push:
branches:
- 'main'
paths:
- '.github/workflows/shellcheck.yml'
- '**/*.sh'
pull_request:
branches:
- 'main'
paths:
- '.github/workflows/shellcheck.yml'
- '**/*.sh'
jobs:
shellcheck:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- name: Run ShellCheck
uses: ludeeus/action-shellcheck@2.0.0
with:
ignore_names: gradlew
ignore_paths: ./userspace/ksud/src/installer.sh

View File

@@ -1,40 +0,0 @@
name: Build susfs
on:
push:
branches: [ "mian" ]
paths:
- '.github/workflows/susfs.yml'
- 'userspace/susfs/**'
workflow_dispatch:
workflow_call:
inputs:
target:
required: true
type: string
os:
required: false
type: string
default: self-hosted
jobs:
build-susfs:
name: Build userspace susfs
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Build susfs
working-directory: ./userspace/susfs
run: |
$ANDROID_NDK_HOME/ndk-build
- name: Upload a Build Artifact
uses: actions/upload-artifact@v4
with:
name: susfs-aarch64-linux-android
path: ./userspace/susfs/libs

View File

@@ -1,40 +0,0 @@
name: Build user_scanner
on:
push:
branches: [ "mian" ]
paths:
- '.github/workflows/user_scanner.yml'
- 'userspace/user_scanner/**'
workflow_dispatch:
workflow_call:
inputs:
target:
required: true
type: string
os:
required: false
type: string
default: self-hosted
jobs:
build-user_scanner:
name: Build userspace user_scanner
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Build user_scanner
working-directory: ./userspace/user_scanner
run: |
$ANDROID_NDK_HOME/ndk-build
- name: Upload a Build Artifact
uses: actions/upload-artifact@v4
with:
name: userscanner-all-linux-android
path: ./userspace/user_scanner/libs

4
.gitignore vendored
View File

@@ -1,3 +1 @@
.idea
.vscode
.DS_Store
manager

View File

@@ -1,7 +0,0 @@
# Reporting Security Issues
The KernelSU team and community take security bugs in KernelSU seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/tiann/KernelSU/security/advisories/new) tab, or you can mailto [weishu](mailto:twsxtd@gmail.com) directly.
The KernelSU team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.

89
Website/.gitignore vendored
View File

@@ -1,89 +0,0 @@
node_modules
pnpm-lock.yaml
package-lock.json
yarn.lock
.wrangler
.DS_Store
.vscode
.idea
.vite_opt_cache
# Build artifacts
docs/.vitepress/dist/
docs/.vitepress/cache/
docs/.vitepress/.temp/
dist/
# Generated files
docs/public/sw.js
docs/public/favicon*.png
docs/public/favicon.ico
docs/public/android-chrome-*.png
docs/public/apple-touch-icon*.png
docs/public/safari-pinned-tab.svg
docs/public/browserconfig.xml
docs/public/site.webmanifest
docs/public/manifest.webmanifest
docs/public/mstile-*.png
docs/public/favicons.html
favicon-data.json
# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Coverage directory used by tools like istanbul
coverage/
*.lcov
# Dependency directories
.pnpm-store/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Stores VSCode versions used for testing VSCode extensions
.vscode-test

View File

@@ -1,14 +0,0 @@
# Build artifacts
node_modules/
dist/
docs/.vitepress/cache/
docs/.vitepress/dist/
# Logs
*.log
# Lockfiles backup
pnpm-debug.log*
# Generated
.DS_Store

View File

@@ -1,10 +0,0 @@
{
"$schema": "https://json.schemastore.org/prettierrc",
"singleQuote": true,
"semi": false,
"trailingComma": "es5",
"printWidth": 100,
"tabWidth": 2,
"arrowParens": "always",
"endOfLine": "lf"
}

View File

@@ -1,7 +0,0 @@
# SukiSU-Ultra Documentation
[![Website](https://img.shields.io/website?url=https%3A%2F%2Fsukisu.org&logo=Cloudflare&label=Cloudflare%20Pages&style=flat-square)](https://sukisu.org)
[![VitePress](https://img.shields.io/badge/VitePress-2.0.0--alpha.12-646cff?logo=vite&logoColor=white&style=flat-square)](https://vitepress.dev)
[![License](https://img.shields.io/badge/License-Multiple-blue?style=flat-square)](https://sukisu.org/guide/license)
[![Last Commit](https://img.shields.io/github/last-commit/sukisu-ultra/sukisu-ultra?style=flat-square)](https://github.com/sukisu-ultra/sukisu-ultra/commits/main)
[![GitHub Stars](https://img.shields.io/github/stars/sukisu-ultra/sukisu-ultra?style=flat-square)](https://github.com/sukisu-ultra/sukisu-ultra/stargazers)

View File

@@ -1,18 +0,0 @@
/coverage
/src/client/shared.ts
/src/node/shared.ts
*.log
*.tgz
.DS_Store
.idea
.temp
.vite_opt_cache
.vscode
dist
cache
temp
examples-temp
node_modules
pnpm-global
TODOs.md
*.timestamp-*.mjs

View File

@@ -1,248 +0,0 @@
import { defineConfig } from 'vitepress'
import { groupIconMdPlugin, groupIconVitePlugin } from 'vitepress-plugin-group-icons'
import {
GitChangelog,
GitChangelogMarkdownSection,
} from '@nolebase/vitepress-plugin-git-changelog/vite'
import footnote from 'markdown-it-footnote'
import mark from 'markdown-it-mark'
import sub from 'markdown-it-sub'
import taskLists from 'markdown-it-task-lists'
export default defineConfig({
title: 'SukiSU-Ultra',
description: 'Next-Generation Android root solution.',
lastUpdated: true,
cleanUrls: true,
metaChunk: true,
// Global performance optimizations
cacheDir: './.vitepress/cache',
ignoreDeadLinks: false,
// Enhanced markdown with performance focus
markdown: {
math: true,
config(md) {
md.use(groupIconMdPlugin)
md.use(footnote)
md.use(mark)
md.use(sub)
md.use(taskLists)
},
linkify: true,
typographer: true,
lineNumbers: true,
image: {
lazyLoading: true,
},
toc: {
level: [1, 2, 3],
},
theme: {
light: 'github-light',
dark: 'github-dark',
},
},
sitemap: {
hostname: 'https://sukisu.org',
transformItems(items) {
return items
.filter((item) => !item.url.includes('404'))
.map((item) => ({
...item,
changefreq:
item.url === '/' ? 'daily' : item.url.includes('/guide/') ? 'weekly' : 'monthly',
priority: item.url === '/' ? 1.0 : item.url.includes('/guide/') ? 0.9 : 0.7,
}))
},
},
// Critical performance transformations
transformPageData(pageData) {
const canonicalUrl = `https://sukisu.org${pageData.relativePath}`
.replace(/index\.md$/, '')
.replace(/\.md$/, '')
pageData.frontmatter.head ??= []
pageData.frontmatter.head.push(
['link', { rel: 'canonical', href: canonicalUrl }],
['meta', { property: 'og:url', content: canonicalUrl }],
['link', { rel: 'preload', href: '/logo.svg', as: 'image' }]
)
return pageData
},
head: [
// Critical resource hints for global performance
['link', { rel: 'dns-prefetch', href: '//github.com' }],
['link', { rel: 'dns-prefetch', href: '//t.me' }],
['link', { rel: 'dns-prefetch', href: '//sukisu.org' }],
// Essential favicon setup - synced from /favicon during build/dev
['link', { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
['link', { rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' }],
['link', { rel: 'icon', type: 'image/png', sizes: '96x96', href: '/favicon-96x96.png' }],
['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' }],
['link', { rel: 'mask-icon', href: '/safari-pinned-tab.svg', color: '#64edff' }],
// (Removed msapplication meta to avoid referencing non-existent files)
// Web App Manifest
['link', { rel: 'manifest', href: '/site.webmanifest' }],
// Theme and app configuration
['meta', { name: 'theme-color', content: '#64edff' }],
['meta', { name: 'application-name', content: 'SukiSU-Ultra' }],
['meta', { name: 'apple-mobile-web-app-title', content: 'SukiSU-Ultra' }],
['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'default' }],
// Viewport and mobile optimization
[
'meta',
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, viewport-fit=cover' },
],
['meta', { name: 'format-detection', content: 'telephone=no' }],
['meta', { property: 'og:type', content: 'website' }],
['meta', { property: 'og:site_name', content: 'SukiSU-Ultra' }],
['meta', { property: 'og:url', content: 'https://sukisu.org/' }],
['meta', { property: 'og:locale', content: 'en_US' }],
['meta', { property: 'og:locale:alternate', content: 'zh_CN' }],
// Twitter optimization for global audience
['meta', { property: 'twitter:card', content: 'summary_large_image' }],
['meta', { property: 'twitter:site', content: '@sukisu_ultra' }],
['meta', { property: 'twitter:creator', content: '@sukisu_ultra' }],
// (Removed Twitter image as no PNG social image is provided)
// Additional SEO optimizations
[
'meta',
{
name: 'robots',
content: 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1',
},
],
['meta', { name: 'bingbot', content: 'index, follow' }],
['meta', { name: 'referrer', content: 'strict-origin-when-cross-origin' }],
// Global SEO optimization
[
'meta',
{
name: 'keywords',
content:
'Android root, KernelSU, SukiSU-Ultra, Android kernel, root management, 安卓 root, カーネル, рут',
},
],
['meta', { name: 'author', content: 'SukiSU-Ultra Team' }],
// Enhanced structured data for global search engines
[
'script',
{ type: 'application/ld+json' },
JSON.stringify({
'@context': 'https://schema.org',
'@type': 'SoftwareApplication',
name: 'SukiSU-Ultra',
description: 'Next-Generation Android Root Solution',
applicationCategory: 'SystemApplication',
operatingSystem: 'Android',
url: 'https://sukisu.org',
downloadUrl: 'https://github.com/sukisu-ultra/sukisu-ultra/releases',
supportingData: {
'@type': 'DataCatalog',
name: 'Compatibility Database',
},
offers: {
'@type': 'Offer',
price: '0',
priceCurrency: 'USD',
},
author: {
'@type': 'Organization',
name: 'SukiSU-Ultra Team',
url: 'https://github.com/sukisu-ultra',
},
}),
],
// PWA optimization for global mobile users (manifest declared above)
['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black-translucent' }],
['meta', { name: 'apple-mobile-web-app-title', content: 'SukiSU-Ultra' }],
// Cloudflare Web Analytics
[
'script',
{
defer: '',
src: 'https://static.cloudflareinsights.com/beacon.min.js',
'data-cf-beacon': '{"token": "dcc5feef58bf4c56a170a99f4cec4798"}',
},
],
],
themeConfig: {
logo: { src: '/logo.svg', width: 24, height: 24 },
socialLinks: [
{ icon: 'github', link: 'https://github.com/sukisu-ultra/sukisu-ultra' },
{
icon: {
svg: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-brand-telegram"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 10l-4 4l6 6l4 -16l-18 7l4 2l2 6l3 -4" /></svg>',
},
link: 'https://t.me/sukiksu',
},
],
search: {
provider: 'local',
},
},
rewrites: {
'en/:rest*': ':rest*',
},
locales: {
root: {
label: 'English',
},
zh: {
label: '简体中文',
link: '/zh/',
},
},
vite: {
plugins: [
groupIconVitePlugin({
customIcon: {
bash: '<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256"><g fill="none"><rect width="256" height="256" fill="#242938" rx="60"/><path fill="#242938" fill-rule="evenodd" d="m203.819 68.835l-63.14-37.48a23.79 23.79 0 0 0-24.361 0l-63.14 37.48C45.642 73.31 41 81.575 41 90.522v74.961c0 8.945 4.643 17.215 12.18 21.689l63.14 37.473a23.8 23.8 0 0 0 12.179 3.354a23.8 23.8 0 0 0 12.178-3.354l63.14-37.473c7.536-4.474 12.182-12.744 12.182-21.689v-74.96c0-8.948-4.646-17.214-12.18-21.688" clip-rule="evenodd"/><path fill="#fff" fill-rule="evenodd" d="m118.527 220.808l-63.14-37.474c-6.176-3.666-10.013-10.506-10.013-17.852V90.523c0-7.346 3.837-14.186 10.01-17.85l63.143-37.48a19.55 19.55 0 0 1 9.972-2.747c3.495 0 6.943.95 9.973 2.747l63.14 37.48c5.204 3.089 8.714 8.438 9.701 14.437c-2.094-4.469-6.817-5.684-12.32-2.47l-59.734 36.897c-7.448 4.354-12.94 9.24-12.945 18.221v73.604c-.004 5.378 2.168 8.861 5.504 9.871c-1.096.19-2.201.322-3.319.322a19.55 19.55 0 0 1-9.972-2.747m85.292-151.974l-63.14-37.478A23.8 23.8 0 0 0 128.499 28a23.8 23.8 0 0 0-12.181 3.356l-63.14 37.478C45.642 73.308 41 81.576 41 90.524v74.958c0 8.945 4.643 17.215 12.18 21.689l63.14 37.475A23.84 23.84 0 0 0 128.499 228a23.83 23.83 0 0 0 12.178-3.354l63.142-37.475c7.536-4.474 12.18-12.744 12.18-21.689V90.523c0-8.947-4.644-17.215-12.18-21.689" clip-rule="evenodd"/><path fill="#47b353" fill-rule="evenodd" d="m187.267 172.729l-15.722 9.41c-.417.243-.723.516-.726 1.017v4.114c0 .503.338.712.754.467l15.966-9.703c.416-.243.48-.708.483-1.209v-3.629c0-.5-.338-.71-.755-.467" clip-rule="evenodd"/><path fill="#242938" fill-rule="evenodd" d="M153.788 138.098c.509-.258.928.059.935.725l.053 5.439c2.277-.906 4.255-1.148 6.047-.734c.389.104.561.633.402 1.261l-1.197 4.82c-.093.364-.298.732-.545.961a1.3 1.3 0 0 1-.315.234a.7.7 0 0 1-.472.077c-.818-.185-2.763-.61-5.823.94c-3.21 1.625-4.333 4.414-4.311 6.484c.027 2.472 1.295 3.221 5.673 3.296c5.834.097 8.355 2.646 8.416 8.522c.06 5.77-3.02 11.966-7.732 15.763l.104 5.384c.006.648-.415 1.391-.924 1.649l-3.189 1.837c-.511.258-.93-.06-.937-.708l-.055-5.296c-2.731 1.135-5.499 1.409-7.267.699c-.333-.13-.476-.622-.344-1.182l1.156-4.868c.092-.384.295-.768.571-1.012q.147-.142.299-.219c.183-.092.362-.112.514-.055c1.905.642 4.342.342 6.685-.844c2.977-1.506 4.968-4.542 4.937-7.558c-.029-2.737-1.51-3.874-5.113-3.901c-4.586.013-8.861-.891-8.932-7.642c-.057-5.558 2.833-11.342 7.408-14.999l-.057-5.435c-.007-.668.401-1.403.926-1.667z" clip-rule="evenodd"/></g></svg>',
},
}),
GitChangelog({ repoURL: () => 'https://github.com/SukiSU-Ultra/Website' }),
GitChangelogMarkdownSection({
exclude: (id) => id.endsWith('index.md'),
sections: { disableContributors: true },
}),
],
build: {
minify: 'terser',
chunkSizeWarningLimit: 800,
assetsInlineLimit: 8192,
target: 'esnext',
cssCodeSplit: true,
sourcemap: false,
},
server: {
fs: {
allow: ['..'],
},
},
},
})

View File

@@ -1,195 +0,0 @@
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useData } from 'vitepress'
const props = defineProps({
shareText: {
type: String,
default: undefined,
},
copiedText: {
type: String,
default: undefined,
},
includeQuery: {
type: Boolean,
default: false,
},
includeHash: {
type: Boolean,
default: false,
},
copiedTimeout: {
type: Number,
default: 2000,
},
})
defineOptions({ name: 'ArticleShare' })
const copied = ref(false)
const isClient = typeof window !== 'undefined' && typeof document !== 'undefined'
const { theme, lang } = useData()
const defaultShareText = computed(() =>
lang.value?.toLowerCase().startsWith('zh') ? '分享链接' : 'Share link'
)
const defaultCopiedText = computed(() =>
lang.value?.toLowerCase().startsWith('zh') ? '已复制!' : 'Copied!'
)
const defaultCopyFailedText = computed(() =>
lang.value?.toLowerCase().startsWith('zh') ? '复制链接失败:' : 'Failed to copy link:'
)
const i18nShareText = computed(
() => props.shareText ?? (theme.value as any)?.articleShare?.shareText ?? defaultShareText.value
)
const i18nCopiedText = computed(
() =>
props.copiedText ?? (theme.value as any)?.articleShare?.copiedText ?? defaultCopiedText.value
)
const i18nCopyFailedText = computed(
() => (theme.value as any)?.articleShare?.copyFailed ?? defaultCopyFailedText.value
)
const shareLink = computed(() => {
if (!isClient) return ''
const { origin, pathname, search, hash } = window.location
const finalSearch = props.includeQuery ? search : ''
const finalHash = props.includeHash ? hash : ''
return `${origin}${pathname}${finalSearch}${finalHash}`
})
async function copyToClipboard() {
if (copied.value || !isClient) return
try {
if (navigator.clipboard) {
await navigator.clipboard.writeText(shareLink.value)
} else {
const input = document.createElement('input')
input.setAttribute('readonly', 'readonly')
input.setAttribute('value', shareLink.value)
document.body.appendChild(input)
input.select()
document.execCommand('copy')
document.body.removeChild(input)
}
copied.value = true
setTimeout(() => {
copied.value = false
}, props.copiedTimeout)
} catch (error) {
console.error(i18nCopyFailedText.value, error)
}
}
const shareIconSvg = `
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"></path>
<polyline points="16 6 12 2 8 6"></polyline>
<line x1="12" y1="2" x2="12" y2="15"></line>
</svg>
`
const copiedIconSvg = `
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M20 6 9 17l-5-5"></path>
</svg>
`
</script>
<template>
<div class="article-share">
<button
:class="['article-share__button', { copied: copied }]"
:aria-label="copied ? i18nCopiedText : i18nShareText"
aria-live="polite"
@click="copyToClipboard"
>
<div v-if="!copied" class="content-wrapper">
<span class="icon" v-html="shareIconSvg"></span>
{{ i18nShareText }}
</div>
<div v-else class="content-wrapper">
<span class="icon" v-html="copiedIconSvg"></span>
{{ i18nCopiedText }}
</div>
</button>
</div>
</template>
<style scoped>
.article-share {
padding: 14px 0;
}
.article-share__button {
display: flex;
justify-content: center;
align-items: center;
font-weight: 500;
font-size: 14px;
position: relative;
z-index: 1;
transition: all 0.4s var(--ease-out-cubic, cubic-bezier(0.33, 1, 0.68, 1));
cursor: pointer;
border: 1px solid transparent;
border-radius: 14px;
padding: 7px 14px;
width: 100%;
overflow: hidden;
color: var(--vp-c-text-1, #333);
background-color: var(--vp-c-bg-alt, #f6f6f7);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.02);
will-change: transform, box-shadow;
}
.article-share__button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
z-index: -1;
transition: left 0.6s ease;
background-color: var(--vp-c-brand-soft, #ddf4ff);
width: 100%;
height: 100%;
}
.article-share__button:hover {
transform: translateY(-1px);
border-color: var(--vp-c-brand-soft, #ddf4ff);
background-color: var(--vp-c-brand-soft, #ddf4ff);
}
.article-share__button:active {
transform: scale(0.9);
}
.article-share__button.copied {
color: var(--vp-c-brand-1, #007acc);
background-color: var(--vp-c-brand-soft, #ddf4ff);
}
.article-share__button.copied::before {
left: 0;
background-color: var(--vp-c-brand-soft, #ddf4ff);
}
.content-wrapper {
display: flex;
align-items: center;
justify-content: center;
}
.icon {
display: inline-flex;
align-items: center;
margin-right: 6px;
}
</style>

View File

@@ -1,12 +0,0 @@
<script setup lang="ts">
import confetti from 'canvas-confetti'
const media = window.matchMedia('(prefers-reduced-motion: reduce)')
if (!media.matches) {
confetti({
particleCount: 100,
spread: 170,
origin: { y: 0.6 },
})
}
</script>

View File

@@ -1,150 +0,0 @@
<script setup>
import { onBeforeUnmount, onMounted, ref, computed } from 'vue'
const showBackTop = ref(false) // 初始状态设为false
const scrollProgress = ref(0)
// 圆形进度条计算
const radius = 42
const circumference = computed(() => 2 * Math.PI * radius)
function scrollToTop() {
window.scrollTo({
top: 0,
behavior: 'smooth',
})
}
// 使用更高效的节流函数
function throttle(fn, delay = 50) {
let timer = null
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, args)
timer = null
}, delay)
}
}
}
const updateScrollProgress = () => {
const { scrollY, innerHeight } = window
const { scrollHeight } = document.documentElement
const totalScroll = scrollHeight - innerHeight
scrollProgress.value = totalScroll > 0 ? Math.min(scrollY / totalScroll, 1) : 0
}
const handleScroll = throttle(() => {
// 当滚动超过100px时显示否则隐藏
const shouldShow = window.scrollY > 100
showBackTop.value = shouldShow
updateScrollProgress()
})
onMounted(() => {
window.addEventListener('scroll', handleScroll)
updateScrollProgress()
})
onBeforeUnmount(() => {
window.removeEventListener('scroll', handleScroll)
})
</script>
<template>
<Transition name="fade">
<div class="back-top-container" v-show="showBackTop">
<svg class="progress-ring" viewBox="0 0 100 100">
<circle class="progress-ring-background" cx="50" cy="50" r="42" />
<circle
class="progress-ring-circle"
cx="50"
cy="50"
r="42"
:style="{ 'stroke-dashoffset': circumference - scrollProgress * circumference }"
/>
</svg>
<div class="vitepress-backTop-main" title="返回顶部" @click="scrollToTop()">
<svg class="icon" viewBox="0 0 1024 1024">
<path
d="M752.736 431.063C757.159 140.575 520.41 8.97 504.518 0.41V0l-0.45 0.205-0.41-0.205v0.41c-15.934 8.56-252.723 140.165-248.259 430.653-48.21 31.457-98.713 87.368-90.685 184.074 8.028 96.666 101.007 160.768 136.601 157.287 35.595-3.482 25.232-30.31 25.232-30.31l12.206-50.095s52.47 80.569 69.304 80.528c15.114-1.23 87-0.123 95.6 0h0.82c8.602-0.123 80.486-1.23 95.6 0 16.794 0 69.305-80.528 69.305-80.528l12.165 50.094s-10.322 26.83 25.272 30.31c35.595 3.482 128.574-60.62 136.602-157.286 8.028-96.665-42.475-152.617-90.685-184.074z m-248.669-4.26c-6.758-0.123-94.781-3.359-102.891-107.192 2.95-98.714 95.97-107.438 102.891-107.93 6.964 0.492 99.943 9.216 102.892 107.93-8.11 103.833-96.174 107.07-102.892 107.192z m-52.019 500.531c0 11.838-9.42 21.382-21.012 21.382a21.217 21.217 0 0 1-21.054-21.34V821.74c0-11.797 9.421-21.382 21.054-21.382 11.591 0 21.012 9.585 21.012 21.382v105.635z m77.333 57.222a21.504 21.504 0 0 1-21.34 21.626 21.504 21.504 0 0 1-21.34-21.626V827.474c0-11.96 9.543-21.668 21.299-21.668 11.796 0 21.38 9.708 21.38 21.668v157.082z m71.147-82.043c0 11.796-9.42 21.34-21.053 21.34a21.217 21.217 0 0 1-21.013-21.34v-75.367c0-11.755 9.421-21.299 21.013-21.299 11.632 0 21.053 9.544 21.053 21.3v75.366z"
fill="#FFF"
/>
</svg>
</div>
</div>
</Transition>
</template>
<style scoped>
.back-top-container {
position: fixed;
bottom: 20px;
right: 20px;
width: 60px;
height: 60px;
z-index: 999;
}
.vitepress-backTop-main {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
cursor: pointer;
width: 44px;
height: 44px;
border-radius: 50%;
background-color: #3eaf7c;
padding: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
transition: background-color 0.2s ease;
}
.vitepress-backTop-main:hover {
background-color: #71cda3;
}
.progress-ring {
position: absolute;
width: 100%;
height: 100%;
transform: rotate(-90deg);
z-index: 1;
}
.progress-ring-background {
fill: none;
stroke: rgba(62, 175, 124, 0.15);
stroke-width: 3;
}
.progress-ring-circle {
fill: none;
stroke: #3eaf7c;
stroke-width: 3;
stroke-dasharray: 264; /* 2 * π * 42 */
stroke-linecap: round;
transition: stroke-dashoffset 0.15s ease-out;
}
.icon {
width: 24px;
height: 24px;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>

View File

@@ -1,33 +0,0 @@
// .vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import { NolebaseGitChangelogPlugin } from '@nolebase/vitepress-plugin-git-changelog/client'
import 'virtual:group-icons.css'
import { h, onMounted } from 'vue'
import './style/style.css'
import ArticleShare from './components/ArticleShare.vue'
import backtotop from './components/backtotop.vue'
import '@nolebase/vitepress-plugin-git-changelog/client/style.css'
export default {
extends: DefaultTheme,
Layout: () => {
return h(DefaultTheme.Layout, null, {
'aside-outline-before': () => h(ArticleShare),
'doc-footer-before': () => h(backtotop),
})
},
enhanceApp({ app }) {
app.use(NolebaseGitChangelogPlugin)
// Register service worker in production for offline support and caching
if (
typeof window !== 'undefined' &&
'serviceWorker' in navigator &&
(import.meta as any).env?.PROD
) {
onMounted(() => {
navigator.serviceWorker.register('/sw.js').catch(() => {})
})
}
},
}

View File

@@ -1,192 +0,0 @@
/* .vitepress/theme/style/custom-block.css */
/* 深浅色卡 */
:root {
--custom-block-info-left: #cccccc;
--custom-block-info-bg: #fafafa;
--custom-block-tip-left: #009400;
--custom-block-tip-bg: #e6f6e6;
--custom-block-warning-left: #e6a700;
--custom-block-warning-bg: #fff8e6;
--custom-block-danger-left: #e13238;
--custom-block-danger-bg: #ffebec;
--custom-block-note-left: #4cb3d4;
--custom-block-note-bg: #eef9fd;
--custom-block-important-left: #a371f7;
--custom-block-important-bg: #f4eefe;
--custom-block-caution-left: #e0575b;
--custom-block-caution-bg: #fde4e8;
}
.dark {
--custom-block-info-left: #cccccc;
--custom-block-info-bg: #474748;
--custom-block-tip-left: #009400;
--custom-block-tip-bg: #003100;
--custom-block-warning-left: #e6a700;
--custom-block-warning-bg: #4d3800;
--custom-block-danger-left: #e13238;
--custom-block-danger-bg: #4b1113;
--custom-block-note-left: #4cb3d4;
--custom-block-note-bg: #193c47;
--custom-block-important-left: #a371f7;
--custom-block-important-bg: #230555;
--custom-block-caution-left: #e0575b;
--custom-block-caution-bg: #391c22;
}
/* 标题字体大小 */
.custom-block-title {
font-size: 16px;
}
/* info容器:背景色、左侧 */
.custom-block.info {
border-left: 5px solid var(--custom-block-info-left);
background-color: var(--custom-block-info-bg);
}
/* info容器:svg图 */
.custom-block.info [class*='custom-block-title']::before {
content: '';
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-11v6h2v-6h-2zm0-4v2h2V7h-2z' fill='%23ccc'/%3E%3C/svg%3E");
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
position: relative;
margin-right: 4px;
left: -5px;
top: -1px;
}
/* 提示容器:边框色、背景色、左侧 */
.custom-block.tip {
/* border-color: var(--custom-block-tip); */
border-left: 5px solid var(--custom-block-tip-left);
background-color: var(--custom-block-tip-bg);
}
/* 提示容器:svg图 */
.custom-block.tip [class*='custom-block-title']::before {
content: '';
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23009400' d='M7.941 18c-.297-1.273-1.637-2.314-2.187-3a8 8 0 1 1 12.49.002c-.55.685-1.888 1.726-2.185 2.998H7.94zM16 20v1a2 2 0 0 1-2 2h-4a2 2 0 0 1-2-2v-1h8zm-3-9.995V6l-4.5 6.005H11v4l4.5-6H13z'/%3E%3C/svg%3E");
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
position: relative;
margin-right: 4px;
left: -5px;
top: -2px;
}
/* 警告容器:背景色、左侧 */
.custom-block.warning {
border-left: 5px solid var(--custom-block-warning-left);
background-color: var(--custom-block-warning-bg);
}
/* 警告容器:svg图 */
.custom-block.warning [class*='custom-block-title']::before {
content: '';
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024'%3E%3Cpath d='M576.286 752.57v-95.425q0-7.031-4.771-11.802t-11.3-4.772h-96.43q-6.528 0-11.3 4.772t-4.77 11.802v95.424q0 7.031 4.77 11.803t11.3 4.77h96.43q6.528 0 11.3-4.77t4.77-11.803zm-1.005-187.836 9.04-230.524q0-6.027-5.022-9.543-6.529-5.524-12.053-5.524H456.754q-5.524 0-12.053 5.524-5.022 3.516-5.022 10.547l8.538 229.52q0 5.023 5.022 8.287t12.053 3.265h92.913q7.032 0 11.803-3.265t5.273-8.287zM568.25 95.65l385.714 707.142q17.578 31.641-1.004 63.282-8.538 14.564-23.354 23.102t-31.892 8.538H126.286q-17.076 0-31.892-8.538T71.04 866.074q-18.582-31.641-1.004-63.282L455.75 95.65q8.538-15.57 23.605-24.61T512 62t32.645 9.04 23.605 24.61z' fill='%23e6a700'/%3E%3C/svg%3E");
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
position: relative;
margin-right: 4px;
left: -5px;
}
/* 危险容器:背景色、左侧 */
.custom-block.danger {
border-left: 5px solid var(--custom-block-danger-left);
background-color: var(--custom-block-danger-bg);
}
/* 危险容器:svg图 */
.custom-block.danger [class*='custom-block-title']::before {
content: '';
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2c5.523 0 10 4.477 10 10v3.764a2 2 0 0 1-1.106 1.789L18 19v1a3 3 0 0 1-2.824 2.995L14.95 23a2.5 2.5 0 0 0 .044-.33L15 22.5V22a2 2 0 0 0-1.85-1.995L13 20h-2a2 2 0 0 0-1.995 1.85L9 22v.5c0 .171.017.339.05.5H9a3 3 0 0 1-3-3v-1l-2.894-1.447A2 2 0 0 1 2 15.763V12C2 6.477 6.477 2 12 2zm-4 9a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4z' fill='%23e13238'/%3E%3C/svg%3E");
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
position: relative;
margin-right: 4px;
left: -5px;
top: -1px;
}
/* 提醒容器:背景色、左侧 */
.custom-block.note {
border-left: 5px solid var(--custom-block-note-left);
background-color: var(--custom-block-note-bg);
}
/* 提醒容器:svg图 */
.custom-block.note [class*='custom-block-title']::before {
content: '';
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-11v6h2v-6h-2zm0-4v2h2V7h-2z' fill='%234cb3d4'/%3E%3C/svg%3E");
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
position: relative;
margin-right: 4px;
left: -5px;
top: -1px;
}
/* 重要容器:背景色、左侧 */
.custom-block.important {
border-left: 5px solid var(--custom-block-important-left);
background-color: var(--custom-block-important-bg);
}
/* 重要容器:svg图 */
.custom-block.important [class*='custom-block-title']::before {
content: '';
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024'%3E%3Cpath d='M512 981.333a84.992 84.992 0 0 1-84.907-84.906h169.814A84.992 84.992 0 0 1 512 981.333zm384-128H128v-42.666l85.333-85.334v-256A298.325 298.325 0 0 1 448 177.92V128a64 64 0 0 1 128 0v49.92a298.325 298.325 0 0 1 234.667 291.413v256L896 810.667v42.666zm-426.667-256v85.334h85.334v-85.334h-85.334zm0-256V512h85.334V341.333h-85.334z' fill='%23a371f7'/%3E%3C/svg%3E");
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
position: relative;
margin-right: 4px;
left: -5px;
top: -1px;
}
/* 注意容器:背景色、左侧 */
.custom-block.caution {
border-left: 5px solid var(--custom-block-caution-left);
background-color: var(--custom-block-caution-bg);
}
/* 注意容器:svg图 */
.custom-block.caution [class*='custom-block-title']::before {
content: '';
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2c5.523 0 10 4.477 10 10v3.764a2 2 0 0 1-1.106 1.789L18 19v1a3 3 0 0 1-2.824 2.995L14.95 23a2.5 2.5 0 0 0 .044-.33L15 22.5V22a2 2 0 0 0-1.85-1.995L13 20h-2a2 2 0 0 0-1.995 1.85L9 22v.5c0 .171.017.339.05.5H9a3 3 0 0 1-3-3v-1l-2.894-1.447A2 2 0 0 1 2 15.763V12C2 6.477 6.477 2 12 2zm-4 9a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4z' fill='%23e13238'/%3E%3C/svg%3E");
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
position: relative;
margin-right: 4px;
left: -5px;
top: -1px;
}

View File

@@ -1,125 +0,0 @@
#app a:focus-visible,
#app button:focus-visible,
#app input[type='checkbox']:focus-visible {
--at-apply: outline-1 outline-primary ring-2 ring-primary;
}
.VPSidebar::-webkit-scrollbar {
background: transparent;
height: 8px;
width: 8px;
margin-right: 8px;
}
#app > div > div.VPLocalNav > div > div > div.outline {
outline-style: none !important;
}
.vp-doc .color-swatch {
display: inline-block;
width: 0.85em;
height: 0.85em;
min-width: 12px;
min-height: 12px;
font-size: inherit;
border: 0;
border-radius: 2px;
margin: 0 3px 0 6px;
cursor: pointer;
}
.medium-zoom-overlay {
z-index: 20;
}
.medium-zoom-image {
z-index: 21;
}
@keyframes slide-enter {
0% {
transform: translateY(10px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 100;
}
}
@media (prefers-reduced-motion: no-preference) {
html:not(.no-sliding) [slide-enter],
html:not(.no-sliding) .slide-enter,
html:not(.no-sliding) .main > div > *,
html:not(.no-sliding) #VPContent > div > div.VPFeatures.VPHomeFeatures > *,
html:not(.no-sliding) .TeamPage > *,
html:not(.no-sliding) .VPHomeHero > * {
--enter-stage: 0;
--enter-step: 90ms;
--enter-initial: 0ms;
animation: slide-enter 1s both 1;
animation-delay: calc(var(--enter-initial) + var(--enter-stage) * var(--enter-step));
}
.main > div > *:nth-child(1) {
--enter-stage: 1;
}
.main > div > *:nth-child(2) {
--enter-stage: 2;
}
.main > div > *:nth-child(3) {
--enter-stage: 3;
}
.main > div > *:nth-child(4) {
--enter-stage: 4;
}
.main > div > *:nth-child(5) {
--enter-stage: 5;
}
.main > div > *:nth-child(6) {
--enter-stage: 6;
}
.main > div > *:nth-child(7) {
--enter-stage: 7;
}
.main > div > *:nth-child(8) {
--enter-stage: 8;
}
.main > div > *:nth-child(9) {
--enter-stage: 9;
}
.main > div > *:nth-child(10) {
--enter-stage: 10;
}
.main > div > *:nth-child(11) {
--enter-stage: 11;
}
.main > div > *:nth-child(12) {
--enter-stage: 12;
}
.main > div > *:nth-child(13) {
--enter-stage: 13;
}
.main > div > *:nth-child(14) {
--enter-stage: 14;
}
.main > div > *:nth-child(15) {
--enter-stage: 15;
}
.main > div > *:nth-child(16) {
--enter-stage: 16;
}
.main > div > *:nth-child(17) {
--enter-stage: 17;
}
.main > div > *:nth-child(18) {
--enter-stage: 18;
}
.main > div > *:nth-child(19) {
--enter-stage: 19;
}
.main > div > *:nth-child(20) {
--enter-stage: 20;
}
}

View File

@@ -1,158 +0,0 @@
@import './custom-block.css';
@import './doc-fade-in.css';
:root:where(:lang(fa)) {
--vp-font-family-base:
'Vazirmatn', 'Inter', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}
:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe 30%, #41d1ff);
--vp-home-hero-image-background-image: linear-gradient(-45deg, #bd34fe 50%, #47caff 50%);
--vp-home-hero-image-filter: blur(44px);
/* Enhanced brand color for better contrast */
--vp-c-brand-1: #1e40af;
--vp-c-brand-2: #2563eb;
--vp-c-brand-3: #3b82f6;
--vp-c-brand-soft: rgba(30, 64, 175, 0.14);
/* Button contrast improvements */
--vp-button-brand-bg: #1e40af;
--vp-button-brand-text: #ffffff;
--vp-button-brand-hover-bg: #1d4ed8;
--vp-button-brand-hover-text: #ffffff;
--vp-button-brand-active-bg: #1e3a8a;
--vp-button-brand-active-text: #ffffff;
}
/* Dark mode color overrides for better contrast */
.dark:root {
--vp-c-brand-1: #60a5fa;
--vp-c-brand-2: #3b82f6;
--vp-c-brand-3: #2563eb;
--vp-c-brand-soft: rgba(96, 165, 250, 0.16);
--vp-button-brand-bg: #3b82f6;
--vp-button-brand-text: #000000;
--vp-button-brand-hover-bg: #60a5fa;
--vp-button-brand-hover-text: #000000;
--vp-button-brand-active-bg: #2563eb;
--vp-button-brand-active-text: #000000;
}
@media (min-width: 640px) {
:root {
--vp-home-hero-image-filter: blur(56px);
}
}
@media (min-width: 960px) {
:root {
--vp-home-hero-image-filter: blur(68px);
}
}
.VPHero .VPImage {
filter: drop-shadow(-2px 4px 6px rgba(0, 0, 0, 0.2));
padding: 18px;
}
/* used in reference/default-theme-search */
img[src='/search.png'] {
width: 100%;
aspect-ratio: 1 / 1;
}
/* Enhanced button contrast for accessibility */
.VPButton.brand {
background-color: var(--vp-button-brand-bg) !important;
color: var(--vp-button-brand-text) !important;
border: none;
font-weight: 600;
text-shadow: none;
}
.VPButton.brand:hover {
background-color: var(--vp-button-brand-hover-bg) !important;
color: var(--vp-button-brand-hover-text) !important;
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(30, 64, 175, 0.4);
}
.VPButton.brand:active {
background-color: var(--vp-button-brand-active-bg) !important;
color: var(--vp-button-brand-active-text) !important;
transform: translateY(0);
}
/* Dark mode support for buttons */
.dark .VPButton.brand {
background-color: #3b82f6 !important;
color: #000000 !important;
}
.dark .VPButton.brand:hover {
background-color: #60a5fa !important;
color: #000000 !important;
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
}
.dark .VPButton.brand:active {
background-color: #2563eb !important;
color: #000000 !important;
}
/* Ensure proper contrast for all text elements */
.VPButton.brand .text {
color: inherit !important;
}
/* Focus states for accessibility */
.VPButton.brand:focus-visible {
outline: 2px solid #ffffff;
outline-offset: 2px;
}
.dark .VPButton.brand:focus-visible {
outline: 2px solid #000000;
outline-offset: 2px;
}
@font-face {
font-family: 'HarmonyOS Sans SC';
src: url('/HarmonyOS_Sans_SC.ttf') format('truetype');
}
body {
font-family: 'HarmonyOS Sans SC', sans-serif;
line-height: 1.8;
letter-spacing: 0.05em;
word-spacing: 0.05em;
}
p,
li,
a,
span,
div,
h1,
h2,
h3,
h4,
h5,
h6 {
word-break: break-word;
text-justify: inter-ideograph;
-ms-text-autospace: ideograph-alpha;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
pre,
code {
letter-spacing: normal;
word-spacing: normal;
}

View File

@@ -1,101 +0,0 @@
import { defineConfig, type DefaultTheme } from 'vitepress'
import { groupIconMdPlugin, groupIconVitePlugin } from 'vitepress-plugin-group-icons'
export default defineConfig({
lang: 'en-US',
description:
'Next-Generation Android Root Solution - Advanced kernel-based root management for Android devices with KernelSU integration',
themeConfig: {
nav: nav(),
sidebar: {
'/': { base: '/', items: sidebar() },
},
search: { options: searchOptions() },
editLink: {
pattern: 'https://github.com/sukisu-ultra/sukisu-ultra/edit/main/docs/:path',
text: 'Edit this page on GitHub',
},
docFooter: {
prev: 'Previous',
next: 'Next',
},
outline: {
label: 'On this page',
},
lastUpdated: {
text: 'Last updated',
},
notFound: {
title: 'Page Not Found',
quote: "Sorry, we couldn't find what you're looking for.",
linkLabel: 'Go to home',
linkText: 'Take me home',
},
langMenuLabel: 'Languages',
returnToTopLabel: 'Return to top',
sidebarMenuLabel: 'Menu',
darkModeSwitchLabel: 'Theme',
lightModeSwitchTitle: 'Switch to light theme',
darkModeSwitchTitle: 'Switch to dark theme',
skipToContentLabel: 'Skip to content',
},
})
function nav(): DefaultTheme.NavItem[] {
return [
{ text: 'Home', link: '/' },
{
text: 'Getting Started',
items: [
{ text: 'Introduction', link: '/guide/' },
{ text: 'Installation', link: '/guide/installation' },
{ text: 'Compatibility', link: '/guide/compatibility' },
{ text: 'Links', link: '/guide/links' },
{ text: 'license', link: '/guide/license' },
],
},
]
}
function sidebar(): DefaultTheme.SidebarItem[] {
return [
{
text: 'Getting Started',
items: [
{ text: 'Introduction', link: '/guide/' },
{ text: 'Installation', link: '/guide/installation' },
{ text: 'Compatibility', link: '/guide/compatibility' },
{ text: 'Links', link: '/guide/links' },
{ text: 'license', link: '/guide/license' },
],
},
]
}
function searchOptions(): Partial<DefaultTheme.LocalSearchOptions> {
return {
translations: {
button: {
buttonText: 'Search docs',
buttonAriaLabel: 'Search docs',
},
modal: {
noResultsText: 'No results found',
resetButtonTitle: 'Clear query',
footer: {
selectText: 'Select',
navigateText: 'Navigate',
closeText: 'Close',
},
},
},
}
}

View File

@@ -1,23 +0,0 @@
# Compatibility Status
::: info KernelSU
KernelSU (versions prior to v0.9.5) officially supports Android GKI 2.0 devices (kernel 5.10+)
:::
::: warning Legacy Kernel Support
Older kernels (4.4+) are also compatible, but the kernel must be built manually
:::
::: tip Extended Compatibility
SukiSu-Ultra can support 3.x kernels (3.4-3.18) through additional back ports
:::
## Architecture Support
Currently supports the following processor architectures:
| Architecture | Support Level | Notes |
| --------------- | ------------------ | --------------------------- |
| **arm64-v8a** | ✅ Full Support | Primary target architecture |
| **armeabi-v7a** | ✅ Basic Support | Bare minimum functionality |
| **X86_64** | 🟡 Partial Support | Some devices supported |

View File

@@ -1,85 +0,0 @@
# Introduction
Welcome to SukiSU-Ultra, the next-generation Android root solution that provides advanced kernel-based root management for Android devices.
## What is SukiSU-Ultra?
SukiSU-Ultra is a modern, secure, and powerful root solution designed specifically for Android devices. It offers kernel-level root access management with enhanced security features and improved compatibility.
## Key Features
### 🔒 Kernel-based su and root access management
Secure root access management at the kernel level, providing better security and performance compared to traditional solutions.
### 🚫 Not based on OverlayFS module system
Built on Magic Mount technology from 5ec1cff, offering a more stable and reliable foundation.
### 📱 App Profile
Advanced application profiling system that allows you to lock root privileges in a controlled environment.
### 🔧 Enhanced Device Support
Bringing back support for non-GKI/GKI 1.0 devices, ensuring compatibility with older Android devices.
### ⚙️ Extensive Customization
Comprehensive customization options to tailor the root experience to your specific needs.
### 🔌 KPM Kernel Module Support
Full KernelPatch Module (KPM) functionality for advanced kernel modifications and enhancements.
## Why Choose SukiSU-Ultra?
- **Security First**: Advanced security features protect your device and data
- **Modern Architecture**: Built with modern Android security models in mind
- **Wide Compatibility**: Supports both GKI and non-GKI devices
- **Active Development**: Continuously updated with latest Android versions
- **Community Driven**: Open source with active community support
## Getting Started
Ready to get started with SukiSU-Ultra? Follow our step-by-step guide:
1. **[Installation](./installation)** - Learn how to install SukiSU-Ultra on your device
2. **[Compatibility](./compatibility)** - Check device compatibility requirements
3. **[Links](./links)** - Find additional resources and downloads
## System Requirements
Before installing SukiSU-Ultra, ensure your device meets these requirements:
- **Android Version**: Android 8.0 (API 26) or higher
- **Bootloader**: Unlocked bootloader
- **Recovery**: Custom recovery (TWRP recommended)
- **Storage**: At least 100MB free space
- **Knowledge**: Basic understanding of Android modding
## Safety Notice
::: danger Important
⚠️ **Rooting your device can void your warranty and may cause permanent damage if done incorrectly.**
Always:
- Create a full backup before proceeding
- Ensure your device is compatible
- Follow instructions carefully
- Have a recovery plan ready
:::
## Support
Need help? We're here to assist:
- **📖 Documentation**: Comprehensive guides and tutorials
- **💬 Community**: Active community forums and chat
- **🐛 Bug Reports**: GitHub issue tracker
- **📧 Direct Support**: Contact developers for critical issues
---
**Ready to unlock the full potential of your Android device?** Start with our [installation guide](./installation) and join thousands of users who trust SukiSU-Ultra for their root needs.

View File

@@ -1,121 +0,0 @@
# Installation Guide
This guide provides comprehensive instructions for installing SukiSU-Ultra on your Android device. Please follow the steps carefully.
## Prerequisites
Before you begin, ensure you have the following:
- [ ] A compatible device. Check the [Compatibility Guide](./compatibility.md) for details.
- [ ] Unlocked bootloader.
- [ ] Custom recovery installed, such as TWRP.
- [ ] Basic knowledge of flashing custom ROMs and kernels.
- [ ] Your device's kernel source or a compatible pre-built kernel.
## Installation Methods
There are several ways to install SukiSU-Ultra, depending on your device and preference.
### Method 1: Using Pre-built GKI Packages
This is the recommended method for devices with Generic Kernel Image (GKI) 2.0, such as many Xiaomi, Redmi, and Samsung models.[^1]
[^1]: This method is not suitable for devices from manufacturers that heavily modify the kernel, like Meizu, OnePlus, Realme, and Oppo.
#### Steps:
1. **Download GKI Build**: Visit our [resources section](./links.md) to find the appropriate GKI build for your device's kernel version. Download the `.zip` file that includes `AnyKernel3` in its name.
2. **Flash via Recovery**:
- [ ] Boot your device into TWRP recovery.
- [ ] Select "Install".
- [ ] Navigate to the downloaded `AnyKernel3` zip file and select it.
- [ ] Swipe to confirm the flash.
- [ ] Once flashing is complete, reboot your system.
3. **Verify Installation**:
- [ ] Install the SukiSU-Ultra Manager app.
- [ ] Open the app and check if root access is granted and working correctly.
- [ ] You can also verify the new kernel version in your device's settings.
::: details File Format Guide
The `.zip` archive without a suffix is uncompressed. The `.gz` suffix indicates compression used for specific models.
:::
### Method 2: Custom Build for OnePlus Devices
For OnePlus devices, you'll need to create a custom build.
#### Steps:
1. **Gather Device Information**: You will need:
- Your kernel version (e.g., `5.10`, `5.15`).
- Your processor's codename.
- The branch and configuration files from the OnePlus open-source kernel repository.
2. **Create Custom Build**: Use the link in our [resources section](./links.md) to generate a custom build with your device's information.
3. **Flash the Build**:
- [ ] Download the generated `AnyKernel3` zip file.
- [ ] Boot into recovery.
- [ ] Flash the zip file.
- [ ] Reboot and verify the installation.
### Method 3: Manual Kernel Integration (Advanced)
This method is for advanced users who are building a kernel from source.
#### Integration Scripts:
- **Main Branch (GKI)**:
```sh [bash]
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
- **Non-GKI Branch**:
```sh [bash]
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s nongki
```
- **SUSFS-Dev Branch (Recommended)**:
```sh [bash]
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s susfs-main
```
::: warning Required Kernel Configs
For KPM support, you must enable `CONFIG_KPM=y`.
For non-GKI devices, you also need to enable `CONFIG_KALLSYMS=y` and `CONFIG_KALLSYMS_ALL=y`.
:::
## Post-Installation
### Maintaining Root After OTA Updates
To keep root access after an Over-the-Air (OTA) update, follow these steps ==before rebooting==.
1. **Flash to Inactive Slot**:
- [ ] After the OTA update is downloaded and installed, **do not reboot**.
- [ ] Open the SukiSU-Ultra Manager.
- [ ] Go to the flashing/patching interface.
- [ ] Select your `AnyKernel3` kernel zip file.
- [ ] Choose to install it to the inactive slot.
- [ ] Once flashed, you can safely reboot.
2. **Alternative: LKM Mode**: You can also use LKM mode to install to the unused slot after an OTA.
::: tip
For non-GKI devices, the safest method to retain root after an OTA is to use TWRP to flash the kernel again.
:::
## Verification Checklist
After installation, please verify the following:
- [ ] **Manager App**: The SukiSU-Ultra Manager app opens and shows a successful root status.
- [ ] **Root Access**: Root checker apps confirm that root access is working.
- [ ] **Kernel Version**: The kernel version in `Settings > About Phone` reflects the SukiSU-Ultra kernel.
## Troubleshooting
If you encounter any issues:
1. Double-check the [Compatibility Guide](./compatibility.md).
2. Visit our [GitHub repository](https://github.com/sukisu-ultra/sukisu-ultra) for issues and solutions.
3. Join our [Telegram community](https://t.me/sukiksu) for live support.
::: danger Safety Reminder
⚠️ **Always have a backup!** Keep a copy of your original `boot.img` and be prepared to restore your device if something goes wrong.
:::

View File

@@ -1,77 +0,0 @@
# License
## 📄 Software Licensing
### Kernel Components
::: info GPL-2.0 License
The files in the "kernel" directory are under GPL-2.0-only license
:::
**License:** [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
### Application Core
::: tip GPL-3.0 License
All other parts (except mentioned below) are under GPL-3.0 or later license
:::
**License:** [GPL-3.0 or later](https://www.gnu.org/licenses/gpl-3.0.html)
## Artwork & Brand Assets
### Launcher Icons & Character Art
::: warning Copyright Notice
Special licensing requirements for anime character artwork
:::
The images of the files `ic_launcher(?!.*alt.*).*` with anime character emoticons have specific copyright terms:
**Copyright Holders:**
- **Anime Character Art:** [五十根大虾仁](https://space.bilibili.com/370927)
- **Brand Intellectual Property:** [明风OuO](https://space.bilibili.com/274939213)
- **Vectorization:** @MiRinChan
**License Requirements:**
1. **Creative Commons License:** [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.txt)
2. **Author Authorization:** Required from both copyright holders
3. **Attribution:** Must credit all contributors listed above
::: details Usage Requirements
Before using these artistic assets, you must:
- Comply with Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International license
- Obtain authorization from both original authors for use of artistic content
- Provide proper attribution to all contributors
:::
## 📋 License Summary
| Component | License | Notes |
| -------------------- | ------------------------------------------------------------------------- | ------------------------------------- |
| **Kernel Files** | [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) | Files in `/kernel/` directory |
| **Application Code** | [GPL-3.0+](https://www.gnu.org/licenses/gpl-3.0.html) | Main application components |
| **Character Art** | [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) | + Author authorization required |
| **Brand Assets** | Mixed Licensing | See specific attribution requirements |
## 🔗 License Links
- **GPL-2.0:** [Full License Text](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
- **GPL-3.0:** [Full License Text](https://www.gnu.org/licenses/gpl-3.0.html)
- **CC BY-NC-SA 4.0:** [Full License Text](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.txt)
## 📞 Licensing Questions
For questions about licensing or usage permissions:
1. **Code Licensing:** Refer to respective GPL license terms
2. **Artwork Usage:** Contact original authors for authorization
3. **Commercial Use:** Review CC BY-NC-SA 4.0 restrictions
4. **Distribution:** Ensure compliance with all applicable licenses
::: tip Compliance Note
When redistributing or modifying SukiSU-Ultra, ensure you comply with all applicable licenses and attribution requirements for each component.
:::

View File

@@ -1,77 +0,0 @@
# More Links
## 🌐 Translation & Localization
::: info Contribute Translations
If you need to submit a translation for the manager, please visit our Crowdin project
:::
**Translation Platform:** [Crowdin - SukiSU-Ultra](https://crowdin.com/project/SukiSU-Ultra)
## 🔧 Projects & Builds
Projects compiled based on Sukisu and susfs:
### GKI Builds
::: tip Universal GKI Support
Generic Kernel Image builds with KernelSU and SUSFS integration
:::
**Repository:** [GKI_KernelSU_SUSFS](https://github.com/ShirkNeko/GKI_KernelSU_SUSFS)
### OnePlus Builds
::: tip Device-Specific Builds
Automated OnePlus kernel builds with MKSU and SUSFS
:::
**Repository:** [Action_OnePlus_MKSU_SUSFS](https://github.com/ShirkNeko/Action_OnePlus_MKSU_SUSFS)
## 📱 Community & Support
### Telegram Community
::: info Join Our Community
Connect with other users, get support, and stay updated
:::
**Main Group:** [Tg Group](https://t.me/sukiksu)
### Test Builds
::: warning Experimental Builds
Test builds are experimental and may be unstable
:::
**Test Builds Channel:** [Latest Test Build](https://t.me/Sukiksu/7114)
## Downloads & Releases
### Official Releases
::: tip Stable Releases
Download the latest stable versions from our GitHub releases
:::
**GitHub Releases:** [SukiSU-Ultra Releases](https://github.com/sukisu-ultra/sukisu-ultra/releases)
### Issue Reporting
::: info Bug Reports & Feature Requests
Report bugs or request new features on our GitHub repository
:::
**GitHub Issues:** [Report Issues](https://github.com/sukisu-ultra/sukisu-ultra/issues)
## 🔗 Quick Links Summary
| Resource | Link | Description |
| ------------------ | ---------------------------------------------------------------------------- | ---------------------- |
| **Translations** | [Crowdin](https://crowdin.com/project/SukiSU-Ultra) | Submit translations |
| **Telegram Group** | [t.me/sukiksu](https://t.me/sukiksu) | Community support |
| **Test Builds** | [Test Channel](https://t.me/Sukiksu/7114) | Experimental builds |
| **Releases** | [GitHub Releases](https://github.com/sukisu-ultra/sukisu-ultra/releases) | Stable downloads |
| **Issues** | [GitHub Issues](https://github.com/sukisu-ultra/sukisu-ultra/issues) | Bug reports |
| **GKI Builds** | [GKI Repository](https://github.com/ShirkNeko/GKI_KernelSU_SUSFS) | Universal builds |
| **OnePlus Builds** | [OnePlus Repository](https://github.com/ShirkNeko/Action_OnePlus_MKSU_SUSFS) | Device-specific builds |

View File

@@ -1,37 +0,0 @@
---
layout: home
hero:
name: 'SukiSU-Ultra'
text: 'Next-Generation Android Root Solution'
tagline: Advanced kernel-based root management for Android devices
image:
src: /logo.svg
alt: SukiSU-Ultra
actions:
- theme: brand
text: Get Started
link: /guide/
- theme: alt
text: View on GitHub
link: https://github.com/sukisu-ultra/sukisu-ultra
features:
- title: Kernel-based su and root access management
details: Secure root access management at the kernel level.
- title: Not based on OverlayFS module system
details: Based on Magic Mount from 5ec1cff.
- title: App Profile
details: Lock root privileges in a cage.
- title: Bringing back non-GKI/GKI 1.0 support
details: Enhanced compatibility for older devices.
- title: More customization
details: Extensive customization options available.
- title: Support for KPM kernel modules
details: Full KernelPatch Module functionality.
---

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 200 KiB

View File

@@ -1,60 +0,0 @@
# Global headers for security and performance
/*
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Strict-Transport-Security: "max-age=31536000; includeSubDomains; preload"
Permissions-Policy: "camera=(), microphone=(), geolocation=()"
Content-Security-Policy: "default-src 'self'; script-src 'self' https://static.cloudflareinsights.com; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; font-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'"
# Cache static assets for maximum performance
/assets/*
Cache-Control: public, max-age=31536000, immutable
/*.js
Cache-Control: public, max-age=31536000, immutable
/*.css
Cache-Control: public, max-age=31536000, immutable
/*.woff2
Cache-Control: public, max-age=31536000, immutable
/*.woff
Cache-Control: public, max-age=31536000, immutable
# Images - 30 days cache
/*.svg
Cache-Control: public, max-age=2592000
/*.png
Cache-Control: public, max-age=2592000
/*.jpg
Cache-Control: public, max-age=2592000
/*.jpeg
Cache-Control: public, max-age=2592000
/*.webp
Cache-Control: public, max-age=2592000
/*.avif
Cache-Control: public, max-age=2592000
/*.ico
Cache-Control: public, max-age=2592000
# Manifest and service worker
/site.webmanifest
Cache-Control: public, max-age=86400
/sw.js
Cache-Control: public, max-age=0, must-revalidate
# Offline page and HTML caching
/*.html
Cache-Control: public, max-age=60, must-revalidate
/offline.html
Cache-Control: public, max-age=3600

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -1,535 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="512"
height="512"
viewBox="0 0 512 512"
version="1.1"
id="svg1"
xml:space="preserve"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
sodipodi:docname="zako.optizmism.svg"
inkscape:export-filename="zako.plain.svg"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#999999"
borderopacity="1"
inkscape:showpageshadow="2"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showguides="false"
inkscape:zoom="2"
inkscape:cx="219"
inkscape:cy="370"
inkscape:window-width="1280"
inkscape:window-height="702"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false"><inkscape:page
x="0"
y="0"
width="512"
height="512"
id="page2"
margin="0"
bleed="0" /></sodipodi:namedview><defs
id="defs1"><inkscape:path-effect
effect="simplify"
id="path-effect79"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /><inkscape:path-effect
effect="simplify"
id="path-effect78"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /><inkscape:path-effect
effect="simplify"
id="path-effect77"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /><inkscape:path-effect
effect="simplify"
id="path-effect76"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /><inkscape:path-effect
effect="simplify"
id="path-effect75"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /><inkscape:path-effect
effect="simplify"
id="path-effect61"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /><inkscape:path-effect
effect="simplify"
id="path-effect42"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /></defs><g
inkscape:label="main"
inkscape:groupmode="layer"
id="layer1"><path
style="display:inline;opacity:1;fill:#fff9f6;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 164.23888,424.64081 -31.07097,26.05282 c 0,0 -5.19317,18.17613 25.96589,28.93342 31.15907,10.7573 213.29123,1.48377 213.29123,1.48377 0,0 52.30272,11.87012 80.86519,-37.09413 -0.37094,0.74188 -8.90259,19.28895 -8.90259,19.28895 l 1.48377,19.28894 c 0,0 57.73516,-9.41425 30.45647,-148.95524 4.19672,-9.44262 8.39344,-15.21311 8.39344,-15.21311 l -3.14754,-21.77049 c 0,0 5.65758,-40.33533 7.88323,-45.52851 2.22564,-5.19317 9.64447,-11.12823 9.64447,-11.12823 0,0 -2.78206,-20.40177 -6.67694,-26.15136 -0.74189,-3.33847 6.86241,-35.05395 2.04017,-58.05231 -7.04788,-11.87012 -4.82223,-11.87012 -18.918,-25.59495 0,0.37094 8.90259,-44.88389 -0.74188,-73.446367 -2.96753,0 -32.27189,-10.757296 -96.81567,23.740241 -0.37094,1.112824 -26.33683,-30.046242 -153.56969,-15.950474 -0.74188,0 -43.40012,-37.836009 -66.76942,-40.432598 -1.11283,-0.370941 -22.62742,-4.080354 -25.22401,48.964247 0,1.112824 -44.14201,15.950474 -56.01213,64.914721 -11.87012,48.96425 -11.128238,80.86519 -11.128238,80.86519 0,0 -18.904912,27.6632 -9.798121,25.03308 5.346826,-1.54421 4.975885,23.56023 4.975885,23.56023 l -2.225648,39.31977 c 0,0 -14.466709,35.23942 -14.83765,59.72155 -0.370942,24.48212 -0.741883,34.12659 4.822236,48.5933 5.564119,14.46671 20.772711,46.7386 42.658245,63.06002 8.902591,0.37094 18.918001,1.8547 18.918001,1.8547 l 3.70942,-20.77271 c 0,0 18.918,15.95048 32.27189,14.83765 13.35388,-1.11282 -0.74189,-0.74188 -0.74189,-0.74188 l -13.72482,-17.80518 z"
id="path2"
sodipodi:nodetypes="ccscccccccscccccccccscsccsscccsccc"
inkscape:label="整个人的边框" /><path
id="path91"
style="opacity:1;fill:#93d4fa;fill-opacity:1;stroke:#4c4f59;stroke-width:6.9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 133.91016,110.16992 -69.738285,47.48047 18.263976,30.75433 -31.617492,55.67536 28.5625,17.0625 14.837891,-1.48438 2.226562,-55.64062 2.577791,-4.39109 18.193697,-21.94485 23.74023,-49.70703 z"
sodipodi:nodetypes="ccccccccccc" /><path
style="display:inline;opacity:1;fill:#ace0fe;fill-opacity:1;stroke:#4c4f59;stroke-width:6.54357;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 217.01397,405.82758 c 0,0 7.41728,-25.94462 41.16595,-27.07265 33.74866,-1.12802 53.77534,4.1361 53.77534,4.1361 0,0 11.12594,6.39215 17.80149,14.66435 6.67557,8.2722 28.92743,40.60895 41.53682,48.88115 12.60939,8.27219 15.20545,15.41636 15.20545,15.41636 l -1.85433,11.28027 c 0,0 -14.83458,10.15224 -30.78175,11.65627 -15.94717,1.50404 -147.60404,0 -147.60404,0 l -30.04002,-3.00807"
id="path71"
inkscape:label="衣服底色" /><path
style="fill:#ffffff;fill-opacity:1;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 363.54127,444.68178 c 0,0 -6.89429,4.06586 -4.86135,6.8059 2.03293,2.74004 5.92201,3.44715 5.92201,3.44715 0,0 4.5962,0.26516 5.12653,-3.53554 0.53033,-3.8007 -3.00521,-6.8059 -3.00521,-6.8059"
id="path60" /><path
style="fill:#ffffff;fill-opacity:1;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 349.67678,459.82583 c 0,0 4.5,-7.25 7,-5.5 2.5,1.75 -4.25,7.25 -4.25,7.25"
id="path59" /><path
id="path73-8"
style="fill:#ffffff;stroke-width:8.7;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 228.96985,465.10941 a 8.0341015,5.6995392 0 0 1 -8.0341,5.69953 8.0341015,5.6995392 0 0 1 -8.03411,-5.69953 8.0341015,5.6995392 0 0 1 8.03411,-5.69954 8.0341015,5.6995392 0 0 1 8.0341,5.69954 z" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#6c9cb2;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 220.85246,408.91803 c -0.22678,0.7374 0.77024,1.47887 0.20184,0.3709 -0.55918,-1.08999 0.45864,1.0858 0.58075,1.39596 2.10089,5.33666 1.96407,11.16153 3.60742,16.6426 0.30205,1.00744 0.58829,2.039 0.5936,3.09874"
id="path75"
inkscape:path-effect="#path-effect75"
inkscape:original-d="m 220.85246,408.91803 c 0.0874,0.34973 -0.0874,1.13662 0.26229,1.04918 0.34973,-0.0874 -0.42351,-1.37161 -0.26229,-1.04918 2.70315,5.4063 2.32215,10.60009 3.67213,16 0.44415,1.77662 1.31148,3.74741 1.31148,5.5082" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#6c9cb2;stroke-width:6.9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 225.57377,436.98361 c -1.22213,4.37272 0.0774,9.22771 2.41807,12.85195 2.34183,3.626 0.85866,8.30929 2.56554,12.06608 1.71568,3.77616 2.21068,8.39349 -0.30117,12.16042 -1.9802,2.96963 -5.23922,5.13567 -6.38674,8.61546 0,0 -0.0736,0.66095 -0.0736,0.66095"
id="path76"
inkscape:path-effect="#path-effect76"
inkscape:original-d="m 225.57377,436.98361 c -1.27879,3.14891 0.64852,9.42818 3.40984,14.95082 0.92316,1.84632 0.76302,8.34571 1.57377,9.96721 1.05661,2.11323 2.18032,6.57378 1.31147,9.18033 -1.55473,4.66419 -8.07296,8.77008 -8.07296,12.2565"
sodipodi:nodetypes="csssc" /><path
style="opacity:1;fill:#fbf3ef;fill-opacity:1;stroke:none;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 259.14754,381.90164 c 0,0 8.91803,15.47541 9.18033,20.98361 0.26229,5.50819 32.26229,-1.83607 32.26229,-1.83607 0,0 -4.45901,-16.78688 -7.34426,-19.40983 -2.88524,-2.62296 -34.09836,0.26229 -34.09836,0.26229 z"
id="path89" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#6c9cb2;stroke-width:4.6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 247.86885,386.36066 c 0.62439,0.76152 1.31219,1.32242 0.35251,0.10604 -0.98535,-1.24891 -0.63523,-0.56343 0.0935,0.24171 1.40155,1.54849 2.30926,3.40606 3.10338,5.34166 1.48771,3.62621 2.15649,7.53104 4.02075,11.02472 1.24886,2.3404 2.74915,4.53757 3.97084,6.89242"
id="path77"
inkscape:path-effect="#path-effect77"
inkscape:original-d="m 247.86885,386.36066 c 3.34102,3.56326 -3.68025,-4.79705 1.83607,2.09836 1.23825,1.54782 3.18087,7.73986 3.67213,9.70492 1.00623,4.02493 4.53306,8.80383 6.03279,11.80327" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#6c9cb2;stroke-width:4.6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 306.62295,386.88525 c 1.62958,6.07854 4.04229,11.93568 6.81967,17.57377"
id="path78"
inkscape:path-effect="#path-effect78"
inkscape:original-d="m 306.62295,386.88525 c 1.57569,6.03983 4.44925,12.83291 6.81967,17.57377" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#6c9cb2;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 335.73771,431.21312 c 0.7696,3.76393 3.24862,7.26774 5.48726,10.89168 2.09754,3.39553 3.33574,7.13199 4.87926,10.7955 2.06975,4.91248 6.75146,8.7424 7.699,13.95386 0.92029,5.06165 5.24206,8.89669 5.27874,14.19502"
id="path79"
inkscape:path-effect="#path-effect79"
inkscape:original-d="m 335.73771,431.21312 c -1.15649,1.03916 3.66917,4.97179 4.45901,8.13114 0.96754,3.87016 3.8848,6.88344 4.72131,10.22951 1.09547,4.38186 5.88097,12.49359 8.39345,16.2623 0.80744,1.21116 0.89968,3.11084 1.57377,4.45901 1.7539,3.50782 4.19672,6.9619 4.19672,10.7541" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 258.62295,384.2623 c 0,0 8.13115,6.81967 11.27869,27.01639"
id="path80" /><path
style="opacity:1;fill:#fbf3ef;fill-opacity:1;stroke:#4c4f59;stroke-width:6.9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 127.23285,329.0249 c 0,0 -2.59659,60.46343 13.72483,75.30108 8.16071,-8.16071 10.01541,-10.38636 10.01541,-10.38636 l 12.24107,8.53165 5.19317,-4.45129 2.22565,-19.65989 5.19318,-10.01542 5.93506,-12.24106 -8.53165,-8.53165 -15.95047,-19.28894 -3.33848,-4.82224 -4.45129,9.27353 c 0,0 -12.24106,0 -15.95048,-2.59659 -3.70941,-2.59658 -6.306,-1.11282 -6.306,-1.11282 z"
id="path90" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 291.67213,381.37705 c 0,0 7.08197,6.55738 10.22951,26.4918"
id="path81" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 270.16393,404.19672 c 0,0 16.00001,-3.93442 27.80328,-2.62295"
id="path82" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 253.90164,417.83607 c 0,0 37.2459,-13.11476 69.77049,-9.18033 2.09836,3.67213 5.77049,16.78688 -5.77049,20.98361 -4.72131,0 -19.14754,-1.57378 -22.55738,-0.5246 -3.40983,1.04919 -12.59016,0.5246 -18.36065,4.45902 -5.77049,3.93443 -14.68853,8.91803 -18.36066,3.14754 -3.67213,-5.77049 -4.72131,-12.32787 -4.72131,-12.32787 z"
id="path83" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 276.45902,482.62295 c 0,0 -9.70492,-1.57377 1.04918,-46.42623"
id="path84" /><path
style="opacity:1;fill:#fcf6fa;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 287.21312,432.78689 6.29508,50.88524 13.90164,-0.78688 -6.81968,-54.03279 z"
id="path88" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 287.73771,430.95082 5.77049,50.88525"
id="path85" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 300.32787,428.06557 c 0,0 2.09836,37.7705 7.34426,52.98361"
id="path86" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 313.18033,431.21312 c 0,0 7.60656,27.54098 10.22951,35.93442 2.62295,8.39344 -8.13115,15.73771 -8.13115,15.73771"
id="path87" /><path
style="opacity:1;fill:#bce4fd;fill-opacity:1;stroke:none;stroke-width:8.7;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 164.23888,424.64081 -31.07097,26.05282 5.00771,13.72483 20.95818,15.20859 17.08508,2.15431 -11.1287,-20.55238 -1.54637,-22.78395 z"
id="path74" /><path
id="path73"
style="opacity:1;fill:#ffffff;stroke-width:8.7;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 163.81755,451.10144 a 8.0341015,5.6995392 0 0 1 -8.0341,5.69954 8.0341015,5.6995392 0 0 1 -8.0341,-5.69954 8.0341015,5.6995392 0 0 1 8.0341,-5.69954 8.0341015,5.6995392 0 0 1 8.0341,5.69954 z" /><path
style="opacity:1;fill:#fff9f6;fill-opacity:1;stroke:none;stroke-width:8.7;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 338.36066,376.13115 c 0,0 1.83605,30.95081 -6.29509,51.40983 2.88525,1.04918 14.48107,0.26606 26.91267,-7.34238 12.4316,-7.60844 11.38242,-22.03467 11.38242,-22.03467 l 2.09836,28.85246 c 0,0 24.31867,-28.09873 24.2249,-52.60674 -0.0938,-24.50801 -1.66753,-26.08178 -1.66753,-26.08178 l -11.83407,-1.12685 z"
id="path72" /><path
style="opacity:1;fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:2.845;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 339.7822,389.85927 c 0,0 38.20695,-7.78977 56.38307,-25.96589 5.56412,8.53165 8.16071,32.64283 8.16071,32.64283 l 2.59659,12.98294 16.32141,-62.68907 -6.67694,-5.19318 -5.93506,-17.43424 c 0,0 -15.20859,15.2086 -27.44966,22.99836 -12.24106,7.78977 -34.12659,19.28895 -34.12659,19.28895 l -10.7573,3.70941 z"
id="path70" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#c3b4b0;stroke-width:2.845;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 347.01555,369.64297 c 0,0 2.22565,10.01541 -1.8547,19.84536 -4.08036,9.82994 -5.00771,9.459 -5.00771,9.459"
id="path69" /><path
style="opacity:1;fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:6.945;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 380.85246,480 c 0,0 44.59016,-17.31147 59.27869,-87.08197 6.81967,-2.62295 34.09836,-14.68852 39.34426,-25.70491 2.62295,-9.96722 -3.67213,-32 -3.67213,-32 l -24.65574,0.52459 -26.7541,4.72131 -4.72131,11.54098 -8.39344,52.45902 -13.11475,28.32787 -15.73771,36.19672 z"
id="path68" /><path
style="fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:8.74203;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 147.6556,277.03379 c 0,0 -11.12655,104.13607 127.58449,103.38689 138.71104,-0.74917 149.83759,-100.39017 149.83759,-100.39017"
id="path41"
inkscape:label="脸蛋" /><path
style="opacity:1;fill:#fff9f6;fill-opacity:1;stroke:none;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 123.27869,147.93443 304.78688,21.50819 -24.65573,-40.39344 c 0,0 44.06557,-58.754098 50.88524,-60.327868 6.81967,-1.573771 15.73771,-9.967214 15.73771,-9.967214 l -13.11476,-3.672131 -77.11475,22.032787 c 0,0 -122.7541,-33.57377 -168.39344,-6.295082 -45.63935,27.278689 -69.7705,46.163938 -69.7705,46.163938 z"
id="path33"
inkscape:label="头发底色2" /><path
style="fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 331.44501,66.651771 16.22882,30.84274 47.82991,31.367399 6.30629,1.07795 26.88325,-35.335399 -32.10312,-22.211018 -18.88524,5.245901 -30.42623,-11.540983 z"
id="path35"
inkscape:label="头发部件111" /><path
style="opacity:1;fill:#ace0fe;fill-opacity:1;stroke:none;stroke-width:14.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 431.03375,175.82616 17.06329,-17.0633 50.44802,71.96261 -5.93506,17.80518 -33.38472,18.54706 -12.612,-16.32142 17.80518,-11.12823 z"
id="path29"
inkscape:label="蓝色发卡上" /><path
style="opacity:1;fill:#ace0fe;fill-opacity:1;stroke:#4c4f59;stroke-width:6.945;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 465.90223,261.88453 c 0,0 35.61036,54.52837 2.96753,73.44637 -25.22401,4.08036 -48.22237,2.22565 -48.22237,2.22565 l 10.38636,-26.33683 21.51459,-41.91636 z"
id="path66"
inkscape:label="蓝色发卡下" /><path
style="opacity:1;fill:#febdc7;fill-opacity:1;stroke:none;stroke-width:4.6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 471.86885,57.704918 c 0,0 17.04918,68.983602 -11.01639,110.426232 -7.34426,0.26229 -9.18033,-10.49181 -9.18033,-10.49181 l 2.09836,-6.55737 -1.04918,-9.18033 2.36066,-10.7541 1.83606,-5.5082 -6.29508,-6.03278 -6.55738,-5.2459 -2.88524,-5.24591 2.88524,-5.2459 -2.62295,-5.245899 -4.19672,-2.885246 -3.14754,-1.57377 5.2459,-11.540984 11.80328,-7.344262 z"
id="path64" /><path
id="path57"
style="opacity:1;fill:#ff1c1c;fill-opacity:0.0509804;stroke-width:3.92397;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 244.26691,326.81357 a 35.587568,21.480417 0 0 1 -35.58757,21.48042 35.587568,21.480417 0 0 1 -35.58757,-21.48042 35.587568,21.480417 0 0 1 35.58757,-21.48042 35.587568,21.480417 0 0 1 35.58757,21.48042 z" /><path
id="path57-1"
style="fill:#ff1c1c;fill-opacity:0.05044398;stroke-width:3.65169;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 355.20429,336.75188 a 31.611719,20.942554 0 0 1 -31.61171,20.94255 31.611719,20.942554 0 0 1 -31.61172,-20.94255 31.611719,20.942554 0 0 1 31.61172,-20.94255 31.611719,20.942554 0 0 1 31.61171,20.94255 z" /><path
style="display:inline;opacity:1;fill:#fbf3ef;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 188.32787,343.60656 c 0,0 12.06557,-28.32787 15.7377,6.29508 5.24591,-8.91803 9.96722,-17.31148 17.31148,-8.39344 6.81967,2.09836 15.21311,7.34426 4.72131,22.03278 -10.4918,14.68853 16.33814,-18.37136 15.445,-1.63289 -0.72099,13.51206 -24.52214,46.81129 -24.52214,46.81129 0,0 -6.33782,64.18547 -33.41466,70.23144 -36.5485,8.16089 -12.06558,-103.86885 -12.06558,-103.86885 z"
id="path1"
sodipodi:nodetypes="cccsscscc"
inkscape:label="右手" /><path
id="path5"
style="fill:#fbe7e5;stroke-width:10.4;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke;fill-opacity:0.40581462"
inkscape:label="右手踝阴影"
d="m 193.63133,383.92419 a 12.612,12.241061 0 0 1 -12.612,12.24107 12.612,12.241061 0 0 1 -12.612,-12.24107 12.612,12.241061 0 0 1 12.612,-12.24106 12.612,12.241061 0 0 1 12.612,12.24106 z" /><path
style="fill:#fee4e0;fill-opacity:0.42411327;stroke:none;stroke-width:10.4;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 179.09741,356.52608 14.09576,-20.77271 7.04789,1.48377 0.74188,13.72482 11.49918,-11.49918 9.27353,4.08036 8.53165,5.93506 -5.56412,14.83765 13.72483,-4.82224 -3.33847,17.80518 -47.85143,-27.44965 z"
id="path9"
inkscape:label="右手手指阴影" /><path
style="display:inline;fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 188.32787,343.60656 c 0,0 12.06557,-28.32787 15.7377,6.29508 5.24591,-8.91803 9.96722,-17.31148 17.31148,-8.39344 6.81967,2.09836 15.21311,7.34426 4.72131,22.03278 -10.4918,14.68853 16.33814,-18.37136 15.445,-1.63289 -0.72099,13.51206 -24.52214,46.81129 -24.52214,46.81129 0,0 -6.33782,64.18547 -33.41466,70.23144 -36.5485,8.16089 -12.06558,-103.86885 -12.06558,-103.86885 z"
id="path1-6"
sodipodi:nodetypes="cccsscscc"
inkscape:label="右手遮挡" /><path
style="opacity:1;fill:#fff9f6;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 137.44262,123.2787 c 0,0 49.33852,-48.649769 86.97684,-58.734919 0.10513,0.76769 -120.16719,-122.15824 -86.97684,58.734919 z"
id="path3"
inkscape:label="头发部件19 左猫耳" /><path
style="fill:#fde9e7;fill-opacity:1;stroke-width:1.18016;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 198.85246,42 -63.6342,39.016573 3.84123,40.939237 L 184.82787,87 224,64.5 Z"
id="path58"
sodipodi:nodetypes="cccccc" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0.465732;stroke:#a18f90;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path4"
d="m 404.96447,131.7729 c 0.52512,-0.76931 1.0357,-1.54875 1.57536,-2.30793 2.82418,-3.97291 5.82035,-7.82036 8.67758,-11.76948 2.39309,-3.30762 3.93978,-5.54326 6.29133,-8.89998 5.32612,-7.58044 11.18023,-14.760796 17.20894,-21.78699 3.02173,-3.55064 6.06655,-7.098864 9.47662,-10.289082 1.96198,-1.835492 4.21906,-3.672787 6.27415,-5.392122 5.10823,-4.357455 10.66931,-8.109574 16.22169,-11.862072 0,0 -2.92504,-1.864176 -2.92504,-1.864176 v 0 c -5.41592,3.900149 -10.90348,7.705144 -15.99184,12.040062 -1.99887,1.645368 -4.44389,3.611151 -6.36286,5.369248 -3.45237,3.162941 -6.48944,6.731577 -9.48752,10.316639 -5.95526,7.087894 -11.63254,14.399231 -17.00034,21.944173 -5.47138,7.72885 -10.96322,15.45542 -17.11251,22.66867 z"
inkscape:label="头发部件18" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0.465732;stroke:#a18f90;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path6"
d="m 431.7055,96.885136 c 0.68345,-0.01683 1.36993,0.008 2.05351,0.03239 1.26616,0.04274 2.52519,0.175792 3.77564,0.374299 1.34943,0.219358 2.67703,0.547853 3.99756,0.89747 1.30448,0.342355 2.58658,0.760225 3.8587,1.206247 0.34787,0.132122 0.88919,0.332358 1.23164,0.483411 0.1893,0.0835 0.73774,0.373687 0.5597,0.268307 -4.92017,-2.912189 -2.83776,-1.86942 -2.01609,-0.911603 0.4665,0.942833 -0.25414,1.810973 -0.83258,2.515753 -1.05305,1.11546 -2.37988,1.92349 -3.65077,2.76486 -0.70455,0.52564 -1.84263,0.99551 -2.02707,1.9792 -0.13577,0.72412 0.14689,1.00706 0.45808,1.64499 0.25805,0.31484 0.49646,0.64686 0.77415,0.94453 0.63085,0.67625 1.54885,1.45348 2.25243,2.03623 1.28413,1.06359 2.61277,2.07518 3.92585,3.10243 2.22765,1.73231 4.46676,3.44711 6.4408,5.4696 1.24472,1.36548 2.33589,2.86124 3.10757,4.54226 0.57402,1.31239 0.61894,2.68201 0.46471,4.08008 -0.15236,1.542 -1.01177,2.74753 -1.96982,3.90485 -1.25092,1.39253 -2.70297,2.57966 -3.98322,3.94302 -0.61776,0.76458 -1.19371,1.60995 -1.3359,2.60746 -0.0756,0.53059 -0.0152,0.87319 0.031,1.40055 0.18192,1.34638 0.59785,2.64226 1.03422,3.92358 0.46172,1.36123 1.10075,2.65093 1.71056,3.94949 0.57934,1.12566 0.88081,2.32829 0.97901,3.58284 0.0285,1.01273 -0.14083,2.01608 -0.35002,3.00302 -0.18321,0.8594 -0.39147,1.62037 -0.92358,2.32955 -0.69384,0.72591 -1.52468,1.30006 -2.31082,1.91913 0,0 3.13155,1.96912 3.13155,1.96912 v 0 c 0.80747,-0.64335 1.66352,-1.23803 2.37418,-1.9921 0.58364,-0.77755 0.80933,-1.52536 1.00495,-2.4688 0.21825,-1.01967 0.38801,-2.05558 0.38421,-3.10149 -0.0761,-1.29512 -0.34601,-2.55043 -0.93895,-3.71574 -0.60728,-1.2882 -1.24849,-2.56502 -1.72185,-3.91075 -0.43768,-1.25837 -0.85635,-2.529 -1.07055,-3.84806 -0.053,-0.43231 -0.12968,-0.85315 -0.0855,-1.29165 0.0948,-0.94059 0.64999,-1.73394 1.21835,-2.45227 1.27656,-1.3752 2.72864,-2.57131 3.98645,-3.96542 1.00742,-1.20382 1.92485,-2.46496 2.104,-4.07351 0.17452,-1.45227 0.1673,-2.88462 -0.39573,-4.26425 -0.74413,-1.73945 -1.85028,-3.26977 -3.10544,-4.6809 -0.76822,-0.80351 -0.91233,-0.98548 -1.76144,-1.74089 -1.5106,-1.3439 -3.15419,-2.52947 -4.72414,-3.80078 -1.30934,-1.02359 -2.63319,-2.03185 -3.9193,-3.08473 -0.71006,-0.5813 -1.57278,-1.30278 -2.22387,-1.96185 -0.27049,-0.2738 -0.51217,-0.57463 -0.76826,-0.86194 -0.2502,-0.39692 -0.62512,-0.79772 -0.57512,-1.31981 0.0792,-0.82671 1.33713,-1.38331 1.899,-1.81756 1.29884,-0.86671 2.65474,-1.69887 3.73107,-2.84377 0.6873,-0.83746 1.4042,-1.79633 1.075,-2.93575 -0.0816,-0.13585 -0.14456,-0.28482 -0.24481,-0.40755 -0.1097,-0.13429 -0.23095,-0.26613 -0.3791,-0.356228 -1.82458,-1.109627 -3.48552,-2.166773 -5.4739,-2.822822 -1.27815,-0.438878 -2.56689,-0.847162 -3.87638,-1.183261 -1.32827,-0.341807 -2.66392,-0.6605 -4.021,-0.867076 -1.26646,-0.185139 -2.54065,-0.306124 -3.82011,-0.354118 -0.68835,-0.02484 -1.39159,-0.0088 -2.07079,-0.120664 z"
inkscape:label="头发部件17" /><path
style="display:inline;opacity:1;fill:#1a1a1a;fill-opacity:0.465732;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path7"
d="m 472.56515,132.89174 c 0.0148,0.77317 -0.10076,1.54619 -0.19578,2.31209 -0.22663,1.66469 -0.65036,3.29152 -1.09324,4.90909 -0.61155,2.16519 -1.31643,4.30298 -2.07388,6.4211 -0.85906,2.40245 -1.88628,4.73722 -3.04362,7.0095 -1.12519,2.18837 -2.40662,4.28829 -3.77255,6.3331 -1.20044,1.78353 -2.51232,3.48695 -3.85961,5.16088 -0.77567,0.94691 -1.56273,1.88443 -2.34905,2.82249 0,0 3.09439,1.85764 3.09439,1.85764 v 0 c 0.78058,-0.94434 1.56325,-1.88703 2.331,-2.84187 1.33972,-1.69155 2.6509,-3.40675 3.84535,-5.20534 1.36483,-2.06191 2.64248,-4.17929 3.77385,-6.37958 1.16439,-2.28454 2.19746,-4.6314 3.07763,-7.04092 0.77266,-2.11878 1.49327,-4.25705 2.12518,-6.4224 0.46749,-1.62041 0.91079,-3.25003 1.1854,-4.9163 0.11547,-0.76691 0.21504,-1.53597 0.32143,-2.30416 z"
inkscape:label="头发部件16" /><path
style="display:inline;opacity:1;fill:#fff9f6;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 322.62295,86.032787 c 0,0 75.43341,26.120553 110.16394,89.180323 33.44261,60.72132 33.04918,62.42623 33.04918,62.42623 0,0 0.52459,8.39345 -19.93443,11.54099 -2.62295,0 14.68852,30.95082 19.93443,37.2459 -14.68853,7.34426 -16.78689,8.91803 -16.78689,8.91803 0,0 6.29508,7.86885 4.72131,15.73771 -17.31147,-0.52459 -22.55738,-1.04918 -22.55738,-1.04918 0,0 -4.19672,17.31147 -15.7377,33.04918 C 410.22951,333.11475 410.22951,320 410.22951,320 c 0,0 -24.13115,36.72131 -72.39344,41.44262 -1.57377,-2.62295 12.59016,-14.16393 17.83606,-28.32787 -11.54098,1.57377 -14.68852,2.09836 -14.68852,2.09836 l 10.4918,-16.78688 c 0,0 11.01639,-24.13115 9.44262,-28.32787 -1.04918,-2.62295 -32,-57.70492 -32,-57.70492 0,0 -24.65573,33.04918 -43.54098,49.83607 -6.81967,-4.19672 -13.63934,-14.68853 -13.63934,-14.68853 l -12.59017,11.54099 c 0,0 -48.43778,-50.76436 -42.0945,-90.18318 -3.14754,12.06557 0.12729,56.60941 -5.6432,62.3799 -5.24591,-2.09836 -16.2623,-14.68853 -14.16394,-40.91803 -0.52459,-0.52459 -29.90164,41.44262 -29.90164,41.44262 0,0 -4.19672,48.78688 16.2623,73.44262 1.57377,2.62295 -1.57377,16.2623 -31.47541,-2.62295 1.04918,-1.57377 -1.04918,9.96721 -1.04918,9.96721 0,0 -46.68853,2.09836 -45.63935,-60.85245 -2.62295,-2.62296 -13.639341,34.09836 -13.639341,34.09836 0,0 -24.131151,-32 -0.52459,-92.85246 11.803281,-30.42623 23.344261,-52.85246 31.934421,-67.67213 8.59017,-14.81968 14.22951,-22.03279 14.22951,-22.03279"
id="path8"
sodipodi:nodetypes="csccccccccccccccccccccccccccssc"
inkscape:label="头发部件15 头发底色" /><path
id="path36"
style="fill:#fffdfc;stroke-width:7.4278;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
inkscape:label="头发打光"
d="m 355.67214,146.88524 a 91.803276,41.967213 0 0 1 -91.80327,41.96721 91.803276,41.967213 0 0 1 -91.80328,-41.96721 91.803276,41.967213 0 0 1 91.80328,-41.96721 91.803276,41.967213 0 0 1 91.80327,41.96721 z" /><path
style="fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 349.37705,329.44262 c 0,0 71.34426,-41.96721 78.68852,-91.27868 0,1.04918 26.22951,28.32786 26.22951,28.32786 l 11.54099,24.13115 -15.73771,7.34426 2.09836,13.63935 -22.03279,-1.04918 -12.59016,30.42623 -12.59016,-17.83607 -23.08197,26.22951 -45.11475,14.68852 z"
id="path37"
inkscape:label="头发阴影"
sodipodi:nodetypes="cccccccccccc" /><path
style="fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 325.2459,144.78689 c 0,0 10.49181,44.06557 2.09836,78.68852 0,10.4918 33.57377,60.85246 33.57377,60.85246 0,0 14.68853,-71.34426 -25.18032,-132.19672 -8.39345,-5.2459 -10.49181,-7.34426 -10.49181,-7.34426 z"
id="path38"
inkscape:label="头发阴影2" /><path
style="fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 186.7541,166.81967 23.08197,1.04918 c 0,0 -14.68853,26.22951 -13.63935,46.16394 -2.09836,-3.14754 -22.03279,31.47541 -22.03279,31.47541 0,0 -9.44262,-14.68853 -3.14754,-50.36066 9.44263,-16.78688 15.73771,-28.32787 15.73771,-28.32787 z"
id="path39"
inkscape:label="头发阴影" /><path
id="path36-5"
style="fill:#fffdfc;stroke-width:6.94619;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
inkscape:label="头发打光"
transform="matrix(0.99965843,-0.02613486,0,1,0,0)"
d="m 340.28017,112.23744 a 80.289719,41.967213 0 0 1 -80.28972,41.96721 80.289719,41.967213 0 0 1 -80.28972,-41.96721 80.289719,41.967213 0 0 1 80.28972,-41.967211 80.289719,41.967213 0 0 1 80.28972,41.967211 z" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#a18f90;stroke-width:7.7;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 138.62295,122.4918 c 0,0 53.63935,-52.983604 92.98361,-58.229505"
id="path65"
sodipodi:nodetypes="cc" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 436.45902,268.06557 c 0,0 3.67213,18.36066 -2.62295,42.49181"
id="path17"
inkscape:label="头发部件7" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 418.09836,305.83607 -8.91803,17.83606"
id="path16"
inkscape:label="头发部件8" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 377.70492,300.59016 c 0,0 2.62295,12.06558 -22.03279,32"
id="path15"
inkscape:label="头发部件9" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:4.2;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 284.32787,97.573771 c 0,0 12.06557,39.344259 -27.80328,119.081969 0.52459,0 53.5082,-38.81967 56.13115,-89.18033"
id="path10"
inkscape:label="头发部件14" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:5.1;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 272.78689,87.081967 c 0,0 13.63934,-8.393442 18.88524,-0.52459 17.17267,10.839383 13.03281,30.236103 24.19672,44.393443 1.79263,1.85342 7.1718,-0.78131 7.80328,1.77049 4.88126,19.72513 14.81582,50.80617 4.32401,100.11764"
id="path11"
sodipodi:nodetypes="csssc"
inkscape:label="头发部件13" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:4.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 171.00392,241.8537 c 0,0 -28.56248,-60.09248 92.36438,-147.634619 2.22564,0.741882 -59.35061,54.157419 -66.02755,111.282379"
id="path12"
inkscape:label="头发部件12" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:3;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 327.34426,143.7377 c 0,0 25.18033,20.45902 32,65.57378"
id="path13"
inkscape:label="头发部件11" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 362.4918,268.59016 -3.14754,19.93443"
id="path14"
inkscape:label="头发部件10" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 421.77049,344.13115 c 0,0 -2.62295,58.22951 -33.57377,111.7377 -30.95082,53.5082 38.29508,15.73771 38.29508,15.73771"
id="path18"
inkscape:label="头发部件6" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 395.01639,348.32787 12.06558,60.32787"
id="path19"
inkscape:label="头发部件5" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 371.93443,423.86885 c 0,0 30.95082,-25.70492 24.65573,-73.96721"
id="path20"
inkscape:label="头发部件4" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 332.06557,427.54098 c 0,0 36.72132,1.57377 38.81968,-29.37705"
id="path21"
inkscape:label="头发部件3" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 372.45902,427.01639 -2.09836,-28.85246"
id="path22"
inkscape:label="头发部件2" /><path
style="fill:#93cefc;fill-opacity:1;stroke:#4d4e59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 377.50929,228.61046 c 0,0 24.13115,1.57377 24.13115,10.49181 -0.52459,3.67213 -11.54099,17.83606 -23.60656,18.88524 -2.09836,-1.57377 -0.52459,-29.37705 -0.52459,-29.37705 z"
id="path34"
sodipodi:nodetypes="cccc"
inkscape:label="兔子发卡后" /><path
style="opacity:1;fill:#fffdfe;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 350.95082,235.54098 c 0,0 -6.55738,-22.03278 1.04918,-22.03278 7.60656,0 13.37705,13.90164 13.37705,13.90164 0,0 5.05941,-17.72738 9.96722,-15.21311 11.79758,6.04389 3.40983,21.77048 3.40983,21.77048 0,0 18.62295,25.96722 -12.06558,27.27869 -30.16717,1.28919 -15.7377,-25.70492 -15.7377,-25.70492 z"
id="path24"
sodipodi:nodetypes="cscscsc"
inkscape:label="兔子发卡" /><path
style="display:inline;opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 332.06557,425.96721 c 0,0 10.49181,-25.18032 6.29509,-49.83606"
id="path23"
inkscape:label="头发部件" /><path
style="display:inline;opacity:1;fill:#e85240;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 192.2623,268.85246 c 0,0 -15.47541,22.03279 -2.62296,35.40984 42.7541,0.26229 43.27869,0.52459 43.27869,0.52459 0,0 11.27869,-8.39345 5.5082,-32 -25.44262,-9.96722 -46.16393,-3.93443 -46.16393,-3.93443 z"
id="path25"
inkscape:label="左眼白" /><path
style="opacity:1;fill:#fbb579;fill-opacity:1;stroke:none;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 188.06557,301.11475 c -0.44151,-8.78192 13.4528,-14.01636 22.29509,-14.42623 8.67244,-0.402 23.2398,3.38526 23.08196,12.06558 -0.0775,4.26198 -11.54098,5.5082 -11.54098,5.5082 0,0 -33.2673,8.16555 -33.83607,-3.14755 z"
id="path27"
sodipodi:nodetypes="saacs"
inkscape:label="左眼瞳" /><path
id="path26"
style="display:inline;opacity:1;fill:#ffffff;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
inkscape:label="眼光"
d="m 217.96721,273.04919 a 7.8688526,7.0819674 0 0 1 -7.86885,7.08197 7.8688526,7.0819674 0 0 1 -7.86885,-7.08197 7.8688526,7.0819674 0 0 1 7.86885,-7.08196 7.8688526,7.0819674 0 0 1 7.86885,7.08196 z" /><path
style="fill:none;fill-opacity:1;stroke:#ebc2bf;stroke-width:2.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 174.16393,245.5082 c 15.08644,-4.76649 31.53934,-7.45293 47.09358,-3.51527 3.29779,0.83486 6.51821,1.99257 9.56216,3.51527"
id="path42"
inkscape:path-effect="#path-effect42"
inkscape:original-d="m 174.16393,245.5082 c 11.60252,-3.79212 36.99244,-9.83166 56.65574,0"
transform="translate(0,4)" /><path
style="opacity:1;fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:6.945;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 477.77235,132.79697 c 0,0 13.35388,10.01542 14.83765,17.43424 1.48376,7.41883 1.48376,57.4959 1.48376,57.4959 l -4.45129,1.11282 -30.78813,-37.46507 c 0,0 8.90259,-14.46671 11.12824,-22.62741 2.22565,-8.16071 7.78977,-15.95048 7.78977,-15.95048 z"
id="path67" /><path
style="fill:#e85240;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 192.2623,268.85246 c 0,0 -15.47541,22.03279 -2.62296,35.40984 42.7541,0.26229 43.27869,0.52459 43.27869,0.52459 0,0 11.27869,-8.39345 5.5082,-32 -25.44262,-9.96722 -46.16393,-3.93443 -46.16393,-3.93443 z"
id="path25-9"
inkscape:label="左眼遮挡上" /><path
style="display:inline;fill:#e85240;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 325.52138,272.81871 c 17.02505,1.06627 38.81967,23.08196 17.83607,48.26229 -1.57377,0.52459 -48.98481,-5.30599 -49.57378,-9.18033 -0.80561,-5.29953 -7.95666,-41.56799 31.73771,-39.08196 z"
id="path40"
sodipodi:nodetypes="scss"
inkscape:label="右眼白" /><path
style="fill:#fbb579;fill-opacity:1;stroke:none;stroke-width:7.14054;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 293.04592,306.32136 c 2.55323,-8.53469 20.43105,-9.52962 30.78942,-7.36618 10.1594,2.12188 25.66784,9.9581 22.45763,18.22228 -1.5762,4.05766 -15.25453,1.93723 -15.25453,1.93723 0,0 -41.28165,-1.79873 -37.99252,-12.79333 z"
id="path27-0"
sodipodi:nodetypes="saacs"
inkscape:label="左眼瞳" /><path
style="display:inline;fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 325.52138,272.81871 c 17.02505,1.06627 38.81967,23.08196 17.83607,48.26229 -1.57377,0.52459 -48.98481,-5.30599 -49.57378,-9.18033 -0.80561,-5.29953 -7.95666,-41.56799 31.73771,-39.08196 z"
id="path40-2"
sodipodi:nodetypes="scss"
inkscape:label="右眼遮挡上" /><path
style="fill:none;fill-opacity:1;stroke:#ebc2bf;stroke-width:2.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 309.32819,258.43459 c 0,0 26.2295,-5.2459 36.72131,4.19672"
id="path43" /><path
id="path26-9"
style="display:inline;fill:#ffffff;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
inkscape:label="眼光"
d="m 329.6342,284.99301 a 7.8688526,7.0819674 0 0 1 -7.86885,7.08197 7.8688526,7.0819674 0 0 1 -7.86885,-7.08197 7.8688526,7.0819674 0 0 1 7.86885,-7.08197 7.8688526,7.0819674 0 0 1 7.86885,7.08197 z" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:14.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 170.4918,266.4918 c 0,0 32,-19.93442 70.29509,-2.09836"
id="path28"
inkscape:label="眉毛" /><path
style="fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:14.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 292.9971,274.17683 c 0,0 35.55098,-12.55026 69.08832,13.13797"
id="path28-2"
inkscape:label="眉毛" /><path
style="display:inline;opacity:1;fill:none;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 431.03375,176.1971 18.17612,-17.43424 41.54542,54.15742"
id="path30"
inkscape:label="蓝色发卡遮挡上" /><path
style="opacity:1;fill:none;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 454.0321,267.44865 43.21466,-23.92571"
id="path31"
sodipodi:nodetypes="cc"
inkscape:label="蓝色发卡遮挡下" /><path
style="display:inline;fill:#fff9f6;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 164.23888,424.64081 -31.07097,26.05282 c 0,0 -5.19317,18.17613 25.96589,28.93342 31.15907,10.7573 213.29123,1.48377 213.29123,1.48377 0,0 52.30272,11.87012 80.86519,-37.09413 -0.37094,0.74188 -8.90259,19.28895 -8.90259,19.28895 l 1.48377,19.28894 c 0,0 57.73516,-9.41425 30.45647,-148.95524 4.19672,-9.44262 8.39344,-15.21311 8.39344,-15.21311 l -3.14754,-21.77049 c 0,0 5.65758,-40.33533 7.88323,-45.52851 2.22564,-5.19317 8.51558,-6.35116 9.64447,-11.12823 2.06907,-8.75561 -2.78206,-20.40177 -6.67694,-26.15136 -0.74189,-3.33847 6.86241,-35.05395 2.04017,-58.05231 -7.04788,-11.87012 -4.82223,-11.87012 -18.918,-25.59495 0,0.37094 8.90259,-44.88389 -0.74188,-73.446367 -2.96753,0 -32.27189,-10.757296 -96.81567,23.740241 -0.37094,1.112824 -26.33683,-30.046242 -153.56969,-15.950474 -0.74188,0 -43.40012,-37.836009 -66.76942,-40.432598 -1.11283,-0.370941 -22.62742,-4.080354 -25.22401,48.964247 0,1.112824 -44.14201,15.950474 -56.01213,64.914721 -11.87012,48.96425 -11.128238,80.86519 -11.128238,80.86519 0,0 -18.904912,27.6632 -9.798121,25.03308 5.346826,-1.54421 4.975885,23.56023 4.975885,23.56023 l -2.225648,39.31977 c 0,0 -14.466709,35.23942 -14.83765,59.72155 -0.370942,24.48212 -0.741883,34.12659 4.822236,48.5933 5.564119,14.46671 20.772711,46.7386 42.658245,63.06002 8.902591,0.37094 18.918001,1.8547 18.918001,1.8547 l 3.70942,-20.77271 c 0,0 18.918,15.95048 32.27189,14.83765 13.35388,-1.11282 -0.74189,-0.74188 -0.74189,-0.74188 l -13.72482,-17.80518 z"
id="path2-4"
sodipodi:nodetypes="ccscccccccsaccccccccscsccsscccsccc"
inkscape:label="上发层" /><path
style="fill:none;fill-opacity:1;stroke:#c3b4b0;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 197.5082,220.06557 18.36065,-12.32786"
id="path46" /><path
style="fill:none;fill-opacity:1;stroke:#c3b4b0;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 327.54114,234.24941 c 0,0 -6.27192,4.90452 -15.85821,-0.991"
id="path47"
sodipodi:nodetypes="cc" /><path
style="display:inline;fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 322.62295,86.03279 c 0,0 75.43341,26.12055 110.16394,89.18032 33.44261,60.72132 33.04918,62.42623 33.04918,62.42623 0,0 0.52459,8.39345 -19.93443,11.54099 -2.62295,0 14.68852,30.95082 19.93443,37.2459 -14.68853,7.34426 -16.78689,8.91803 -16.78689,8.91803 0,0 6.29508,7.86885 4.72131,15.73771 -17.31147,-0.52459 -22.55738,-1.04918 -22.55738,-1.04918 0,0 -4.19672,17.31147 -15.7377,33.04918 C 410.22951,333.11475 410.22951,320 410.22951,320 c 0,0 -24.13115,36.72131 -72.39344,41.44262 -1.57377,-2.62295 12.59016,-14.16393 17.83606,-28.32787 -11.54098,1.57377 -14.68852,2.09836 -14.68852,2.09836 l 10.4918,-16.78688 c 0,0 11.01639,-24.13115 9.44262,-28.32787 -1.04918,-2.62295 -32,-57.70492 -32,-57.70492 0,0 -24.65573,33.04918 -43.54098,49.83607 -6.81967,-4.19672 -13.63934,-14.68853 -13.63934,-14.68853 l -12.59017,11.54099 c 0,0 -48.43778,-50.76436 -42.0945,-90.18318 -3.14754,12.06557 0.12729,56.60941 -5.6432,62.3799 -5.24591,-2.09836 -16.2623,-14.68853 -14.16394,-40.91803 -0.52459,-0.52459 -29.90164,41.44262 -29.90164,41.44262 0,0 -4.19672,48.78688 16.2623,73.44262 1.57377,2.62295 -1.57377,16.2623 -31.47541,-2.62295 1.04918,-1.57377 -1.04918,9.96721 -1.04918,9.96721 0,0 -46.68853,2.09836 -45.63935,-60.85245 -2.62295,-2.62296 -13.63934,34.09836 -13.63934,34.09836 0,0 -24.13115,-32 -0.52459,-92.85246 11.80328,-30.42623 23.34426,-52.85246 31.93442,-67.67213 8.59017,-14.81968 14.22951,-22.03279 14.22951,-22.03279"
id="path8-0"
sodipodi:nodetypes="csccccccccccccccccccccccccccssc"
inkscape:label="头发部件15 头发底色" /><path
id="path44-3"
style="fill:#a88a8f;stroke:#4c4f59;stroke-width:2.8623;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 216.29183,255.53888 a 8.8904896,7.4928694 0 0 1 -8.89049,7.49287 8.8904896,7.4928694 0 0 1 -8.89049,-7.49287 8.8904896,7.4928694 0 0 1 8.89049,-7.49287 8.8904896,7.4928694 0 0 1 8.89049,7.49287 z" /><path
id="path44"
style="fill:#a88a8f;stroke:#4c4f59;stroke-width:2.8623;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 336.16933,270.5473 a 8.8904896,7.4928694 0 0 1 -8.89049,7.49287 8.8904896,7.4928694 0 0 1 -8.89049,-7.49287 8.8904896,7.4928694 0 0 1 8.89049,-7.49287 8.8904896,7.4928694 0 0 1 8.89049,7.49287 z" /><path
style="opacity:1;fill:none;fill-opacity:0;stroke:#a18f90;stroke-width:10.4;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 318.7189,85.461784 c 0,0 50.44801,17.063296 76.78484,43.400126 26.33683,26.33683 32.64283,39.31978 32.64283,39.31978"
id="path32"
inkscape:label="上方头发边缘加厚" /><path
style="fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 186.7541,224.52459 10.4918,1.04918"
id="path45" /><path
style="opacity:1;fill:#fcbeb5;fill-opacity:1;stroke:#e99c9b;stroke-width:3.4;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 250.94176,349.98308 c 0,0 -13.91029,-8.90259 -10.0154,-16.69235 3.89488,-7.78977 17.80517,-4.4513 17.80517,-4.4513 0,0 12.98295,-1.29829 20.03083,-3.89488 7.04788,-2.59659 9.64447,5.0077 9.64447,5.0077 0,0 4.76461,6.06544 -4.26583,16.50689 -5.93505,6.86241 -21.14364,7.04788 -21.14364,7.04788"
id="path48"
sodipodi:nodetypes="cscscsc" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e99c9b;stroke-width:1.8;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 276.20884,325.76493 c 0,0 4.35031,3.01904 5.37456,7.95235 0.57119,0.10629 3.33355,-3.08729 2.97647,-6.87263 -0.67968,-1.48531 -8.35103,-1.07972 -8.35103,-1.07972 z"
id="path49" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e99c9b;stroke-width:1.8;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 245.0067,329.39584 -4.17308,2.78206 -0.0927,6.0278 -0.0956,-0.0355 7.07328,-8.8174 z"
id="path50"
sodipodi:nodetypes="cccccc" /><path
style="fill:none;fill-opacity:1;stroke:#e99c9b;stroke-width:3.4;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 250.94176,349.98308 c 0,0 -13.91029,-8.90259 -10.0154,-16.69235 3.89488,-7.78977 17.80517,-4.4513 17.80517,-4.4513 0,0 12.98295,-1.29829 20.03083,-3.89488 7.04788,-2.59659 9.64447,5.0077 9.64447,5.0077 0,0 4.76461,6.06544 -4.26583,16.50689 -5.93505,6.86241 -21.14364,7.04788 -21.14364,7.04788"
id="path48-2"
sodipodi:nodetypes="cscscsc" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e89493;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 190.84928,314.92913 6.12053,15.02312"
id="path51" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e89493;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 204.94505,316.96931 5.56412,14.28124"
id="path52" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e89493;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 217.92799,317.34025 7.41883,16.50689"
id="path53" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e89493;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 300.64789,328.46849 6.86242,18.17612"
id="path54" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e89493;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 312.70348,329.21037 6.67695,17.0633"
id="path55" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e89493;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 326.24284,328.65396 7.04788,17.99065"
id="path56" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#e49589;stroke-width:4.6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 218.4918,348.98361 c -1.87307,1.30472 -3.33608,3.11401 -4.70333,4.91603 -1.02497,1.35089 -2.00187,2.75003 -2.77208,4.2643"
id="path61"
inkscape:path-effect="#path-effect61"
inkscape:original-d="m 218.4918,348.98361 c -1.70592,0.99645 -5.82749,5.88449 -7.47541,9.18033"
transform="rotate(-3.3120949,219.55256,344.63259)" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 127.47541,375.08197 c 0,0 -14.42623,-19.14754 -12.06557,-59.54099"
id="path92" /><path
style="opacity:1;fill:#ffffff;fill-opacity:0.734285;stroke:#c1545a;stroke-width:7.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 136.39344,322.09836 c 0,0 9.44263,-18.88525 -4.19672,-39.86885 -3.14754,-0.52459 27.80328,-27.80328 5.2459,-77.11476 -1.57377,0.52459 23.60656,-55.60655 -24.13115,-82.88524 -4.19672,-8.39344 -45.639336,-69.245904 -89.180316,13.11475 0,11.54099 -1.04918,36.19672 -1.04918,36.19672 0,0 -14.6885299,38.81968 -6.29509,71.86886 2.09837,3.14754 -20.9835999,49.83606 11.0164,106.4918 0.52459,0.52459 -16.78689,57.70492 12.59016,82.88525 1.04918,4.72131 13.63935,33.57377 42.49181,39.34426 12.59016,0.52459 19.409826,-0.52459 19.409826,-0.52459 0,0 31.47541,-4.72131 47.73771,-67.14754 -2.09836,-27.80328 -4.19672,-50.36066 -11.0164,-70.81968"
id="path93" /><path
id="path101"
style="opacity:1;fill:#ffffff;fill-opacity:0.734285;stroke:#000000;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 109.69769,219.48859 c 0,0 -15.208592,-11.87012 -21.143652,-19.65989 m -37.09413,20.03083 22.25648,-21.88553 m 0.37094,-14.09577 5.93506,41.91636 m -35.23942,-24.11118 56.012132,-4.82224 m 11.12824,-17.43424 -19.288952,0.37094 m -0.37094,-0.74188 -1.48376,-29.6753 m -38.94883,3.33847 37.836,-2.96753 m -24.85306,-11.49918 0.74188,39.69072"
inkscape:label="杂" /><path
id="path111"
style="opacity:1;fill:#ffffff;fill-opacity:0.734285;stroke:#000000;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 58.507798,352.28556 54.157422,-3.33847 m -46.367662,-13.72483 35.610372,-2.96753 m -21.514602,-32.27189 2.59659,33.38472 m -18.918,-16.32142 37.094122,-3.33847 m 1.48377,18.54706 0.74188,-33.75565 m -0.37094,0.37094 -40.803542,2.22565 m 0,-0.37094 4.4513,33.38471 m 27.44965,-48.22237 3.33847,-14.4667 m 0,-1.48377 -27.44965,1.48377 m -1.48377,14.83765 0.74188,-20.03083"
inkscape:label="鱼" /><path
d="m 69.453989,376.46984 c -4.220665,0.22086 -8.079406,1.8518 -10.783191,4.54882 -2.980547,2.98155 -4.241957,7.10139 -3.534076,11.54824 0.904812,5.67433 4.763552,11.7394 11.384623,17.90216 1.405115,1.30393 2.39508,2.14912 4.390984,3.74184 3.507462,2.79468 6.679618,5.01174 11.04931,7.70876 1.559468,0.96838 4.635815,2.76496 5.796096,3.38931 l 0.335314,0.18263 0.48966,-0.26758 c 1.783005,-0.98111 4.960482,-2.86264 6.844609,-4.05189 7.126702,-4.49782 12.832312,-9.01266 17.063632,-13.50625 6.86057,-7.28827 9.77725,-14.38543 8.43068,-20.49298 -0.93142,-4.20475 -4.04502,-7.68327 -8.46261,-9.45012 -1.90011,-0.76026 -3.74699,-1.15525 -5.83869,-1.24869 -2.7091,-0.12316 -5.37562,0.33977 -7.91973,1.37185 -4.332435,1.75413 -7.951675,5.17315 -10.229661,9.66674 -0.159681,0.3143 -0.308701,0.59038 -0.329985,0.60737 -0.0692,0.0553 -0.143707,-0.051 -0.431122,-0.62859 -0.681263,-1.35913 -2.01719,-3.3341 -3.065699,-4.52331 -1.07513,-1.22747 -2.804909,-2.72251 -4.092931,-3.54224 -3.326503,-2.11937 -7.222503,-3.15569 -11.097213,-2.95607 z"
id="path1-4"
style="fill:#d96477;fill-opacity:1;stroke:none;stroke-width:0.00475452" /></g></svg>

Before

Width:  |  Height:  |  Size: 60 KiB

View File

@@ -1,80 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Offline | SukiSU-Ultra</title>
<meta name="theme-color" content="#64edff" />
<style>
html,
body {
height: 100%;
margin: 0;
font-family:
system-ui,
-apple-system,
Segoe UI,
Roboto,
Ubuntu,
Cantarell,
'Noto Sans',
sans-serif;
}
.wrap {
min-height: 100%;
display: grid;
place-items: center;
padding: 2rem;
}
.card {
max-width: 560px;
background: #fff;
color: #111;
border-radius: 12px;
box-shadow: 0 6px 30px rgba(0, 0, 0, 0.06);
padding: 24px;
}
.card h1 {
margin: 0 0 8px;
font-size: 1.4rem;
}
.card p {
margin: 0.5rem 0;
line-height: 1.5;
}
.muted {
color: #666;
font-size: 0.9rem;
}
.actions {
margin-top: 1rem;
display: flex;
gap: 0.75rem;
}
.btn {
padding: 0.6rem 0.9rem;
border-radius: 8px;
border: 1px solid #d0d0d0;
background: #f7f7f7;
color: #111;
text-decoration: none;
}
</style>
</head>
<body>
<div class="wrap">
<div class="card">
<h1>You're offline</h1>
<p>We couldn't load this page because your device has no internet connection.</p>
<p class="muted">
When you're back online, try again. Some pages you visited before may still work from
cache.
</p>
<div class="actions">
<a class="btn" href="/">Go to home</a>
<a class="btn" href="/guide/">Docs guide</a>
</div>
</div>
</div>
</body>
</html>

View File

@@ -1,76 +0,0 @@
User-agent: *
Allow: /
Disallow: /admin/
Disallow: /.git/
Disallow: /node_modules/
Disallow: /api/
Disallow: /.vitepress/
# Sitemap
Sitemap: https://sukisu.org/sitemap.xml
# Crawl-delay for high-traffic optimization
Crawl-delay: 0.5
# Major search engines (global optimization)
User-agent: Googlebot
Allow: /
Crawl-delay: 0.5
User-agent: Bingbot
Allow: /
Crawl-delay: 1
User-agent: Slurp
Allow: /
Crawl-delay: 1
User-agent: DuckDuckBot
Allow: /
Crawl-delay: 0.5
User-agent: Baiduspider
Allow: /
Crawl-delay: 2
# Asian search engines (for China, Japan, etc.)
User-agent: YandexBot
Allow: /
Crawl-delay: 1
User-agent: NaverBot
Allow: /
Crawl-delay: 1
User-agent: SogouSpider
Allow: /
Crawl-delay: 2
# Block resource-intensive bots for performance
User-agent: AhrefsBot
Disallow: /
User-agent: MJ12bot
Disallow: /
User-agent: SemrushBot
Disallow: /
User-agent: DotBot
Disallow: /
# Block AI training crawlers to save bandwidth
User-agent: GPTBot
Disallow: /
User-agent: ChatGPT-User
Disallow: /
User-agent: CCBot
Disallow: /
User-agent: anthropic-ai
Disallow: /
User-agent: Claude-Web
Disallow: /

View File

@@ -1,535 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="512"
height="512"
viewBox="0 0 512 512"
version="1.1"
id="svg1"
xml:space="preserve"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
sodipodi:docname="zako.optizmism.svg"
inkscape:export-filename="zako.plain.svg"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#999999"
borderopacity="1"
inkscape:showpageshadow="2"
inkscape:pageopacity="1"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showguides="false"
inkscape:zoom="2"
inkscape:cx="219"
inkscape:cy="370"
inkscape:window-width="1280"
inkscape:window-height="702"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false"><inkscape:page
x="0"
y="0"
width="512"
height="512"
id="page2"
margin="0"
bleed="0" /></sodipodi:namedview><defs
id="defs1"><inkscape:path-effect
effect="simplify"
id="path-effect79"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /><inkscape:path-effect
effect="simplify"
id="path-effect78"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /><inkscape:path-effect
effect="simplify"
id="path-effect77"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /><inkscape:path-effect
effect="simplify"
id="path-effect76"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /><inkscape:path-effect
effect="simplify"
id="path-effect75"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /><inkscape:path-effect
effect="simplify"
id="path-effect61"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /><inkscape:path-effect
effect="simplify"
id="path-effect42"
is_visible="true"
lpeversion="1.3"
threshold="32.467532"
steps="1"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false" /></defs><g
inkscape:label="main"
inkscape:groupmode="layer"
id="layer1"><path
style="display:inline;opacity:1;fill:#fff9f6;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 164.23888,424.64081 -31.07097,26.05282 c 0,0 -5.19317,18.17613 25.96589,28.93342 31.15907,10.7573 213.29123,1.48377 213.29123,1.48377 0,0 52.30272,11.87012 80.86519,-37.09413 -0.37094,0.74188 -8.90259,19.28895 -8.90259,19.28895 l 1.48377,19.28894 c 0,0 57.73516,-9.41425 30.45647,-148.95524 4.19672,-9.44262 8.39344,-15.21311 8.39344,-15.21311 l -3.14754,-21.77049 c 0,0 5.65758,-40.33533 7.88323,-45.52851 2.22564,-5.19317 9.64447,-11.12823 9.64447,-11.12823 0,0 -2.78206,-20.40177 -6.67694,-26.15136 -0.74189,-3.33847 6.86241,-35.05395 2.04017,-58.05231 -7.04788,-11.87012 -4.82223,-11.87012 -18.918,-25.59495 0,0.37094 8.90259,-44.88389 -0.74188,-73.446367 -2.96753,0 -32.27189,-10.757296 -96.81567,23.740241 -0.37094,1.112824 -26.33683,-30.046242 -153.56969,-15.950474 -0.74188,0 -43.40012,-37.836009 -66.76942,-40.432598 -1.11283,-0.370941 -22.62742,-4.080354 -25.22401,48.964247 0,1.112824 -44.14201,15.950474 -56.01213,64.914721 -11.87012,48.96425 -11.128238,80.86519 -11.128238,80.86519 0,0 -18.904912,27.6632 -9.798121,25.03308 5.346826,-1.54421 4.975885,23.56023 4.975885,23.56023 l -2.225648,39.31977 c 0,0 -14.466709,35.23942 -14.83765,59.72155 -0.370942,24.48212 -0.741883,34.12659 4.822236,48.5933 5.564119,14.46671 20.772711,46.7386 42.658245,63.06002 8.902591,0.37094 18.918001,1.8547 18.918001,1.8547 l 3.70942,-20.77271 c 0,0 18.918,15.95048 32.27189,14.83765 13.35388,-1.11282 -0.74189,-0.74188 -0.74189,-0.74188 l -13.72482,-17.80518 z"
id="path2"
sodipodi:nodetypes="ccscccccccscccccccccscsccsscccsccc"
inkscape:label="整个人的边框" /><path
id="path91"
style="opacity:1;fill:#93d4fa;fill-opacity:1;stroke:#4c4f59;stroke-width:6.9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 133.91016,110.16992 -69.738285,47.48047 18.263976,30.75433 -31.617492,55.67536 28.5625,17.0625 14.837891,-1.48438 2.226562,-55.64062 2.577791,-4.39109 18.193697,-21.94485 23.74023,-49.70703 z"
sodipodi:nodetypes="ccccccccccc" /><path
style="display:inline;opacity:1;fill:#ace0fe;fill-opacity:1;stroke:#4c4f59;stroke-width:6.54357;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 217.01397,405.82758 c 0,0 7.41728,-25.94462 41.16595,-27.07265 33.74866,-1.12802 53.77534,4.1361 53.77534,4.1361 0,0 11.12594,6.39215 17.80149,14.66435 6.67557,8.2722 28.92743,40.60895 41.53682,48.88115 12.60939,8.27219 15.20545,15.41636 15.20545,15.41636 l -1.85433,11.28027 c 0,0 -14.83458,10.15224 -30.78175,11.65627 -15.94717,1.50404 -147.60404,0 -147.60404,0 l -30.04002,-3.00807"
id="path71"
inkscape:label="衣服底色" /><path
style="fill:#ffffff;fill-opacity:1;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 363.54127,444.68178 c 0,0 -6.89429,4.06586 -4.86135,6.8059 2.03293,2.74004 5.92201,3.44715 5.92201,3.44715 0,0 4.5962,0.26516 5.12653,-3.53554 0.53033,-3.8007 -3.00521,-6.8059 -3.00521,-6.8059"
id="path60" /><path
style="fill:#ffffff;fill-opacity:1;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 349.67678,459.82583 c 0,0 4.5,-7.25 7,-5.5 2.5,1.75 -4.25,7.25 -4.25,7.25"
id="path59" /><path
id="path73-8"
style="fill:#ffffff;stroke-width:8.7;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 228.96985,465.10941 a 8.0341015,5.6995392 0 0 1 -8.0341,5.69953 8.0341015,5.6995392 0 0 1 -8.03411,-5.69953 8.0341015,5.6995392 0 0 1 8.03411,-5.69954 8.0341015,5.6995392 0 0 1 8.0341,5.69954 z" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#6c9cb2;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 220.85246,408.91803 c -0.22678,0.7374 0.77024,1.47887 0.20184,0.3709 -0.55918,-1.08999 0.45864,1.0858 0.58075,1.39596 2.10089,5.33666 1.96407,11.16153 3.60742,16.6426 0.30205,1.00744 0.58829,2.039 0.5936,3.09874"
id="path75"
inkscape:path-effect="#path-effect75"
inkscape:original-d="m 220.85246,408.91803 c 0.0874,0.34973 -0.0874,1.13662 0.26229,1.04918 0.34973,-0.0874 -0.42351,-1.37161 -0.26229,-1.04918 2.70315,5.4063 2.32215,10.60009 3.67213,16 0.44415,1.77662 1.31148,3.74741 1.31148,5.5082" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#6c9cb2;stroke-width:6.9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 225.57377,436.98361 c -1.22213,4.37272 0.0774,9.22771 2.41807,12.85195 2.34183,3.626 0.85866,8.30929 2.56554,12.06608 1.71568,3.77616 2.21068,8.39349 -0.30117,12.16042 -1.9802,2.96963 -5.23922,5.13567 -6.38674,8.61546 0,0 -0.0736,0.66095 -0.0736,0.66095"
id="path76"
inkscape:path-effect="#path-effect76"
inkscape:original-d="m 225.57377,436.98361 c -1.27879,3.14891 0.64852,9.42818 3.40984,14.95082 0.92316,1.84632 0.76302,8.34571 1.57377,9.96721 1.05661,2.11323 2.18032,6.57378 1.31147,9.18033 -1.55473,4.66419 -8.07296,8.77008 -8.07296,12.2565"
sodipodi:nodetypes="csssc" /><path
style="opacity:1;fill:#fbf3ef;fill-opacity:1;stroke:none;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 259.14754,381.90164 c 0,0 8.91803,15.47541 9.18033,20.98361 0.26229,5.50819 32.26229,-1.83607 32.26229,-1.83607 0,0 -4.45901,-16.78688 -7.34426,-19.40983 -2.88524,-2.62296 -34.09836,0.26229 -34.09836,0.26229 z"
id="path89" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#6c9cb2;stroke-width:4.6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 247.86885,386.36066 c 0.62439,0.76152 1.31219,1.32242 0.35251,0.10604 -0.98535,-1.24891 -0.63523,-0.56343 0.0935,0.24171 1.40155,1.54849 2.30926,3.40606 3.10338,5.34166 1.48771,3.62621 2.15649,7.53104 4.02075,11.02472 1.24886,2.3404 2.74915,4.53757 3.97084,6.89242"
id="path77"
inkscape:path-effect="#path-effect77"
inkscape:original-d="m 247.86885,386.36066 c 3.34102,3.56326 -3.68025,-4.79705 1.83607,2.09836 1.23825,1.54782 3.18087,7.73986 3.67213,9.70492 1.00623,4.02493 4.53306,8.80383 6.03279,11.80327" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#6c9cb2;stroke-width:4.6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 306.62295,386.88525 c 1.62958,6.07854 4.04229,11.93568 6.81967,17.57377"
id="path78"
inkscape:path-effect="#path-effect78"
inkscape:original-d="m 306.62295,386.88525 c 1.57569,6.03983 4.44925,12.83291 6.81967,17.57377" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#6c9cb2;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 335.73771,431.21312 c 0.7696,3.76393 3.24862,7.26774 5.48726,10.89168 2.09754,3.39553 3.33574,7.13199 4.87926,10.7955 2.06975,4.91248 6.75146,8.7424 7.699,13.95386 0.92029,5.06165 5.24206,8.89669 5.27874,14.19502"
id="path79"
inkscape:path-effect="#path-effect79"
inkscape:original-d="m 335.73771,431.21312 c -1.15649,1.03916 3.66917,4.97179 4.45901,8.13114 0.96754,3.87016 3.8848,6.88344 4.72131,10.22951 1.09547,4.38186 5.88097,12.49359 8.39345,16.2623 0.80744,1.21116 0.89968,3.11084 1.57377,4.45901 1.7539,3.50782 4.19672,6.9619 4.19672,10.7541" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 258.62295,384.2623 c 0,0 8.13115,6.81967 11.27869,27.01639"
id="path80" /><path
style="opacity:1;fill:#fbf3ef;fill-opacity:1;stroke:#4c4f59;stroke-width:6.9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 127.23285,329.0249 c 0,0 -2.59659,60.46343 13.72483,75.30108 8.16071,-8.16071 10.01541,-10.38636 10.01541,-10.38636 l 12.24107,8.53165 5.19317,-4.45129 2.22565,-19.65989 5.19318,-10.01542 5.93506,-12.24106 -8.53165,-8.53165 -15.95047,-19.28894 -3.33848,-4.82224 -4.45129,9.27353 c 0,0 -12.24106,0 -15.95048,-2.59659 -3.70941,-2.59658 -6.306,-1.11282 -6.306,-1.11282 z"
id="path90" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 291.67213,381.37705 c 0,0 7.08197,6.55738 10.22951,26.4918"
id="path81" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 270.16393,404.19672 c 0,0 16.00001,-3.93442 27.80328,-2.62295"
id="path82" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 253.90164,417.83607 c 0,0 37.2459,-13.11476 69.77049,-9.18033 2.09836,3.67213 5.77049,16.78688 -5.77049,20.98361 -4.72131,0 -19.14754,-1.57378 -22.55738,-0.5246 -3.40983,1.04919 -12.59016,0.5246 -18.36065,4.45902 -5.77049,3.93443 -14.68853,8.91803 -18.36066,3.14754 -3.67213,-5.77049 -4.72131,-12.32787 -4.72131,-12.32787 z"
id="path83" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 276.45902,482.62295 c 0,0 -9.70492,-1.57377 1.04918,-46.42623"
id="path84" /><path
style="opacity:1;fill:#fcf6fa;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 287.21312,432.78689 6.29508,50.88524 13.90164,-0.78688 -6.81968,-54.03279 z"
id="path88" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 287.73771,430.95082 5.77049,50.88525"
id="path85" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 300.32787,428.06557 c 0,0 2.09836,37.7705 7.34426,52.98361"
id="path86" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#494d55;stroke-width:5.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 313.18033,431.21312 c 0,0 7.60656,27.54098 10.22951,35.93442 2.62295,8.39344 -8.13115,15.73771 -8.13115,15.73771"
id="path87" /><path
style="opacity:1;fill:#bce4fd;fill-opacity:1;stroke:none;stroke-width:8.7;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 164.23888,424.64081 -31.07097,26.05282 5.00771,13.72483 20.95818,15.20859 17.08508,2.15431 -11.1287,-20.55238 -1.54637,-22.78395 z"
id="path74" /><path
id="path73"
style="opacity:1;fill:#ffffff;stroke-width:8.7;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 163.81755,451.10144 a 8.0341015,5.6995392 0 0 1 -8.0341,5.69954 8.0341015,5.6995392 0 0 1 -8.0341,-5.69954 8.0341015,5.6995392 0 0 1 8.0341,-5.69954 8.0341015,5.6995392 0 0 1 8.0341,5.69954 z" /><path
style="opacity:1;fill:#fff9f6;fill-opacity:1;stroke:none;stroke-width:8.7;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 338.36066,376.13115 c 0,0 1.83605,30.95081 -6.29509,51.40983 2.88525,1.04918 14.48107,0.26606 26.91267,-7.34238 12.4316,-7.60844 11.38242,-22.03467 11.38242,-22.03467 l 2.09836,28.85246 c 0,0 24.31867,-28.09873 24.2249,-52.60674 -0.0938,-24.50801 -1.66753,-26.08178 -1.66753,-26.08178 l -11.83407,-1.12685 z"
id="path72" /><path
style="opacity:1;fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:2.845;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 339.7822,389.85927 c 0,0 38.20695,-7.78977 56.38307,-25.96589 5.56412,8.53165 8.16071,32.64283 8.16071,32.64283 l 2.59659,12.98294 16.32141,-62.68907 -6.67694,-5.19318 -5.93506,-17.43424 c 0,0 -15.20859,15.2086 -27.44966,22.99836 -12.24106,7.78977 -34.12659,19.28895 -34.12659,19.28895 l -10.7573,3.70941 z"
id="path70" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#c3b4b0;stroke-width:2.845;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 347.01555,369.64297 c 0,0 2.22565,10.01541 -1.8547,19.84536 -4.08036,9.82994 -5.00771,9.459 -5.00771,9.459"
id="path69" /><path
style="opacity:1;fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:6.945;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 380.85246,480 c 0,0 44.59016,-17.31147 59.27869,-87.08197 6.81967,-2.62295 34.09836,-14.68852 39.34426,-25.70491 2.62295,-9.96722 -3.67213,-32 -3.67213,-32 l -24.65574,0.52459 -26.7541,4.72131 -4.72131,11.54098 -8.39344,52.45902 -13.11475,28.32787 -15.73771,36.19672 z"
id="path68" /><path
style="fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:8.74203;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 147.6556,277.03379 c 0,0 -11.12655,104.13607 127.58449,103.38689 138.71104,-0.74917 149.83759,-100.39017 149.83759,-100.39017"
id="path41"
inkscape:label="脸蛋" /><path
style="opacity:1;fill:#fff9f6;fill-opacity:1;stroke:none;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 123.27869,147.93443 304.78688,21.50819 -24.65573,-40.39344 c 0,0 44.06557,-58.754098 50.88524,-60.327868 6.81967,-1.573771 15.73771,-9.967214 15.73771,-9.967214 l -13.11476,-3.672131 -77.11475,22.032787 c 0,0 -122.7541,-33.57377 -168.39344,-6.295082 -45.63935,27.278689 -69.7705,46.163938 -69.7705,46.163938 z"
id="path33"
inkscape:label="头发底色2" /><path
style="fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 331.44501,66.651771 16.22882,30.84274 47.82991,31.367399 6.30629,1.07795 26.88325,-35.335399 -32.10312,-22.211018 -18.88524,5.245901 -30.42623,-11.540983 z"
id="path35"
inkscape:label="头发部件111" /><path
style="opacity:1;fill:#ace0fe;fill-opacity:1;stroke:none;stroke-width:14.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 431.03375,175.82616 17.06329,-17.0633 50.44802,71.96261 -5.93506,17.80518 -33.38472,18.54706 -12.612,-16.32142 17.80518,-11.12823 z"
id="path29"
inkscape:label="蓝色发卡上" /><path
style="opacity:1;fill:#ace0fe;fill-opacity:1;stroke:#4c4f59;stroke-width:6.945;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 465.90223,261.88453 c 0,0 35.61036,54.52837 2.96753,73.44637 -25.22401,4.08036 -48.22237,2.22565 -48.22237,2.22565 l 10.38636,-26.33683 21.51459,-41.91636 z"
id="path66"
inkscape:label="蓝色发卡下" /><path
style="opacity:1;fill:#febdc7;fill-opacity:1;stroke:none;stroke-width:4.6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 471.86885,57.704918 c 0,0 17.04918,68.983602 -11.01639,110.426232 -7.34426,0.26229 -9.18033,-10.49181 -9.18033,-10.49181 l 2.09836,-6.55737 -1.04918,-9.18033 2.36066,-10.7541 1.83606,-5.5082 -6.29508,-6.03278 -6.55738,-5.2459 -2.88524,-5.24591 2.88524,-5.2459 -2.62295,-5.245899 -4.19672,-2.885246 -3.14754,-1.57377 5.2459,-11.540984 11.80328,-7.344262 z"
id="path64" /><path
id="path57"
style="opacity:1;fill:#ff1c1c;fill-opacity:0.0509804;stroke-width:3.92397;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 244.26691,326.81357 a 35.587568,21.480417 0 0 1 -35.58757,21.48042 35.587568,21.480417 0 0 1 -35.58757,-21.48042 35.587568,21.480417 0 0 1 35.58757,-21.48042 35.587568,21.480417 0 0 1 35.58757,21.48042 z" /><path
id="path57-1"
style="fill:#ff1c1c;fill-opacity:0.05044398;stroke-width:3.65169;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 355.20429,336.75188 a 31.611719,20.942554 0 0 1 -31.61171,20.94255 31.611719,20.942554 0 0 1 -31.61172,-20.94255 31.611719,20.942554 0 0 1 31.61172,-20.94255 31.611719,20.942554 0 0 1 31.61171,20.94255 z" /><path
style="display:inline;opacity:1;fill:#fbf3ef;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 188.32787,343.60656 c 0,0 12.06557,-28.32787 15.7377,6.29508 5.24591,-8.91803 9.96722,-17.31148 17.31148,-8.39344 6.81967,2.09836 15.21311,7.34426 4.72131,22.03278 -10.4918,14.68853 16.33814,-18.37136 15.445,-1.63289 -0.72099,13.51206 -24.52214,46.81129 -24.52214,46.81129 0,0 -6.33782,64.18547 -33.41466,70.23144 -36.5485,8.16089 -12.06558,-103.86885 -12.06558,-103.86885 z"
id="path1"
sodipodi:nodetypes="cccsscscc"
inkscape:label="右手" /><path
id="path5"
style="fill:#fbe7e5;stroke-width:10.4;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke;fill-opacity:0.40581462"
inkscape:label="右手踝阴影"
d="m 193.63133,383.92419 a 12.612,12.241061 0 0 1 -12.612,12.24107 12.612,12.241061 0 0 1 -12.612,-12.24107 12.612,12.241061 0 0 1 12.612,-12.24106 12.612,12.241061 0 0 1 12.612,12.24106 z" /><path
style="fill:#fee4e0;fill-opacity:0.42411327;stroke:none;stroke-width:10.4;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 179.09741,356.52608 14.09576,-20.77271 7.04789,1.48377 0.74188,13.72482 11.49918,-11.49918 9.27353,4.08036 8.53165,5.93506 -5.56412,14.83765 13.72483,-4.82224 -3.33847,17.80518 -47.85143,-27.44965 z"
id="path9"
inkscape:label="右手手指阴影" /><path
style="display:inline;fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 188.32787,343.60656 c 0,0 12.06557,-28.32787 15.7377,6.29508 5.24591,-8.91803 9.96722,-17.31148 17.31148,-8.39344 6.81967,2.09836 15.21311,7.34426 4.72131,22.03278 -10.4918,14.68853 16.33814,-18.37136 15.445,-1.63289 -0.72099,13.51206 -24.52214,46.81129 -24.52214,46.81129 0,0 -6.33782,64.18547 -33.41466,70.23144 -36.5485,8.16089 -12.06558,-103.86885 -12.06558,-103.86885 z"
id="path1-6"
sodipodi:nodetypes="cccsscscc"
inkscape:label="右手遮挡" /><path
style="opacity:1;fill:#fff9f6;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 137.44262,123.2787 c 0,0 49.33852,-48.649769 86.97684,-58.734919 0.10513,0.76769 -120.16719,-122.15824 -86.97684,58.734919 z"
id="path3"
inkscape:label="头发部件19 左猫耳" /><path
style="fill:#fde9e7;fill-opacity:1;stroke-width:1.18016;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 198.85246,42 -63.6342,39.016573 3.84123,40.939237 L 184.82787,87 224,64.5 Z"
id="path58"
sodipodi:nodetypes="cccccc" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0.465732;stroke:#a18f90;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path4"
d="m 404.96447,131.7729 c 0.52512,-0.76931 1.0357,-1.54875 1.57536,-2.30793 2.82418,-3.97291 5.82035,-7.82036 8.67758,-11.76948 2.39309,-3.30762 3.93978,-5.54326 6.29133,-8.89998 5.32612,-7.58044 11.18023,-14.760796 17.20894,-21.78699 3.02173,-3.55064 6.06655,-7.098864 9.47662,-10.289082 1.96198,-1.835492 4.21906,-3.672787 6.27415,-5.392122 5.10823,-4.357455 10.66931,-8.109574 16.22169,-11.862072 0,0 -2.92504,-1.864176 -2.92504,-1.864176 v 0 c -5.41592,3.900149 -10.90348,7.705144 -15.99184,12.040062 -1.99887,1.645368 -4.44389,3.611151 -6.36286,5.369248 -3.45237,3.162941 -6.48944,6.731577 -9.48752,10.316639 -5.95526,7.087894 -11.63254,14.399231 -17.00034,21.944173 -5.47138,7.72885 -10.96322,15.45542 -17.11251,22.66867 z"
inkscape:label="头发部件18" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0.465732;stroke:#a18f90;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path6"
d="m 431.7055,96.885136 c 0.68345,-0.01683 1.36993,0.008 2.05351,0.03239 1.26616,0.04274 2.52519,0.175792 3.77564,0.374299 1.34943,0.219358 2.67703,0.547853 3.99756,0.89747 1.30448,0.342355 2.58658,0.760225 3.8587,1.206247 0.34787,0.132122 0.88919,0.332358 1.23164,0.483411 0.1893,0.0835 0.73774,0.373687 0.5597,0.268307 -4.92017,-2.912189 -2.83776,-1.86942 -2.01609,-0.911603 0.4665,0.942833 -0.25414,1.810973 -0.83258,2.515753 -1.05305,1.11546 -2.37988,1.92349 -3.65077,2.76486 -0.70455,0.52564 -1.84263,0.99551 -2.02707,1.9792 -0.13577,0.72412 0.14689,1.00706 0.45808,1.64499 0.25805,0.31484 0.49646,0.64686 0.77415,0.94453 0.63085,0.67625 1.54885,1.45348 2.25243,2.03623 1.28413,1.06359 2.61277,2.07518 3.92585,3.10243 2.22765,1.73231 4.46676,3.44711 6.4408,5.4696 1.24472,1.36548 2.33589,2.86124 3.10757,4.54226 0.57402,1.31239 0.61894,2.68201 0.46471,4.08008 -0.15236,1.542 -1.01177,2.74753 -1.96982,3.90485 -1.25092,1.39253 -2.70297,2.57966 -3.98322,3.94302 -0.61776,0.76458 -1.19371,1.60995 -1.3359,2.60746 -0.0756,0.53059 -0.0152,0.87319 0.031,1.40055 0.18192,1.34638 0.59785,2.64226 1.03422,3.92358 0.46172,1.36123 1.10075,2.65093 1.71056,3.94949 0.57934,1.12566 0.88081,2.32829 0.97901,3.58284 0.0285,1.01273 -0.14083,2.01608 -0.35002,3.00302 -0.18321,0.8594 -0.39147,1.62037 -0.92358,2.32955 -0.69384,0.72591 -1.52468,1.30006 -2.31082,1.91913 0,0 3.13155,1.96912 3.13155,1.96912 v 0 c 0.80747,-0.64335 1.66352,-1.23803 2.37418,-1.9921 0.58364,-0.77755 0.80933,-1.52536 1.00495,-2.4688 0.21825,-1.01967 0.38801,-2.05558 0.38421,-3.10149 -0.0761,-1.29512 -0.34601,-2.55043 -0.93895,-3.71574 -0.60728,-1.2882 -1.24849,-2.56502 -1.72185,-3.91075 -0.43768,-1.25837 -0.85635,-2.529 -1.07055,-3.84806 -0.053,-0.43231 -0.12968,-0.85315 -0.0855,-1.29165 0.0948,-0.94059 0.64999,-1.73394 1.21835,-2.45227 1.27656,-1.3752 2.72864,-2.57131 3.98645,-3.96542 1.00742,-1.20382 1.92485,-2.46496 2.104,-4.07351 0.17452,-1.45227 0.1673,-2.88462 -0.39573,-4.26425 -0.74413,-1.73945 -1.85028,-3.26977 -3.10544,-4.6809 -0.76822,-0.80351 -0.91233,-0.98548 -1.76144,-1.74089 -1.5106,-1.3439 -3.15419,-2.52947 -4.72414,-3.80078 -1.30934,-1.02359 -2.63319,-2.03185 -3.9193,-3.08473 -0.71006,-0.5813 -1.57278,-1.30278 -2.22387,-1.96185 -0.27049,-0.2738 -0.51217,-0.57463 -0.76826,-0.86194 -0.2502,-0.39692 -0.62512,-0.79772 -0.57512,-1.31981 0.0792,-0.82671 1.33713,-1.38331 1.899,-1.81756 1.29884,-0.86671 2.65474,-1.69887 3.73107,-2.84377 0.6873,-0.83746 1.4042,-1.79633 1.075,-2.93575 -0.0816,-0.13585 -0.14456,-0.28482 -0.24481,-0.40755 -0.1097,-0.13429 -0.23095,-0.26613 -0.3791,-0.356228 -1.82458,-1.109627 -3.48552,-2.166773 -5.4739,-2.822822 -1.27815,-0.438878 -2.56689,-0.847162 -3.87638,-1.183261 -1.32827,-0.341807 -2.66392,-0.6605 -4.021,-0.867076 -1.26646,-0.185139 -2.54065,-0.306124 -3.82011,-0.354118 -0.68835,-0.02484 -1.39159,-0.0088 -2.07079,-0.120664 z"
inkscape:label="头发部件17" /><path
style="display:inline;opacity:1;fill:#1a1a1a;fill-opacity:0.465732;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path7"
d="m 472.56515,132.89174 c 0.0148,0.77317 -0.10076,1.54619 -0.19578,2.31209 -0.22663,1.66469 -0.65036,3.29152 -1.09324,4.90909 -0.61155,2.16519 -1.31643,4.30298 -2.07388,6.4211 -0.85906,2.40245 -1.88628,4.73722 -3.04362,7.0095 -1.12519,2.18837 -2.40662,4.28829 -3.77255,6.3331 -1.20044,1.78353 -2.51232,3.48695 -3.85961,5.16088 -0.77567,0.94691 -1.56273,1.88443 -2.34905,2.82249 0,0 3.09439,1.85764 3.09439,1.85764 v 0 c 0.78058,-0.94434 1.56325,-1.88703 2.331,-2.84187 1.33972,-1.69155 2.6509,-3.40675 3.84535,-5.20534 1.36483,-2.06191 2.64248,-4.17929 3.77385,-6.37958 1.16439,-2.28454 2.19746,-4.6314 3.07763,-7.04092 0.77266,-2.11878 1.49327,-4.25705 2.12518,-6.4224 0.46749,-1.62041 0.91079,-3.25003 1.1854,-4.9163 0.11547,-0.76691 0.21504,-1.53597 0.32143,-2.30416 z"
inkscape:label="头发部件16" /><path
style="display:inline;opacity:1;fill:#fff9f6;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 322.62295,86.032787 c 0,0 75.43341,26.120553 110.16394,89.180323 33.44261,60.72132 33.04918,62.42623 33.04918,62.42623 0,0 0.52459,8.39345 -19.93443,11.54099 -2.62295,0 14.68852,30.95082 19.93443,37.2459 -14.68853,7.34426 -16.78689,8.91803 -16.78689,8.91803 0,0 6.29508,7.86885 4.72131,15.73771 -17.31147,-0.52459 -22.55738,-1.04918 -22.55738,-1.04918 0,0 -4.19672,17.31147 -15.7377,33.04918 C 410.22951,333.11475 410.22951,320 410.22951,320 c 0,0 -24.13115,36.72131 -72.39344,41.44262 -1.57377,-2.62295 12.59016,-14.16393 17.83606,-28.32787 -11.54098,1.57377 -14.68852,2.09836 -14.68852,2.09836 l 10.4918,-16.78688 c 0,0 11.01639,-24.13115 9.44262,-28.32787 -1.04918,-2.62295 -32,-57.70492 -32,-57.70492 0,0 -24.65573,33.04918 -43.54098,49.83607 -6.81967,-4.19672 -13.63934,-14.68853 -13.63934,-14.68853 l -12.59017,11.54099 c 0,0 -48.43778,-50.76436 -42.0945,-90.18318 -3.14754,12.06557 0.12729,56.60941 -5.6432,62.3799 -5.24591,-2.09836 -16.2623,-14.68853 -14.16394,-40.91803 -0.52459,-0.52459 -29.90164,41.44262 -29.90164,41.44262 0,0 -4.19672,48.78688 16.2623,73.44262 1.57377,2.62295 -1.57377,16.2623 -31.47541,-2.62295 1.04918,-1.57377 -1.04918,9.96721 -1.04918,9.96721 0,0 -46.68853,2.09836 -45.63935,-60.85245 -2.62295,-2.62296 -13.639341,34.09836 -13.639341,34.09836 0,0 -24.131151,-32 -0.52459,-92.85246 11.803281,-30.42623 23.344261,-52.85246 31.934421,-67.67213 8.59017,-14.81968 14.22951,-22.03279 14.22951,-22.03279"
id="path8"
sodipodi:nodetypes="csccccccccccccccccccccccccccssc"
inkscape:label="头发部件15 头发底色" /><path
id="path36"
style="fill:#fffdfc;stroke-width:7.4278;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
inkscape:label="头发打光"
d="m 355.67214,146.88524 a 91.803276,41.967213 0 0 1 -91.80327,41.96721 91.803276,41.967213 0 0 1 -91.80328,-41.96721 91.803276,41.967213 0 0 1 91.80328,-41.96721 91.803276,41.967213 0 0 1 91.80327,41.96721 z" /><path
style="fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 349.37705,329.44262 c 0,0 71.34426,-41.96721 78.68852,-91.27868 0,1.04918 26.22951,28.32786 26.22951,28.32786 l 11.54099,24.13115 -15.73771,7.34426 2.09836,13.63935 -22.03279,-1.04918 -12.59016,30.42623 -12.59016,-17.83607 -23.08197,26.22951 -45.11475,14.68852 z"
id="path37"
inkscape:label="头发阴影"
sodipodi:nodetypes="cccccccccccc" /><path
style="fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 325.2459,144.78689 c 0,0 10.49181,44.06557 2.09836,78.68852 0,10.4918 33.57377,60.85246 33.57377,60.85246 0,0 14.68853,-71.34426 -25.18032,-132.19672 -8.39345,-5.2459 -10.49181,-7.34426 -10.49181,-7.34426 z"
id="path38"
inkscape:label="头发阴影2" /><path
style="fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 186.7541,166.81967 23.08197,1.04918 c 0,0 -14.68853,26.22951 -13.63935,46.16394 -2.09836,-3.14754 -22.03279,31.47541 -22.03279,31.47541 0,0 -9.44262,-14.68853 -3.14754,-50.36066 9.44263,-16.78688 15.73771,-28.32787 15.73771,-28.32787 z"
id="path39"
inkscape:label="头发阴影" /><path
id="path36-5"
style="fill:#fffdfc;stroke-width:6.94619;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
inkscape:label="头发打光"
transform="matrix(0.99965843,-0.02613486,0,1,0,0)"
d="m 340.28017,112.23744 a 80.289719,41.967213 0 0 1 -80.28972,41.96721 80.289719,41.967213 0 0 1 -80.28972,-41.96721 80.289719,41.967213 0 0 1 80.28972,-41.967211 80.289719,41.967213 0 0 1 80.28972,41.967211 z" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#a18f90;stroke-width:7.7;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 138.62295,122.4918 c 0,0 53.63935,-52.983604 92.98361,-58.229505"
id="path65"
sodipodi:nodetypes="cc" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 436.45902,268.06557 c 0,0 3.67213,18.36066 -2.62295,42.49181"
id="path17"
inkscape:label="头发部件7" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 418.09836,305.83607 -8.91803,17.83606"
id="path16"
inkscape:label="头发部件8" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 377.70492,300.59016 c 0,0 2.62295,12.06558 -22.03279,32"
id="path15"
inkscape:label="头发部件9" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:4.2;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 284.32787,97.573771 c 0,0 12.06557,39.344259 -27.80328,119.081969 0.52459,0 53.5082,-38.81967 56.13115,-89.18033"
id="path10"
inkscape:label="头发部件14" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:5.1;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 272.78689,87.081967 c 0,0 13.63934,-8.393442 18.88524,-0.52459 17.17267,10.839383 13.03281,30.236103 24.19672,44.393443 1.79263,1.85342 7.1718,-0.78131 7.80328,1.77049 4.88126,19.72513 14.81582,50.80617 4.32401,100.11764"
id="path11"
sodipodi:nodetypes="csssc"
inkscape:label="头发部件13" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:4.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 171.00392,241.8537 c 0,0 -28.56248,-60.09248 92.36438,-147.634619 2.22564,0.741882 -59.35061,54.157419 -66.02755,111.282379"
id="path12"
inkscape:label="头发部件12" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#c3b4b0;stroke-width:3;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 327.34426,143.7377 c 0,0 25.18033,20.45902 32,65.57378"
id="path13"
inkscape:label="头发部件11" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 362.4918,268.59016 -3.14754,19.93443"
id="path14"
inkscape:label="头发部件10" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 421.77049,344.13115 c 0,0 -2.62295,58.22951 -33.57377,111.7377 -30.95082,53.5082 38.29508,15.73771 38.29508,15.73771"
id="path18"
inkscape:label="头发部件6" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 395.01639,348.32787 12.06558,60.32787"
id="path19"
inkscape:label="头发部件5" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 371.93443,423.86885 c 0,0 30.95082,-25.70492 24.65573,-73.96721"
id="path20"
inkscape:label="头发部件4" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 332.06557,427.54098 c 0,0 36.72132,1.57377 38.81968,-29.37705"
id="path21"
inkscape:label="头发部件3" /><path
style="opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 372.45902,427.01639 -2.09836,-28.85246"
id="path22"
inkscape:label="头发部件2" /><path
style="fill:#93cefc;fill-opacity:1;stroke:#4d4e59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 377.50929,228.61046 c 0,0 24.13115,1.57377 24.13115,10.49181 -0.52459,3.67213 -11.54099,17.83606 -23.60656,18.88524 -2.09836,-1.57377 -0.52459,-29.37705 -0.52459,-29.37705 z"
id="path34"
sodipodi:nodetypes="cccc"
inkscape:label="兔子发卡后" /><path
style="opacity:1;fill:#fffdfe;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 350.95082,235.54098 c 0,0 -6.55738,-22.03278 1.04918,-22.03278 7.60656,0 13.37705,13.90164 13.37705,13.90164 0,0 5.05941,-17.72738 9.96722,-15.21311 11.79758,6.04389 3.40983,21.77048 3.40983,21.77048 0,0 18.62295,25.96722 -12.06558,27.27869 -30.16717,1.28919 -15.7377,-25.70492 -15.7377,-25.70492 z"
id="path24"
sodipodi:nodetypes="cscscsc"
inkscape:label="兔子发卡" /><path
style="display:inline;opacity:1;fill:#1a1a1a;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 332.06557,425.96721 c 0,0 10.49181,-25.18032 6.29509,-49.83606"
id="path23"
inkscape:label="头发部件" /><path
style="display:inline;opacity:1;fill:#e85240;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 192.2623,268.85246 c 0,0 -15.47541,22.03279 -2.62296,35.40984 42.7541,0.26229 43.27869,0.52459 43.27869,0.52459 0,0 11.27869,-8.39345 5.5082,-32 -25.44262,-9.96722 -46.16393,-3.93443 -46.16393,-3.93443 z"
id="path25"
inkscape:label="左眼白" /><path
style="opacity:1;fill:#fbb579;fill-opacity:1;stroke:none;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 188.06557,301.11475 c -0.44151,-8.78192 13.4528,-14.01636 22.29509,-14.42623 8.67244,-0.402 23.2398,3.38526 23.08196,12.06558 -0.0775,4.26198 -11.54098,5.5082 -11.54098,5.5082 0,0 -33.2673,8.16555 -33.83607,-3.14755 z"
id="path27"
sodipodi:nodetypes="saacs"
inkscape:label="左眼瞳" /><path
id="path26"
style="display:inline;opacity:1;fill:#ffffff;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
inkscape:label="眼光"
d="m 217.96721,273.04919 a 7.8688526,7.0819674 0 0 1 -7.86885,7.08197 7.8688526,7.0819674 0 0 1 -7.86885,-7.08197 7.8688526,7.0819674 0 0 1 7.86885,-7.08196 7.8688526,7.0819674 0 0 1 7.86885,7.08196 z" /><path
style="fill:none;fill-opacity:1;stroke:#ebc2bf;stroke-width:2.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 174.16393,245.5082 c 15.08644,-4.76649 31.53934,-7.45293 47.09358,-3.51527 3.29779,0.83486 6.51821,1.99257 9.56216,3.51527"
id="path42"
inkscape:path-effect="#path-effect42"
inkscape:original-d="m 174.16393,245.5082 c 11.60252,-3.79212 36.99244,-9.83166 56.65574,0"
transform="translate(0,4)" /><path
style="opacity:1;fill:#fde9e7;fill-opacity:1;stroke:none;stroke-width:6.945;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 477.77235,132.79697 c 0,0 13.35388,10.01542 14.83765,17.43424 1.48376,7.41883 1.48376,57.4959 1.48376,57.4959 l -4.45129,1.11282 -30.78813,-37.46507 c 0,0 8.90259,-14.46671 11.12824,-22.62741 2.22565,-8.16071 7.78977,-15.95048 7.78977,-15.95048 z"
id="path67" /><path
style="fill:#e85240;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 192.2623,268.85246 c 0,0 -15.47541,22.03279 -2.62296,35.40984 42.7541,0.26229 43.27869,0.52459 43.27869,0.52459 0,0 11.27869,-8.39345 5.5082,-32 -25.44262,-9.96722 -46.16393,-3.93443 -46.16393,-3.93443 z"
id="path25-9"
inkscape:label="左眼遮挡上" /><path
style="display:inline;fill:#e85240;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 325.52138,272.81871 c 17.02505,1.06627 38.81967,23.08196 17.83607,48.26229 -1.57377,0.52459 -48.98481,-5.30599 -49.57378,-9.18033 -0.80561,-5.29953 -7.95666,-41.56799 31.73771,-39.08196 z"
id="path40"
sodipodi:nodetypes="scss"
inkscape:label="右眼白" /><path
style="fill:#fbb579;fill-opacity:1;stroke:none;stroke-width:7.14054;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 293.04592,306.32136 c 2.55323,-8.53469 20.43105,-9.52962 30.78942,-7.36618 10.1594,2.12188 25.66784,9.9581 22.45763,18.22228 -1.5762,4.05766 -15.25453,1.93723 -15.25453,1.93723 0,0 -41.28165,-1.79873 -37.99252,-12.79333 z"
id="path27-0"
sodipodi:nodetypes="saacs"
inkscape:label="左眼瞳" /><path
style="display:inline;fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 325.52138,272.81871 c 17.02505,1.06627 38.81967,23.08196 17.83607,48.26229 -1.57377,0.52459 -48.98481,-5.30599 -49.57378,-9.18033 -0.80561,-5.29953 -7.95666,-41.56799 31.73771,-39.08196 z"
id="path40-2"
sodipodi:nodetypes="scss"
inkscape:label="右眼遮挡上" /><path
style="fill:none;fill-opacity:1;stroke:#ebc2bf;stroke-width:2.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 309.32819,258.43459 c 0,0 26.2295,-5.2459 36.72131,4.19672"
id="path43" /><path
id="path26-9"
style="display:inline;fill:#ffffff;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
inkscape:label="眼光"
d="m 329.6342,284.99301 a 7.8688526,7.0819674 0 0 1 -7.86885,7.08197 7.8688526,7.0819674 0 0 1 -7.86885,-7.08197 7.8688526,7.0819674 0 0 1 7.86885,-7.08197 7.8688526,7.0819674 0 0 1 7.86885,7.08197 z" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:14.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 170.4918,266.4918 c 0,0 32,-19.93442 70.29509,-2.09836"
id="path28"
inkscape:label="眉毛" /><path
style="fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:14.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 292.9971,274.17683 c 0,0 35.55098,-12.55026 69.08832,13.13797"
id="path28-2"
inkscape:label="眉毛" /><path
style="display:inline;opacity:1;fill:none;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 431.03375,176.1971 18.17612,-17.43424 41.54542,54.15742"
id="path30"
inkscape:label="蓝色发卡遮挡上" /><path
style="opacity:1;fill:none;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 454.0321,267.44865 43.21466,-23.92571"
id="path31"
sodipodi:nodetypes="cc"
inkscape:label="蓝色发卡遮挡下" /><path
style="display:inline;fill:#fff9f6;fill-opacity:0;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 164.23888,424.64081 -31.07097,26.05282 c 0,0 -5.19317,18.17613 25.96589,28.93342 31.15907,10.7573 213.29123,1.48377 213.29123,1.48377 0,0 52.30272,11.87012 80.86519,-37.09413 -0.37094,0.74188 -8.90259,19.28895 -8.90259,19.28895 l 1.48377,19.28894 c 0,0 57.73516,-9.41425 30.45647,-148.95524 4.19672,-9.44262 8.39344,-15.21311 8.39344,-15.21311 l -3.14754,-21.77049 c 0,0 5.65758,-40.33533 7.88323,-45.52851 2.22564,-5.19317 8.51558,-6.35116 9.64447,-11.12823 2.06907,-8.75561 -2.78206,-20.40177 -6.67694,-26.15136 -0.74189,-3.33847 6.86241,-35.05395 2.04017,-58.05231 -7.04788,-11.87012 -4.82223,-11.87012 -18.918,-25.59495 0,0.37094 8.90259,-44.88389 -0.74188,-73.446367 -2.96753,0 -32.27189,-10.757296 -96.81567,23.740241 -0.37094,1.112824 -26.33683,-30.046242 -153.56969,-15.950474 -0.74188,0 -43.40012,-37.836009 -66.76942,-40.432598 -1.11283,-0.370941 -22.62742,-4.080354 -25.22401,48.964247 0,1.112824 -44.14201,15.950474 -56.01213,64.914721 -11.87012,48.96425 -11.128238,80.86519 -11.128238,80.86519 0,0 -18.904912,27.6632 -9.798121,25.03308 5.346826,-1.54421 4.975885,23.56023 4.975885,23.56023 l -2.225648,39.31977 c 0,0 -14.466709,35.23942 -14.83765,59.72155 -0.370942,24.48212 -0.741883,34.12659 4.822236,48.5933 5.564119,14.46671 20.772711,46.7386 42.658245,63.06002 8.902591,0.37094 18.918001,1.8547 18.918001,1.8547 l 3.70942,-20.77271 c 0,0 18.918,15.95048 32.27189,14.83765 13.35388,-1.11282 -0.74189,-0.74188 -0.74189,-0.74188 l -13.72482,-17.80518 z"
id="path2-4"
sodipodi:nodetypes="ccscccccccsaccccccccscsccsscccsccc"
inkscape:label="上发层" /><path
style="fill:none;fill-opacity:1;stroke:#c3b4b0;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 197.5082,220.06557 18.36065,-12.32786"
id="path46" /><path
style="fill:none;fill-opacity:1;stroke:#c3b4b0;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 327.54114,234.24941 c 0,0 -6.27192,4.90452 -15.85821,-0.991"
id="path47"
sodipodi:nodetypes="cc" /><path
style="display:inline;fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 322.62295,86.03279 c 0,0 75.43341,26.12055 110.16394,89.18032 33.44261,60.72132 33.04918,62.42623 33.04918,62.42623 0,0 0.52459,8.39345 -19.93443,11.54099 -2.62295,0 14.68852,30.95082 19.93443,37.2459 -14.68853,7.34426 -16.78689,8.91803 -16.78689,8.91803 0,0 6.29508,7.86885 4.72131,15.73771 -17.31147,-0.52459 -22.55738,-1.04918 -22.55738,-1.04918 0,0 -4.19672,17.31147 -15.7377,33.04918 C 410.22951,333.11475 410.22951,320 410.22951,320 c 0,0 -24.13115,36.72131 -72.39344,41.44262 -1.57377,-2.62295 12.59016,-14.16393 17.83606,-28.32787 -11.54098,1.57377 -14.68852,2.09836 -14.68852,2.09836 l 10.4918,-16.78688 c 0,0 11.01639,-24.13115 9.44262,-28.32787 -1.04918,-2.62295 -32,-57.70492 -32,-57.70492 0,0 -24.65573,33.04918 -43.54098,49.83607 -6.81967,-4.19672 -13.63934,-14.68853 -13.63934,-14.68853 l -12.59017,11.54099 c 0,0 -48.43778,-50.76436 -42.0945,-90.18318 -3.14754,12.06557 0.12729,56.60941 -5.6432,62.3799 -5.24591,-2.09836 -16.2623,-14.68853 -14.16394,-40.91803 -0.52459,-0.52459 -29.90164,41.44262 -29.90164,41.44262 0,0 -4.19672,48.78688 16.2623,73.44262 1.57377,2.62295 -1.57377,16.2623 -31.47541,-2.62295 1.04918,-1.57377 -1.04918,9.96721 -1.04918,9.96721 0,0 -46.68853,2.09836 -45.63935,-60.85245 -2.62295,-2.62296 -13.63934,34.09836 -13.63934,34.09836 0,0 -24.13115,-32 -0.52459,-92.85246 11.80328,-30.42623 23.34426,-52.85246 31.93442,-67.67213 8.59017,-14.81968 14.22951,-22.03279 14.22951,-22.03279"
id="path8-0"
sodipodi:nodetypes="csccccccccccccccccccccccccccssc"
inkscape:label="头发部件15 头发底色" /><path
id="path44-3"
style="fill:#a88a8f;stroke:#4c4f59;stroke-width:2.8623;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 216.29183,255.53888 a 8.8904896,7.4928694 0 0 1 -8.89049,7.49287 8.8904896,7.4928694 0 0 1 -8.89049,-7.49287 8.8904896,7.4928694 0 0 1 8.89049,-7.49287 8.8904896,7.4928694 0 0 1 8.89049,7.49287 z" /><path
id="path44"
style="fill:#a88a8f;stroke:#4c4f59;stroke-width:2.8623;stroke-linecap:round;stroke-miterlimit:1.3;paint-order:fill markers stroke"
d="m 336.16933,270.5473 a 8.8904896,7.4928694 0 0 1 -8.89049,7.49287 8.8904896,7.4928694 0 0 1 -8.89049,-7.49287 8.8904896,7.4928694 0 0 1 8.89049,-7.49287 8.8904896,7.4928694 0 0 1 8.89049,7.49287 z" /><path
style="opacity:1;fill:none;fill-opacity:0;stroke:#a18f90;stroke-width:10.4;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 318.7189,85.461784 c 0,0 50.44801,17.063296 76.78484,43.400126 26.33683,26.33683 32.64283,39.31978 32.64283,39.31978"
id="path32"
inkscape:label="上方头发边缘加厚" /><path
style="fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:6.5;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 186.7541,224.52459 10.4918,1.04918"
id="path45" /><path
style="opacity:1;fill:#fcbeb5;fill-opacity:1;stroke:#e99c9b;stroke-width:3.4;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 250.94176,349.98308 c 0,0 -13.91029,-8.90259 -10.0154,-16.69235 3.89488,-7.78977 17.80517,-4.4513 17.80517,-4.4513 0,0 12.98295,-1.29829 20.03083,-3.89488 7.04788,-2.59659 9.64447,5.0077 9.64447,5.0077 0,0 4.76461,6.06544 -4.26583,16.50689 -5.93505,6.86241 -21.14364,7.04788 -21.14364,7.04788"
id="path48"
sodipodi:nodetypes="cscscsc" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e99c9b;stroke-width:1.8;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 276.20884,325.76493 c 0,0 4.35031,3.01904 5.37456,7.95235 0.57119,0.10629 3.33355,-3.08729 2.97647,-6.87263 -0.67968,-1.48531 -8.35103,-1.07972 -8.35103,-1.07972 z"
id="path49" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e99c9b;stroke-width:1.8;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 245.0067,329.39584 -4.17308,2.78206 -0.0927,6.0278 -0.0956,-0.0355 7.07328,-8.8174 z"
id="path50"
sodipodi:nodetypes="cccccc" /><path
style="fill:none;fill-opacity:1;stroke:#e99c9b;stroke-width:3.4;stroke-linecap:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 250.94176,349.98308 c 0,0 -13.91029,-8.90259 -10.0154,-16.69235 3.89488,-7.78977 17.80517,-4.4513 17.80517,-4.4513 0,0 12.98295,-1.29829 20.03083,-3.89488 7.04788,-2.59659 9.64447,5.0077 9.64447,5.0077 0,0 4.76461,6.06544 -4.26583,16.50689 -5.93505,6.86241 -21.14364,7.04788 -21.14364,7.04788"
id="path48-2"
sodipodi:nodetypes="cscscsc" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e89493;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 190.84928,314.92913 6.12053,15.02312"
id="path51" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e89493;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 204.94505,316.96931 5.56412,14.28124"
id="path52" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e89493;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 217.92799,317.34025 7.41883,16.50689"
id="path53" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e89493;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 300.64789,328.46849 6.86242,18.17612"
id="path54" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e89493;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 312.70348,329.21037 6.67695,17.0633"
id="path55" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e89493;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 326.24284,328.65396 7.04788,17.99065"
id="path56" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#e49589;stroke-width:4.6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 218.4918,348.98361 c -1.87307,1.30472 -3.33608,3.11401 -4.70333,4.91603 -1.02497,1.35089 -2.00187,2.75003 -2.77208,4.2643"
id="path61"
inkscape:path-effect="#path-effect61"
inkscape:original-d="m 218.4918,348.98361 c -1.70592,0.99645 -5.82749,5.88449 -7.47541,9.18033"
transform="rotate(-3.3120949,219.55256,344.63259)" /><path
style="opacity:1;fill:none;fill-opacity:1;stroke:#4c4f59;stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 127.47541,375.08197 c 0,0 -14.42623,-19.14754 -12.06557,-59.54099"
id="path92" /><path
style="opacity:1;fill:#ffffff;fill-opacity:0.734285;stroke:#c1545a;stroke-width:7.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 136.39344,322.09836 c 0,0 9.44263,-18.88525 -4.19672,-39.86885 -3.14754,-0.52459 27.80328,-27.80328 5.2459,-77.11476 -1.57377,0.52459 23.60656,-55.60655 -24.13115,-82.88524 -4.19672,-8.39344 -45.639336,-69.245904 -89.180316,13.11475 0,11.54099 -1.04918,36.19672 -1.04918,36.19672 0,0 -14.6885299,38.81968 -6.29509,71.86886 2.09837,3.14754 -20.9835999,49.83606 11.0164,106.4918 0.52459,0.52459 -16.78689,57.70492 12.59016,82.88525 1.04918,4.72131 13.63935,33.57377 42.49181,39.34426 12.59016,0.52459 19.409826,-0.52459 19.409826,-0.52459 0,0 31.47541,-4.72131 47.73771,-67.14754 -2.09836,-27.80328 -4.19672,-50.36066 -11.0164,-70.81968"
id="path93" /><path
id="path101"
style="opacity:1;fill:#ffffff;fill-opacity:0.734285;stroke:#000000;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 109.69769,219.48859 c 0,0 -15.208592,-11.87012 -21.143652,-19.65989 m -37.09413,20.03083 22.25648,-21.88553 m 0.37094,-14.09577 5.93506,41.91636 m -35.23942,-24.11118 56.012132,-4.82224 m 11.12824,-17.43424 -19.288952,0.37094 m -0.37094,-0.74188 -1.48376,-29.6753 m -38.94883,3.33847 37.836,-2.96753 m -24.85306,-11.49918 0.74188,39.69072"
inkscape:label="杂" /><path
id="path111"
style="opacity:1;fill:#ffffff;fill-opacity:0.734285;stroke:#000000;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 58.507798,352.28556 54.157422,-3.33847 m -46.367662,-13.72483 35.610372,-2.96753 m -21.514602,-32.27189 2.59659,33.38472 m -18.918,-16.32142 37.094122,-3.33847 m 1.48377,18.54706 0.74188,-33.75565 m -0.37094,0.37094 -40.803542,2.22565 m 0,-0.37094 4.4513,33.38471 m 27.44965,-48.22237 3.33847,-14.4667 m 0,-1.48377 -27.44965,1.48377 m -1.48377,14.83765 0.74188,-20.03083"
inkscape:label="鱼" /><path
d="m 69.453989,376.46984 c -4.220665,0.22086 -8.079406,1.8518 -10.783191,4.54882 -2.980547,2.98155 -4.241957,7.10139 -3.534076,11.54824 0.904812,5.67433 4.763552,11.7394 11.384623,17.90216 1.405115,1.30393 2.39508,2.14912 4.390984,3.74184 3.507462,2.79468 6.679618,5.01174 11.04931,7.70876 1.559468,0.96838 4.635815,2.76496 5.796096,3.38931 l 0.335314,0.18263 0.48966,-0.26758 c 1.783005,-0.98111 4.960482,-2.86264 6.844609,-4.05189 7.126702,-4.49782 12.832312,-9.01266 17.063632,-13.50625 6.86057,-7.28827 9.77725,-14.38543 8.43068,-20.49298 -0.93142,-4.20475 -4.04502,-7.68327 -8.46261,-9.45012 -1.90011,-0.76026 -3.74699,-1.15525 -5.83869,-1.24869 -2.7091,-0.12316 -5.37562,0.33977 -7.91973,1.37185 -4.332435,1.75413 -7.951675,5.17315 -10.229661,9.66674 -0.159681,0.3143 -0.308701,0.59038 -0.329985,0.60737 -0.0692,0.0553 -0.143707,-0.051 -0.431122,-0.62859 -0.681263,-1.35913 -2.01719,-3.3341 -3.065699,-4.52331 -1.07513,-1.22747 -2.804909,-2.72251 -4.092931,-3.54224 -3.326503,-2.11937 -7.222503,-3.15569 -11.097213,-2.95607 z"
id="path1-4"
style="fill:#d96477;fill-opacity:1;stroke:none;stroke-width:0.00475452" /></g></svg>

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -1,101 +0,0 @@
import { defineConfig, type DefaultTheme } from 'vitepress'
export default defineConfig({
lang: 'zh-Hans',
description: '下一代 Android Root 解决方案 - Android 上的内核级的高级 root 方案',
themeConfig: {
nav: nav(),
sidebar: {
'/zh/': { base: '/zh/', items: sidebar() },
},
search: { options: searchOptions() },
editLink: {
pattern: 'https://github.com/sukisu-ultra/sukisu-ultra/edit/main/docs/:path',
text: '在 GitHub 上编辑此页面',
},
docFooter: {
prev: '上一页',
next: '下一页',
},
outline: {
label: '页面导航',
},
lastUpdated: {
text: '最后更新于',
},
notFound: {
title: '页面未找到',
quote: '抱歉,我们无法找到您要查找的页面。',
linkLabel: '前往首页',
linkText: '带我回首页',
},
langMenuLabel: '多语言',
returnToTopLabel: '回到顶部',
sidebarMenuLabel: '菜单',
darkModeSwitchLabel: '主题',
lightModeSwitchTitle: '切换到浅色模式',
darkModeSwitchTitle: '切换到深色模式',
skipToContentLabel: '跳转到内容',
},
})
function nav(): DefaultTheme.NavItem[] {
return [
{ text: '首页', link: '/zh/' },
{
text: '开始使用',
items: [
{ text: '介绍', link: '/zh/guide/' },
{ text: '安装', link: '/zh/guide/installation' },
{ text: '集成', link: '/zh/guide/how-to-integrate' },
{ text: '兼容性', link: '/zh/guide/compatibility' },
{ text: '链接', link: '/zh/guide/links' },
{ text: '许可', link: '/zh/guide/license' },
],
},
]
}
function sidebar(): DefaultTheme.SidebarItem[] {
return [
{
text: '开始使用',
items: [
{ text: '介绍', link: '/guide/' },
{ text: '安装', link: '/guide/installation' },
{ text: '集成', link: '/guide/how-to-integrate' },
{ text: '兼容性', link: '/guide/compatibility' },
{ text: '链接', link: '/guide/links' },
{ text: '许可', link: '/guide/license' },
],
},
]
}
function searchOptions(): Partial<DefaultTheme.LocalSearchOptions> {
return {
translations: {
button: {
buttonText: '搜索文档',
buttonAriaLabel: '搜索文档',
},
modal: {
noResultsText: '无法找到相关结果',
resetButtonTitle: '清除查询条件',
footer: {
selectText: '选择',
navigateText: '切换',
closeText: '关闭',
},
},
},
}
}

View File

@@ -1,23 +0,0 @@
# 兼容性状态
::: info KernelSU
KernelSUv0.9.5 之前的版本)官方支持 Android GKI 2.0 设备(内核 5.10+
:::
::: warning 传统内核支持
较旧的内核4.4+)也兼容,但内核必须手动构建
:::
::: tip 扩展兼容性
SukiSU-Ultra 可以通过额外的反向移植支持 3.x 内核3.4-3.18
:::
## 架构支持
目前支持以下处理器架构:
| 架构 | 支持级别 | 备注 |
| --------------- | :---------: | -----------: |
| **arm64-v8a** | ✅ 完全支持 | 主要目标架构 |
| **armeabi-v7a** | ✅ 基础支持 | 最低功能要求 |
| **X86_64** | 🟡 部分支持 | 支持部分设备 |

View File

@@ -1,94 +0,0 @@
# 集成指导
SukiSU 可以集成到 GKI 和 non-GKI 内核中,并且已反向移植到 4.14 版本。
<!-- 应该是 3.4 版本,但 backslashxx 的 syscall manual hook 无法在 SukiSU 中使用-->
有些 OEM 定制可能导致多达 50% 的内核代码超出内核树代码,而非来自上游 Linux 内核或 ACK。因此non-GKI 内核的定制特性导致了严重的内核碎片化,而且我们缺乏构建它们的通用方法。因此,我们无法提供 non-GKI 内核的启动映像。
前提条件:开源的、可启动的内核。
## Hook 方法
1. **KPROBES hook:**
- GKI kernels 的默认 hook 方法。
- 需要 `# CONFIG_KSU_MANUAL_HOOK is not set`(未设定) & `CONFIG_KPROBES=y`
- 用作可加载的内核模块 (LKM).
2. **Manual hook:**
<!-- - backslashxx's syscall manual hook: https://github.com/backslashxx/KernelSU/issues/5 (v1.5 version is not available at the moment, if you want to use it, please use v1.4 version, or standard KernelSU hooks)-->
- 需要 `CONFIG_KSU_MANUAL_HOOK=y`
- 需要 [`guide/how-to-integrate.md`](how-to-integrate.md)
- 需要 [https://github.com/~](https://github.com/tiann/KernelSU/blob/main/website/docs/guide/how-to-integrate-for-non-gki.md#manually-modify-the-kernel-source)
3. **Tracepoint Hook:**
- 自 SukiSU commit [49b01aad](https://github.com/SukiSU-Ultra/SukiSU-Ultra/commit/49b01aad74bcca6dba5a8a2e053bb54b648eb124) 引入的 hook 方法
- 需要 `CONFIG_KSU_TRACEPOINT_HOOK=y`
- 需要 [`guide/tracepoint-hook.md`](tracepoint-hook.md)
<!-- This part refer to [rsuntk/KernelSU](https://github.com/rsuntk/KernelSU). -->
如果您能够构建可启动内核,有两种方法可以将 KernelSU 集成到内核源代码中:
1. 使用 `kprobe` 自动集成
2. 手动集成
## 与 kprobe 集成
适用:
- GKI 内核
不适用:
- non-GKI 内核
KernelSU 使用 kprobe 机制来做内核的相关 hook如果 _kprobe_ 可以在你编译的内核中正常运行,那么推荐用这个方法来集成。
请参阅此文档 [https://github.com/~](https://github.com/tiann/KernelSU/blob/main/website/docs/guide/how-to-integrate-for-non-gki.md#integrate-with-kprobe)。虽然标题为“适用于 non-GKI”但仅适用于 GKI。
替换 KernelSU 添加到内核源代码树的步骤的执行命令为:
```sh [bash]
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
## 手动修改内核源代码
适用:
- GKI 内核
- non-GKI 内核
请参考此文档 [https://github.com/~ (non-GKI 内核集成)](https://github.com/tiann/KernelSU/blob/main/website/docs/guide/how-to-integrate-for-non-gki.md#manually-modify-the-kernel-source) 和 [https://github.com/~ (GKI 内核构建)](https://kernelsu.org/zh_CN/guide/how-to-build.html) 进行手动集成。虽然第一个链接的标题是“适用于 non-GKI”但它也适用于 GKI。两者都可以正常工作。
还有另一种集成方法,但是仍在开发中。
<!-- 这是 backslashxx 的syscall manual hook但目前无法使用。 -->
将 KernelSUSukiSU添加到内核源代码树的步骤的运行命令将被替换为
### GKI 内核
```sh [bash]
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
### non-GKI 内核
```sh [bash]
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s nongki
```
### 带有 susfs 的 GKI / non-GKI 内核(实验)
```sh [bash]
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s susfs-{{branch}}
```
分支:
- `main` (susfs-main)
- `test` (susfs-test)
- 版本号 (例如: susfs-1.5.7, 你需要在 [分支](https://github.com/SukiSU-Ultra/SukiSU-Ultra/branches) 里找到它)

View File

@@ -1,35 +0,0 @@
# 什么是 SukiSU-Ultra
一个 Android 上基于内核的 root 方案,由 [`tiann/KernelSU`](https://github.com/tiann/KernelSU) 分叉而来,添加了一些有趣的变更。
## 特性
1. 基于内核的 su 和权限管理。
2. 基于 Magic Mount 的模块系统。
3. App Profile: 把 Root 权限关进笼子里。
4. 支持 non-GKI 与 GKI 1.0。
5. KPM 支持
6. 可调整管理器外观,可自定义 susfs 配置。
## 如何安装
了解如何在您的设备上 **[安装](./installation)** SukiSU-Ultra
## 如何集成
阅读 **[集成](./how-to-integrate.md)** 将 SukiSU 集成到你的内核中
## 了解兼容性
检查设备 **[兼容性](./compatibility)** 要求
## 资源获取
查找其他资源和 **[下载](./links)**
## 获取支持
需要帮助?我们在这里为您提供帮助:
- **错误报告**: [GitHub Issues](https://github.com/SukiSU-Ultra/SukiSU-Ultra/issues)
- **直接支持**: 联系开发者处理关键问题

View File

@@ -1,149 +0,0 @@
# 安装参考
::: details 将会了解 SukiSU-Ultra 安装过程
[[toc]]
:::
::: danger 警告
**Root 您的设备可能会使保修失效,如果操作不当可能会造成永久性损坏。**
请务必在继续之前创建完整备份,阅读文档确保与您的设备兼容,遵循文档参考,准备好恢复计划
:::
## 通用 GKI
请**全部**参考 [KernelSU 安装指南](https://kernelsu.org/zh_CN/guide/installation.html)
1. 适用于 GKI 2.0 设备,如小米、红米、三星等(不包括内核修改的制造商,如魅族、一加、真我和 OPPO
2. 在[更多链接](./links)中查找 GKI 构建。找到设备内核版本,然后下载并使用 TWRP 或内核刷写工具刷入带有 `AnyKernel3` 后缀的
zip 文件。
3. 无后缀的 `.zip` 档案是未压缩的,`gz` 后缀是特定型号使用的压缩格式。
## 一加设备
使用[更多链接](./links)部分提到的链接,用您的设备信息创建自定义构建,然后刷入带有 AnyKernel3 后缀的 zip 文件。
::: details 展开
- 只需要填写内核版本的前两部分,如 `5.10``5.15``6.1``6.6`
- 请自行搜索处理器代号,通常是不含数字的英文字母。
- 可以从一加开源内核仓库中找到分支和配置文件。
- 第三方 Recovery推荐 TWRP
:::
## 开始安装
### 通用 GKI 安装
::: tip
适用于 GKI 2.0 设备,如小米、红米、三星等(不包括内核修改的制造商,如魅族、一加、真我和 OPPO
:::
#### 步骤:
1. 下载 GKI 构建文件
从我们的[资源部分](./links)查找 GKI 构建。查找您设备的内核版本并下载带有 `AnyKernel3` 后缀的 `zip` 文件。
2. 通过 Recovery 刷入
启动到 `TWRP recovery`,选择 **Install**,导航到下载的 `AnyKernel3 zip` 文件,滑动刷入后重启系统
3. [验证安装](#验证)
::: details 文件格式说明
无后缀的 `.zip` 档案是未压缩的,`gz` 后缀是特定型号使用的压缩格式。
:::
### 一加设备安装
1. 获取设备信息
- 内核版本(前两部分,例如 `5.10``5.15``6.1``6.6`
- 处理器代号(通常是不含数字的英文)
- 来自一加开源内核仓库的分支和配置文件
2. 创建自定义构建
使用我们[资源部分](./links)中提到的链接,用您的设备信息创建自定义构建。
3. 刷入构建
下载生成的带有 AnyKernel3 后缀的 zip 文件,启动到 `TWRP recovery`,选择 **Install**,导航到下载的 `AnyKernel3 zip` 文件,滑动刷入后重启系统
::: tip
您只需要填写内核版本的前两部分。自行搜索处理器代号
:::
### 手动内核集成
面向希望将 SukiSU Ultra 集成到自己内核构建中的高级用户
#### 主分支GKI
```sh [bash]
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
#### 非 GKI 分支
```sh [bash]
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s nongki
```
#### SUSFS-Dev 分支(推荐)
```sh [bash]
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s susfs-dev
```
```bash
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s susfs-main
```
::: warning 必需的内核配置
为了支持 KPM添加 `CONFIG_KPM=y`
对于非 GKI 设备,还要添加 `CONFIG_KALLSYMS=y` 和 `CONFIG_KALLSYMS_ALL=y`
:::
## 安装后设置
### 系统更新时保持 Root
> [!IMPORTANT]
> 如何在 OTA 更新后保持 root 访问权限:
#### 步骤:
1. 系统更新后重启前
- OTA 安装后不要立即重启,将 SukiSU Ultra 安装到第二插槽
- 打开 SukiSU Ultra 管理器,在**刷入/修补内核**界面选择 **GKI/non_GKI install**,选择您的 `AnyKernel3` 内核 `zip` 文件,选择与当前运行插槽相对的插槽然后刷入重启。
2. 替代方案LKM 模式
使用 [LKM 模式](#通用-gki) 在 OTA 后安装到未使用的插槽。
::: warning 警告
**非 GKI 设备注意事项:** 此方法不支持所有非 GKI 设备。对于非 GKI 设备,使用 TWRP 是最安全的方法。
:::
## 验证
安装后,验证一切是否正常工作,
- 打开 SukiSU Ultra 管理器检查 root 工作状态
- 使用 root 权限的应用程序来验证 root 访问是否工作正常
- 在设置 -> 关于手机中检查内核版本
## 需要帮助?
如果在安装过程中遇到问题:
1. 查看我们的[兼容性指南](./compatibility)了解设备要求
2. 访问我们的 [GitHub 仓库](https://github.com/sukisu-ultra/sukisu-ultra)获取支持
3. 加入我们的 [Telegram 社区](https://t.me/sukiksu)获取帮助
::: danger 安全提醒
**始终有备用计划!** 保留您的原始 `boot.img/init_boot.img` 并知道如何在出现问题时恢复设备。
:::

View File

@@ -1,77 +0,0 @@
# 许可证
## 软件许可
### 内核组件
::: info GPL-2.0 许可证
"kernel" 目录中的文件采用 GPL-2.0-only 许可证
:::
**许可证:** [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
### 应用程序核心
::: tip GPL-3.0 许可证
所有其他部分(除下述特别说明外)采用 GPL-3.0 或更高版本许可证
:::
**许可证:** [GPL-3.0 或更高版本](https://www.gnu.org/licenses/gpl-3.0.html)
## 艺术作品与品牌资产
### 启动器图标与角色艺术
::: warning 版权声明
动画角色艺术作品有特殊许可要求
:::
包含动画角色表情的文件 `ic_launcher(?!.*alt.*).*` 图像有特定的版权条款:
**版权持有者:**
- **动画角色艺术:** [怡子曰曰](https://space.bilibili.com/10545509)
- **品牌知识产权:** [明风OuO](https://space.bilibili.com/274939213)
- **矢量化制作:** @MiRinChan
**许可要求:**
1. **知识共享许可证:** [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.txt)
2. **作者授权:** 需要获得两位版权持有者的授权
3. **署名要求:** 必须署名上述所有贡献者
::: details 使用要求
在使用这些艺术资产之前,您必须:
- 遵守知识共享署名-非商业性使用-相同方式共享 4.0 国际许可证
- 获得两位原作者对艺术内容使用的授权
- 为所有贡献者提供适当的署名
:::
## 摘要
| 组件 | 许可证 | 备注 |
| ---------------- | ------------------------------------------------------------------------- | ----------------------- |
| **内核文件** | [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) | `/kernel/` 目录中的文件 |
| **应用程序代码** | [GPL-3.0+](https://www.gnu.org/licenses/gpl-3.0.html) | 主要应用程序组件 |
| **角色艺术** | [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) | + 需要作者授权 |
| **品牌资产** | 混合许可 | 查看具体署名要求 |
## 链接
- **GPL-2.0** [完整许可证文本](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
- **GPL-3.0** [完整许可证文本](https://www.gnu.org/licenses/gpl-3.0.html)
- **CC BY-NC-SA 4.0** [完整许可证文本](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.txt)
## 问题
关于许可证或使用权限的问题:
1. **代码许可:** 参考相应的 GPL 许可证条款
2. **艺术作品使用:** 联系原作者获取授权
3. **商业使用:** 查看 CC BY-NC-SA 4.0 限制条款
4. **分发:** 确保遵守所有适用的许可证
::: tip 合规提示
在重新分发或修改 SukiSU-Ultra 时,请确保遵守各个组件的所有适用许可证和署名要求。
:::

View File

@@ -1,71 +0,0 @@
# 更多链接
## 参与翻译
::: info 贡献翻译
如果您需要为管理器提交翻译,请访问我们的 Crowdin 项目
:::
**翻译平台:** [Crowdin - SukiSU-Ultra](https://crowdin.com/project/SukiSU-Ultra)
## 项目与构建
基于 Sukisu 和 susfs 编译的项目:
### GKI 构建
::: tip 通用 GKI 支持
集成 KernelSU 和 SUSFS 的通用内核映像构建
:::
**仓库:** [GKI_KernelSU_SUSFS](https://github.com/ShirkNeko/GKI_KernelSU_SUSFS)
### OnePlus 构建
::: tip 设备特定构建
带有 MKSU 和 SUSFS 的自动化 OnePlus 内核构建
:::
**仓库:** [Action_OnePlus_MKSU_SUSFS](https://github.com/ShirkNeko/Action_OnePlus_MKSU_SUSFS)
## 社区与支持
### Telegram 社区
> 与其他用户联系,获取支持并保持更新
**主群组:** [Tg Group](https://t.me/sukiksu)
### 测试构建
::: warning 实验性构建
测试构建是实验性的,可能不稳定
:::
**测试构建频道:** [最新测试构建](https://t.me/Sukiksu/7114)
## 下载与发布
### 官方发布
> 从我们的 GitHub 发布页面下载最新稳定版本
**GitHub 发布:** [SukiSU-Ultra 发布](https://github.com/sukisu-ultra/sukisu-ultra/releases)
### 问题报告
> 在我们的 GitHub 仓库上报告错误或请求新功能
**GitHub 问题:** [报告问题](https://github.com/sukisu-ultra/sukisu-ultra/issues)
## 快速链接汇总
| 资源 | 链接 | 描述 |
| ----------------- | :--------------------------------------------------------------------: | -----------: |
| **翻译** | [Crowdin](https://crowdin.com/project/SukiSU-Ultra) | 提交翻译 |
| **Telegram 群组** | [t.me/sukiksu](https://t.me/sukiksu) | 社区支持 |
| **测试构建** | [测试频道](https://t.me/Sukiksu/7114) | 实验性构建 |
| **发布** | [GitHub 发布](https://github.com/sukisu-ultra/sukisu-ultra/releases) | 稳定下载 |
| **问题** | [GitHub 问题](https://github.com/sukisu-ultra/sukisu-ultra/issues) | 错误报告 |
| **GKI 构建** | [GKI 仓库](https://github.com/ShirkNeko/GKI_KernelSU_SUSFS) | 通用构建 |
| **OnePlus 构建** | [OnePlus 仓库](https://github.com/ShirkNeko/Action_OnePlus_MKSU_SUSFS) | 设备特定构建 |

View File

@@ -1,266 +0,0 @@
# Tracepoint Hook 集成
## 介绍
自 commit [49b01aad](https://github.com/SukiSU-Ultra/SukiSU-Ultra/commit/49b01aad74bcca6dba5a8a2e053bb54b648eb124) 起SukiSU 引入了 Tracepoint Hook
**该 Hook 理论上相比于 Kprobes Hook性能开销更小但次于 Manual Hook / Syscall Hook**
::: warning
目前 Tracepoint Hook 在 6.x 设备上并不稳定,请勿使用,否则可能出现无法开机或无法获取 `ROOT` 权限等问题。
:::
> [!NOTE]
> 本教程参考了 [backslashxx/KernelSU#5](https://github.com/backslashxx/KernelSU/issues/5) 的 syscall hook v1.4 版本钩子,以及原版 KernelSU 的 [Manual Hook](https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#manually-modify-the-kernel-source)
## 在内核中放置 TP 钩子
::: code-group
```diff[exec.c]
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -78,6 +78,10 @@
#include <trace/hooks/sched.h>
#endif
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
EXPORT_TRACEPOINT_SYMBOL_GPL(task_rename);
static int bprm_creds_from_file(struct linux_binprm *bprm);
@@ -2037,6 +2041,9 @@ static int do_execve(struct filename *filename,
{
struct user_arg_ptr argv = { .ptr.native = __argv };
struct user_arg_ptr envp = { .ptr.native = __envp };
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_execveat_hook((int *)AT_FDCWD, &filename, &argv, &envp, 0);
+#endif
return do_execveat_common(AT_FDCWD, filename, argv, envp, 0);
}
@@ -2064,6 +2071,9 @@ static int compat_do_execve(struct filename *filename,
.is_compat = true,
.ptr.compat = __envp,
};
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_execveat_sucompat_hook((int *)AT_FDCWD, &filename, NULL, NULL, NULL); /* 32-bit su */
+#endif
return do_execveat_common(AT_FDCWD, filename, argv, envp, 0);
}
```
```diff[open.c]
--- a/fs/open.c
+++ b/fs/open.c
@@ -37,6 +37,10 @@
#include "internal.h"
#include <trace/hooks/syscall_check.h>
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
int do_truncate(struct user_namespace *mnt_userns, struct dentry *dentry,
loff_t length, unsigned int time_attrs, struct file *filp)
{
@@ -468,6 +472,9 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla
SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
{
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_faccessat_hook(&dfd, &filename, &mode, NULL);
+#endif
return do_faccessat(dfd, filename, mode, 0);
}
```
```diff[read_write.c]
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -25,6 +25,10 @@
#include <linux/uaccess.h>
#include <asm/unistd.h>
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
const struct file_operations generic_ro_fops = {
.llseek = generic_file_llseek,
.read_iter = generic_file_read_iter,
@@ -630,6 +634,9 @@ ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count)
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_sys_read_hook(fd, &buf, &count);
+#endif
return ksys_read(fd, buf, count);
}
```
```diff[stat.c]
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -24,6 +24,10 @@
#include "internal.h"
#include "mount.h"
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
/**
* generic_fillattr - Fill in the basic attributes from the inode struct
* @mnt_userns: user namespace of the mount the inode was found from
@@ -408,6 +412,10 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename,
struct kstat stat;
int error;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_stat_hook(&dfd, &filename, &flag);
+#endif
+
error = vfs_fstatat(dfd, filename, &stat, flag);
if (error)
return error;
@@ -559,6 +567,10 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename,
struct kstat stat;
int error;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_stat_hook(&dfd, &filename, &flag); /* 32-bit su support */
+#endif
+
error = vfs_fstatat(dfd, filename, &stat, flag);
if (error)
return error;
```
:::
通常是要改四个地方:
1. compat_do_execve通常位于 `fs/exec.c`
2. do_faccessat通常位于 `/fs/open.c`
3. sys_read通常位于 `fs/read_write.c`
4. newfstatat SYSCALL通常位于 `fs/stat.c`
如果没有 do_faccessat 方法,可以找 faccessat 的 SYSCALL 定义(对于早于 4.17 的内核)
```diff
--- a/fs/open.c
+++ b/fs/open.c
@@ -31,6 +31,9 @@
#include <linux/ima.h>
#include <linux/dnotify.h>
#include <linux/compat.h>
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
#include "internal.h"
@@ -369,6 +372,9 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
int res;
unsigned int lookup_flags = LOOKUP_FOLLOW;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_faccessat_hook(&dfd, &filename, &mode, NULL);
+#endif
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
return -EINVAL;
```
如果没有 sys_read 方法,并且 4.14 及以下需要修改 read 的 SYSCALL 定义
```diff
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -25,6 +25,11 @@
#include <linux/uaccess.h>
#include <asm/unistd.h>
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
+
const struct file_operations generic_ro_fops = {
.llseek = generic_file_llseek,
.read_iter = generic_file_read_iter,
@@ -575,6 +580,9 @@ SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
if (f.file) {
loff_t pos = file_pos_read(f.file);
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_sys_read_hook(fd, &buf, &count);
+#endif
ret = vfs_read(f.file, buf, count, &pos);
if (ret >= 0)
file_pos_write(f.file, pos);
```
## 安全模式
要使用 KernelSU 内置的安全模式,你还需要修改 `drivers/input/input.c` 中的 input_handle_event 方法:
```diff
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -26,6 +26,10 @@
#include "input-compat.h"
#include "input-poller.h"
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../../drivers/kernelsu/ksu_trace.h>
+#endif
+
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("Input core");
MODULE_LICENSE("GPL");
@@ -451,6 +455,10 @@ void input_event(struct input_dev *dev,
{
unsigned long flags;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_input_hook(&type, &code, &value);
+#endif
+
if (is_event_supported(type, dev->evbit, EV_MAX)) {
spin_lock_irqsave(&dev->event_lock, flags);
```
## pm 命令执行失败?
你需要修改 `drivers/tty/pty.c`
```diff
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -31,6 +31,10 @@
#include <linux/compat.h>
#include "tty.h"
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../../drivers/kernelsu/ksu_trace.h>
+#endif
+
#undef TTY_DEBUG_HANGUP
#ifdef TTY_DEBUG_HANGUP
# define tty_debug_hangup(tty, f, args...) tty_debug(tty, f, ##args)
@@ -707,6 +711,10 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
{
struct tty_struct *tty;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_devpts_hook((struct inode *)file->f_path.dentry->d_inode);
+#endif
+
mutex_lock(&devpts_mutex);
tty = devpts_get_priv(file->f_path.dentry);
mutex_unlock(&devpts_mutex);
```

View File

@@ -1,37 +0,0 @@
---
layout: home
hero:
name: 'SukiSU-Ultra'
text: '下一代 Android Root 解决方案'
tagline: Android 上的内核级的高级 root 方案
image:
src: /logo.svg
alt: SukiSU-Ultra
actions:
- theme: brand
text: 开始使用
link: /zh/guide/
- theme: alt
text: 在 GitHub 上查看
link: https://github.com/sukisu-ultra/sukisu-ultra
features:
- title: 内核级的 su 和 root 权限管理
details: 在内核进行安全的 root 权限管理。
- title: 不基于 OverlayFS 的模块系统
details: 模块系统基于来自 5ec1cff 的 Magic Mount。
- title: App Profile
details: 把 root 权限关进笼子里。
- title: 重新支持非 GKI 与 GKI 1.0 内核
details: 增强对旧设备的兼容性。
- title: 更多自定义选项
details: 提供广泛的自定义选项。
- title: 支持 KPM
details: 完整的基于 KernelPatch 的 KPM 功能。
---

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -1,26 +0,0 @@
{
"name": "SukiSU",
"short_name": "SukiSU",
"icons": [
{
"src": "/favicon.svg",
"type": "image/svg+xml",
"purpose": "any"
},
{
"src": "/web-app-manifest-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/web-app-manifest-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
],
"theme_color": "#000000",
"background_color": "#000000",
"display": "standalone"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -1,57 +0,0 @@
{
"name": "sukisu-ultra-docs",
"version": "2.0.0",
"description": "SukiSU-Ultra Documentation - Next-Generation Android Root Solution",
"type": "module",
"scripts": {
"dev": "tsx scripts/rebuild-ico.ts && tsx scripts/sync-favicons.ts && vitepress dev docs --host",
"build": "tsx scripts/sync-favicons.ts && vitepress build docs && pnpm build:sw:dist",
"preview": "vitepress preview docs",
"build:sw": "tsc scripts/sw.ts --target ES2022 --lib ES2022,WebWorker --outDir docs/public --skipLibCheck",
"build:sw:dist": "tsc scripts/sw.ts --target ES2022 --lib ES2022,WebWorker --outDir docs/.vitepress/dist --skipLibCheck",
"build:scripts": "pnpm build:sw",
"type-check": "tsc --noEmit",
"format": "prettier --write .",
"format:check": "prettier --check ."
},
"keywords": [
"android",
"root",
"kernelsu",
"sukisu",
"documentation",
"vitepress"
],
"repository": {
"type": "git",
"url": "https://github.com/sukisu-ultra/sukisu-ultra.git"
},
"homepage": "https://sukisu.org",
"bugs": {
"url": "https://github.com/sukisu-ultra/sukisu-ultra/issues"
},
"devDependencies": {
"@types/node": "^24.3.0",
"@types/serviceworker": "^0.0.152",
"markdown-it-footnote": "^4.0.0",
"markdown-it-mark": "^4.0.0",
"markdown-it-mathjax3": "^4.3.2",
"markdown-it-sub": "^2.0.0",
"markdown-it-task-lists": "^2.1.1",
"prettier": "^3.6.2",
"terser": "^5.44.0",
"ts-node": "^10.9.2",
"tsx": "^4.20.5",
"typescript": "^5.9.2",
"vitepress": "1.6.4",
"vue": "^3.5.21"
},
"engines": {
"node": ">=22"
},
"packageManager": "pnpm@10.17.1",
"dependencies": {
"@nolebase/vitepress-plugin-git-changelog": "^2.18.2",
"vitepress-plugin-group-icons": "^1.6.3"
}
}

View File

@@ -1,6 +0,0 @@
packages:
- docs
- .
onlyBuiltDependencies:
- esbuild

View File

@@ -1,207 +0,0 @@
/// <reference lib="webworker" />
const CACHE_NAME: string = 'sukisu-ultra-v2.0'
const STATIC_CACHE: string = 'sukisu-static-v2.0'
const RUNTIME_CACHE: string = 'sukisu-runtime-v2.0'
const IMAGE_CACHE: string = 'sukisu-images-v2.0'
const CRITICAL_ASSETS: string[] = [
'/',
'/guide/',
'/guide/installation',
'/guide/compatibility',
'/zh/',
'/zh/guide/',
'/logo.svg',
'/favicon.ico',
'/offline.html',
]
const CACHE_STRATEGIES: {
static: string[]
images: string[]
documents: string[]
} = {
static: ['.css', '.js', '.woff2', '.woff', '.ttf', '.otf'],
images: ['.png', '.jpg', '.jpeg', '.svg', '.webp', '.avif', '.gif', '.ico'],
documents: ['.html', '.json', '.xml'],
}
self.addEventListener('install', (event: ExtendableEvent) => {
event.waitUntil(
(async (): Promise<void> => {
const cache: Cache = await caches.open(STATIC_CACHE)
try {
await cache.addAll(CRITICAL_ASSETS)
} catch (error) {
console.warn('Failed to cache some assets:', error)
}
;(self as any).skipWaiting()
})()
)
})
self.addEventListener('activate', (event: ExtendableEvent) => {
event.waitUntil(
(async (): Promise<void> => {
const cacheNames: string[] = await caches.keys()
const validCaches: string[] = [STATIC_CACHE, RUNTIME_CACHE, IMAGE_CACHE, CACHE_NAME]
await Promise.all(
cacheNames
.filter((name: string) => !validCaches.includes(name))
.map((name: string) => caches.delete(name))
)
;(self as any).clients.claim()
})()
)
})
self.addEventListener('fetch', (event: FetchEvent) => {
const { request } = event
const url: URL = new URL(request.url)
if (request.method !== 'GET' || url.origin !== location.origin) return
if (url.pathname.startsWith('/api/')) return
event.respondWith(handleRequest(request, url))
})
async function handleRequest(request: Request, url: URL): Promise<Response> {
const isStatic: boolean = CACHE_STRATEGIES.static.some((ext: string) =>
url.pathname.endsWith(ext)
)
const isImage: boolean = CACHE_STRATEGIES.images.some((ext: string) => url.pathname.endsWith(ext))
const isDocument: boolean =
CACHE_STRATEGIES.documents.some((ext: string) => url.pathname.endsWith(ext)) ||
url.pathname.endsWith('/')
try {
if (isStatic) {
return await handleStatic(request)
} else if (isImage) {
return await handleImage(request)
} else if (isDocument) {
return await handleDocument(request)
} else {
return await handleDefault(request)
}
} catch (error) {
return await handleOffline(request)
}
}
async function handleStatic(request: Request): Promise<Response> {
const cache: Cache = await caches.open(STATIC_CACHE)
const cached: Response | undefined = await cache.match(request)
if (cached) {
fetch(request)
.then((response: Response) => {
if (response.ok) cache.put(request, response.clone())
})
.catch(() => {})
return cached
}
const response: Response = await fetch(request)
if (response.ok) {
cache.put(request, response.clone())
}
return response
}
async function handleImage(request: Request): Promise<Response> {
const cache: Cache = await caches.open(IMAGE_CACHE)
const cached: Response | undefined = await cache.match(request)
if (cached) return cached
const response: Response = await fetch(request)
if (response.ok) {
cache.put(request, response.clone())
}
return response
}
async function handleDocument(request: Request): Promise<Response> {
const cache: Cache = await caches.open(RUNTIME_CACHE)
try {
const response: Response = await fetch(request)
if (response.ok) {
cache.put(request, response.clone())
}
return response
} catch (error) {
const cached: Response | undefined = await cache.match(request)
if (cached) return cached
if (request.mode === 'navigate') {
const offlinePage: Response | undefined = await caches.match('/offline.html')
if (offlinePage) return offlinePage
}
throw error
}
}
async function handleDefault(request: Request): Promise<Response> {
const cache: Cache = await caches.open(RUNTIME_CACHE)
try {
const response: Response = await fetch(request)
if (response.ok) {
cache.put(request, response.clone())
}
return response
} catch (error) {
const cached: Response | undefined = await cache.match(request)
if (cached) return cached
throw error
}
}
async function handleOffline(request: Request): Promise<Response> {
const cache: Cache = await caches.open(STATIC_CACHE)
if (request.mode === 'navigate') {
const offlinePage: Response | undefined = await caches.match('/offline.html')
if (offlinePage) return offlinePage
}
return new Response('Offline', {
status: 503,
statusText: 'Service Unavailable',
headers: new Headers({
'Content-Type': 'text/plain',
}),
})
}
self.addEventListener('sync', (event: any) => {
if (event.tag === 'data-sync') {
event.waitUntil(syncData())
}
})
async function syncData(): Promise<void> {
try {
console.log('Syncing application data...')
} catch (error) {
console.error('Data sync failed:', error)
}
}
interface PerformanceMessage {
type: string
name: string
}
self.addEventListener('message', (event: MessageEvent) => {
const data = event.data as PerformanceMessage
if (data && data.type === 'PERFORMANCE_MARK') {
performance.mark(data.name)
}
})

View File

@@ -1,38 +0,0 @@
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const srcDir = path.join(__dirname, '../favicon')
const dstDir = path.join(__dirname, '../docs/public')
function ensureDir(dir: string) {
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })
}
function copyAll(src: string, dst: string) {
ensureDir(dst)
const entries = fs.readdirSync(src, { withFileTypes: true })
let count = 0
for (const entry of entries) {
const s = path.join(src, entry.name)
const d = path.join(dst, entry.name)
if (entry.isDirectory()) {
copyAll(s, d)
} else if (entry.isFile()) {
fs.copyFileSync(s, d)
count++
}
}
return count
}
if (!fs.existsSync(srcDir)) {
console.warn('Favicons source folder not found:', srcDir)
process.exit(0)
}
const copied = copyAll(srcDir, dstDir)
console.log(`✅ Synced ${copied} favicon file(s) from \'favicon\' to docs/public`)

View File

@@ -1,25 +0,0 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true,
"outDir": "./dist",
"rootDir": "./",
"types": ["node", "serviceworker"],
"lib": ["ES2022", "WebWorker"],
"ignoreDeprecations": "5.0"
},
"ts-node": {
"esm": true,
"experimentalSpecifierResolution": "node"
},
"include": ["scripts/**/*"],
"exclude": ["node_modules", "dist", "docs/.vitepress/dist"]
}

View File

@@ -1,11 +0,0 @@
# Cloudflare Pages Configuration for SukiSU-Ultra
name = "sukisu-ultra-docs"
compatibility_date = "2025-08-04"
compatibility_flags = ["nodejs_compat"]
pages_build_output_dir = "docs/.vitepress/dist"
[env.production]
name = "sukisu-ultra-docs"
[env.preview]
name = "sukisu-ultra-docs-preview"

View File

@@ -1,6 +0,0 @@
project_id_env: CROWDIN_PROJECT_ID
api_token_env: CROWDIN_API_TOKEN
preserve_hierarchy: 1
files:
- source: /manager/app/src/main/res/values/strings.xml
translation: /manager/app/src/main/res/values-%two_letters_code%/strings.xml

View File

@@ -1,101 +0,0 @@
# SukiSU Ultra
<img align='right' src='SukiSU-mini.svg' width='220px' alt="sukisu logo">
**English** | [简体中文](./zh/README.md) | [日本語](./ja/README.md) | [Türkçe](./tr/README.md)
A kernel-based root solution for Android devices, forked from [`tiann/KernelSU`](https://github.com/tiann/KernelSU), and added some interesting changes.
[![Latest release](https://img.shields.io/github/v/release/SukiSU-Ultra/SukiSU-Ultra?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Channel](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/Sukiksu)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## Features
1. Kernel-based `su` and root access management
2. Module system based on [Magic Mount](https://github.com/5ec1cff/KernelSU)
3. [App Profile](https://kernelsu.org/guide/app-profile.html): Lock up the root power in a cage
4. Support non-GKI and GKI 1.0
5. KPM Support
6. Tweaks to the manager theme and the built-in susfs management tool.
## Compatibility Status
- KernelSU (before v1.0.0) officially supports Android GKI 2.0 devices (kernel 5.10+).
- Older kernels (4.4+) are also compatible, but the kernel will have to be built manually.
- With more backports, KernelSU can supports 3.x kernel (3.4-3.18).
- Currently, only `arm64-v8a`, `armeabi-v7a (bare)` and `X86_64`(some) are supported.
## Installation
See [`guide/installation.md`](guide/installation.md)
## Integration
See [`guide/how-to-integrate.md`](guide/how-to-integrate.md)
## Translation
If you need to submit a translation for the manager, please go to [Crowdin](https://crowdin.com/project/SukiSU-Ultra).
## KPM Support
- Based on KernelPatch, we removed features redundant with KSU and retained only KPM support.
- Work in Progress: Expanding APatch compatibility by integrating additional functions to ensure compatibility across different implementations.
**Open-source repository**: [https://github.com/ShirkNeko/SukiSU_KernelPatch_patch](https://github.com/ShirkNeko/SukiSU_KernelPatch_patch)
**KPM template**: [https://github.com/udochina/KPM-Build-Anywhere](https://github.com/udochina/KPM-Build-Anywhere)
> [!Note]
>
> 1. Requires `CONFIG_KPM=y`
> 2. Non-GKI devices requires `CONFIG_KALLSYMS=y` and `CONFIG_KALLSYMS_ALL=y`
> 3. For kernels below `4.19`, backporting from `set_memory.h` from `4.19` is required.
## Troubleshooting
1. Device stuck upon manager app uninstallation?
Uninstall _com.sony.playmemories.mobile_
## Sponsor
- [ShirkNeko](https://afdian.com/a/shirkneko) (maintainer of SukiSU)
- [weishu](https://github.com/sponsors/tiann) (author of KernelSU)
## ShirkNeko's sponsorship list
- [Ktouls](https://github.com/Ktouls) Thanks so much for bringing me support.
- [zaoqi123](https://github.com/zaoqi123) Thanks for the milk tea.
- [wswzgdg](https://github.com/wswzgdg) Many thanks for supporting this project.
- [yspbwx2010](https://github.com/yspbwx2010) Many thanks.
- [DARKWWEE](https://github.com/DARKWWEE) 100 USDT
- [Saksham Singla](https://github.com/TypeFlu) Provide and maintain the website
- [OukaroMF](https://github.com/OukaroMF) Donation of website domain name
## License
- The file in the “kernel” directory is under [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) license.
- The images of the files `ic_launcher(?!.*alt.*).*` with anime character sticker are copyrighted by [怡子曰曰](https://space.bilibili.com/10545509), the Brand Intellectual Property in the images is owned by [明风 OuO](https://space.bilibili.com/274939213), and the vectorization is done by @MiRinChan. Before using these files, in addition to complying with [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.txt), you also need to comply with the authorization of the two authors to use these artistic contents.
- Except for the files or directories mentioned above, all other parts are under [GPL-3.0 or later](https://www.gnu.org/licenses/gpl-3.0.html) license.
## Credit
- [KernelSU](https://github.com/tiann/KernelSU): upstream
- [MKSU](https://github.com/5ec1cff/KernelSU): Magic Mount
- [RKSU](https://github.com/rsuntk/KernelsU): support non-GKI
- [susfs](https://gitlab.com/simonpunk/susfs4ksu): An addon root hiding kernel patches and userspace module for KernelSU.
- [KernelPatch](https://github.com/bmax121/KernelPatch): KernelPatch is a key part of the APatch implementation of the kernel module
<details>
<summary>KernelSU's credit</summary>
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): The KernelSU idea.
- [Magisk](https://github.com/topjohnwu/Magisk): The powerful root tool.
- [genuine](https://github.com/brevent/genuine/): APK v2 signature validation.
- [Diamorphine](https://github.com/m0nad/Diamorphine): Some rootkit skills.
</details>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 185 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 200 KiB

View File

@@ -1,97 +0,0 @@
# Integrate
SukiSU can be integrated into both _GKI_ and _non-GKI_ kernels and has been backported to _4.14_.
<!-- It should be 3.4, but backslashxx's syscall manual hook cannot use in SukiSU-->
Some OEMs' customization could result in as much as 50% of kernel code being out-of-tree code and not from upstream Linux kernels or ACKs. Due to this, the custom nature of _non-GKI_ kernels resulted in significant kernel fragmentation, and we lacked a universal method for building them. Therefore, we cannot provide boot images of _non-GKI_ kernels.
Prerequisites: open source bootable kernel.
### Hook method
1. **KPROBES hook:**
- Default hook method on GKI kernels.
- Requires `# CONFIG_KSU_MANUAL_HOOK is not set` & `CONFIG_KPROBES=y`
- Used for Loadable Kernel Module (LKM).
2. **Manual hook:**
<!-- - backslashxx's syscall manual hook: https://github.com/backslashxx/KernelSU/issues/5 (v1.5 version is not available at the moment, if you want to use it, please use v1.4 version, or standard KernelSU hooks)-->
- Requires `CONFIG_KSU_MANUAL_HOOK=y`
- Requires [`guide/how-to-integrate.md`](guide/how-to-integrate.md)
- Requires [https://github.com/~](https://github.com/tiann/KernelSU/blob/main/website/docs/guide/how-to-integrate-for-non-gki.md#manually-modify-the-kernel-source)
3. **Tracepoint Hook:**
- Hook method introduced since SukiSU commit [49b01aad](https://github.com/SukiSU-Ultra/SukiSU-Ultra/commit/49b01aad74bcca6dba5a8a2e053bb54b648eb124)
- Requires `CONFIG_KSU_TRACEPOINT_HOOK=y`
- Requires [`guide/tracepoint-hook.md`](tracepoint-hook.md)
<!-- This part refer to [rsuntk/KernelSU](https://github.com/rsuntk/KernelSU). -->
If you're able to build a bootable kernel, there are two ways to integrate KernelSU into the kernel source code:
1. Automatically with `kprobe`
2. Manually
## Integrate with kprobe
Applicable:
- _GKI_ kernel
Not applicable:
- _non-GKI_ kernel
KernelSU uses kprobe to do kernel hooks. If kprobe runs well in your kernel, it's recommended to use it this way.
Please refer to this document [https://github.com/~](https://github.com/tiann/KernelSU/blob/main/website/docs/guide/how-to-integrate-for-non-gki.md#integrate-with-kprobe). Although it is titled “for _non-GKI_,” it only applies to _GKI_.
The execution command for the step that adds KernelSU to your kernel source tree is replaced with:
```sh
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
## Manually modify the kernel source
Applicable:
- GKI kernel
- non-GKI kernel
Please refer to this document [https://github.com/~ (Integrate for non-GKI)](https://github.com/tiann/KernelSU/blob/main/website/docs/guide/how-to-integrate-for-non-gki.md#manually-modify-the-kernel-source) and [https://github.com/~ (Build for GKI)](https://kernelsu.org/zh_CN/guide/how-to-build.html) to integrate manually, although first link is titled “for non-GKI,” it also applies to GKI. It can work on them both.
There is another way to integrate but still work in the process.
<!-- It is backslashxx's syscall manual hook, but it cannot be used now. -->
Run command for the step that adds KernelSU(SukiSU) to your kernel source tree is replaced with:
### GKI kernel
```sh
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
### non-GKI kernel
```sh
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s nongki
```
### GKI / non-GKI kernel with susfs (experiment)
```sh
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s susfs-{{branch}}
```
Branch:
- `main` (susfs-main)
- `test` (susfs-test)
- version (for example: susfs-1.5.7, you should check the [branches](https://github.com/SukiSU-Ultra/SukiSU-Ultra/branches))

View File

@@ -1,34 +0,0 @@
# Installation
You can go to [KernelSU Documentation - Installation](https://kernelsu.org/guide/installation.html) for a reference on how to install it, here are just additional instructions.
## Installation by loading the Loadable Kernel Module(LKM)
See [KernelSU Documentation - LKM Installation](https://kernelsu.org/guide/installation.html#lkm-installation)
Beginning with **Android™** (trademark meaning licensed Google Mobile Services) 12, devices shipping with kernel version 5.10 or higher must ship with the GKI kernel. You may be able to use LKM mode.
## Installation by installing the kernel
See [KernelSU Documentation - GKI mode Installation](https://kernelsu.org/guide/installation.html#gki-mode-installation)
We provide pre-built kernels for you to use:
- [ShirkNeko flavor kernel](https://github.com/ShirkNeko/GKI_KernelSU_SUSFS) (add ZRAM compression algorithm patch, susfs, KPM. Works on many devices.)
- [MiRinFork flavored kernel](https://github.com/MiRinFork/GKI_SukiSU_SUSFS) (adds susfs, KPM. Closest kernel to GKI, works on most devices.)
Although some devices can be installed using LKM mode, they cannot be installed on the device by using the GKI kernel; therefore, the kernel needs to be modified manually to compile it. For example:
- OPPO(OnePlus, REALME)
- Meizu
Also, we provide pre-built kernels for your OnePlus device to use:
- [ShirkNeko/Action_OnePlus_MKSU_SUSFS](https://github.com/ShirkNeko/Action_OnePlus_MKSU_SUSFS) (add ZRAM compression algorithm patch, susfs, KPM.)
Using the link above, Fork into GitHub Action, fill in the build parameters, compile, and finally flush in the zip with the AnyKernel3 suffix.
> [!Note]
>
> - You only need to fill in the first two parts of the version number, e.g. `5.10`, `6.1`...
> - Make sure you know the processor designation, kernel version, etc. before you use it.

View File

@@ -1,270 +0,0 @@
# Tracepoint Hook Integration
## Introduction
Since commit [49b01aad](https://github.com/SukiSU-Ultra/SukiSU-Ultra/commit/49b01aad74bcca6dba5a8a2e053bb54b648eb124), SukiSU has introduced Tracepoint Hook
This Hook theoretically has lower performance overhead compared to Kprobes Hook, but is inferior to Manual Hook / Syscall Hook
> [!NOTE]
> This tutorial references the syscall hook v1.4 version from [backslashxx/KernelSU#5](https://github.com/backslashxx/KernelSU/issues/5), as well as the original KernelSU's [Manual Hook](https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#manually-modify-the-kernel-source)
## Guide
### execve Hook (`exec.c`)
Generally need to modify the `do_execve` and `compat_do_execve` methods in `fs/exec.c`
```patch
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -78,6 +78,10 @@
#include <trace/hooks/sched.h>
#endif
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
EXPORT_TRACEPOINT_SYMBOL_GPL(task_rename);
static int bprm_creds_from_file(struct linux_binprm *bprm);
@@ -2037,6 +2041,9 @@ static int do_execve(struct filename *filename,
{
struct user_arg_ptr argv = { .ptr.native = __argv };
struct user_arg_ptr envp = { .ptr.native = __envp };
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_execveat_hook((int *)AT_FDCWD, &filename, &argv, &envp, 0);
+#endif
return do_execveat_common(AT_FDCWD, filename, argv, envp, 0);
}
@@ -2064,6 +2071,9 @@ static int compat_do_execve(struct filename *filename,
.is_compat = true,
.ptr.compat = __envp,
};
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_execveat_sucompat_hook((int *)AT_FDCWD, &filename, NULL, NULL, NULL); /* 32-bit su */
+#endif
return do_execveat_common(AT_FDCWD, filename, argv, envp, 0);
}
```
### faccessat Hook (`open.c`)
Generally need to modify the `do_faccessat` method in `/fs/open.c`
```patch
--- a/fs/open.c
+++ b/fs/open.c
@@ -37,6 +37,10 @@
#include "internal.h"
#include <trace/hooks/syscall_check.h>
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
int do_truncate(struct user_namespace *mnt_userns, struct dentry *dentry,
loff_t length, unsigned int time_attrs, struct file *filp)
{
@@ -468,6 +472,9 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla
SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
{
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_faccessat_hook(&dfd, &filename, &mode, NULL);
+#endif
return do_faccessat(dfd, filename, mode, 0);
}
```
If there's no `do_faccessat` method, you can find the `faccessat` SYSCALL definition (for kernels earlier than 4.17)
```patch
--- a/fs/open.c
+++ b/fs/open.c
@@ -31,6 +31,9 @@
#include <linux/ima.h>
#include <linux/dnotify.h>
#include <linux/compat.h>
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
#include "internal.h"
@@ -369,6 +372,9 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
int res;
unsigned int lookup_flags = LOOKUP_FOLLOW;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_faccessat_hook(&dfd, &filename, &mode, NULL);
+#endif
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
return -EINVAL;
```
### sys_read Hook (`read_write.c`)
Need to modify the `sys_read` method in `fs/read_write.c` (4.19 and above)
```patch
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -25,6 +25,10 @@
#include <linux/uaccess.h>
#include <asm/unistd.h>
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
const struct file_operations generic_ro_fops = {
.llseek = generic_file_llseek,
.read_iter = generic_file_read_iter,
@@ -630,6 +634,9 @@ ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count)
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_sys_read_hook(fd, &buf, &count);
+#endif
return ksys_read(fd, buf, count);
}
```
Or the `read` SYSCALL definition (4.14 and below)
```patch
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -25,6 +25,11 @@
#include <linux/uaccess.h>
#include <asm/unistd.h>
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
+
const struct file_operations generic_ro_fops = {
.llseek = generic_file_llseek,
.read_iter = generic_file_read_iter,
@@ -575,6 +580,9 @@ SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
if (f.file) {
loff_t pos = file_pos_read(f.file);
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_sys_read_hook(fd, &buf, &count);
+#endif
ret = vfs_read(f.file, buf, count, &pos);
if (ret >= 0)
file_pos_write(f.file, pos);
```
### fstatat Hook (`stat.c`)
Need to modify the `newfstatat` SYSCALL definition in `stat.c`
If 32-bit support is needed, also need to modify the `statat64` SYSCALL definition
```patch
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -24,6 +24,10 @@
#include "internal.h"
#include "mount.h"
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
/**
* generic_fillattr - Fill in the basic attributes from the inode struct
* @mnt_userns: user namespace of the mount the inode was found from
@@ -408,6 +412,10 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename,
struct kstat stat;
int error;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_stat_hook(&dfd, &filename, &flag);
+#endif
+
error = vfs_fstatat(dfd, filename, &stat, flag);
if (error)
return error;
@@ -559,6 +567,10 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename,
struct kstat stat;
int error;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_stat_hook(&dfd, &filename, &flag); /* 32-bit su support */
+#endif
+
error = vfs_fstatat(dfd, filename, &stat, flag);
if (error)
return error;
```
### input Hook (`input.c`, for entering KSU built-in security mode)
Need to modify the `input_event` method in `drivers/input/input.c`, not `input_handle_event`
```patch
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -26,6 +26,10 @@
#include "input-compat.h"
#include "input-poller.h"
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../../drivers/kernelsu/ksu_trace.h>
+#endif
+
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("Input core");
MODULE_LICENSE("GPL");
@@ -451,6 +455,10 @@ void input_event(struct input_dev *dev,
{
unsigned long flags;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_input_hook(&type, &code, &value);
+#endif
+
if (is_event_supported(type, dev->evbit, EV_MAX)) {
spin_lock_irqsave(&dev->event_lock, flags);
```
### devpts Hook (`pty.c`)
Need to modify the `pts_unix98_lookup` method in `drivers/tty/pty.c`
```patch
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -31,6 +31,10 @@
#include <linux/compat.h>
#include "tty.h"
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../../drivers/kernelsu/ksu_trace.h>
+#endif
+
#undef TTY_DEBUG_HANGUP
#ifdef TTY_DEBUG_HANGUP
# define tty_debug_hangup(tty, f, args...) tty_debug(tty, f, ##args)
@@ -707,6 +711,10 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
{
struct tty_struct *tty;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_devpts_hook((struct inode *)file->f_path.dentry->d_inode);
+#endif
+
mutex_lock(&devpts_mutex);
tty = devpts_get_priv(file->f_path.dentry);
mutex_unlock(&devpts_mutex);
```

View File

@@ -1,153 +0,0 @@
# SukiSU Ultra
<img align='right' src='SukiSU-mini.svg' width='220px' alt="sukisu logo">
[English](../README.md) | [简体中文](../zh/README.md) | **日本語** | [Türkçe](../tr/README.md)
[KernelSU](https://github.com/tiann/KernelSU) をベースとした Android デバイスの root ソリューション
**試験中なビルドです!自己責任で使用してください!**<br>
このソリューションは [KernelSU](https://github.com/tiann/KernelSU) に基づいていますが、試験中なビルドです。
> これは非公式なフォークです。すべての権利は [@tiann](https://github.com/tiann) に帰属します。
>
> ただし、将来的には KSU とは別に管理されるブランチとなる予定です。
## 追加する方法
メインブランチを使用 (非 GKI のデバイスのビルドは非対応) (susfs を手動で統合が必要)
```
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
非 GKI のデバイスに対応するブランチを使用 (susfs を手動で統合が必要)
```
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s nongki
```
## 統合された susfs の使い方
1. susfs-main または他の susfs-\* ブランチを直接で使用、susfs の統合は不要 (非 GKI デバイスのビルドに対応)
```
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s susfs-main
```
## フックの方式
- この方式は (https://github.com/rsuntk/KernelSU) のフック方式を参照してください。
1. **KPROBES でフック:**
- 読み込み可能なカーネルモジュールの場合 (LKM)
- GKI カーネルのデフォルトとなるフック方式
- `CONFIG_KPROBES=y` が必要です
2. **手動でフック:**
- 標準の KernelSU フック: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#manually-modify-the-kernel-source
- backslashxx syscall フック: https://github.com/backslashxx/KernelSU/issues/5
- 非 GKI カーネル用のデフォルトフック方式
- `CONFIG_KSU_MANUAL_HOOK=y` が必要です
## KPM に対応
- KernelPatch に基づいて重複した KSU の機能を削除、KPM の対応を維持させています。
- KPM 機能の整合性を確保するために、APatch の互換機能を更に向上させる予定です。
オープンソースアドレス: https://github.com/ShirkNeko/SukiSU_KernelPatch_patch
KPM テンプレートのアドレス: https://github.com/udochina/KPM-Build-Anywhere
> [!Note]
>
> 1. `CONFIG_KPM=y` が必要です。
> 2. 非 GKI デバイスには `CONFIG_KALLSYMS=y` と `CONFIG_KALLSYMS_ALL=y` も必要です。
> 3. いくつかのカーネル `4.19` およびそれ以降のソースコードでは、 `4.19` からバックポートされた `set_memory.h` ヘッダーファイルも必要です。
## ROOT を保持した状態でのシステムアップデートの方法
- 始めに OTA 後すぐに再起動せずにマネージャーのカーネルのフラッシュ、パッチのインターフェースを開いて`GKI/非 GKI のインストール`を見つけます。フラッシュする AnyKernel3 の zip ファイルを選択し、フラッシュする実行中のスロットと逆のスロットを選択後に再起動をして GKI モードの更新が保持できます (この方法はすべての非 GKI のデバイスが対応している訳ではないので、自分でお試しください。これは非 GKI のデバイスで TWRP を使用する最も安全な方法です)。
- または LKM モードを使用して未使用のスロットにインストールします (OTA 後)。
## 互換性の状態
- KernelSU (v1.0.0 より前) は Android GKI 2.0 のデバイス (カーネル 5.10 以降) を公式に対応しています。
- 古いカーネル (4.4 以降) も互換性がありますが、カーネルを手動で再ビルドする必要があります。
- KernelSU は追加のリバースポートを通じて 3.x カーネル (3.4-3.18) で対応可能です。
- 現在 `arm64-v8a`, `armeabi-v7a (bare)` および一部の `X86_64` に対応しています。
## その他のリンク
**マネージャーの翻訳を行う場合** https://crowdin.com/project/SukiSU-Ultra
- [その他パッチ済み GKI](https://github.com/ShirkNeko/GKI_KernelSU_SUSFS) ZRAM パッチ、KPM、susfs が含まれています...
- [パッチの少ない GKI](https://github.com/MiRinFork/GKI_SukiSU_SUSFS/releases) susfs のみ
- [OnePlus](https://github.com/ShirkNeko/Action_OnePlus_MKSU_SUSFS)
## 使い方
### Universal GKI
**すべて**参照してください https://kernelsu.org/ja_JP/guide/installation.html
> [!Note]
>
> 1. Xiaomi、Redmi、Samsung などの GKI 2.0 を搭載したデバイス向け (Meizu、OnePlus、Zenith、Oppo などカーネルが変更されているメーカーを除く)
> 2. GKI のビルドは[その他のリンク](#その他のリンク)から入手できます。デバイスのカーネルバージョンを確認してください。ダウンロード後に TWRP またはカーネルフラッシュツールを使用して AnyKernel3 の接頭辞を持つ zip ファイルをフラッシュしてください。Pixel のユーザーは、パッチの少ない GKI を使用する必要があります。
> 3. 接頭辞のない .zip アーカイブは圧縮されていません。.gz の接頭辞は Tenguet モデルで使用される圧縮になります。
### OnePlus
1. `その他のリンク`の項目に記載されているリンクを開き、デバイス情報を使用してカスタマイズされたカーネルをビルドし、AnyKernel3 の接頭辞を持つ .zip ファイルをフラッシュします。
> [!Note]
>
> - 5.10、5.15、6.1、6.6 などのカーネルバージョンの最初の 2 文字のみを入力する必要があります。
> - SoC のコードネームは自分で検索してください。通常は、数字がなく英語表記のみです。
> - ブランチと構成ファイルは、OnePlus オープンソースカーネルリポジトリから見つけることができます。
## 機能
1. カーネルベースな `su` および root アクセスの管理。
2. [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS) モジュールシステムではなく、 5ec1cff 氏の [Magic Mount](https://github.com/5ec1cff/KernelSU) に基づいています。
3. [アプリプロファイル](https://kernelsu.org/guide/app-profile.html): root 権限をケージ内にロックします。
4. 非 GKI / GKI 1.0 の対応を復活
5. その他のカスタマイズ
6. KPM カーネルモジュールに対応
## トラブルシューティング
1. KernelSU Manager のアンインストールが停止してしまう → com.sony.playmemories.mobile のアプリをアンインストールしてください。
## ライセンス
- 「kernel」のディレクトリ内のファイルは [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) のライセンスに基づいています。
- アニメキャラクター画像とスタンプを含むこれらのファイルの `ic_launcher(?!.*alt.*).*` は[怡子曰曰](https://space.bilibili.com/10545509)によって著作権保護されており、画像の Brand Intellectual Property は[明风 OuO](https://space.bilibili.com/274939213)によって所有され、ベクター化は @MiRinChan によって行われています。 これらのファイルを使用する前に、[Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.txt)を遵守することに加えて、アートコンテンツを使用するために前の 2 人の作者から許可を得る必要があります。
- 上記のファイルまたはディレクトリを除き、その他のすべての部分は[GPL-3.0 以降](https://www.gnu.org/licenses/gpl-3.0.html)です。
## スポンサーシップの一覧
- [Ktouls](https://github.com/Ktouls) 応援してくれてありがとう
- [zaoqi123](https://github.com/zaoqi123) ミルクティーを買ってあげるのも良い考えですね
- [wswzgdg](https://github.com/wswzgdg) このプロジェクトにご支援いただき、ありがとうございます
- [yspbwx2010](https://github.com/yspbwx2010) ありがとうございます
- [DARKWWEE](https://github.com/DARKWWEE) ラオスから 100 USDT の支援に感謝します
- [Saksham Singla](https://github.com/TypeFlu) ウェブサイトの提供とメンテナンス
- [OukaroMF](https://github.com/OukaroMF) ウェブサイトのドメインと寄付
## 貢献者
- [KernelSU](https://github.com/tiann/KernelSU): オリジナルのプロジェクト
- [MKSU](https://github.com/5ec1cff/KernelSU): 使用しているプロジェクト
- [RKSU](https://github.com/rsuntk/KernelsU): このプロジェクトのカーネルを使用した非 GKI デバイスのサポートの再導入
- [susfs](https://gitlab.com/simonpunk/susfs4ksu): susfs ファイルシステムの使用
- [KernelSU](https://git.zx2c4.com/kernel-assisted-superuser/about/): KernelSU の概念化
- [Magisk](https://github.com/topjohnwu/Magisk): パワフルな root ユーティリティ
- [genuine](https://github.com/brevent/genuine/): APK v2 署名認証
- [Diamorphine](https://github.com/m0nad/Diamorphine): いくつかの root キットユーティリティ
- [KernelPatch](https://github.com/bmax121/KernelPatch): KernelPatch はカーネルモジュールの APatch 実装の重要な部分での活用

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 185 KiB

View File

@@ -1,151 +0,0 @@
# SukiSU Ultra
<img align='right' src='SukiSU-mini.svg' width='250px' alt="sukisu logo">
[English](../README.md) | [简体中文](../zh/README.md) | [日本語](../ja/README.md) | **Türkçe**
[KernelSU](https://github.com/tiann/KernelSU) tabanlı Android cihaz root çözümü
**Deneysel! Kullanım riski size aittir!**
> Bu resmi olmayan bir daldır, tüm hakları saklıdır [@tiann](https://github.com/tiann)
>
> Ancak, gelecekte ayrı bir KSU dalı olarak devam edeceğiz
## Nasıl Eklenir
Çekirdek kaynak kodunun kök dizininde aşağıdaki komutları çalıştırın:
Ana dalı kullanın (GKI olmayan cihazlar için desteklenmez)
```
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
GKI olmayan cihazları destekleyen dalı kullanın
```
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s nongki
```
## susfs Nasıl Entegre Edilir
1. Doğrudan susfs-main veya susfs-\* dalını kullanın, susfs entegrasyonuna gerek yok
```
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s susfs-main
```
## Kanca Yöntemleri
- Bu bölüm [rsuntk\'nin kanca yöntemlerinden](https://github.com/rsuntk/KernelSU) alıntılanmıştır
1. **KPROBES Kancası:**
- Yüklenebilir çekirdek modülleri (LKM) için kullanılır
- GKI 2.0 çekirdeğinin varsayılan kanca yöntemi
- `CONFIG_KPROBES=y` gerektirir
2. **Manuel Kanca:**
- Standart KernelSU kancası: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#manually-modify-the-kernel-source
- backslashxx\'nin syscall manuel kancası: https://github.com/backslashxx/KernelSU/issues/5
- GKI olmayan çekirdeğin varsayılan kanca yöntemi
- `CONFIG_KSU_MANUAL_HOOK=y` gerektirir
## KPM Desteği
- KernelPatch tabanlı olarak KSU ile çakışan işlevleri kaldırdık ve yalnızca KPM desteğini koruduk
- APatch ile daha fazla uyumlu fonksiyon ekleyerek KPM işlevlerinin bütünlüğünü sağlayacağız
Kaynak kodu: https://github.com/ShirkNeko/SukiSU_KernelPatch_patch
KPM şablonu: https://github.com/udochina/KPM-Build-Anywhere
> [!Note]
>
> 1. `CONFIG_KPM=y` gerektirir
> 2. GKI olmayan cihazlar ayrıca `CONFIG_KALLSYMS=y` ve `CONFIG_KALLSYMS_ALL=y` gerektirir
> 3. Bazı çekirdek `4.19` altı kaynak kodları, `4.19`dan geri taşınan başlık dosyası `set_memory.h` gerektirir
## Sistem Güncellemesini Yaparak ROOT\'u Koruma
- OTA\'dan sonra hemen yeniden başlatmayın, yöneticiye girin ve çekirdek yazma/onarma arayüzüne gidin, `GKI/non_GKI yükleme` seçeneğini bulun ve Anykernel3 çekirdek sıkıştırma dosyasını seçin, şu anda sistemin çalıştığı yuva ile zıt yuvaya yazın ve yeniden başlatın, böylece GKI modu güncellemesini koruyabilirsiniz (şu anda tüm GKI olmayan cihazlar bu yöntemi desteklemiyor, lütfen kendiniz deneyin. GKI olmayan cihazlar için TWRP kullanmak en güvenlidir)
- Veya kullanılmayan yuvaya LKM modunu kullanarak yükleyin (OTA\'dan sonra)
## Uyumluluk Durumu
- KernelSU (v1.0.0 öncesi sürümler) resmi olarak Android GKI 2.0 cihazlarını destekler (çekirdek 5.10+)
- Eski çekirdekler (4.4+) de uyumludur, ancak çekirdeği manuel olarak oluşturmanız gerekir
- Daha fazla geri taşımayla KernelSU, 3.x çekirdeğini (3.4-3.18) destekleyebilir
- Şu anda `arm64-v8a`, `armeabi-v7a (bare)` ve bazı `X86_64` desteklenmektedir
## Daha Fazla Bağlantı
SukiSU ve susfs tabanlı derlenen projeler
- [GKI](https://github.com/ShirkNeko/GKI_KernelSU_SUSFS)
- [OnePlus](https://github.com/ShirkNeko/Action_OnePlus_MKSU_SUSFS)
## Kullanım Yöntemi
### Evrensel GKI
Lütfen **tümünü** https://kernelsu.org/zh_CN/guide/installation.html adresinden inceleyin
> [!Note]
>
> 1. Xiaomi, Redmi, Samsung gibi GKI 2.0 cihazlar için uygundur (Meizu, OnePlus, Realme ve Oppo gibi değiştirilmiş çekirdekli üreticiler hariç)
> 2. [Daha fazla bağlantı](#daha-fazla-bağlantı) bölümündeki GKI tabanlı projeleri bulun. Cihaz çekirdek sürümünü bulun. Ardından indirin ve TWRP veya çekirdek yazma aracı kullanarak AnyKernel3 soneki olan sıkıştırılmış paketi yazın
> 3. Genellikle sonek olmayan .zip sıkıştırılmış paketler sıkıştırılmamıştır, gz soneki olanlar ise Dimensity modelleri için kullanılan sıkıştırma yöntemidir
### OnePlus
1. Daha fazla bağlantı bölümündeki OnePlus projesini bulun ve kendiniz doldurun, ardından bulut derleme yapın ve AnyKernel3 soneki olan sıkıştırılmış paketi yazın
> [!Note]
>
> - Çekirdek sürümü için yalnızca ilk iki haneyi doldurmanız yeterlidir, örneğin 5.10, 5.15, 6.1, 6.6
> - İşlemci kod adını kendiniz arayın, genellikle tamamen İngilizce ve sayı içermeden oluşur
> - Dal ve yapılandırma dosyasını kendiniz OnePlus çekirdek kaynak kodundan doldurun
## Özellikler
1. Çekirdek tabanlı `su` ve root erişim yönetimi
2. 5ec1cff\'nin [Magic Mount](https://github.com/5ec1cff/KernelSU) tabanlı modül sistemi
3. [App Profile](https://kernelsu.org/guide/app-profile.html): root yetkilerini kafeste kilitleyin
4. GKI 2.0 olmayan çekirdekler için desteğin geri getirilmesi
5. Daha fazla özelleştirme özelliği
6. KPM çekirdek modülleri için destek
## Lisans
- `kernel` dizinindeki dosyalar [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) lisansı altındadır.
- Anime karakter ifadeleri içeren `ic_launcher(?!.*alt.*).*` dosyalarının görüntüleri [怡子曰曰](https://space.bilibili.com/10545509) tarafından telif hakkıyla korunmaktadır, görüntülerdeki Marka Fikri Mülkiyeti [明风 OuO](https://space.bilibili.com/274939213)'ye aittir ve vektörleştirme @MiRinChan tarafından yapılmıştır. Bu dosyaları kullanmadan önce, [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.txt) ile uyumlu olmanın yanı sıra, bu sanatsal içerikleri kullanmak için iki yazarın yetkilendirmesine de uymanız gerekir.
- Yukarıda belirtilen dosyalar veya dizinler hariç, diğer tüm parçalar [GPL-3.0 veya üzeri](https://www.gnu.org/licenses/gpl-3.0.html)'dir.
## Afdian Bağlantısı
- https://afdian.com/a/shirkneko
## Sponsor Listesi
- [Ktouls](https://github.com/Ktouls) Bana sağladığınız destek için çok teşekkür ederim
- [zaoqi123](https://github.com/zaoqi123) Bana sütlü çay ısmarlamanız da güzel
- [wswzgdg](https://github.com/wswzgdg) Bu projeye olan desteğiniz için çok teşekkür ederim
- [yspbwx2010](https://github.com/yspbwx2010) Çok teşekkür ederim
- [DARKWWEE](https://github.com/DARKWWEE) 100 USDT için teşekkürler
## Katkıda Bulunanlar
- [KernelSU](https://github.com/tiann/KernelSU): Orijinal proje
- [MKSU](https://github.com/5ec1cff/KernelSU): Kullanılan proje
- [RKSU](https://github.com/rsuntk/KernelsU): GKI olmayan cihazlar için destek sağlayan proje
- [susfs4ksu](https://gitlab.com/simonpunk/susfs4ksu): Kullanılan susfs dosya sistemi
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): KernelSU fikri
- [Magisk](https://github.com/topjohnwu/Magisk): Güçlü root aracı
- [genuine](https://github.com/brevent/genuine/): APK v2 imza doğrulama
- [Diamorphine](https://github.com/m0nad/Diamorphine): Bazı rootkit becerileri
- [KernelPatch](https://github.com/bmax121/KernelPatch): KernelPatch, APatch\'in çekirdek modüllerini uygulamak için kritik bir parçadır

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 185 KiB

View File

@@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="128"
height="128"
viewBox="0 0 128 128"
version="1.1"
id="svg1"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="zakomonochrome-128.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#999999"
borderopacity="1"
inkscape:showpageshadow="2"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
inkscape:zoom="2.6185048"
inkscape:cx="59.957881"
inkscape:cy="71.032903"
inkscape:window-width="1280"
inkscape:window-height="696"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="图层 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#ffffff;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;paint-order:fill markers stroke;fill-opacity:1"
id="rect1"
width="128"
height="128"
x="0"
y="0"
rx="7.772471"
ry="7.772471" />
<path
id="path101"
style="fill:#ffffff;fill-opacity:0.734285;stroke:#000000;stroke-width:4.27504;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 42.510282,81.796052 c 0,0 -7.224141,-5.638356 -10.043315,-9.338525 M 14.847106,81.97224 25.41902,71.576535 m 0.17619,-6.695549 2.819179,19.910444 M 11.675534,73.338532 38.281518,71.047931 M 43.567475,62.7666 34.40515,62.942814 M 34.22896,62.590425 33.524162,48.494537 m -18.500855,1.58577 17.972249,-1.409582 m -11.8053,-5.462154 0.352397,18.853251"
inkscape:label="杂" />
<path
id="path111"
style="fill:#ffffff;fill-opacity:0.734285;stroke:#000000;stroke-width:3.94824;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.3;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="M 55.912937,82.876745 79.671596,81.412163 M 59.330273,75.391135 74.952411,74.089291 m -9.43837,-14.157553 1.139102,14.645756 m -8.299247,-7.160159 16.273048,-1.464569 m 0.650926,8.136525 0.325472,-14.808482 m -0.162747,0.162739 -17.900363,0.976379 m 0,-0.162738 1.952774,14.645756 m 12.042061,-21.154974 1.464576,-6.346492 m 0,-0.650928 -12.042063,0.650928 m -0.650918,6.509218 0.325459,-8.787441"
inkscape:label="鱼" />
<path
d="m 95.08569,51.121163 c -1.90515,0.116064 -3.64694,0.97349 -4.86738,2.391307 -1.34538,1.56738 -1.91476,3.733159 -1.59523,6.070852 0.40842,2.982962 2.1502,6.17135 5.13887,9.411078 0.63424,0.68546 1.08109,1.129773 1.98202,1.967071 1.58321,1.469144 3.01507,2.634638 4.9875,4.052454 0.70392,0.50905 2.09253,1.453525 2.61627,1.781734 l 0.15133,0.09594 0.22103,-0.140663 c 0.80481,-0.515755 2.23909,-1.504852 3.08956,-2.130057 3.21689,-2.364488 5.79232,-4.737902 7.70228,-7.100167 3.09676,-3.831409 4.4133,-7.562359 3.80549,-10.773058 -0.42043,-2.210414 -1.82588,-4.039057 -3.81992,-4.967887 -0.85767,-0.399664 -1.69132,-0.607312 -2.6355,-0.656431 -1.22285,-0.0647 -2.42648,0.178619 -3.57485,0.721182 -1.95561,0.922124 -3.58927,2.719503 -4.61752,5.081755 -0.072,0.165235 -0.1394,0.310355 -0.14895,0.319295 -0.0312,0.02902 -0.0648,-0.02679 -0.19458,-0.330457 -0.30752,-0.714476 -0.91055,-1.752718 -1.38382,-2.377871 -0.4853,-0.645282 -1.2661,-1.431214 -1.84749,-1.862143 -1.50155,-1.114153 -3.26013,-1.658924 -5.00914,-1.553996 z"
id="path1-4"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.00231605" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -1,101 +0,0 @@
# SukiSU Ultra
<img align='right' src='SukiSU-mini.svg' width='220px' alt="sukisu logo">
[English](../README.md) | **简体中文** | [日本語](../ja/README.md) | [Türkçe](../tr/README.md)
一个 Android 上基于内核的 root 方案,由 [`tiann/KernelSU`](https://github.com/tiann/KernelSU) 分叉而来,添加了一些有趣的变更。
[![最新发行](https://img.shields.io/github/v/release/SukiSU-Ultra/SukiSU-Ultra?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![频道](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/Sukiksu)
[![协议: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub 协议](https://img.shields.io/github/license/tiann/KernelSU?logo=gnu)](/LICENSE)
## 特性
1. 基于内核的 `su` 和权限管理。
2. 基于 [Magic Mount](https://github.com/5ec1cff/KernelSU) 的模块系统。
3. [App Profile](https://kernelsu.org/zh_CN/guide/app-profile.html): 把 Root 权限关进笼子里。
4. 支持 non-GKI 与 GKI 1.0。
5. KPM 支持
6. 可调整管理器外观,可自定义 susfs 配置。
## 兼容状态
- KernelSU 官方支持 GKI 2.0 的设备(内核版本 5.10 以上)。
- 旧内核也是兼容的(最低 4.14+),不过需要自己编译内核。
- 通过更多的反向移植KernelSU 可以支持 3.x 内核3.4-3.18)。
- 目前支持架构 : `arm64-v8a``armeabi-v7a (bare)``X86_64`
## 安装指导
查看 [`guide/installation.md`](guide/installation.md)
## 集成指导
查看 [`guide/how-to-integrate.md`](guide/how-to-integrate.md)
## 参与翻译
要将 SukiSU 翻译成您的语言,或完善现有的翻译,请使用 [Crowdin](https://crowdin.com/project/SukiSU-Ultra).
## KPM 支持
- 基于 KernelPatch 开发,移除了与 KernelSU 重复的功能。
- 正在进行WIP通过集成附加功能来扩展 APatch 兼容性,以确保跨不同实现的兼容性。
**开源仓库**: [https://github.com/ShirkNeko/SukiSU_KernelPatch_patch](https://github.com/ShirkNeko/SukiSU_KernelPatch_patch)
**KPM 模板**: [https://github.com/udochina/KPM-Build-Anywhere](https://github.com/udochina/KPM-Build-Anywhere)
> [!Note]
>
> 1. 需要 `CONFIG_KPM=y`
> 2. Non-GKI 设备需要 `CONFIG_KALLSYMS=y` and `CONFIG_KALLSYMS_ALL=y`
> 3. 对于低于 `4.19` 的内核,需要从 `4.19` 的 `set_memory.h` 进行反向移植。
## 故障排除
1. 卸载管理器后系统卡住?
卸载 _com.sony.playmemories.mobile_
## 许可证
- 目录 `kernel` 下所有文件为 [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)。
- 有动漫人物图片表情包的这些文件 `ic_launcher(?!.*alt.*).*` 的图像版权为[怡子曰曰](https://space.bilibili.com/10545509)所有,图像中的知识产权由[明风 OuO](https://space.bilibili.com/274939213)所有,矢量化由 @MiRinChan 完成,在使用这些文件之前,除了必须遵守 [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.txt) 以外,还需要遵守向前两者索要使用这些艺术内容的授权。
- 除上述文件及目录的其他部分均为 [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html)。
## 赞助
- [ShirkNeko](https://afdian.com/a/shirkneko) (SukiSU 主要维护者)
- [weishu](https://github.com/sponsors/tiann) (KernelSU 作者)
## ShirkNeko 的赞助列表
- [Ktouls](https://github.com/Ktouls) 非常感谢你给我带来的支持
- [zaoqi123](https://github.com/zaoqi123) 请我喝奶茶也不错
- [wswzgdg](https://github.com/wswzgdg) 非常感谢对此项目的支持
- [yspbwx2010](https://github.com/yspbwx2010) 非常感谢
- [DARKWWEE](https://github.com/DARKWWEE) 感谢老哥的 100 USDT
- [Saksham Singla](https://github.com/TypeFlu) 网站的提供以及维护
- [OukaroMF](https://github.com/OukaroMF) 网站域名捐赠
## 鸣谢
- [KernelSU](https://github.com/tiann/KernelSU): 上游
- [MKSU](https://github.com/5ec1cff/KernelSU): 魔法坐骑支持
- [RKSU](https://github.com/rsuntk/KernelsU): non-GKI 支持
- [susfs](https://gitlab.com/simonpunk/susfs4ksu): 隐藏内核补丁以及用户空间模组的 KernelSU 附件
- [KernelPatch](https://github.com/bmax121/KernelPatch): KernelPatch 是内核模块 APatch 实现的关键部分
<details>
<summary>KernelSU 的鸣谢</summary>
- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/)KernelSU 的灵感。
- [Magisk](https://github.com/topjohnwu/Magisk):强大的 root 工具箱。
- [genuine](https://github.com/brevent/genuine/)apk v2 签名验证。
- [Diamorphine](https://github.com/m0nad/Diamorphine):一些 rootkit 技巧。
</details>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 185 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 200 KiB

View File

@@ -1,97 +0,0 @@
# 集成指导
SukiSU 可以集成到 GKI 和 non-GKI 内核中,并且已反向移植到 4.14 版本。
<!-- 应该是 3.4 版本,但 backslashxx 的 syscall manual hook 无法在 SukiSU 中使用-->
有些 OEM 定制可能导致多达 50% 的内核代码超出内核树代码,而非来自上游 Linux 内核或 ACK。因此non-GKI 内核的定制特性导致了严重的内核碎片化,而且我们缺乏构建它们的通用方法。因此,我们无法提供 non-GKI 内核的启动映像。
前提条件:开源的、可启动的内核。
## Hook 方法
1. **KPROBES hook:**
- GKI kernels 的默认 hook 方法。
- 需要 `# CONFIG_KSU_MANUAL_HOOK is not set`(未设定) & `CONFIG_KPROBES=y`
- 用作可加载的内核模块 (LKM).
2. **Manual hook:**
<!-- - backslashxx's syscall manual hook: https://github.com/backslashxx/KernelSU/issues/5 (v1.5 version is not available at the moment, if you want to use it, please use v1.4 version, or standard KernelSU hooks)-->
- 需要 `CONFIG_KSU_MANUAL_HOOK=y`
- 需要 [`guide/how-to-integrate.md`](how-to-integrate.md)
- 需要 [https://github.com/~](https://github.com/tiann/KernelSU/blob/main/website/docs/guide/how-to-integrate-for-non-gki.md#manually-modify-the-kernel-source)
3. **Tracepoint Hook:**
- 自 SukiSU commit [49b01aad](https://github.com/SukiSU-Ultra/SukiSU-Ultra/commit/49b01aad74bcca6dba5a8a2e053bb54b648eb124) 引入的 hook 方法
- 需要 `CONFIG_KSU_TRACEPOINT_HOOK=y`
- 需要 [`guide/tracepoint-hook.md`](tracepoint-hook.md)
<!-- This part refer to [rsuntk/KernelSU](https://github.com/rsuntk/KernelSU). -->
如果您能够构建可启动内核,有两种方法可以将 KernelSU 集成到内核源代码中:
1. 使用 `kprobe` 自动集成
2. 手动集成
## 与 kprobe 集成
适用:
- GKI 内核
不适用:
- non-GKI 内核
KernelSU 使用 kprobe 机制来做内核的相关 hook如果 _kprobe_ 可以在你编译的内核中正常运行,那么推荐用这个方法来集成。
请参阅此文档 [https://github.com/~](https://github.com/tiann/KernelSU/blob/main/website/docs/guide/how-to-integrate-for-non-gki.md#integrate-with-kprobe)。虽然标题为“适用于 non-GKI”但仅适用于 GKI。
替换 KernelSU 添加到内核源代码树的步骤的执行命令为:
```sh
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
## 手动修改内核源代码
适用:
- GKI 内核
- non-GKI 内核
请参考此文档 [https://github.com/~ (non-GKI 内核集成)](https://github.com/tiann/KernelSU/blob/main/website/docs/guide/how-to-integrate-for-non-gki.md#manually-modify-the-kernel-source) 和 [https://github.com/~ (GKI 内核构建)](https://kernelsu.org/zh_CN/guide/how-to-build.html) 进行手动集成。虽然第一个链接的标题是“适用于 non-GKI”但它也适用于 GKI。两者都可以正常工作。
还有另一种集成方法,但是仍在开发中。
<!-- 这是 backslashxx 的syscall manual hook但目前无法使用。 -->
将 KernelSUSukiSU添加到内核源代码树的步骤的运行命令将被替换为
### GKI 内核
```sh
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
### non-GKI 内核
```sh
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s nongki
```
### 带有 susfs 的 GKI / non-GKI 内核(实验)
```sh
curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s susfs-{{branch}}
```
分支:
- `main` (susfs-main)
- `test` (susfs-test)
- 版本号 (例如: susfs-1.5.7, 你需要在 [分支](https://github.com/SukiSU-Ultra/SukiSU-Ultra/branches) 里找到它)

View File

@@ -1,34 +0,0 @@
# 安装指导
您可以前往 [KernelSU 文档 - 安装](https://kernelsu.org/guide/installation.html) 获取有关如何安装的参考,这里只是额外的说明。
## 通过加载可加载内核模块 (LKM) 进行安装
请参阅 [KernelSU 文档 - LKM 安装](https://kernelsu.org/guide/installation.html#lkm-installation)
**Android™**(商标,意为获得 Google 移动服务的许可12 开始,搭载内核版本 5.10 或更高版本的设备必须搭载 GKI 内核。因此你或许可以使用 LKM 模式。
## 通过安装内核进行安装
请参阅 [KernelSU 文档 - GKI 模式安装](https://kernelsu.org/guide/installation.html#gki-mode-installation)
我们提供预编译的内核供您使用:
- [ShirkNeko 内核](https://github.com/ShirkNeko/GKI_KernelSU_SUSFS)(添加了 ZRAM 压缩算法补丁、susfs 文件和 KPM 文件。适用于很多设备。)
- [MiRinFork 内核](https://github.com/MiRinFork/GKI_SukiSU_SUSFS)(添加了 susfs 文件和 KPM 文件。最接近 GKI 的内核,适用于大多数设备。)
虽然某些设备可以使用 LKM 模式安装,但无法使用 GKI 内核将其安装到设备上;因此,需要手动修改内核进行编译。例如:
- 欧珀(一加、真我)
- 魅族
此外,我们还为您的 OnePlus 设备提供预编译的内核:
- [ShirkNeko/Action_OnePlus_MKSU_SUSFS](https://github.com/ShirkNeko/Action_OnePlus_MKSU_SUSFS)(添加 ZRAM 压缩算法补丁、susfs 和 KPM。
使用上面的链接Fork 到 GitHub Action填写构建参数进行编译最后将 zip 文件以 AnyKernel3 后缀上传到 GitHub Action。
> [!Note]
>
> - 使用时,您只需填写版本号的前两部分,例如 `5.10`、`6.1`...
> - 使用前请确保您了解处理器名称、内核版本等信息。

View File

@@ -1,270 +0,0 @@
# Tracepoint Hook 集成
## 介绍
自 commit [49b01aad](https://github.com/SukiSU-Ultra/SukiSU-Ultra/commit/49b01aad74bcca6dba5a8a2e053bb54b648eb124) 起SukiSU 引入了 Tracepoint Hook
该 Hook 理论上相比于 Kprobes Hook性能开销更小但次于 Manual Hook / Syscall Hook
> [!NOTE]
> 本教程参考了 [backslashxx/KernelSU#5](https://github.com/backslashxx/KernelSU/issues/5) 的 syscall hook v1.4 版本钩子,以及原版 KernelSU 的 [Manual Hook](https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#manually-modify-the-kernel-source)
## Guide
### execve 钩子(`exec.c`
一般需要修改 `fs/exec.c``do_execve``compat_do_execve` 方法
```patch
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -78,6 +78,10 @@
#include <trace/hooks/sched.h>
#endif
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
EXPORT_TRACEPOINT_SYMBOL_GPL(task_rename);
static int bprm_creds_from_file(struct linux_binprm *bprm);
@@ -2037,6 +2041,9 @@ static int do_execve(struct filename *filename,
{
struct user_arg_ptr argv = { .ptr.native = __argv };
struct user_arg_ptr envp = { .ptr.native = __envp };
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_execveat_hook((int *)AT_FDCWD, &filename, &argv, &envp, 0);
+#endif
return do_execveat_common(AT_FDCWD, filename, argv, envp, 0);
}
@@ -2064,6 +2071,9 @@ static int compat_do_execve(struct filename *filename,
.is_compat = true,
.ptr.compat = __envp,
};
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_execveat_sucompat_hook((int *)AT_FDCWD, &filename, NULL, NULL, NULL); /* 32-bit su */
+#endif
return do_execveat_common(AT_FDCWD, filename, argv, envp, 0);
}
```
### faccessat 钩子 (`open.c`)
一般需要修改 `/fs/open.c``do_faccessat` 方法
```patch
--- a/fs/open.c
+++ b/fs/open.c
@@ -37,6 +37,10 @@
#include "internal.h"
#include <trace/hooks/syscall_check.h>
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
int do_truncate(struct user_namespace *mnt_userns, struct dentry *dentry,
loff_t length, unsigned int time_attrs, struct file *filp)
{
@@ -468,6 +472,9 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla
SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
{
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_faccessat_hook(&dfd, &filename, &mode, NULL);
+#endif
return do_faccessat(dfd, filename, mode, 0);
}
```
如果没有 `do_faccessat` 方法,可以找 `faccessat` 的 SYSCALL 定义(对于早于 4.17 的内核)
```patch
--- a/fs/open.c
+++ b/fs/open.c
@@ -31,6 +31,9 @@
#include <linux/ima.h>
#include <linux/dnotify.h>
#include <linux/compat.h>
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
#include "internal.h"
@@ -369,6 +372,9 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
int res;
unsigned int lookup_flags = LOOKUP_FOLLOW;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_faccessat_hook(&dfd, &filename, &mode, NULL);
+#endif
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
return -EINVAL;
```
### sys_read 钩子 ( `read_write.c` )
需要修改 `fs/read_write.c``sys_read` 方法4.19 及以上)
```patch
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -25,6 +25,10 @@
#include <linux/uaccess.h>
#include <asm/unistd.h>
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
const struct file_operations generic_ro_fops = {
.llseek = generic_file_llseek,
.read_iter = generic_file_read_iter,
@@ -630,6 +634,9 @@ ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count)
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_sys_read_hook(fd, &buf, &count);
+#endif
return ksys_read(fd, buf, count);
}
```
或者是 `read` 的 SYSCALL 定义4.14 及以下)
```patch
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -25,6 +25,11 @@
#include <linux/uaccess.h>
#include <asm/unistd.h>
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
+
const struct file_operations generic_ro_fops = {
.llseek = generic_file_llseek,
.read_iter = generic_file_read_iter,
@@ -575,6 +580,9 @@ SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
if (f.file) {
loff_t pos = file_pos_read(f.file);
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_sys_read_hook(fd, &buf, &count);
+#endif
ret = vfs_read(f.file, buf, count, &pos);
if (ret >= 0)
file_pos_write(f.file, pos);
```
### fstatat 钩子 ( `stat.c` )
需要修改 `stat.c``newfstatat` SYSCALL 定义
如果需要 32 位支持,还需要修改 `statat64` SYSCALL 定义
```patch
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -24,6 +24,10 @@
#include "internal.h"
#include "mount.h"
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../drivers/kernelsu/ksu_trace.h>
+#endif
+
/**
* generic_fillattr - Fill in the basic attributes from the inode struct
* @mnt_userns: user namespace of the mount the inode was found from
@@ -408,6 +412,10 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename,
struct kstat stat;
int error;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_stat_hook(&dfd, &filename, &flag);
+#endif
+
error = vfs_fstatat(dfd, filename, &stat, flag);
if (error)
return error;
@@ -559,6 +567,10 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename,
struct kstat stat;
int error;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_stat_hook(&dfd, &filename, &flag); /* 32-bit su support */
+#endif
+
error = vfs_fstatat(dfd, filename, &stat, flag);
if (error)
return error;
```
### input 钩子 (`input.c` ,用于进入KSU系的内置安全模式)
需要修改 `drivers/input/input.c``input_event` 方法,而不是 `input_handle_event`
```patch
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -26,6 +26,10 @@
#include "input-compat.h"
#include "input-poller.h"
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../../drivers/kernelsu/ksu_trace.h>
+#endif
+
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("Input core");
MODULE_LICENSE("GPL");
@@ -451,6 +455,10 @@ void input_event(struct input_dev *dev,
{
unsigned long flags;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_input_hook(&type, &code, &value);
+#endif
+
if (is_event_supported(type, dev->evbit, EV_MAX)) {
spin_lock_irqsave(&dev->event_lock, flags);
```
### devpts 钩子 (`pty.c`)
需要修改 `drivers/tty/pty.c``pts_unix98_lookup` 方法
```patch
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -31,6 +31,10 @@
#include <linux/compat.h>
#include "tty.h"
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+#include <../../drivers/kernelsu/ksu_trace.h>
+#endif
+
#undef TTY_DEBUG_HANGUP
#ifdef TTY_DEBUG_HANGUP
# define tty_debug_hangup(tty, f, args...) tty_debug(tty, f, ##args)
@@ -707,6 +711,10 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
{
struct tty_struct *tty;
+#if defined(CONFIG_KSU) && defined(CONFIG_KSU_TRACEPOINT_HOOK)
+ trace_ksu_trace_devpts_hook((struct inode *)file->f_path.dentry->d_inode);
+#endif
+
mutex_lock(&devpts_mutex);
tty = devpts_get_priv(file->f_path.dentry);
mutex_unlock(&devpts_mutex);
```

View File

@@ -1,121 +0,0 @@
# Library for KernelSU's module WebUI
## Install
```sh
yarn add kernelsu
```
## API
### exec
Spawns a **root** shell and runs a command within that shell, returning a Promise that resolves with the `stdout` and `stderr` outputs upon completion.
- `command` `<string>` The command to run, with space-separated arguments.
- `options` `<Object>`
- `cwd` - Current working directory of the child process.
- `env` - Environment key-value pairs.
```javascript
import { exec } from 'kernelsu';
const { errno, stdout, stderr } = await exec('ls -l', { cwd: '/tmp' });
if (errno === 0) {
// success
console.log(stdout);
}
```
### spawn
Spawns a new process using the given `command` in **root** shell, with command-line arguments in `args`. If omitted, `args` defaults to an empty array.
Returns a `ChildProcess` instance. Instances of `ChildProcess` represent spawned child processes.
- `command` `<string>` The command to run.
- `args` `<string[]>` List of string arguments.
- `options` `<Object>`:
- `cwd` `<string>` - Current working directory of the child process.
- `env` `<Object>` - Environment key-value pairs.
Example of running `ls -lh /data`, capturing `stdout`, `stderr`, and the exit code:
```javascript
import { spawn } from 'kernelsu';
const ls = spawn('ls', ['-lh', '/data']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
ls.on('exit', (code) => {
console.log(`child process exited with code ${code}`);
});
```
#### ChildProcess
##### Event 'exit'
- `code` `<number>` The exit code if the child process exited on its own.
The `'exit'` event is emitted when the child process ends. If the process exits, `code` contains the final exit code; otherwise, it is null.
##### Event 'error'
- `err` `<Error>` The error.
The `'error'` event is emitted whenever:
- The process could not be spawned.
- The process could not be killed.
##### `stdout`
A `Readable Stream` that represents the child process's `stdout`.
```javascript
const subprocess = spawn('ls');
subprocess.stdout.on('data', (data) => {
console.log(`Received chunk ${data}`);
});
```
#### `stderr`
A `Readable Stream` that represents the child process's `stderr`.
### fullScreen
Request the WebView enter/exit full screen.
```javascript
import { fullScreen } from 'kernelsu';
fullScreen(true);
```
### toast
Show a toast message.
```javascript
import { toast } from 'kernelsu';
toast('Hello, world!');
```
### moduleInfo
Get module info.
```javascript
import { moduleInfo } from 'kernelsu';
// print moduleId in console
console.log(moduleInfo());
```

Some files were not shown because too many files have changed in this diff Show More