You've already forked KernelSU-Next
mirror of
https://github.com/KernelSU-Next/KernelSU-Next.git
synced 2025-08-27 23:46:34 +00:00
userspace: implement OSS ksuinit
This commit is contained in:
10
.github/dependabot.yml
vendored
10
.github/dependabot.yml
vendored
@@ -8,6 +8,16 @@ updates:
|
||||
actions:
|
||||
patterns:
|
||||
- "*"
|
||||
- package-ecosystem: cargo
|
||||
directory: userspace/ksuinit
|
||||
schedule:
|
||||
interval: daily
|
||||
allow:
|
||||
- dependency-type: "all"
|
||||
groups:
|
||||
crates:
|
||||
patterns:
|
||||
- "*"
|
||||
- package-ecosystem: cargo
|
||||
directory: userspace/ksud_magic
|
||||
schedule:
|
||||
|
||||
22
.github/workflows/build-manager-ci.yml
vendored
22
.github/workflows/build-manager-ci.yml
vendored
@@ -69,9 +69,22 @@ jobs:
|
||||
with:
|
||||
os: ${{ matrix.os }}
|
||||
|
||||
build-ksud:
|
||||
build-ksuinit:
|
||||
needs: [check-cache, build-susfsd]
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- target: aarch64-linux-android
|
||||
os: ubuntu-latest
|
||||
uses: ./.github/workflows/ksuinit.yml
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
os: ${{ matrix.os }}
|
||||
|
||||
build-ksud:
|
||||
needs: [check-cache, build-ksuinit]
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@@ -97,6 +110,13 @@ jobs:
|
||||
name: susfsd-linux-android
|
||||
path: cached-artifacts/susfsd
|
||||
|
||||
- name: Download ksuinit artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: ksuinit-aarch64-linux-android
|
||||
path: cached-artifacts/ksuinit
|
||||
merge-multiple: true
|
||||
|
||||
- name: Download ksud_overlayfs artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
|
||||
22
.github/workflows/build-manager-spoofed.yml
vendored
22
.github/workflows/build-manager-spoofed.yml
vendored
@@ -71,9 +71,22 @@ jobs:
|
||||
with:
|
||||
os: ${{ matrix.os }}
|
||||
|
||||
build-ksud:
|
||||
build-ksuinit:
|
||||
needs: [check-cache, build-susfsd]
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- target: aarch64-linux-android
|
||||
os: ubuntu-latest
|
||||
uses: ./.github/workflows/ksuinit.yml
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
os: ${{ matrix.os }}
|
||||
|
||||
build-ksud:
|
||||
needs: [check-cache, build-ksuinit]
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@@ -99,6 +112,13 @@ jobs:
|
||||
name: susfsd-linux-android
|
||||
path: cached-artifacts/susfsd
|
||||
|
||||
- name: Download ksuinit artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: ksuinit-aarch64-linux-android
|
||||
path: cached-artifacts/ksuinit
|
||||
merge-multiple: true
|
||||
|
||||
- name: Download ksud_overlayfs artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
|
||||
14
.github/workflows/build-manager.yml
vendored
14
.github/workflows/build-manager.yml
vendored
@@ -33,8 +33,20 @@ jobs:
|
||||
with:
|
||||
os: ${{ matrix.os }}
|
||||
|
||||
build-ksud:
|
||||
build-ksuinit:
|
||||
needs: build-susfsd
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- target: aarch64-linux-android
|
||||
os: ubuntu-latest
|
||||
uses: ./.github/workflows/ksuinit.yml
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
os: ${{ matrix.os }}
|
||||
|
||||
build-ksud:
|
||||
needs: build-ksuinit
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
|
||||
9
.github/workflows/clippy.yml
vendored
9
.github/workflows/clippy.yml
vendored
@@ -6,6 +6,7 @@ on:
|
||||
- next
|
||||
paths:
|
||||
- '.github/workflows/clippy.yml'
|
||||
- 'userspace/ksuinit/**'
|
||||
- 'userspace/ksud_magic/**'
|
||||
- 'userspace/ksud_overlayfs/**'
|
||||
pull_request:
|
||||
@@ -13,6 +14,7 @@ on:
|
||||
- next
|
||||
paths:
|
||||
- '.github/workflows/clippy.yml'
|
||||
- 'userspace/ksuinit/**'
|
||||
- 'userspace/ksud_magic/**'
|
||||
- 'userspace/ksud_overlayfs/**'
|
||||
|
||||
@@ -32,6 +34,11 @@ jobs:
|
||||
- name: Setup Cross
|
||||
run: RUSTFLAGS="" cargo install cross
|
||||
|
||||
- name: Cache ksuinit
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: userspace/ksuinit
|
||||
|
||||
- name: Cache ksud_overlayfs
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
@@ -44,6 +51,8 @@ jobs:
|
||||
|
||||
- name: Run Clippy
|
||||
run: |
|
||||
cross clippy --manifest-path userspace/ksuinit/Cargo.toml --target aarch64-linux-android --release
|
||||
|
||||
cross clippy --manifest-path userspace/ksud_magic/Cargo.toml --target aarch64-linux-android --release
|
||||
cross clippy --manifest-path userspace/ksud_overlayfs/Cargo.toml --target aarch64-linux-android --release
|
||||
|
||||
|
||||
13
.github/workflows/ksud.yml
vendored
13
.github/workflows/ksud.yml
vendored
@@ -39,16 +39,17 @@ jobs:
|
||||
run: |
|
||||
cp susfsd-linux-android/arm64-v8a/susfsd ./userspace/ksud_overlayfs/bin/aarch64/
|
||||
cp susfsd-linux-android/arm64-v8a/susfsd ./userspace/ksud_magic/bin/aarch64/
|
||||
cp susfsd-linux-android/armeabi-v7a/susfsd ./userspace/ksud_overlayfs/bin/arm/
|
||||
cp susfsd-linux-android/armeabi-v7a/susfsd ./userspace/ksud_magic/bin/arm/
|
||||
cp susfsd-linux-android/x86_64/susfsd ./userspace/ksud_overlayfs/bin/x86_64/
|
||||
cp susfsd-linux-android/x86_64/susfsd ./userspace/ksud_magic/bin/x86_64/
|
||||
|
||||
- name: Import ksuinit Binaries
|
||||
run: |
|
||||
cp ksuinit-aarch64-linux-android/aarch64-linux-android/release/ksuinit ./userspace/ksud_overlayfs/bin/aarch64/
|
||||
cp ksuinit-aarch64-linux-android/aarch64-linux-android/release/ksuinit ./userspace/ksud_magic/bin/aarch64/
|
||||
|
||||
- name: Setup Rust
|
||||
run: |
|
||||
rustup update stable
|
||||
rustup target add x86_64-apple-darwin
|
||||
rustup target add aarch64-apple-darwin
|
||||
rustup target add x86_64-linux-android
|
||||
rustup target add aarch64-linux-android
|
||||
|
||||
- name: Cache ksud_overlayfs
|
||||
uses: Swatinem/rust-cache@v2
|
||||
|
||||
57
.github/workflows/ksuinit.yml
vendored
Normal file
57
.github/workflows/ksuinit.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: Build ksuinit
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
target:
|
||||
required: true
|
||||
type: string
|
||||
os:
|
||||
required: false
|
||||
type: string
|
||||
default: ubuntu-latest
|
||||
pack_lkm:
|
||||
required: false
|
||||
type: boolean
|
||||
default: true
|
||||
use_cache:
|
||||
required: false
|
||||
type: boolean
|
||||
default: true
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ inputs.os }}
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Rust
|
||||
run: |
|
||||
rustup update stable
|
||||
rustup target add aarch64-linux-android
|
||||
|
||||
- name: Set Rust & Android linker
|
||||
run: |
|
||||
TOOLCHAIN="$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64"
|
||||
if [ ! -d "$TOOLCHAIN" ]; then
|
||||
echo "Android NDK not found at $ANDROID_NDK"
|
||||
exit 1
|
||||
fi
|
||||
echo "CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=$TOOLCHAIN/bin/aarch64-linux-android21-clang" >> $GITHUB_ENV
|
||||
|
||||
- name: Cache ksuinit
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: userspace/ksuinit
|
||||
cache-targets: false
|
||||
|
||||
- name: Build ksuinit
|
||||
run: |
|
||||
cargo build --target ${{ inputs.target }} --release --manifest-path ./userspace/ksuinit/Cargo.toml
|
||||
|
||||
- name: Upload ksuinit artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ksuinit-${{ inputs.target }}
|
||||
path: userspace/ksuinit/target/**/release/ksuinit
|
||||
7
.github/workflows/rustfmt.yml
vendored
7
.github/workflows/rustfmt.yml
vendored
@@ -6,6 +6,7 @@ on:
|
||||
- 'next'
|
||||
paths:
|
||||
- '.github/workflows/rustfmt.yml'
|
||||
- 'userspace/ksuinit/**'
|
||||
- 'userspace/ksud_magic/**'
|
||||
- 'userspace/ksud_overlayfs/**'
|
||||
pull_request:
|
||||
@@ -13,6 +14,7 @@ on:
|
||||
- 'next'
|
||||
paths:
|
||||
- '.github/workflows/rustfmt.yml'
|
||||
- 'userspace/ksuinit/**'
|
||||
- 'userspace/ksud_magic/**'
|
||||
- 'userspace/ksud_overlayfs/**'
|
||||
|
||||
@@ -29,6 +31,11 @@ jobs:
|
||||
with:
|
||||
components: rustfmt
|
||||
|
||||
- uses: LoliGothick/rustfmt-check@master
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
working-directory: userspace/ksuinit
|
||||
|
||||
- uses: LoliGothick/rustfmt-check@master
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
|
||||
8
build.sh
8
build.sh
@@ -6,6 +6,14 @@
|
||||
|
||||
# For LKM make sure you have imported the androidX-X.X_kernelsu.ko drivers to userspace/ksud_*/bin/aarch64 directory.
|
||||
|
||||
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="aarch64-linux-android21-clang"
|
||||
|
||||
cross build --target aarch64-linux-android --release --manifest-path ./userspace/ksuinit/Cargo.toml
|
||||
|
||||
cp userspace/ksuinit/target/aarch64-linux-android/release/ksuinit userspace/ksud_magic/bin/aarch64/ksuinit
|
||||
|
||||
cp userspace/ksuinit/target/aarch64-linux-android/release/ksuinit userspace/ksud_overlayfs/bin/aarch64/ksuinit
|
||||
|
||||
cross build --target aarch64-linux-android --release --manifest-path ./userspace/ksud_magic/Cargo.toml
|
||||
|
||||
cp userspace/ksud_magic/target/aarch64-linux-android/release/ksud manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
|
||||
|
||||
@@ -81,35 +81,6 @@ import com.rifsxd.ksunext.ui.util.rootAvailable
|
||||
@Destination<RootGraph>
|
||||
@Composable
|
||||
fun InstallScreen(navigator: DestinationsNavigator) {
|
||||
var showLkmWarning by rememberSaveable { mutableStateOf(true) }
|
||||
|
||||
if (showLkmWarning) {
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
showLkmWarning = false
|
||||
navigator.popBackStack()
|
||||
},
|
||||
title = { Text(
|
||||
text = stringResource(R.string.warning),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.SemiBold
|
||||
) },
|
||||
text = { Text(stringResource(R.string.lkm_warning_message)) },
|
||||
confirmButton = {
|
||||
TextButton(onClick = { showLkmWarning = false }) {
|
||||
Text(stringResource(R.string.proceed))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = {
|
||||
showLkmWarning = false
|
||||
navigator.popBackStack()
|
||||
}) {
|
||||
Text(stringResource(R.string.cancel))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var installMethod by remember {
|
||||
mutableStateOf<InstallMethod?>(null)
|
||||
|
||||
3
userspace/ksud_magic/bin/.gitignore
vendored
3
userspace/ksud_magic/bin/.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
**/*.ko
|
||||
susfsd
|
||||
susfsd
|
||||
ksuinit
|
||||
3
userspace/ksud_overlayfs/bin/.gitignore
vendored
3
userspace/ksud_overlayfs/bin/.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
**/*.ko
|
||||
susfsd
|
||||
susfsd
|
||||
ksuinit
|
||||
1
userspace/ksuinit/.gitignore
vendored
Normal file
1
userspace/ksuinit/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
target
|
||||
227
userspace/ksuinit/Cargo.lock
generated
Normal file
227
userspace/ksuinit/Cargo.lock
generated
Normal file
@@ -0,0 +1,227 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "goblin"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/tiann/goblin#138d40d4c36471cfbb611eb493f0378ee9fc63f5"
|
||||
dependencies = [
|
||||
"log",
|
||||
"plain",
|
||||
"scroll",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernlog"
|
||||
version = "0.3.1"
|
||||
source = "git+https://github.com/tiann/kernlog.rs#ff0b1bd6d5261eae0fa297cec6951fe8d982151a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ksuinit"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"goblin",
|
||||
"kernlog",
|
||||
"log",
|
||||
"obfstr",
|
||||
"rustix",
|
||||
"scroll",
|
||||
"syscalls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "obfstr"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3ba2979b86cc910a6d13837ef97fef0c6b68fa807c5e014d622449db18351dc"
|
||||
|
||||
[[package]]
|
||||
name = "plain"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.34"
|
||||
source = "git+https://github.com/Kernel-SU/rustix.git?rev=4a53fbc#4a53fbc7cb7a07cabe87125cc21dbc27db316259"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scroll"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6"
|
||||
dependencies = [
|
||||
"scroll_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scroll_derive"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syscalls"
|
||||
version = "0.6.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56b389b38331a454883a34fd19f25cbd1510b3510ff7aa28cb8d6de85d888439"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
||||
34
userspace/ksuinit/Cargo.toml
Normal file
34
userspace/ksuinit/Cargo.toml
Normal file
@@ -0,0 +1,34 @@
|
||||
[package]
|
||||
name = "ksuinit"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
||||
# for elf parsing
|
||||
goblin = { git = "https://github.com/tiann/goblin" }
|
||||
scroll = "0.12"
|
||||
|
||||
anyhow = "1"
|
||||
# If you want to use the following dependencies, please use aarch64-unknown-linux-musl & x86_64-unknown-linux-musl to compile statically
|
||||
# rustix = { git = "https://github.com/bytecodealliance/rustix", rev = "7b44528", features = ["mount", "fs", "runtime", "system", "process"] }
|
||||
rustix = { git = "https://github.com/Kernel-SU/rustix.git", rev = "4a53fbc", features = ["mount", "fs", "runtime", "system", "process"] }
|
||||
|
||||
syscalls = { version = "0.6", default-features = false, features = [
|
||||
"aarch64",
|
||||
"x86_64",
|
||||
] }
|
||||
|
||||
# for kmsg logging
|
||||
log = "0.4"
|
||||
kernlog = { git = "https://github.com/tiann/kernlog.rs" }
|
||||
|
||||
obfstr = "0.4"
|
||||
|
||||
[profile.release]
|
||||
strip = true
|
||||
lto = true
|
||||
opt-level = "z"
|
||||
panic = "abort"
|
||||
185
userspace/ksuinit/src/init.rs
Normal file
185
userspace/ksuinit/src/init.rs
Normal file
@@ -0,0 +1,185 @@
|
||||
use std::io::{ErrorKind, Write};
|
||||
|
||||
use crate::loader::load_module;
|
||||
use anyhow::Result;
|
||||
use rustix::fs::{chmodat, symlink, unlink, AtFlags, Mode};
|
||||
use rustix::{
|
||||
fd::AsFd,
|
||||
fs::{access, makedev, mkdir, mknodat, Access, FileType, CWD},
|
||||
mount::{
|
||||
fsconfig_create, fsmount, fsopen, move_mount, unmount, FsMountFlags, FsOpenFlags,
|
||||
MountAttrFlags, MoveMountFlags, UnmountFlags,
|
||||
},
|
||||
};
|
||||
|
||||
use obfstr::obfstr as s;
|
||||
|
||||
struct AutoUmount {
|
||||
mountpoints: Vec<String>,
|
||||
}
|
||||
|
||||
impl Drop for AutoUmount {
|
||||
fn drop(&mut self) {
|
||||
for mountpoint in self.mountpoints.iter().rev() {
|
||||
if let Err(e) = unmount(mountpoint.as_str(), UnmountFlags::DETACH) {
|
||||
log::error!("{} {}: {}", s!("Cannot umount"), mountpoint, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare_mount() -> AutoUmount {
|
||||
let mut mountpoints = vec![];
|
||||
|
||||
// mount procfs
|
||||
let result = mkdir("/proc", Mode::from_raw_mode(0o755))
|
||||
.or_else(|err| match err.kind() {
|
||||
ErrorKind::AlreadyExists => Ok(()),
|
||||
_ => Err(err),
|
||||
})
|
||||
.and_then(|_| fsopen("proc", FsOpenFlags::FSOPEN_CLOEXEC))
|
||||
.and_then(|fd| fsconfig_create(fd.as_fd()).map(|_| fd))
|
||||
.and_then(|fd| {
|
||||
fsmount(
|
||||
fd.as_fd(),
|
||||
FsMountFlags::FSMOUNT_CLOEXEC,
|
||||
MountAttrFlags::empty(),
|
||||
)
|
||||
})
|
||||
.and_then(|fd| {
|
||||
move_mount(
|
||||
fd.as_fd(),
|
||||
"",
|
||||
CWD,
|
||||
"/proc",
|
||||
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
|
||||
)
|
||||
});
|
||||
match result {
|
||||
Ok(_) => mountpoints.push("/proc".to_string()),
|
||||
Err(e) => log::error!("{} {:?}", s!("Cannot mount procfs: "), e),
|
||||
}
|
||||
|
||||
// mount sysfs
|
||||
let result = mkdir("/sys", Mode::from_raw_mode(0o755))
|
||||
.or_else(|err| match err.kind() {
|
||||
ErrorKind::AlreadyExists => Ok(()),
|
||||
_ => Err(err),
|
||||
})
|
||||
.and_then(|_| fsopen("sysfs", FsOpenFlags::FSOPEN_CLOEXEC))
|
||||
.and_then(|fd| fsconfig_create(fd.as_fd()).map(|_| fd))
|
||||
.and_then(|fd| {
|
||||
fsmount(
|
||||
fd.as_fd(),
|
||||
FsMountFlags::FSMOUNT_CLOEXEC,
|
||||
MountAttrFlags::empty(),
|
||||
)
|
||||
})
|
||||
.and_then(|fd| {
|
||||
move_mount(
|
||||
fd.as_fd(),
|
||||
"",
|
||||
CWD,
|
||||
"/sys",
|
||||
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
|
||||
)
|
||||
});
|
||||
|
||||
match result {
|
||||
Ok(_) => mountpoints.push("/sys".to_string()),
|
||||
Err(e) => log::error!("{} {:?}", s!("Cannot mount sysfs:"), e),
|
||||
}
|
||||
|
||||
AutoUmount { mountpoints }
|
||||
}
|
||||
|
||||
fn setup_kmsg() {
|
||||
const KMSG: &str = "/dev/kmsg";
|
||||
let device = match access(KMSG, Access::EXISTS) {
|
||||
Ok(_) => KMSG,
|
||||
Err(_) => {
|
||||
// try to create it
|
||||
mknodat(
|
||||
CWD,
|
||||
"/kmsg",
|
||||
FileType::CharacterDevice,
|
||||
0o666.into(),
|
||||
makedev(1, 11),
|
||||
)
|
||||
.ok();
|
||||
"/kmsg"
|
||||
}
|
||||
};
|
||||
|
||||
let _ = kernlog::init_with_device(device);
|
||||
}
|
||||
|
||||
fn unlimit_kmsg() {
|
||||
// Disable kmsg rate limiting
|
||||
if let Ok(mut rate) = std::fs::File::options()
|
||||
.write(true)
|
||||
.open(s!("/proc/sys/kernel/printk_devkmsg"))
|
||||
{
|
||||
writeln!(rate, "on").ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init() -> Result<()> {
|
||||
// Setup kernel log first
|
||||
setup_kmsg();
|
||||
|
||||
log::info!("{}", s!("Hello, KernelSU!"));
|
||||
|
||||
// mount /proc and /sys to access kernel interface
|
||||
let _dontdrop = prepare_mount();
|
||||
|
||||
// This relies on the fact that we have /proc mounted
|
||||
unlimit_kmsg();
|
||||
|
||||
if has_kernelsu() {
|
||||
log::info!("{}", s!("KernelSU may be already loaded in kernel, skip!"));
|
||||
} else {
|
||||
log::info!("{}", s!("Loading kernelsu.ko.."));
|
||||
if let Err(e) = load_module(s!("/kernelsu.ko")) {
|
||||
log::error!("{}: {}", s!("Cannot load kernelsu.ko"), e);
|
||||
}
|
||||
}
|
||||
|
||||
// And now we should prepare the real init to transfer control to it
|
||||
unlink("/init")?;
|
||||
|
||||
let real_init = match access("/init.real", Access::EXISTS) {
|
||||
Ok(_) => "init.real",
|
||||
Err(_) => "/system/bin/init",
|
||||
};
|
||||
|
||||
log::info!("{} {}", s!("init is"), real_init);
|
||||
symlink(real_init, "/init")?;
|
||||
|
||||
chmodat(
|
||||
CWD,
|
||||
"/init",
|
||||
Mode::from_raw_mode(0o755),
|
||||
AtFlags::SYMLINK_NOFOLLOW,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn has_kernelsu() -> bool {
|
||||
use syscalls::{syscall, Sysno};
|
||||
let mut version = 0;
|
||||
const CMD_GET_VERSION: i32 = 2;
|
||||
unsafe {
|
||||
let _ = syscall!(
|
||||
Sysno::prctl,
|
||||
0xDEADBEEF,
|
||||
CMD_GET_VERSION,
|
||||
std::ptr::addr_of_mut!(version)
|
||||
);
|
||||
}
|
||||
|
||||
log::info!("{}: {}", s!("KernelSU version"), version);
|
||||
|
||||
version != 0
|
||||
}
|
||||
97
userspace/ksuinit/src/loader.rs
Normal file
97
userspace/ksuinit/src/loader.rs
Normal file
@@ -0,0 +1,97 @@
|
||||
use anyhow::{Context, Result};
|
||||
use goblin::elf::{section_header, sym::Sym, Elf};
|
||||
use rustix::{cstr, system::init_module};
|
||||
use scroll::{ctx::SizeWith, Pwrite};
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
|
||||
use obfstr::obfstr as s;
|
||||
|
||||
struct Kptr {
|
||||
value: String,
|
||||
}
|
||||
|
||||
impl Kptr {
|
||||
pub fn new() -> Result<Self> {
|
||||
let value = fs::read_to_string(s!("/proc/sys/kernel/kptr_restrict"))?;
|
||||
fs::write(s!("/proc/sys/kernel/kptr_restrict"), "1")?;
|
||||
Ok(Kptr { value })
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Kptr {
|
||||
fn drop(&mut self) {
|
||||
let _ = fs::write(s!("/proc/sys/kernel/kptr_restrict"), self.value.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_kallsyms() -> Result<HashMap<String, u64>> {
|
||||
let _dontdrop = Kptr::new()?;
|
||||
|
||||
let allsyms = fs::read_to_string(s!("/proc/kallsyms"))?
|
||||
.lines()
|
||||
.map(|line| line.split_whitespace())
|
||||
.filter_map(|mut splits| {
|
||||
splits
|
||||
.next()
|
||||
.and_then(|addr| u64::from_str_radix(addr, 16).ok())
|
||||
.and_then(|addr| splits.nth(1).map(|symbol| (symbol, addr)))
|
||||
})
|
||||
.map(|(symbol, addr)| {
|
||||
(
|
||||
symbol
|
||||
.find("$").or_else(|| symbol.find(".llvm."))
|
||||
.map_or(symbol, |pos| &symbol[0..pos])
|
||||
.to_owned(),
|
||||
addr,
|
||||
)
|
||||
})
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
Ok(allsyms)
|
||||
}
|
||||
|
||||
pub fn load_module(path: &str) -> Result<()> {
|
||||
// check if self is init process(pid == 1)
|
||||
if !rustix::process::getpid().is_init() {
|
||||
anyhow::bail!("{}", s!("Invalid process"));
|
||||
}
|
||||
|
||||
let mut buffer =
|
||||
fs::read(path).with_context(|| format!("{} {}", s!("Cannot read file"), path))?;
|
||||
let elf = Elf::parse(&buffer)?;
|
||||
|
||||
let kernel_symbols =
|
||||
parse_kallsyms().with_context(|| s!("Cannot parse kallsyms").to_string())?;
|
||||
|
||||
let mut modifications = Vec::new();
|
||||
for (index, mut sym) in elf.syms.iter().enumerate() {
|
||||
if index == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
if sym.st_shndx != section_header::SHN_UNDEF as usize {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(name) = elf.strtab.get_at(sym.st_name) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let offset = elf.syms.offset() + index * Sym::size_with(elf.syms.ctx());
|
||||
let Some(real_addr) = kernel_symbols.get(name) else {
|
||||
log::warn!("{}: {}", s!("Cannot found symbol"), &name);
|
||||
continue;
|
||||
};
|
||||
sym.st_shndx = section_header::SHN_ABS as usize;
|
||||
sym.st_value = *real_addr;
|
||||
modifications.push((sym, offset));
|
||||
}
|
||||
|
||||
let ctx = *elf.syms.ctx();
|
||||
for ele in modifications {
|
||||
buffer.pwrite_with(ele.0, ele.1, ctx)?;
|
||||
}
|
||||
init_module(&buffer, cstr!("")).with_context(|| s!("init_module failed.").to_string())?;
|
||||
Ok(())
|
||||
}
|
||||
19
userspace/ksuinit/src/main.rs
Normal file
19
userspace/ksuinit/src/main.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
#![no_main]
|
||||
|
||||
mod init;
|
||||
mod loader;
|
||||
|
||||
use rustix::{cstr, runtime::execve};
|
||||
/// # Safety
|
||||
/// This is the entry point of the program
|
||||
/// We cannot use the main because rust will abort if we don't have std{in/out/err}
|
||||
/// https://github.com/rust-lang/rust/blob/3071aefdb2821439e2e6f592f41a4d28e40c1e79/library/std/src/sys/unix/mod.rs#L80
|
||||
/// So we use the C main function and call rust code from there
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn main(_argc: i32, argv: *const *const u8, envp: *const *const u8) -> i32 {
|
||||
let _ = init::init();
|
||||
unsafe {
|
||||
execve(cstr!("/init"), argv, envp);
|
||||
}
|
||||
0
|
||||
}
|
||||
Reference in New Issue
Block a user