From fe1cd4b27a0ec54f0f689d28c8ea46db25b2556c Mon Sep 17 00:00:00 2001 From: Kung-chih <42119227+Kaitul@users.noreply.github.com> Date: Sun, 23 Apr 2023 18:54:33 +0800 Subject: [PATCH] website: add Traditional Chinese (#429) Also README_TW added, hope it works :) --- README.md | 2 +- README_CN.md | 2 +- README_TW.md | 42 +++ website/docs/.vitepress/locales/index.ts | 7 + website/docs/.vitepress/locales/zh_TW.ts | 60 ++++ .../zh_TW/guide/difference-with-magisk.md | 26 ++ website/docs/zh_TW/guide/faq.md | 67 +++++ website/docs/zh_TW/guide/hidden-features.md | 7 + website/docs/zh_TW/guide/how-to-build.md | 65 +++++ .../guide/how-to-integrate-for-non-gki.md | 240 ++++++++++++++++ website/docs/zh_TW/guide/installation.md | 169 +++++++++++ website/docs/zh_TW/guide/module.md | 262 ++++++++++++++++++ .../docs/zh_TW/guide/rescue-from-bootloop.md | 50 ++++ .../guide/unofficially-support-devices.md | 30 ++ website/docs/zh_TW/guide/what-is-kernelsu.md | 21 ++ website/docs/zh_TW/index.md | 29 ++ 16 files changed, 1077 insertions(+), 2 deletions(-) create mode 100644 README_TW.md create mode 100644 website/docs/.vitepress/locales/zh_TW.ts create mode 100644 website/docs/zh_TW/guide/difference-with-magisk.md create mode 100644 website/docs/zh_TW/guide/faq.md create mode 100644 website/docs/zh_TW/guide/hidden-features.md create mode 100644 website/docs/zh_TW/guide/how-to-build.md create mode 100644 website/docs/zh_TW/guide/how-to-integrate-for-non-gki.md create mode 100644 website/docs/zh_TW/guide/installation.md create mode 100644 website/docs/zh_TW/guide/module.md create mode 100644 website/docs/zh_TW/guide/rescue-from-bootloop.md create mode 100644 website/docs/zh_TW/guide/unofficially-support-devices.md create mode 100644 website/docs/zh_TW/guide/what-is-kernelsu.md create mode 100644 website/docs/zh_TW/index.md diff --git a/README.md b/README.md index 0cdf4cc2..54bf3b99 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -**English** | [中文](README_CN.md) +**English** | [简体中文](README_CN.md) | [繁體中文](README_TW.md) # KernelSU diff --git a/README_CN.md b/README_CN.md index 6bf7fd3a..c4f86f40 100644 --- a/README_CN.md +++ b/README_CN.md @@ -1,4 +1,4 @@ -[English](README.md) | **中文** +[English](README.md) | **简体中文** | [繁體中文](README_TW.md) # KernelSU diff --git a/README_TW.md b/README_TW.md new file mode 100644 index 00000000..f02a9795 --- /dev/null +++ b/README_TW.md @@ -0,0 +1,42 @@ +[English](README.md) | [简体中文](README_CN.md) | **繁體中文** + +# KernelSU + +一個基於核心的 Android 裝置 Root 解決方案 + +## 功能 + +- 基於核心的 Su 和 Root 存取權管理。 +- 基於 Overlayfs 的模組系統。 + +## 相容性狀態 + +KernelSU 官方支援 Android GKI 2.0 的裝置 (核心版本 5.10+);舊版核心同樣相容 (最低 4.14+),但需要自行編譯核心。 + +WSA 和執行在容器中的 Android 也可以與 KernelSU 一同運作。 + +目前支援架構:`arm64-v8a` 和 `x86_64` + +## 使用方法 + +[安裝教學](https://kernelsu.org/zh_TW/guide/installation.html) + +## 建置 + +[如何建置?](https://kernelsu.org/zh_TW/guide/how-to-build.html) + +### 討論 + +- Telegram:[@KernelSU](https://t.me/KernelSU) + +## 授權 + +- 目錄 `kernel` 下所有檔案為 [GPL-2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) +- 除 `kernel` 目錄的其他部分均為 [GPL-3](https://www.gnu.org/licenses/gpl-3.0.html) + +## 致謝 + +- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/):KernelSU 的靈感。 +- [true](https://github.com/brevent/genuine/):apk v2 簽章驗證。 +- [Diamorphine](https://github.com/m0nad/Diamorphine):一些 rootkit 技巧。 +- [Magisk](https://github.com/topjohnwu/Magisk):sepolicy 實作。 diff --git a/website/docs/.vitepress/locales/index.ts b/website/docs/.vitepress/locales/index.ts index 5239c3b0..3c442313 100644 --- a/website/docs/.vitepress/locales/index.ts +++ b/website/docs/.vitepress/locales/index.ts @@ -1,6 +1,7 @@ import { defineConfig } from 'vitepress' import en from './en' import zh_CN from './zh_CN' +import zh_TW from './zh_TW' import vi_VN from './vi_VN' import id_ID from './id_ID' @@ -18,6 +19,12 @@ export default defineConfig({ themeConfig: zh_CN.themeConfig, description: zh_CN.description }, + zh_TW: { + label: '繁體中文', + lang: zh_TW.lang, + themeConfig: zh_TW.themeConfig, + description: zh_TW.description + }, vi_VN: { label: 'Tiếng Việt', lang: vi_VN.lang, diff --git a/website/docs/.vitepress/locales/zh_TW.ts b/website/docs/.vitepress/locales/zh_TW.ts new file mode 100644 index 00000000..373b2831 --- /dev/null +++ b/website/docs/.vitepress/locales/zh_TW.ts @@ -0,0 +1,60 @@ +import { createRequire } from 'module' +import { defineConfig } from 'vitepress' + +const require = createRequire(import.meta.url) +const pkg = require('vitepress/package.json') + +export default defineConfig({ + lang: 'zh-TW', + description: '一個以核心為基礎,適用於 Android GKI 的 Root 解決方案。', + + themeConfig: { + nav: nav(), + + lastUpdatedText: '上次更新', + + sidebar: { + '/zh_TW/guide/': sidebarGuide() + }, + + socialLinks: [ + { icon: 'github', link: 'https://github.com/tiann/KernelSU' } + ], + + footer: { + message: '係依據 GPL3 授權發行。', + copyright: 'Copyright © 2022-目前 KernelSU 開發人員' + }, + + editLink: { + pattern: 'https://github.com/tiann/KernelSU/edit/main/website/docs/:path', + text: '在 GitHub 中編輯本頁面' + } + } +}) + +function nav() { + return [ + { text: '指南', link: '/zh_TW/guide/what-is-kernelsu' }, + { text: 'Github', link: 'https://github.com/tiann/KernelSU' } + ] +} + +function sidebarGuide() { + return [ + { + text: 'Guide', + items: [ + { text: '什麼是 KernelSU?', link: '/zh_TW/guide/what-is-kernelsu' }, + { text: '安裝', link: '/zh_TW/guide/installation' }, + { text: '如何建置?', link: '/zh_TW/guide/how-to-build' }, + { text: '如何為非 GKI 核心整合 KernelSU', link: '/zh_TW/guide/how-to-integrate-for-non-gki'}, + { text: '非官方支援裝置', link: '/zh_TW/guide/unofficially-support-devices.md' }, + { text: '模組指南', link: '/zh_TW/guide/module.md' }, + { text: '搶救開機迴圈', link: '/zh_TW/guide/rescue-from-bootloop.md' }, + { text: '常見問題', link: '/zh_TW/guide/faq' }, + { text: '隱藏功能', link: '/zh_TW/guide/hidden-features' }, + ] + } + ] +} \ No newline at end of file diff --git a/website/docs/zh_TW/guide/difference-with-magisk.md b/website/docs/zh_TW/guide/difference-with-magisk.md new file mode 100644 index 00000000..ed9b2e0f --- /dev/null +++ b/website/docs/zh_TW/guide/difference-with-magisk.md @@ -0,0 +1,26 @@ +# KernelSU 模組與 Magisk 的差異 {#title} + +儘管 KernelSU 模組和 Magisk 模組之間有許多相似之處,但由於它們完全不同的實作機制,不可避免地存在一些差異;如果您想讓您的模組同時在 Magisk 和 KernelSU 上運作,那麼您必須瞭解這些差異。 + +## 相同之處 {#similarities} + +- 模組檔案格式:都以 Zip 的格式組織模組,並且模組的格式幾乎相同 +- 模組安裝目錄:都位於 `/data/adb/modules` +- Systemless:都支援透過模組的形式以 systemless 修改 /system +- `post-fs-data.sh`:執行時間和語義完全相同 +- `service.sh`:執行時間和語義完全相同 +- `system.prop`:完全相同 +- `sepolicy.rule`:完全相同 +- BusyBox:指令碼在 BusyBox 中以「獨立模式」執行 + +## 不同之處 {#differences} + +在瞭解不同之處之前,您需要知道如何區分您的模組是在 KernelSU 還是 Magisk 中執行;在所有可以執行模組指令碼的位置 (`customize.sh`, `post-fs-data.sh`, `service.sh`),您都可以使用環境變數 `KSU` 來區分,在 KernelSU 中,這個環境變數將被設定為 `true`。 + +以下是一些不同之處: + +1. KernelSU 的模組不支援在 Recovery 中安裝。 +2. KernelSU 的模組沒有內建的 Zygisk 支援 (但您可以透過 [ZygiskOnKernelSU](https://github.com/Dr-TSNG/ZygiskOnKernelSU) 來使用 Zygisk 模組)。 +3. KernelSU 模組取代或刪除檔案與 Magisk 完全不同。KernelSU 不支援 `.replace` 方法,相反,您需要透過 `mknod filename c 0 0` 建立相同名稱的資料夾以刪除對應檔案。 +4. BusyBox 的目錄不同;KernelSU 內建的 BusyBox 在 `/data/adb/ksu/bin/busybox` 而 Magisk 在 `/data/adb/magisk/busybox`;**注意此為 KernelSU 內部行為,未來可能會變更!** +5. KernelSU 不支援 `.replace` 檔案;但 KernelSU 支援 `REPLACE` 和 `REMOVE` 變數以移除或取代檔案 (資料夾)。 diff --git a/website/docs/zh_TW/guide/faq.md b/website/docs/zh_TW/guide/faq.md new file mode 100644 index 00000000..cb892be7 --- /dev/null +++ b/website/docs/zh_TW/guide/faq.md @@ -0,0 +1,67 @@ +# 常見問題 + +## KernelSU 是否支援我的裝置? + +首先,您的裝置應該能解鎖 Bootloader。如果不能,則不支援。 + +然後在您的裝置上安裝 KernelSU 管理員並開啟它,如果它顯示 `不支援`,那麼您的裝置沒有官方支援的開箱即用的 Boot 映像;但您可以自行建置核心來源並整合 KernelSU 以繼續使用。 + +## KernelSU 是否需要解鎖 Bootloader? + +當然需要。 + +## KernelSU 是否支援模組? + +支援,但它是早期版本,可能存在問題。請等候它逐漸穩定 :) + +## KernelSU 是否支援 Xposed ? + +支援。[Dreamland](https://github.com/canyie/Dreamland) 和 [TaiChi](https://taichi.cool) 可以正常運作。LSPosed 可以在 [Zygisk on KernelSU](https://github.com/Dr-TSNG/ZygiskOnKernelSU) 的支援下正常運作。 + +## KernelSU 支援 Zygisk 嗎? + +KernelSU 沒有內建 Zygisk 支援,但是您可以用 [Zygisk on KernelSU](https://github.com/Dr-TSNG/ZygiskOnKernelSU) 來使用 Zygisk 模組。 + +## KernelSU 與 Magisk 相容嗎? + +KernelSU 的模組系統與 Magisk 的 magic mount 存在衝突,如果在 KernelSU 中啟用了任何模組,那麼整個 Magisk 將無法正常運作。 + +但是如果您只使用 KernelSU 的 `su`,那么它會和 Magisk 一同運作:KernelSU 修改 `kernel` 、 Magisk 修改 `ramdisk`,它們可以搭配使用。 + +## KernelSU 会取代 Magisk 嗎? + +我們不這樣認為,這也不是我們的目標。Magisk 對於使用者空間 Root 解決方案來說已經足夠優秀了,它會存在很長一段時間。KernelSU 的目標是為使用者提供核心介面,而非取代 Magisk。 + +## KernelSU 可以支援非 GKI 裝置嗎? + +可以。但是您應該下載核心來源並整合 KernelSU 至來源樹狀結構並自行編譯核心。 + +## KernelSU 支援 Android 12 以下的裝置嗎? + +影響 KernelSU 相容性的是裝置的核心版本,它與 Android 版本並無直接關係。唯一有關聯的是:**原廠** Android 12 的裝置,一定是 5.10 或更高的核心 (GKI 裝置);因此結論如下: + +1. 原廠 Android 12 的裝置必定支援 (GKI 裝置) +2. 舊版核心的裝置 (即使是 Android 12,也可能是舊版核心) 是相容的 (您需要自行建置核心) + +## KernelSU 可以支援舊版核心嗎? + +可以,目前最低支援到 4.14;更低的版本您需要手動移植它,歡迎 PR! + +## 如何為舊版核心整合 KernelSU? + +請參閱[指南](how-to-integrate-for-non-gki) + +## 為何我的 Android 版本為 13,但核心版本卻是 "android12-5.10"? + +核心版本與 Android 版本無關,如果您要刷新 KernelSU,請一律使用**核心版本**而非 Android 版本,如果你為 "android12-5.10" 的裝置刷新 Android 13 的核心,等候您的將會是開機迴圈。 + +## KernelSU 支援 --mount-master/全域掛接命名空間嗎? + +目前沒有 (未來可能會支援),但實際上有很多種方法手動進入全域命名空間,無需 Su 內建支援,比如: + +1. `nsenter -t 1 -m sh` 可以取得一個全域 mount namespace 的 shell. +2. 在您要執行的命令前新增 `nsenter --mount=/proc/1/ns/mnt` 即可使此命令在全域 mount namespace 下執行。KernelSU 本身也使用了 [這種方法](https://github.com/tiann/KernelSU/blob/77056a710073d7a5f7ee38f9e77c9fd0b3256576/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt#L115) + +## 我是 GKI1.0,能用 KernelSU 嗎? + +GKI1 與 GKI2 完全不同,所以您需要自行編譯核心。 diff --git a/website/docs/zh_TW/guide/hidden-features.md b/website/docs/zh_TW/guide/hidden-features.md new file mode 100644 index 00000000..c07762db --- /dev/null +++ b/website/docs/zh_TW/guide/hidden-features.md @@ -0,0 +1,7 @@ +# 隱藏功能 + +## ksurc + +預設狀況下,`/system/bin/sh` 會載入 `/system/etc/mkshrc`。 + +可以透過建立 `/data/adb/ksu/.ksurc` 檔案來讓 Su 載入此檔案而非 `/system/etc/mkshrc`。 \ No newline at end of file diff --git a/website/docs/zh_TW/guide/how-to-build.md b/website/docs/zh_TW/guide/how-to-build.md new file mode 100644 index 00000000..0f95bf7f --- /dev/null +++ b/website/docs/zh_TW/guide/how-to-build.md @@ -0,0 +1,65 @@ +# 如何建置 KernelSU? + +首先,您需要閱讀核心建置的 Android 官方文件: + +1. [建置核心](https://source.android.com/docs/setup/build/building-kernels) +2. [標準核心映像 (GKI) 發行組建](https://source.android.com/docs/core/architecture/kernel/gki-release-builds) + +::: warning +此文件適用於 GKI 裝置,如果您是舊版核心,請參閱[如何為非 GKI 裝置整合 KernelSU](how-to-integrate-for-non-gki) +::: + +## 建置核心 + +### 同步核心原始碼 + +```sh +repo init -u https://android.googlesource.com/kernel/manifest +mv .repo/manifests +repo init -m manifest.xml +repo sync +``` + +`` 是一個可以唯一確定組建的資訊清單檔案,您可以使用這個資訊清單進行可重新預測的組建。您需要從[標準核心映像 (GKI) 發行組建](https://source.android.com/docs/core/architecture/kernel/gki-release-builds) 下載資訊清單檔案 + +### 建置 + +請先查看[官方文件](https://source.android.com/docs/setup/build/building-kernels)。 + +例如,我們需要建置 aarch64 核心映像: + +```sh +LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh +``` + +不要忘記新增 `LTO=thin`,否則,如果您的電腦記憶體小於 24GB,建置可能會失敗。 + +從 Android 13 開始,核心由 `bazel` 建置: + +```sh +tools/bazel build --config=fast //common:kernel_aarch64_dist +``` + +## 使用 KernelSU 建置核心 + +如果您可以成功建置核心,那麼建置 KernelSU 就會非常輕鬆,依自己的需求在核心原始碼根目錄中執行以下任一命令: + +- 最新 tag (穩定版本) + +```sh +curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash - +``` + +- main 分支 (開發版本) + +```sh +curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main +``` + +- 選取 tag (例如 v0.5.2) + +```sh +curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.5.2 +``` + +然後重新建置核心,您將會得到一個帶有 KernelSU 的核心映像! diff --git a/website/docs/zh_TW/guide/how-to-integrate-for-non-gki.md b/website/docs/zh_TW/guide/how-to-integrate-for-non-gki.md new file mode 100644 index 00000000..fe6fc72e --- /dev/null +++ b/website/docs/zh_TW/guide/how-to-integrate-for-non-gki.md @@ -0,0 +1,240 @@ +# 如何為非 GKI 核心整合 KernelSU {#introduction} + +KernelSU 可以被整合到非 GKI 核心中,現在它最低支援到核心 4.14 版本;理論上也可以支援更低的版本。 + +由於非 GKI 核心的片段化極其嚴重,因此通常沒有統一的方法來建置它,所以我們也無法為非 GKI 裝置提供 Boot 映像。但您完全可以自行整合 KernelSU 並建置核心以繼續使用。 + +首先,您必須有能力從您裝置的核心原始碼建置出一個可以開機並且能夠正常使用的核心,如果核心並非開放原始碼,這通常難以做到。 + +如果您已經做好了上述準備,那有兩個方法來將 KernelSU 整合至您的核心之中。 + +1. 藉助 `kprobe` 自動整合 +2. 手動修改核心原始碼 + +## 使用 kprobe 整合 {#using-kprobes} + +KernelSU 使用 kprobe 機制來處理核心的相關 hook,如果 *kprobe* 可以在您建置的核心中正常運作,那麼建議使用這個方法進行整合。 + +首先,把 KernelSU 新增至您的核心來源樹狀結構,再核心的根目錄執行以下命令: + +- 最新 tag (稳定版本) + +```sh +curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash - +``` + +- main 分支(開發版本) + +```sh +curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main +``` + +- 選取 tag (例如 v0.5.2) + +```sh +curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.5.2 +``` + +然後,您需要檢查您的核心是否啟用 *kprobe* 相關組態,如果未啟用,則需要新增以下組態: + +``` +CONFIG_KPROBES=y +CONFIG_HAVE_KPROBES=y +CONFIG_KPROBE_EVENTS=y +``` + +最後,重新建置您的核心即可。 + +如果您發現 KPROBES 仍未生效,很有可能是因為它的相依性 `CONFIG_MODULES` 並未被啟用 (如果還是未生效請輸入 `make menuconfig` 搜尋 KPROBES 的其他相依性並啟用) + +如果您在整合 KernelSU 之後手機無法啟動,那麼很可能您的核心中 **kprobe 無法正常運作**,您需要修正這個錯誤,或者使用第二種方法。 + +:::tip 如何檢查 kprobe 是否損毀? + +將 `KernelSU/kernel/ksu.c` 中的 `ksu_enable_sucompat()` 和 `ksu_enable_ksud()` 取消註解,如果正常開機,即 kprobe 已損毀;或者您可以手動嘗試使用 kprobe 功能,如果不正常,手機會直接重新啟動。 +::: + +## 手動修改核心原始碼 {#modify-kernel-source-code} + +如果 kprobe 無法正常運作 (可能是上游的錯誤或核心版本過低),那您可以嘗試這種方法: + +首先,將 KernelSU 新增至您的原始碼樹狀結構,再核心的根目錄執行以下命令: + +```sh +curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash - +``` + +然後,手動修改核心原始碼,您可以參閱下方的 patch: + +```diff +diff --git a/fs/exec.c b/fs/exec.c +index ac59664eaecf..bdd585e1d2cc 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1890,11 +1890,14 @@ static int __do_execve_file(int fd, struct filename *filename, + return retval; + } + ++extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, ++ void *envp, int *flags); + static int do_execveat_common(int fd, struct filename *filename, + struct user_arg_ptr argv, + struct user_arg_ptr envp, + int flags) + { ++ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); + return __do_execve_file(fd, filename, argv, envp, flags, NULL); + } + +diff --git a/fs/open.c b/fs/open.c +index 05036d819197..965b84d486b8 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -348,6 +348,8 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) + return ksys_fallocate(fd, mode, offset, len); + } + ++extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, ++ int *flags); + /* + * access() needs to use the real uid/gid, not the effective uid/gid. + * We do this by temporarily clearing all FS-related capabilities and +@@ -355,6 +357,7 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) + */ + long do_faccessat(int dfd, const char __user *filename, int mode) + { ++ ksu_handle_faccessat(&dfd, &filename, &mode, NULL); + const struct cred *old_cred; + struct cred *override_cred; + struct path path; +diff --git a/fs/read_write.c b/fs/read_write.c +index 650fc7e0f3a6..55be193913b6 100644 +--- a/fs/read_write.c ++++ b/fs/read_write.c +@@ -434,10 +434,14 @@ ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos) + } + EXPORT_SYMBOL(kernel_read); + ++extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, ++ size_t *count_ptr, loff_t **pos); + ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) + { + ssize_t ret; + ++ ksu_handle_vfs_read(&file, &buf, &count, &pos); ++ + if (!(file->f_mode & FMODE_READ)) + return -EBADF; + if (!(file->f_mode & FMODE_CAN_READ)) +diff --git a/fs/stat.c b/fs/stat.c +index 376543199b5a..82adcef03ecc 100644 +--- a/fs/stat.c ++++ b/fs/stat.c +@@ -148,6 +148,8 @@ int vfs_statx_fd(unsigned int fd, struct kstat *stat, + } + EXPORT_SYMBOL(vfs_statx_fd); + ++extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); ++ + /** + * vfs_statx - Get basic and extra attributes by filename + * @dfd: A file descriptor representing the base dir for a relative filename +@@ -170,6 +172,7 @@ int vfs_statx(int dfd, const char __user *filename, int flags, + int error = -EINVAL; + unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT; + ++ ksu_handle_stat(&dfd, &filename, &flags); + if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | + AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0) + return -EINVAL; +``` + +主要修改四個項目: + +1. do_faccessat,通常位於 `fs/open.c` +2. do_execveat_common,通常位於 `fs/exec.c` +3. vfs_read,通常位於 `fs/read_write.c` +4. vfs_statx,通常位於 `fs/stat.c` + +如果您的核心沒有 `vfs_statx`,使用 `vfs_fstatat` 將其取代: + +```diff +diff --git a/fs/stat.c b/fs/stat.c +index 068fdbcc9e26..5348b7bb9db2 100644 +--- a/fs/stat.c ++++ b/fs/stat.c +@@ -87,6 +87,8 @@ int vfs_fstat(unsigned int fd, struct kstat *stat) + } + EXPORT_SYMBOL(vfs_fstat); + ++extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); ++ + int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat, + int flag) + { +@@ -94,6 +96,8 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat, + int error = -EINVAL; + unsigned int lookup_flags = 0; + ++ ksu_handle_stat(&dfd, &filename, &flag); ++ + if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | + AT_EMPTY_PATH)) != 0) + goto out; +``` + +對於早於 4.17 的核心,如果沒有 `do_faccessat`,可以直接找到 `faccessat` 系統呼叫的定義並進行修改: + +```diff +diff --git a/fs/open.c b/fs/open.c +index 2ff887661237..e758d7db7663 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -355,6 +355,9 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) + return error; + } + ++extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, ++ int *flags); ++ + /* + * access() needs to use the real uid/gid, not the effective uid/gid. + * We do this by temporarily clearing all FS-related capabilities and +@@ -370,6 +373,8 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) + int res; + unsigned int lookup_flags = LOOKUP_FOLLOW; + ++ ksu_handle_faccessat(&dfd, &filename, &mode, NULL); ++ + if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ + return -EINVAL; +``` + +若要啟用 KernelSU 內建的安全模式,您還需要修改 `drivers/input/input.c` 中的 `input_handle_event` 方法: + +:::tip +強烈建議啟用此功能,如果遇到開機迴圈,這將會非常有用! +::: + +```diff +diff --git a/drivers/input/input.c b/drivers/input/input.c +index 45306f9ef247..815091ebfca4 100755 +--- a/drivers/input/input.c ++++ b/drivers/input/input.c +@@ -367,10 +367,13 @@ static int input_get_disposition(struct input_dev *dev, + return disposition; + } + ++extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); ++ + static void input_handle_event(struct input_dev *dev, + unsigned int type, unsigned int code, int value) + { + int disposition = input_get_disposition(dev, type, code, &value); ++ ksu_handle_input_handle_event(&type, &code, &value); + + if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) + add_input_randomness(type, code, value); +``` + +最後,再次建置您的核心,KernelSU 將會如期運作。 diff --git a/website/docs/zh_TW/guide/installation.md b/website/docs/zh_TW/guide/installation.md new file mode 100644 index 00000000..c0944a65 --- /dev/null +++ b/website/docs/zh_TW/guide/installation.md @@ -0,0 +1,169 @@ +# 安裝 {#title} + +## 檢查您的裝置是否受支援 {#check-if-supported} + +從 [GitHub Releases](https://github.com/tiann/KernelSU/releases) 或 [酷安](https://www.coolapk.com/apk/me.weishu.kernelsu) 下載 KernelSU 管理員應用程式,然後將應用程式安裝至裝置並開啟: + +- 如果應用程式顯示「不支援」,則表示您的裝置不支援 KernelSU,您需要自行編譯核心才能繼續使用,,KernelSU 官方也永遠不會為您提供一個可以刷新的 Boot 映像。 +- 如果應用程式顯示「未安裝」,那麼 KernelSU 支援您的裝置;可以進行下一步作業。 + +:::info +對於顯示「不支援」的裝置,這裡有一個[非官方支援裝置清單](unofficially-support-devices.md),您可以使用這個清單裡的核心自行編譯。 +::: + +## 備份您的原廠 boot.img {#backup-boot-image} + +在進行刷新作業前,您必須預先備份您的原廠 boot.img。如果您在後續刷新作業中出現了任何問題,您都可以透過使用 Fastboot 刷新回到原廠 Boot 以還原系統。 + +::: warning +刷新作業可能會造成資料遺失,請確保做好這一步再繼續進行下一步作業!!必要時您還可以備份您手機的所有資料。 +::: + +## 必要知識 {#acknowage} + +### ADB 和 Fastboot {#adb-and-fastboot} + +預設狀況下,您將會使用 ADB 和 Fastboot 工具,如果您不知道它們,建議使用搜尋引擎先瞭解相關內容。 + +### KMI + +KMI 全稱 Kernel Module Interface,相同 KMI 的核心版本是**相容的** 這也是 GKI 中「標準」的涵義所在;反之,如果 KMI 不同,那麼這些核心之間無法彼此相容,刷新與您裝置 KMI 不同的核心映像可能會導致開機迴圈。 + +具體來講,對 GKI 的裝置,其核心版本格式應該如下: + +```txt +KernelRelease := +Version.PatchLevel.SubLevel-AndroidRelease-KmiGeneration-suffix +w .x .y -zzz -k -something +``` + +其中,`w.x-zzz-k` 為 KMI 版本。例如,一部裝置核心版本為 `5.10.101-android12-9-g30979850fc20`,那麼它的 KMI 為 `5.10-android12-9`;理論上刷新其他這個 KMI 的核心也能正常開機。 + +::: tip +請注意,核心版本中的 SubLevel 並非 KMI 的一部分!也就是說 `5.10.101-android12-9-g30979850fc20` 與 `5.10.137-android12-9-g30979850fc20` 的 KMI 相同! +::: + +### 核心版本與 Android 版本 {#kernel-version-vs-android-version} + +請注意:**核心版本與 Android 版本並不一定相同!** + +如果您發現您的核心版本是 `android12-5.10.101`,然而您 Android 系統的版本為 Android 13 或者其他;請不要覺得奇怪,因為 Android 系統的版本與 Linux 核心的版本號碼並非一致;Linux 核心的版本號碼一般與**裝置出廠時隨附的 Android 系統的版本一致**,如果後續 Android 系統更新,核心版本一般不會發生變化。如果您需要刷新,**請以核心版本為準!!** + +## 安裝簡介 {#installation-introduction} + +KernelSU 的安裝方法有以下幾種,各自適用於不同的場景,請視需要選擇: + +1. 使用自訂 Recovery (如 TWRP) 安裝 +2. 使用核心刷新應用程式 (例如 Franco Kernel Manager) 安裝 +3. 使用 KernelSU 提供的 boot.img 透過 Fastboot 安裝 +4. 手動修補 boot.img 並安裝 + +## 使用自訂 Recovery 安裝 {#install-by-recovery} + +先決條件:您的裝置必須有自訂的 Recovery,例如 TWRP;如果沒有或者只有官方 Recovery,請使用其他方法。 + +步驟: + +1. 在 KernelSU 的 [Release 頁面](https://github.com/tiann/KernelSU/releases) 下載與您手機版本相符的以 AnyKernel3 開頭的 Zip 套件;例如,手機核心版本為 `android12-5.10.66`,那麼您應該下載 `AnyKernel3-android12-5.10.66_yyyy-MM.zip` 這個檔案 (其中 `yyyy` 為年份,`MM` 為月份)。 +2. 重新開機手機至 TWRP。 +3. 使用 Adb 將 AnyKernel3-*.zip 放置到手機 /sdcard 然後在 TWRP 圖形使用者介面選擇並安裝;或者您也可以直接 `adb sideload AnyKernel-*.zip` 安裝。 + +PS. 這種方法適用於任何狀況下的安裝 (不限於初次安裝或後續更新),只要您用 TWRP 就可以進行作業。 + +## 使用核心刷新應用程式安裝 {#install-by-kernel-flasher} + +先決條件:您的裝置必須已經 Root。例如您已經安裝了 Magisk 並取得 Root 存取權,或者您已經安裝了舊版本的 KernelSU 需升級到其他版本的 KernelSU;如果您的裝置並未 Root,請嘗試其他方法。 + +步驟: + +1. 下載 AnyKernel3 的 Zip 檔案;請參閱 *使用自訂 Recovery 安裝* 章節的内容。 +2. 開啟核心刷新應用程式提供的 AnyKernel3 Zip 檔案進行刷新。 + +如果您先前並未使用過核心刷新應用程式,可以嘗試下面幾個方法: + +1. [Kernel Flasher](https://github.com/capntrips/KernelFlasher/releases) +2. [Franco Kernel Manager](https://play.google.com/store/apps/details?id=com.franco.kernel) +3. [Ex Kernel Manager](https://play.google.com/store/apps/details?id=flar2.exkernelmanager) + +PS. 這種方法在更新 KernelSU 時比較方便,無需電腦即可完成 (注意備份!)。 + +## 使用 KernelSU 提供的 boot.img 安裝 {#install-by-kernelsu-boot-image} + +這種方法無需您有 TWRP,也無需您的手機有 Root 權限;適用於您初次安裝 KernelSU。 + +### 找到合適的 boot.img {#found-propery-image} + +KernelSU 為 GKI 裝置提供了標準 boot.img,您需要將 boot.img 刷新至裝置的 Boot 分割區。 + +您可以從 [GitHub Release](https://github.com/tiann/KernelSU/releases) 下載 boot.img,請注意,您應該使用正確版本的 boot.img。例如,如果您的裝置顯示核心是 `android12-5.10.101`,需要下載 `android-5.10.101_yyyy-MM.boot-.img`. + +其中 `` 指的是您的官方 boot.img 的核心壓縮格式,請檢查您原有 boot.img 的核心壓縮格式,您應該使用正確的格式,例如 `lz4`、`gz`;如果使用不正確的壓縮格式,刷新 Boot 後可能無法開機。 + +::: info +1. 您可以透過 magiskboot 以取得您的原始 Boot 的壓縮格式;當然,您也可以詢問與您相同型號的其他更有經驗的使用者。另外,核心的壓縮格式通常部會出現變更,如果您使用的某個壓縮格式成功開機,後續可以優先嘗試這個格式。 +2. 小米裝置通常 `gz` 或者 **不壓縮**。 +3. Pixel 裝置有些特殊,請遵循下方的指示。 +::: + +### 將 boot.img 刷新至裝置 {#flash-boot-image} + +使用 `adb` 連接您的裝置,然後執行 `adb reboot bootloader` 進入 fastboot 模式,然後使用此命令刷新 KernelSU: + +```sh +fastboot flash boot boot.img +``` + +::: info +如果您的裝置支援 `fastboot boot`,可以先使用 `fastboot boot boot.img` 來先嘗試使用 boot.img 開機進入系統,如果出現意外,重新啟動即可開機。 +::: + +### 重新開機 {#reboot} + +刷新完成後,您應該重新啟動您的裝置: + +```sh +fastboot reboot +``` + +## 手動修補 boot.img {#patch-boot-image} + +對於某些裝置來說,其 boot.img 格式並不是很常見,比如 `lz4`,`gz` 和未壓縮;最典型的就是 Pixel,它的 boot.img 格式是 `lz4_legacy` 壓縮,ramdisk 可能是 `gz` 也可能是 `lz4_legacy` 壓縮;此時如果您直接刷新 KernelSU 提供的 boot.img,手機可能無法開機;這時,您可以透過手動修補 boot.img 來完成。 + +一般有兩種修補方法: + +1. [Android-Image-Kitchen](https://forum.xda-developers.com/t/tool-android-image-kitchen-unpack-repack-kernel-ramdisk-win-android-linux-mac.2073775/) +2. [magiskboot](https://github.com/topjohnwu/Magisk/releases) + +其中,Android-Image-Kitchen 適用於在電腦上作業,magiskboot 需要手機協作。 + +### 準備 {#patch-preparation} + +1. 取得您手機的原廠 boot.img;您可以聯絡您的裝置製造商,您也可能需要[payload-dumper-go](https://github.com/ssut/payload-dumper-go) +2. 下載 KernelSU 提供的與您的裝置 KMI 一致地 AnyKernel3 Zip 檔案 (可參閱 *使用自訂 Recovery 安裝*)。 +3. 解壓縮 AnyKernel3 Zip 檔案,取得其中的 `Image` 檔案,此檔案為 KernelSU 的核心檔案。 + +### 使用 Android-Image-Kitchen {#using-android-image-kitchen} + +1. 下載 Android-Image-Kitchen 至您的電腦。 +2. 將手機原廠 boot.img 放置於 Android-Image-Kitchen 根目錄。 +3. 在 Android-Image-Kitchen 根目錄執行 `./unpackimg.sh boot.img`;此命令會將 boot.img 解除封裝,您會得到一些檔案。 +4. 將 `split_img` 目錄中的 `boot.img-kernel` 取代為您從 AnyKernel3 解壓縮出來的 `Image` (注意名稱變更為 boot.img-kernel)。 +5. 在 Android-Image-Kitchecn 根目錄執行 `./repackimg.sh`;此時您會得到一個 `image-new.img` 檔案;使用此 boot.img 透過 fastboot 刷新即可 (刷新方法請參閱上一章節)。 + +### 使用 magiskboot {#using magiskboot} + +1. 在 Magisk 的 [Release 頁面](https://github.com/topjohnwu/Magisk/releases) 下載最新的 Magisk 安裝套件。 +2. 將 Magisk-*.apk 重新命名為 Magisk-vesion.zip 然後解壓縮。 +3. 將解壓縮後的 `Magisk-v25.2/lib/arm64-v8a/libmagiskboot.so` 檔案,使用 Adb 推入至手機:`adb push Magisk-v25.2/lib/arm64-v8a/libmagiskboot.so /data/local/tmp/magiskboot` +4. 使用 Adb 將原廠 boot.img 和 AnyKernel3 中的 Image 推入至手機。 +5. adb shell 進入 /data/local/tmp/ 目錄,然後賦予先前推入檔案的可執行權限 `chmod +x magiskboot` +6. adb shell 進入 /data/local/tmp/ 目錄,執行 `./magiskboot unpack boot.img` 此時會將 `boot.img` 解除封裝,得到一個名為 `kernel` 的檔案,這個檔案是您的原廠核心。 +7. 使用 `Image` 取代 `kernel`: `mv -f Image kernel` +8. 執行 `./magiskboot repack boot.img` 重新封裝 img,此時您會得到一個 `new-boot.img` 檔案,透過 Fastboot 將這個檔案刷新至裝置即可。 + +## 其他替代方法 {#other-methods} + +其實所有這些安裝方法的主旨只有一個,那就是**將原廠核心取代為 KernelSU 提供的核心**;只要能實現這個目的,就可以安裝;比如以下是其他可行的方法: + +1. 首先安裝 Magisk,透過 Magisk 取得 Root 權限後使用核心刷新程式刷新 KernelSU 的 AnyKernel Zip。 +2. 使用某些 PC 上的刷新工具組刷新 KernelSU 提供的核心。 diff --git a/website/docs/zh_TW/guide/module.md b/website/docs/zh_TW/guide/module.md new file mode 100644 index 00000000..2412df21 --- /dev/null +++ b/website/docs/zh_TW/guide/module.md @@ -0,0 +1,262 @@ +# 模組指南 {#introduction} + +KernelSU 提供了一個模組機制,它可以在保持系統分割區完整性的同時達到修改系統分割區的效果;這種機制一般被稱為 systemless。 + +KernelSU 的模組運作機制與 Magisk 幾乎相同,如果您熟悉 Magisk 模組的開發,那麼開發 KernelSU 的模組大同小異,您可以跳過下列有關模組的介紹,只需要瞭解 [KernelSU 模組與 Magisk 模組的異同](difference-with-magisk.md)。 + +## Busybox + +KernelSU 提供了一個完備的 BusyBox 二進位檔案 (包括完整的 SELinux 支援)。可執行檔位於 `/data/adb/ksu/bin/busybox`。 +KernelSU 的 BusyBox 支援同時執行時可切換的 "ASH Standalone Shell Mode"。 +這種讀了模式意味著在執行 BusyBox 的 ash shell 時,每個命令都會直接使用 BusyBox 中內建的應用程式,而不論 PATH 的設定為何。 +例如,`ls`、`rm`、`chmod` 等命令將不會使用 PATH 中設定的命令 (在 Android 的狀況下,預設狀況下分別為 `/system/bin/ls`、`/system/bin/rm` 和 `/system/bin/chmod`),而是直接呼叫 BusyBox 內建的應用程式。 +這確保了指令碼始終在可預測的環境中執行,並始終具有完整的命令套件,不論它執行在哪個 Android 版本上。 +要強制下一個命令不使用 BusyBox,您必須使用完整路徑呼叫可執行檔。 + +在 KernelSU 上下文中執行的每個 shell 指令碼都將在 BusyBox 的 ash shell 中以獨立模式執行。對於第三方開發人員相關的內容,包括所有開機指令碼和模組安裝指令碼。 + +對於想要在 KernelSU 之外使用這個「獨立模式」功能的使用者,有兩種啟用方法: + +1. 將環境變數 `ASH_STANDALONE` 設為 `1`。例如:`ASH_STANDALONE=1 /data/adb/ksu/bin/busybox sh + + + + + + + + + + + + + + + + +
維護者存放庫支援裝置
{{ repo.maintainer }}{{ repo.kernel_name }}{{ repo.devices }}
\ No newline at end of file diff --git a/website/docs/zh_TW/guide/what-is-kernelsu.md b/website/docs/zh_TW/guide/what-is-kernelsu.md new file mode 100644 index 00000000..4d1bce75 --- /dev/null +++ b/website/docs/zh_TW/guide/what-is-kernelsu.md @@ -0,0 +1,21 @@ +# 什麼是 KernelSU? {#introduction} + +KernelSU 是 Android GKI 裝置的 Root 解決方案,它以核心模式運作,並直接在核心空間中為使用者空間應用程式授予 Root 權限。 + +## 功能 {#features} + +KernelSU 的主要功能是它是**以核心為基礎的**。 KernelSU 在核心空間中執行,所以它可以向我們提供從未有過的核心介面。例如,我們可以在核心模式中為任何處理程序新增硬體中斷點;我們可以在任何處理程序的實體記憶體中存取,而無人知曉;我們可以在核心空間攔截任何系統呼叫;等等。 + +KernelSU 還提供了一個以 overlayfs 為基礎的模組系統,允許您將自訂外掛程式載入到系統中。它還提供了一種修改 /system 分割區中檔案的機制。 + +## 如何使用 {#how-to-use} + +請參閱:[安裝](installation) + +## 如何建置 {#how-to-build} + +请參閱:[如何建置](how-to-build) + +## 討論 {#discussion} + +- Telegram: [@KernelSU](https://t.me/KernelSU) diff --git a/website/docs/zh_TW/index.md b/website/docs/zh_TW/index.md new file mode 100644 index 00000000..65861eb0 --- /dev/null +++ b/website/docs/zh_TW/index.md @@ -0,0 +1,29 @@ +--- +layout: home +title: Android 上以核心為基礎的 Root 解決方案 + +hero: + name: KernelSU + text: Android 上以核心為基礎的 root 解決方案 + tagline: "" + image: + src: /logo.png + alt: KernelSU + actions: + - theme: brand + text: 開始瞭解 + link: /zh_TW/guide/what-is-kernelsu + - theme: alt + text: 在 GitHub 中檢視 + link: https://github.com/tiann/KernelSU + +features: + - title: 以核心為基礎 + details: KernelSU 以 Linux 核心模式運作,對使用者空間有更強的掌控。 + - title: 白名單存取控制 + details: 僅有被授予 Root 權限的應用程式才可存取 `su`,而其他應用程式完全無法知悉。 + - title: 模組支援 + details: KernelSU 支援透過 overlayfs 修改 /system,它甚至可以使 /system 可寫入。 + - title: 開放原始碼 + details: KernelSU 是 GPL-3 授權下的開放原始碼專案。 +