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
Compare commits
25 Commits
next-susfs
...
next
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1de68a8ed2 | ||
|
|
e0c461322b | ||
|
|
edb99a2c1a | ||
|
|
eaab98b7ec | ||
|
|
aa37bcc368 | ||
|
|
107cd4add0 | ||
|
|
94c4b41ea3 | ||
|
|
0bde9047b9 | ||
|
|
bc9927b9b6 | ||
|
|
d4f4c0a0cc | ||
|
|
0aaae919c0 | ||
|
|
3f4c23a34f | ||
|
|
d69a72c658 | ||
|
|
adbff41a22 | ||
|
|
512f84504e | ||
|
|
c44f48c8a4 | ||
|
|
5c6c3870a0 | ||
|
|
c6b5440682 | ||
|
|
a917314e84 | ||
|
|
948975ba35 | ||
|
|
45ad73e9dd | ||
|
|
892a62afdf | ||
|
|
d61de07c21 | ||
|
|
4382dca515 | ||
|
|
2c9078e038 |
179
.github/workflows/build-manager-ci.yml
vendored
179
.github/workflows/build-manager-ci.yml
vendored
@@ -19,12 +19,48 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
check-cache:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
cache-hit: ${{ steps.cache-artifacts.outputs.cache-hit }}
|
||||
cache-key: ${{ steps.generate-cache-key.outputs.cache-key }}
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Generate cache key from source files
|
||||
id: generate-cache-key
|
||||
run: |
|
||||
# Calculate hash of all files except manager directory
|
||||
HASH=$(find . -type f \
|
||||
-not -path "./manager/*" \
|
||||
-not -path "./.git/*" \
|
||||
-not -path "./.github/workflows/build-manager-ci.yml" \
|
||||
-exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)
|
||||
echo "cache-key=artifacts-$HASH" >> $GITHUB_OUTPUT
|
||||
echo "Generated cache key: artifacts-$HASH"
|
||||
|
||||
- name: Check for cached artifacts
|
||||
id: cache-artifacts
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
cached-artifacts/susfsd
|
||||
cached-artifacts/ksud_overlayfs
|
||||
cached-artifacts/ksud_magic
|
||||
key: ${{ steps.generate-cache-key.outputs.cache-key }}
|
||||
|
||||
build-lkm:
|
||||
needs: check-cache
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: ./.github/workflows/build-lkm.yml
|
||||
secrets: inherit
|
||||
|
||||
build-susfsd:
|
||||
needs: build-lkm
|
||||
needs: [check-cache, build-lkm]
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@@ -34,7 +70,8 @@ jobs:
|
||||
os: ${{ matrix.os }}
|
||||
|
||||
build-ksud:
|
||||
needs: build-susfsd
|
||||
needs: [check-cache, build-susfsd]
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@@ -49,8 +86,43 @@ jobs:
|
||||
target: ${{ matrix.target }}
|
||||
os: ${{ matrix.os }}
|
||||
|
||||
cache-artifacts:
|
||||
needs: [check-cache, build-ksud]
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download susfsd artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: susfsd-linux-android
|
||||
path: cached-artifacts/susfsd
|
||||
|
||||
- name: Download ksud_overlayfs artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: ksud_overlayfs-*
|
||||
path: cached-artifacts/ksud_overlayfs
|
||||
merge-multiple: true
|
||||
|
||||
- name: Download ksud_magic artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: ksud_magic-*
|
||||
path: cached-artifacts/ksud_magic
|
||||
merge-multiple: true
|
||||
|
||||
- name: Cache artifacts
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: |
|
||||
cached-artifacts/susfsd
|
||||
cached-artifacts/ksud_overlayfs
|
||||
cached-artifacts/ksud_magic
|
||||
key: ${{ needs.check-cache.outputs.cache-key }}
|
||||
|
||||
build-manager:
|
||||
needs: build-ksud
|
||||
needs: [check-cache, build-ksud]
|
||||
if: always() && needs.check-cache.result == 'success' && (needs.check-cache.outputs.cache-hit == 'true' || needs.build-ksud.result == 'success')
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
@@ -92,87 +164,122 @@ jobs:
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
|
||||
# Restore cached artifacts if cache hit
|
||||
- name: Restore cached artifacts
|
||||
if: needs.check-cache.outputs.cache-hit == 'true'
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: |
|
||||
cached-artifacts/susfsd
|
||||
cached-artifacts/ksud_overlayfs
|
||||
cached-artifacts/ksud_magic
|
||||
key: ${{ needs.check-cache.outputs.cache-key }}
|
||||
|
||||
# Download fresh artifacts if cache miss
|
||||
- name: Download susfsd
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: susfsd-linux-android
|
||||
path: .
|
||||
|
||||
- name: Copy susfsd to app jniLibs
|
||||
run: |
|
||||
mkdir -p app/src/main/jniLibs/arm64-v8a
|
||||
cp -f ../arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
|
||||
|
||||
mkdir -p app/src/main/jniLibs/armeabi-v7a
|
||||
cp -f ../armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
|
||||
|
||||
mkdir -p app/src/main/jniLibs/x86_64
|
||||
cp -f ../x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
|
||||
|
||||
|
||||
# Download fresh ksud artifacts if cache miss
|
||||
- name: Download arm64 ksud_overlayfs
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ksud_overlayfs-aarch64-linux-android
|
||||
path: ksud_overlayfs
|
||||
|
||||
- name: Download arm ksud_overlayfs
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ksud_overlayfs-armv7-linux-androideabi
|
||||
path: ksud_overlayfs
|
||||
|
||||
- name: Download x86_64 ksud_overlayfs
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ksud_overlayfs-x86_64-linux-android
|
||||
path: ksud_overlayfs
|
||||
|
||||
- name: Copy ksud_overlayfs to app jniLibs
|
||||
run: |
|
||||
mkdir -p app/src/main/jniLibs/arm64-v8a
|
||||
|
||||
mkdir -p app/src/main/jniLibs/armeabi-v7a
|
||||
|
||||
mkdir -p app/src/main/jniLibs/x86_64
|
||||
|
||||
cp -f ../ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
|
||||
|
||||
cp -f ../ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
|
||||
|
||||
cp -f ../ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
|
||||
|
||||
- name: Download arm64 ksud_magic
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ksud_magic-aarch64-linux-android
|
||||
path: ksud_magic
|
||||
|
||||
- name: Download arm ksud_magic
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ksud_magic-armv7-linux-androideabi
|
||||
path: ksud_magic
|
||||
|
||||
- name: Download x86_64 ksud_magic
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ksud_magic-x86_64-linux-android
|
||||
path: ksud_magic
|
||||
|
||||
# Copy artifacts to jniLibs (works for both cached and fresh)
|
||||
- name: Copy susfsd to app jniLibs
|
||||
run: |
|
||||
mkdir -p app/src/main/jniLibs/arm64-v8a
|
||||
mkdir -p app/src/main/jniLibs/armeabi-v7a
|
||||
mkdir -p app/src/main/jniLibs/x86_64
|
||||
|
||||
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
|
||||
# Copy from cached artifacts
|
||||
cp -f ../cached-artifacts/susfsd/arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
|
||||
cp -f ../cached-artifacts/susfsd/armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
|
||||
cp -f ../cached-artifacts/susfsd/x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
|
||||
else
|
||||
# Copy from fresh artifacts
|
||||
cp -f ../arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
|
||||
cp -f ../armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
|
||||
cp -f ../x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
|
||||
fi
|
||||
|
||||
- name: Copy ksud_overlayfs to app jniLibs
|
||||
run: |
|
||||
mkdir -p app/src/main/jniLibs/arm64-v8a
|
||||
mkdir -p app/src/main/jniLibs/armeabi-v7a
|
||||
mkdir -p app/src/main/jniLibs/x86_64
|
||||
|
||||
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
|
||||
# Copy from cached artifacts
|
||||
cp -f ../cached-artifacts/ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
|
||||
cp -f ../cached-artifacts/ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
|
||||
cp -f ../cached-artifacts/ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
|
||||
else
|
||||
# Copy from fresh artifacts
|
||||
cp -f ../ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
|
||||
cp -f ../ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
|
||||
cp -f ../ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
|
||||
fi
|
||||
|
||||
- name: Copy ksud_magic to app jniLibs
|
||||
run: |
|
||||
mkdir -p app/src/main/jniLibs/arm64-v8a
|
||||
|
||||
mkdir -p app/src/main/jniLibs/armeabi-v7a
|
||||
|
||||
mkdir -p app/src/main/jniLibs/x86_64
|
||||
|
||||
cp -f ../ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
|
||||
|
||||
cp -f ../ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
|
||||
|
||||
cp -f ../ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
|
||||
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
|
||||
# Copy from cached artifacts
|
||||
cp -f ../cached-artifacts/ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
|
||||
cp -f ../cached-artifacts/ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
|
||||
cp -f ../cached-artifacts/ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
|
||||
else
|
||||
# Copy from fresh artifacts
|
||||
cp -f ../ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
|
||||
cp -f ../ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
|
||||
cp -f ../ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
|
||||
fi
|
||||
|
||||
- name: Build with Gradle
|
||||
run: |
|
||||
|
||||
173
.github/workflows/build-manager-spoofed.yml
vendored
173
.github/workflows/build-manager-spoofed.yml
vendored
@@ -21,12 +21,48 @@ on:
|
||||
- cron: "0 12 * * *" # 6 PM UTC+6 | 12 PM UTC
|
||||
|
||||
jobs:
|
||||
check-cache:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
cache-hit: ${{ steps.cache-artifacts.outputs.cache-hit }}
|
||||
cache-key: ${{ steps.generate-cache-key.outputs.cache-key }}
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Generate cache key from source files
|
||||
id: generate-cache-key
|
||||
run: |
|
||||
# Calculate hash of all files except manager directory
|
||||
HASH=$(find . -type f \
|
||||
-not -path "./manager/*" \
|
||||
-not -path "./.git/*" \
|
||||
-not -path "./.github/workflows/build-manager-spoofed.yml" \
|
||||
-exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)
|
||||
echo "cache-key=artifacts-spoofed-$HASH" >> $GITHUB_OUTPUT
|
||||
echo "Generated cache key: artifacts-spoofed-$HASH"
|
||||
|
||||
- name: Check for cached artifacts
|
||||
id: cache-artifacts
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
cached-artifacts/susfsd
|
||||
cached-artifacts/ksud_overlayfs
|
||||
cached-artifacts/ksud_magic
|
||||
key: ${{ steps.generate-cache-key.outputs.cache-key }}
|
||||
|
||||
build-lkm:
|
||||
needs: check-cache
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: ./.github/workflows/build-lkm.yml
|
||||
secrets: inherit
|
||||
|
||||
build-susfsd:
|
||||
needs: build-lkm
|
||||
needs: [check-cache, build-lkm]
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@@ -36,7 +72,8 @@ jobs:
|
||||
os: ${{ matrix.os }}
|
||||
|
||||
build-ksud:
|
||||
needs: build-susfsd
|
||||
needs: [check-cache, build-susfsd]
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@@ -51,8 +88,43 @@ jobs:
|
||||
target: ${{ matrix.target }}
|
||||
os: ${{ matrix.os }}
|
||||
|
||||
cache-artifacts:
|
||||
needs: [check-cache, build-ksud]
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download susfsd artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: susfsd-linux-android
|
||||
path: cached-artifacts/susfsd
|
||||
|
||||
- name: Download ksud_overlayfs artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: ksud_overlayfs-*
|
||||
path: cached-artifacts/ksud_overlayfs
|
||||
merge-multiple: true
|
||||
|
||||
- name: Download ksud_magic artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: ksud_magic-*
|
||||
path: cached-artifacts/ksud_magic
|
||||
merge-multiple: true
|
||||
|
||||
- name: Cache artifacts
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: |
|
||||
cached-artifacts/susfsd
|
||||
cached-artifacts/ksud_overlayfs
|
||||
cached-artifacts/ksud_magic
|
||||
key: ${{ needs.check-cache.outputs.cache-key }}
|
||||
|
||||
build-manager:
|
||||
needs: build-ksud
|
||||
needs: [check-cache, build-ksud]
|
||||
if: always() && needs.check-cache.result == 'success' && (needs.check-cache.outputs.cache-hit == 'true' || needs.build-ksud.result == 'success')
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
@@ -99,75 +171,122 @@ jobs:
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
|
||||
# Restore cached artifacts if cache hit
|
||||
- name: Restore cached artifacts
|
||||
if: needs.check-cache.outputs.cache-hit == 'true'
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: |
|
||||
cached-artifacts/susfsd
|
||||
cached-artifacts/ksud_overlayfs
|
||||
cached-artifacts/ksud_magic
|
||||
key: ${{ needs.check-cache.outputs.cache-key }}
|
||||
|
||||
# Download fresh artifacts if cache miss
|
||||
- name: Download susfsd
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: susfsd-linux-android
|
||||
path: .
|
||||
|
||||
- name: Copy susfsd to app jniLibs
|
||||
run: |
|
||||
mkdir -p app/src/main/jniLibs/arm64-v8a
|
||||
cp -f ../arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
|
||||
|
||||
mkdir -p app/src/main/jniLibs/armeabi-v7a
|
||||
cp -f ../armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
|
||||
|
||||
mkdir -p app/src/main/jniLibs/x86_64
|
||||
cp -f ../x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
|
||||
|
||||
|
||||
# Download fresh ksud artifacts if cache miss
|
||||
- name: Download arm64 ksud_overlayfs
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ksud_overlayfs-aarch64-linux-android
|
||||
path: ksud_overlayfs
|
||||
|
||||
- name: Download arm ksud_overlayfs
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ksud_overlayfs-armv7-linux-androideabi
|
||||
path: ksud_overlayfs
|
||||
|
||||
- name: Download x86_64 ksud_overlayfs
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ksud_overlayfs-x86_64-linux-android
|
||||
path: ksud_overlayfs
|
||||
|
||||
- name: Copy ksud_overlayfs to app jniLibs
|
||||
run: |
|
||||
cp -f ../ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
|
||||
|
||||
cp -f ../ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
|
||||
|
||||
cp -f ../ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
|
||||
|
||||
- name: Download arm64 ksud_magic
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ksud_magic-aarch64-linux-android
|
||||
path: ksud_magic
|
||||
|
||||
- name: Download arm ksud_magic
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ksud_magic-armv7-linux-androideabi
|
||||
path: ksud_magic
|
||||
|
||||
- name: Download x86_64 ksud_magic
|
||||
if: needs.check-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ksud_magic-x86_64-linux-android
|
||||
path: ksud_magic
|
||||
|
||||
# Copy artifacts to jniLibs (works for both cached and fresh)
|
||||
- name: Copy susfsd to app jniLibs
|
||||
run: |
|
||||
mkdir -p app/src/main/jniLibs/arm64-v8a
|
||||
mkdir -p app/src/main/jniLibs/armeabi-v7a
|
||||
mkdir -p app/src/main/jniLibs/x86_64
|
||||
|
||||
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
|
||||
# Copy from cached artifacts
|
||||
cp -f ../cached-artifacts/susfsd/arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
|
||||
cp -f ../cached-artifacts/susfsd/armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
|
||||
cp -f ../cached-artifacts/susfsd/x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
|
||||
else
|
||||
# Copy from fresh artifacts
|
||||
cp -f ../arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
|
||||
cp -f ../armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
|
||||
cp -f ../x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
|
||||
fi
|
||||
|
||||
- name: Copy ksud_overlayfs to app jniLibs
|
||||
run: |
|
||||
mkdir -p app/src/main/jniLibs/arm64-v8a
|
||||
mkdir -p app/src/main/jniLibs/armeabi-v7a
|
||||
mkdir -p app/src/main/jniLibs/x86_64
|
||||
|
||||
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
|
||||
# Copy from cached artifacts
|
||||
cp -f ../cached-artifacts/ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
|
||||
cp -f ../cached-artifacts/ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
|
||||
cp -f ../cached-artifacts/ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
|
||||
else
|
||||
# Copy from fresh artifacts
|
||||
cp -f ../ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
|
||||
cp -f ../ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
|
||||
cp -f ../ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
|
||||
fi
|
||||
|
||||
- name: Copy ksud_magic to app jniLibs
|
||||
run: |
|
||||
cp -f ../ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
|
||||
|
||||
cp -f ../ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
|
||||
mkdir -p app/src/main/jniLibs/arm64-v8a
|
||||
mkdir -p app/src/main/jniLibs/armeabi-v7a
|
||||
mkdir -p app/src/main/jniLibs/x86_64
|
||||
|
||||
cp -f ../ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
|
||||
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
|
||||
# Copy from cached artifacts
|
||||
cp -f ../cached-artifacts/ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
|
||||
cp -f ../cached-artifacts/ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
|
||||
cp -f ../cached-artifacts/ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
|
||||
else
|
||||
# Copy from fresh artifacts
|
||||
cp -f ../ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
|
||||
cp -f ../ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
|
||||
cp -f ../ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
|
||||
fi
|
||||
|
||||
- name: Build with Gradle
|
||||
run: |
|
||||
|
||||
12
.github/workflows/gki-kernel.yml
vendored
12
.github/workflows/gki-kernel.yml
vendored
@@ -195,6 +195,18 @@ jobs:
|
||||
sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' build/kernel/*.sh || echo "No unknown symbol scripts found"
|
||||
fi
|
||||
|
||||
- name: Setup Syscall Hooks
|
||||
if: ${{ inputs.build_lkm == false }}
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE/android-kernel/common
|
||||
echo "[+] Patch Kernel"
|
||||
curl -L https://github.com/KernelSU-Next/kernel_patches/raw/main/syscall_hook/min_scope_syscall_hooks_v1.4.patch | patch -p1 --fuzz=3
|
||||
echo "[+] Set Config"
|
||||
echo "CONFIG_KSU=y" >> ./arch/arm64/configs/gki_defconfig
|
||||
echo "CONFIG_KSU_KPROBES_HOOK=n" >> ./arch/arm64/configs/gki_defconfig
|
||||
echo "[+] Disable Config Check"
|
||||
sed -i 's/check_defconfig//' ./build.config.gki
|
||||
|
||||
- name: Make working directory clean to avoid dirty
|
||||
working-directory: android-kernel
|
||||
run: |
|
||||
|
||||
31
build.sh
Executable file
31
build.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script builds the KernelSU Next manager APK.
|
||||
|
||||
# Ensure you have the setup Android SDK & NDK installed and necessary environment variables set and sourced.
|
||||
|
||||
# For LKM make sure you have imported the androidX-X.X_kernelsu.ko drivers to userspace/ksud_*/bin/aarch64 directory.
|
||||
|
||||
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
|
||||
|
||||
cross build --target aarch64-linux-android --release --manifest-path ./userspace/ksud_overlayfs/Cargo.toml
|
||||
|
||||
cp userspace/ksud_overlayfs/target/aarch64-linux-android/release/ksud manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
|
||||
|
||||
cd userspace/susfsd/jni
|
||||
|
||||
ndk-build
|
||||
|
||||
cp ../libs/arm64-v8a/susfsd ../../../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
|
||||
|
||||
cd ../../..
|
||||
|
||||
cd manager
|
||||
|
||||
./setup.sh
|
||||
|
||||
cd ..
|
||||
|
||||
adb install manager/app/build/outputs/apk/release/KernelSU_Next_v*.apk
|
||||
@@ -74,6 +74,7 @@ If you’d like to support the project:
|
||||
|
||||
- **USDT (BEP20, ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
|
||||
- **USDT (TRC20)**: `TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh`
|
||||
- **USDT (SOL)**: `A4wqBXYd6Ey4nK4SJ2bmjeMgGyaLKT9TwDLh8BEo8Zu6`
|
||||
- **ETH (ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
|
||||
- **LTC**: `Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL`
|
||||
- **BTC**: `19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6`
|
||||
@@ -87,5 +88,4 @@ If you’d like to support the project:
|
||||
- [Genuine](https://github.com/brevent/genuine/) – APK v2 signature validation
|
||||
- [Diamorphine](https://github.com/m0nad/Diamorphine) – Rootkit techniques
|
||||
- [KernelSU](https://github.com/tiann/KernelSU) – The original base that made KernelSU Next possible
|
||||
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs) – 💜 to 5ec1cff for keeping KernelSU alive
|
||||
- [Crowdin Translators](https://crowdin.com/project/kernelsu-next/members) – 💬 Thanks to everyone for helping make KernelSU Next multi-lingual!
|
||||
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs) – For magic mount support
|
||||
|
||||
@@ -40,4 +40,11 @@ config KSU_LSM_SECURITY_HOOKS
|
||||
Disabling this is mostly only useful for kernel 4.1 and older.
|
||||
Make sure to implement manual hooks on security/security.c.
|
||||
|
||||
config KSU_SWITCH_MANAGER
|
||||
bool "KernelSU switch manager support"
|
||||
depends on KSU
|
||||
default n
|
||||
help
|
||||
Enable KernelSU switch manager support.
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -49,12 +49,12 @@ ifeq ($(shell grep "ssize_t kernel_write" $(srctree)/fs/read_write.c | grep -q "
|
||||
ccflags-y += -DKSU_KERNEL_WRITE
|
||||
endif
|
||||
|
||||
ifndef KSU_NEXT_EXPECTED_SIZE
|
||||
KSU_NEXT_EXPECTED_SIZE := 0x3e6
|
||||
ifndef KSU_NEXT_MANAGER_SIZE
|
||||
KSU_NEXT_MANAGER_SIZE := 0x3e6
|
||||
endif
|
||||
|
||||
ifndef KSU_NEXT_EXPECTED_HASH
|
||||
KSU_NEXT_EXPECTED_HASH := 79e590113c4c4c0c222978e413a5faa801666957b1212a328e46c00c69821bf7
|
||||
ifndef KSU_NEXT_MANAGER_HASH
|
||||
KSU_NEXT_MANAGER_HASH := 79e590113c4c4c0c222978e413a5faa801666957b1212a328e46c00c69821bf7
|
||||
endif
|
||||
|
||||
ifdef KSU_MANAGER_PACKAGE
|
||||
@@ -62,11 +62,11 @@ ccflags-y += -DKSU_MANAGER_PACKAGE=\"$(KSU_MANAGER_PACKAGE)\"
|
||||
$(info -- KernelSU-Next Manager package name: $(KSU_MANAGER_PACKAGE))
|
||||
endif
|
||||
|
||||
$(info -- KernelSU-Next Manager signature size: $(KSU_NEXT_EXPECTED_SIZE))
|
||||
$(info -- KernelSU-Next Manager signature hash: $(KSU_NEXT_EXPECTED_HASH))
|
||||
$(info -- KernelSU-Next Manager signature size: $(KSU_NEXT_MANAGER_SIZE))
|
||||
$(info -- KernelSU-Next Manager signature hash: $(KSU_NEXT_MANAGER_HASH))
|
||||
|
||||
ccflags-y += -DEXPECTED_NEXT_SIZE=$(KSU_NEXT_EXPECTED_SIZE)
|
||||
ccflags-y += -DEXPECTED_NEXT_HASH=\"$(KSU_NEXT_EXPECTED_HASH)\"
|
||||
ccflags-y += -DEXPECTED_MANAGER_SIZE=$(KSU_NEXT_MANAGER_SIZE)
|
||||
ccflags-y += -DEXPECTED_MANAGER_HASH=\"$(KSU_NEXT_MANAGER_HASH)\"
|
||||
|
||||
ccflags-y += -DKSU_UMOUNT
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/version.h>
|
||||
#ifdef CONFIG_KSU_DEBUG
|
||||
#include <linux/moduleparam.h>
|
||||
#endif
|
||||
#include <crypto/hash.h>
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
|
||||
#include <crypto/sha2.h>
|
||||
@@ -19,6 +18,8 @@
|
||||
#include "kernel_compat.h"
|
||||
#include "throne_tracker.h"
|
||||
|
||||
static unsigned int expected_manager_size = EXPECTED_MANAGER_SIZE;
|
||||
static char expected_manager_hash[SHA256_DIGEST_SIZE * 2 + 1] = EXPECTED_MANAGER_HASH;
|
||||
|
||||
struct sdesc {
|
||||
struct shash_desc shash;
|
||||
@@ -315,6 +316,55 @@ module_param_cb(ksu_debug_manager_uid, &expected_size_ops,
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_SWITCH_MANAGER
|
||||
|
||||
static int set_expected_size(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
int rv = param_set_uint(val, kp);
|
||||
pr_info("expected_manager_size set to %u\n", expected_manager_size);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int get_expected_size(char *buf, const struct kernel_param *kp)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%u\n", expected_manager_size);
|
||||
}
|
||||
|
||||
static int set_expected_hash(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
if (strlen(val) != SHA256_DIGEST_SIZE * 2) {
|
||||
pr_err("Invalid hash length: %s\n", val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
strncpy(expected_manager_hash, val, SHA256_DIGEST_SIZE * 2);
|
||||
expected_manager_hash[SHA256_DIGEST_SIZE * 2] = '\0';
|
||||
|
||||
pr_info("expected_manager_hash set to %s\n", expected_manager_hash);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_expected_hash(char *buf, const struct kernel_param *kp)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", expected_manager_hash);
|
||||
}
|
||||
|
||||
static struct kernel_param_ops expected_size_ops = {
|
||||
.set = set_expected_size,
|
||||
.get = get_expected_size,
|
||||
};
|
||||
|
||||
static struct kernel_param_ops expected_hash_ops = {
|
||||
.set = set_expected_hash,
|
||||
.get = get_expected_hash,
|
||||
};
|
||||
|
||||
module_param_cb(expected_manager_size, &expected_size_ops, &expected_manager_size, 0644);
|
||||
|
||||
module_param_cb(expected_manager_hash, &expected_hash_ops, &expected_manager_hash, 0644);
|
||||
|
||||
#endif
|
||||
|
||||
bool is_manager_apk(char *path)
|
||||
{
|
||||
int tries = 0;
|
||||
@@ -333,5 +383,9 @@ bool is_manager_apk(char *path)
|
||||
return false;
|
||||
}
|
||||
|
||||
return check_v2_signature(path, EXPECTED_NEXT_SIZE, EXPECTED_NEXT_HASH);
|
||||
// set debug info to print size and hash to kernel log
|
||||
pr_info("%s: expected size: %u, expected hash: %s\n",
|
||||
path, expected_manager_size, expected_manager_hash);
|
||||
|
||||
return check_v2_signature(path, expected_manager_size, expected_manager_hash);
|
||||
}
|
||||
|
||||
@@ -255,6 +255,34 @@ static void nuke_ext4_sysfs() {
|
||||
path_put(&path);
|
||||
}
|
||||
|
||||
static bool is_system_bin_su(void)
|
||||
{
|
||||
static const char *su_paths[] = {
|
||||
"/system/bin/su",
|
||||
"/vendor/bin/su",
|
||||
"/product/bin/su",
|
||||
"/system_ext/bin/su",
|
||||
"/odm/bin/su",
|
||||
"/system/xbin/su",
|
||||
"/system_ext/xbin/su"
|
||||
};
|
||||
char path_buf[256];
|
||||
char *pathname;
|
||||
int i;
|
||||
|
||||
struct mm_struct *mm = current->mm;
|
||||
if (mm && mm->exe_file) {
|
||||
pathname = d_path(&mm->exe_file->f_path, path_buf, sizeof(path_buf));
|
||||
if (!IS_ERR(pathname)) {
|
||||
for (i = 0; i < ARRAY_SIZE(su_paths); i++) {
|
||||
if (strcmp(pathname, su_paths[i]) == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
unsigned long arg4, unsigned long arg5)
|
||||
{
|
||||
@@ -277,10 +305,18 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
bool from_root = 0 == current_uid().val;
|
||||
bool from_manager = is_manager();
|
||||
|
||||
#ifdef CONFIG_KSU_KPROBES_HOOK
|
||||
if (!from_root && !from_manager
|
||||
&& !(is_allow_su() && is_system_bin_su())) {
|
||||
// only root or manager can access this interface
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
if (!from_root && !from_manager) {
|
||||
// only root or manager can access this interface
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_DEBUG
|
||||
pr_info("option: 0x%x, cmd: %ld\n", option, arg2);
|
||||
@@ -446,6 +482,32 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_KPROBES_HOOK
|
||||
if (arg2 == CMD_ENABLE_SU) {
|
||||
bool enabled = (arg3 != 0);
|
||||
if (enabled == ksu_su_compat_enabled) {
|
||||
pr_info("cmd enable su but no need to change.\n");
|
||||
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {// return the reply_ok directly
|
||||
pr_err("prctl reply error, cmd: %lu\n", arg2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
ksu_sucompat_init();
|
||||
} else {
|
||||
ksu_sucompat_exit();
|
||||
}
|
||||
ksu_su_compat_enabled = enabled;
|
||||
|
||||
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
|
||||
pr_err("prctl reply error, cmd: %lu\n", arg2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// all other cmds are for 'root manager'
|
||||
if (!from_manager) {
|
||||
return 0;
|
||||
@@ -499,7 +561,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_KSU_KPROBES_HOOK
|
||||
if (arg2 == CMD_ENABLE_SU) {
|
||||
bool enabled = (arg3 != 0);
|
||||
if (enabled == ksu_su_compat_enabled) {
|
||||
@@ -523,6 +585,8 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -58,12 +58,11 @@ static void stop_input_hook();
|
||||
static struct work_struct stop_vfs_read_work;
|
||||
static struct work_struct stop_execve_hook_work;
|
||||
static struct work_struct stop_input_hook_work;
|
||||
#endif
|
||||
|
||||
#else
|
||||
bool ksu_vfs_read_hook __read_mostly = true;
|
||||
bool ksu_execveat_hook __read_mostly = true;
|
||||
bool ksu_input_hook __read_mostly = true;
|
||||
|
||||
#endif
|
||||
|
||||
u32 ksu_devpts_sid;
|
||||
|
||||
@@ -488,10 +487,12 @@ __maybe_unused int ksu_handle_execve_ksud(const char __user *filename_user,
|
||||
struct filename filename_in, *filename_p;
|
||||
char path[32];
|
||||
|
||||
#ifndef CONFIG_KSU_KPROBES_HOOK
|
||||
// return early if disabled.
|
||||
if (!ksu_execveat_hook) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!filename_user)
|
||||
return 0;
|
||||
|
||||
@@ -179,23 +179,8 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user,
|
||||
if (unlikely(!filename_user))
|
||||
return 0;
|
||||
|
||||
// nofault variant fails probably due to pagefault_disable
|
||||
// some cpus dont really have that good speculative execution
|
||||
// substitute set_fs, check if pointer is valid
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)
|
||||
if (!access_ok(VERIFY_READ, *filename_user, sizeof(path)))
|
||||
return 0;
|
||||
#else
|
||||
if (!access_ok(*filename_user, sizeof(path)))
|
||||
return 0;
|
||||
#endif
|
||||
// success = returns number of bytes and should be less than path
|
||||
long len = strncpy_from_user(path, *filename_user, sizeof(path));
|
||||
if (len <= 0 || len > sizeof(path))
|
||||
return 0;
|
||||
|
||||
// strncpy_from_user_nofault does this too
|
||||
path[sizeof(path) - 1] = '\0';
|
||||
memset(path, 0, sizeof(path));
|
||||
ksu_strncpy_from_user_retry(path, *filename_user, sizeof(path));
|
||||
|
||||
if (likely(memcmp(path, su, sizeof(su))))
|
||||
return 0;
|
||||
|
||||
3
manager/.gitignore
vendored
3
manager/.gitignore
vendored
@@ -7,5 +7,4 @@ build
|
||||
captures
|
||||
.cxx
|
||||
local.properties
|
||||
key.jks
|
||||
setup.sh
|
||||
key.jks
|
||||
@@ -16,11 +16,12 @@ object Natives {
|
||||
// 10946: add capabilities
|
||||
// 10977: change groups_count and groups to avoid overflow write
|
||||
// 11071: Fix the issue of failing to set a custom SELinux type.
|
||||
const val MINIMAL_SUPPORTED_KERNEL = 11071
|
||||
// 12797: zygisk query and get manager uid.
|
||||
const val MINIMAL_SUPPORTED_KERNEL = 12797
|
||||
|
||||
// 11640: Support query working mode, LKM or GKI
|
||||
// when MINIMAL_SUPPORTED_KERNEL > 11640, we can remove this constant.
|
||||
const val MINIMAL_SUPPORTED_KERNEL_LKM = 11648
|
||||
const val MINIMAL_SUPPORTED_KERNEL_LKM = 12797
|
||||
|
||||
// 12404: Support disable sucompat mode
|
||||
const val MINIMAL_SUPPORTED_SU_COMPAT = 12404
|
||||
@@ -119,6 +120,9 @@ object Natives {
|
||||
return version < MINIMAL_SUPPORTED_KERNEL
|
||||
}
|
||||
|
||||
val KSU_WORK_DIR = "/data/adb/ksu/"
|
||||
val GLOBAL_NAMESPACE_FILE = KSU_WORK_DIR + ".global_mnt"
|
||||
|
||||
@Immutable
|
||||
@Parcelize
|
||||
@Keep
|
||||
|
||||
@@ -650,7 +650,7 @@ private fun InfoCard(autoExpand: Boolean = false) {
|
||||
|
||||
val suSFS = getSuSFS()
|
||||
if (suSFS == "Supported") {
|
||||
val isSUS_SU = getSuSFSFeatures() == "CONFIG_KSU_SUSFS_SUS_SU"
|
||||
val isSUS_SU = hasSuSFs_SUS_SU() == "Supported"
|
||||
val susSUMode = if (isSUS_SU) {
|
||||
val mode = susfsSUS_SU_Mode()
|
||||
val modeString =
|
||||
|
||||
@@ -88,6 +88,8 @@ import com.rifsxd.ksunext.ui.component.rememberLoadingDialog
|
||||
import com.rifsxd.ksunext.ui.util.LocalSnackbarHost
|
||||
import com.rifsxd.ksunext.ui.util.getBugreportFile
|
||||
import com.rifsxd.ksunext.ui.util.*
|
||||
import com.rifsxd.ksunext.ui.util.isGlobalNamespaceEnabled
|
||||
import com.rifsxd.ksunext.ui.util.setGlobalNamespaceEnabled
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
@@ -101,6 +103,8 @@ import java.time.format.DateTimeFormatter
|
||||
fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
val snackBarHost = LocalSnackbarHost.current
|
||||
var isGlobalNamespaceEnabled by rememberSaveable { mutableStateOf(false) }
|
||||
isGlobalNamespaceEnabled = isGlobalNamespaceEnabled()
|
||||
|
||||
val isManager = Natives.becomeManager(ksuApp.packageName)
|
||||
val ksuVersion = if (isManager) Natives.version else null
|
||||
@@ -196,14 +200,31 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SwitchItem(
|
||||
icon = Icons.Filled.Engineering,
|
||||
title = stringResource(id = R.string.settings_global_namespace_mode),
|
||||
summary = stringResource(id = R.string.settings_global_namespace_mode_summary),
|
||||
checked = isGlobalNamespaceEnabled,
|
||||
onCheckedChange = {
|
||||
setGlobalNamespaceEnabled(
|
||||
if (isGlobalNamespaceEnabled) {
|
||||
"0"
|
||||
} else {
|
||||
"1"
|
||||
}
|
||||
)
|
||||
isGlobalNamespaceEnabled = it
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
|
||||
|
||||
val suSFS = getSuSFS()
|
||||
val isSUS_SU = getSuSFSFeatures()
|
||||
val isSUS_SU = hasSuSFs_SUS_SU() == "Supported"
|
||||
if (suSFS == "Supported") {
|
||||
if (isSUS_SU == "CONFIG_KSU_SUSFS_SUS_SU") {
|
||||
if (isSUS_SU) {
|
||||
var isEnabled by rememberSaveable {
|
||||
mutableStateOf(susfsSUS_SU_Mode() == "2")
|
||||
}
|
||||
|
||||
@@ -103,7 +103,10 @@ fun Uri.getFileName(context: Context): String? {
|
||||
|
||||
fun createRootShell(globalMnt: Boolean = false): Shell {
|
||||
Shell.enableVerboseLogging = BuildConfig.DEBUG
|
||||
val builder = Shell.Builder.create()
|
||||
val builder = Shell.Builder.create().apply {
|
||||
setFlags(Shell.FLAG_MOUNT_MASTER)
|
||||
}
|
||||
|
||||
return try {
|
||||
if (globalMnt) {
|
||||
builder.build(ksuDaemonMagicPath(), "debug", "su", "-g")
|
||||
@@ -403,6 +406,22 @@ fun hasMagisk(): Boolean {
|
||||
return result.isSuccess
|
||||
}
|
||||
|
||||
fun isGlobalNamespaceEnabled(): Boolean {
|
||||
val shell = getRootShell()
|
||||
val result =
|
||||
ShellUtils.fastCmd(shell, "nsenter --mount=/proc/1/ns/mnt cat ${Natives.GLOBAL_NAMESPACE_FILE}")
|
||||
Log.i(TAG, "is global namespace enabled: $result")
|
||||
return result == "1"
|
||||
}
|
||||
|
||||
fun setGlobalNamespaceEnabled(value: String) {
|
||||
getRootShell().newJob()
|
||||
.add("nsenter --mount=/proc/1/ns/mnt echo $value > ${Natives.GLOBAL_NAMESPACE_FILE}")
|
||||
.submit { result ->
|
||||
Log.i(TAG, "setGlobalNamespaceEnabled result: ${result.isSuccess} [${result.out}]")
|
||||
}
|
||||
}
|
||||
|
||||
fun isSepolicyValid(rules: String?): Boolean {
|
||||
if (rules == null) {
|
||||
return true
|
||||
@@ -591,12 +610,19 @@ fun getSuSFSVariant(): String {
|
||||
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} variant")
|
||||
return result
|
||||
}
|
||||
|
||||
fun getSuSFSFeatures(): String {
|
||||
val shell = getRootShell()
|
||||
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} features")
|
||||
return result
|
||||
}
|
||||
|
||||
fun hasSuSFs_SUS_SU(): String {
|
||||
val shell = getRootShell()
|
||||
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} sus_su support")
|
||||
return result
|
||||
}
|
||||
|
||||
fun susfsSUS_SU_0(): String {
|
||||
val shell = getRootShell()
|
||||
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} sus_su 0")
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.rifsxd.ksunext.ui.webui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class AppIconUtil {
|
||||
private static final Map<String, Bitmap> iconCache = new HashMap<>();
|
||||
|
||||
public static Bitmap loadAppIconSync(Context context, String packageName, int sizePx) {
|
||||
Bitmap cached = iconCache.get(packageName);
|
||||
if (cached != null) return cached;
|
||||
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0);
|
||||
Drawable drawable = pm.getApplicationIcon(appInfo);
|
||||
Bitmap raw = drawableToBitmap(drawable, sizePx);
|
||||
Bitmap icon = Bitmap.createScaledBitmap(raw, sizePx, sizePx, true);
|
||||
iconCache.put(packageName, icon);
|
||||
return icon;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Bitmap drawableToBitmap(Drawable drawable, int size) {
|
||||
if (drawable instanceof BitmapDrawable) return ((BitmapDrawable) drawable).getBitmap();
|
||||
|
||||
int width = drawable.getIntrinsicWidth() > 0 ? drawable.getIntrinsicWidth() : size;
|
||||
int height = drawable.getIntrinsicHeight() > 0 ? drawable.getIntrinsicHeight() : size;
|
||||
|
||||
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bmp);
|
||||
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||
drawable.draw(canvas);
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
@@ -96,7 +96,23 @@ class WebUIActivity : ComponentActivity() {
|
||||
view: WebView,
|
||||
request: WebResourceRequest
|
||||
): WebResourceResponse? {
|
||||
return webViewAssetLoader.shouldInterceptRequest(request.url)
|
||||
val url = request.url
|
||||
|
||||
//POC: Handle ksu://icon/[packageName] to serve app icon via WebView
|
||||
if (url.scheme.equals("ksu", ignoreCase = true) && url.host.equals("icon", ignoreCase = true)) {
|
||||
val packageName = url.path?.substring(1)
|
||||
if (!packageName.isNullOrEmpty()) {
|
||||
val icon = AppIconUtil.loadAppIconSync(this@WebUIActivity, packageName, 512)
|
||||
if (icon != null) {
|
||||
val stream = java.io.ByteArrayOutputStream()
|
||||
icon.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, stream)
|
||||
val inputStream = java.io.ByteArrayInputStream(stream.toByteArray())
|
||||
return WebResourceResponse("image/png", null, inputStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return webViewAssetLoader.shouldInterceptRequest(url)
|
||||
}
|
||||
override fun onPageFinished(view: WebView?, url: String?) {
|
||||
super.onPageFinished(view, url)
|
||||
@@ -119,4 +135,4 @@ class WebUIActivity : ComponentActivity() {
|
||||
super.onDestroy()
|
||||
runCatching { rootShell?.close() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,4 +233,6 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,4 +231,6 @@
|
||||
<string name="module_sort_enabled_first">Сортиране (първо активирани)</string>
|
||||
<string name="module_sort_action_first">Сортиране (първо действие)</string>
|
||||
<string name="module_sort_webui_first">Сортиране (първо WebUI)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,4 +231,6 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,4 +231,6 @@
|
||||
<string name="module_sort_enabled_first">Sortierung (aktivierte zuerst)</string>
|
||||
<string name="module_sort_action_first">Sortierung (Aktion zuerst)</string>
|
||||
<string name="module_sort_webui_first">Sortierung (WebUI zuerst)</string>
|
||||
<string name="settings_global_namespace_mode">Globaler Namensraum-Modus</string>
|
||||
<string name="settings_global_namespace_mode_summary">Alle Root-Sitzungen verwenden den globalen Mount-Namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<string name="home_working">Funcionando</string>
|
||||
<string name="home_working_version">Versión: %d</string>
|
||||
<string name="home_module_update_count">Actualizaciones: %d</string>
|
||||
<string name="home_failure">¡No se encontró la firma de KernelSU Next v2 en el kernel! [ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure">¡Firma v2 de KernelSU Next no encontrada en el kernel! [ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure_tip">¡Pídele a tu desarrollador de kernel que integre KernelSU Next!</string>
|
||||
<string name="home_kernel">Versión del kernel</string>
|
||||
<string name="hook_mode">Método de intercepción</string>
|
||||
@@ -119,7 +119,7 @@
|
||||
<string name="profile_template">Plantilla</string>
|
||||
<string name="profile_custom">Personalizado</string>
|
||||
<string name="profile_name">Nombre de perfil</string>
|
||||
<string name="profile_namespace">Espacio de nombres de montaje</string>
|
||||
<string name="profile_namespace">Espacio de montaje aislado</string>
|
||||
<string name="profile_namespace_inherited">Heredado</string>
|
||||
<string name="profile_namespace_global">Global</string>
|
||||
<string name="profile_namespace_individual">Individual</string>
|
||||
@@ -228,7 +228,9 @@
|
||||
<string name="home_module_count_singular">Módulo</string>
|
||||
<string name="home_module_count_plural">Módulos</string>
|
||||
<string name="module_backup_message">Respaldar los módulos actualmente instalados.</string>
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="module_sort_enabled_first">Ordenar (Activados Primero)</string>
|
||||
<string name="module_sort_action_first">Ordenar (Accionables primero)</string>
|
||||
<string name="module_sort_webui_first">Ordenar (WrbUI primero)</string>
|
||||
<string name="settings_global_namespace_mode">Usar el Espacio de Montaje Aislado Global</string>
|
||||
<string name="settings_global_namespace_mode_summary">Todas las sesiones root usan el espacio de montaje aislado global</string>
|
||||
</resources>
|
||||
|
||||
@@ -232,4 +232,6 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -233,4 +233,6 @@
|
||||
<string name="module_sort_enabled_first">Trier (Activé en premier)</string>
|
||||
<string name="module_sort_action_first">Trier (Action en premier)</string>
|
||||
<string name="module_sort_webui_first">Trier (WebUI en premier)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -233,4 +233,6 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,4 +231,6 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="issue_report_title">Ada kendala?</string>
|
||||
<string name="issue_report_body">Menemukan bug atau memiliki umpan balik?</string>
|
||||
<string name="issue_report_body_2">Laporkan sesegera mungkin!</string>
|
||||
<string name="issue_report_title">Memiliki kendala?</string>
|
||||
<string name="issue_report_body">Mengalami kesalahan atau memiliki umpan balik?</string>
|
||||
<string name="issue_report_body_2">Laporkan secepatnya!</string>
|
||||
<string name="issue_report_github">Laporkan di GitHub</string>
|
||||
<string name="issue_report_telegram">Hubungi melalui Telegram</string>
|
||||
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
|
||||
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
|
||||
<string name="confirm">Konfirmasi</string>
|
||||
<string name="confirm">Ya</string>
|
||||
<string name="app_name">KernelSU Next</string>
|
||||
<string name="home">Beranda</string>
|
||||
<string name="home_not_installed">Tidak terpasang</string>
|
||||
<string name="home_click_to_install">Klik untuk memasang</string>
|
||||
<string name="home_not_installed">Tidak terinstal</string>
|
||||
<string name="home_click_to_install">Klik untuk menginstal</string>
|
||||
<string name="lkm_mode_deprecated">Mode LKM sekarang sudah tidak digunakan lagi!</string>
|
||||
<string name="lkm_alternative_suggestion">Pasang kernel GKI atau integrasikan KernelSU Next ke perangkat anda.</string>
|
||||
<string name="home_working">Berfungsi</string>
|
||||
@@ -32,7 +32,7 @@
|
||||
<string name="home_android">Versi android</string>
|
||||
<string name="home_manager_version">Versi manajer</string>
|
||||
<string name="home_abi">ABI</string>
|
||||
<string name="home_selinux_status">Status SELinu</string>
|
||||
<string name="home_selinux_status">SELinux status</string>
|
||||
<string name="selinux_status_disabled">Nonaktif</string>
|
||||
<string name="selinux_status_enforcing">Enforcing</string>
|
||||
<string name="selinux_status_permissive">Permissive</string>
|
||||
@@ -42,7 +42,7 @@
|
||||
<string name="module_failed_to_disable">Gagal menonaktifkan modul: %s</string>
|
||||
<string name="module_empty">Tidak ada modul yang terpasang</string>
|
||||
<string name="module">Modul</string>
|
||||
<string name="module_install_prompt_with_name">Modul berikut akan dipasang: %1$s</string>
|
||||
<string name="module_install_prompt_with_name">Modul yang akan diinstal: %1$s</string>
|
||||
<string name="module_sort_a_to_z">Urutkan (A → Z)</string>
|
||||
<string name="module_sort_z_to_a">Urutkan (Z → A)</string>
|
||||
<string name="module_size_low_to_high">Urutkan (Kecil → Besar)</string>
|
||||
@@ -232,4 +232,6 @@
|
||||
<string name="module_sort_enabled_first">Urutkan (Diaktifkan lebih dulu)</string>
|
||||
<string name="module_sort_action_first">Urutkan (Aksi lebih dulu)</string>
|
||||
<string name="module_sort_webui_first">Urutkan (WebUI lebih dulu)</string>
|
||||
<string name="settings_global_namespace_mode">Mode Namespace Universal</string>
|
||||
<string name="settings_global_namespace_mode_summary">Semua sesi root menggunakan mount namespace universal</string>
|
||||
</resources>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
|
||||
<string name="confirm">Conferma</string>
|
||||
<string name="app_name">KernelSU Next</string>
|
||||
<string name="home">Casa</string>
|
||||
<string name="home">Home</string>
|
||||
<string name="home_not_installed">Non installato</string>
|
||||
<string name="home_click_to_install">Clicca per installare</string>
|
||||
<string name="lkm_mode_deprecated">La modalità LKM è ora obsoleta!</string>
|
||||
@@ -17,7 +17,7 @@
|
||||
<string name="home_working">In esecuzione</string>
|
||||
<string name="home_working_version">Versione: %d</string>
|
||||
<string name="home_module_update_count">Aggiornamenti: %d</string>
|
||||
<string name="home_failure">KernelSU Next firma v2 non trovata nel kernel! [ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure">Firma v2 di KernelSU Next non trovata nel kernel! [ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure_tip">Chiedi allo sviluppatore del kernel d\'integrare KernelSU Next!</string>
|
||||
<string name="home_kernel">Versione kernel</string>
|
||||
<string name="hook_mode">Modalità Hook</string>
|
||||
@@ -37,7 +37,7 @@
|
||||
<string name="selinux_status_enforcing">Enforcing</string>
|
||||
<string name="selinux_status_permissive">Permissive</string>
|
||||
<string name="selinux_status_unknown">Sconosciuto</string>
|
||||
<string name="superuser">Superutente</string>
|
||||
<string name="superuser">Accesso root</string>
|
||||
<string name="module_failed_to_enable">Impossibile abilitare il modulo: %s</string>
|
||||
<string name="module_failed_to_disable">Impossibile disabilitare il modulo: %s</string>
|
||||
<string name="module_empty">Nessun modulo installato</string>
|
||||
@@ -187,7 +187,7 @@
|
||||
<string name="select_file">Seleziona un file</string>
|
||||
<string name="install_inactive_slot">Installa nello slot inattivo (dopo un aggiornamento OTA)</string>
|
||||
<string name="install_inactive_slot_warning">Dopo il riavvio, il dispositivo sarà FORZATO ad avviarsi nello slot attualmente inattivo!\nUtilizza questa opzione solo dopo aver completato l\'aggiornamento OTA.\nVuoi continuare?</string>
|
||||
<string name="install_next"></string>
|
||||
<string name="install_next">Next</string>
|
||||
<string name="select_file_tip">Immagine partizione %1$s consigliata</string>
|
||||
<string name="select_kmi">Seleziona KMI</string>
|
||||
<string name="shrink_sparse_image">Minimizza l\'immagine sparsa</string>
|
||||
@@ -207,7 +207,7 @@
|
||||
<string name="log_saved">Log salvati</string>
|
||||
<string name="send_log">Condividi i log</string>
|
||||
<string name="settings_disable_su">Disattiva la compatibilità su</string>
|
||||
<string name="settings_disable_su_summary">Disattiva temporaneamente la capacità di ogni applicazione di ottenere i permessi di root tramite il comando su (le sessioni di root esistenti non subiranno modifiche).</string>
|
||||
<string name="settings_disable_su_summary">Disattiva temporaneamente la capacità di ogni applicazione di ottenere i permessi root tramite il comando su (le sessioni di root esistenti non subiranno modifiche).</string>
|
||||
<string name="settings_language">Lingua</string>
|
||||
<string name="system_default">Default di sistema</string>
|
||||
<string name="settings_legacyui">Usa lo stile d\'interfaccia precedente</string>
|
||||
@@ -223,12 +223,14 @@
|
||||
<string name="sucompat_disabled">SUCOMPAT DISABILITATO</string>
|
||||
<string name="zygisk_required">Zygisk richiesto</string>
|
||||
<string name="zygisk_status">Iniezione Zygisk</string>
|
||||
<string name="home_superuser_count_singular">Superutente</string>
|
||||
<string name="home_superuser_count_plural">Superutenti</string>
|
||||
<string name="home_superuser_count_singular">Accesso root</string>
|
||||
<string name="home_superuser_count_plural">Accessi root</string>
|
||||
<string name="home_module_count_singular">Modulo</string>
|
||||
<string name="home_module_count_plural">Moduli</string>
|
||||
<string name="module_backup_message">Esegue il backup dei moduli attualmente esistenti.</string>
|
||||
<string name="module_sort_enabled_first">Ordina (prima Abilitato)</string>
|
||||
<string name="module_sort_action_first">Ordina (prima Azione)</string>
|
||||
<string name="module_sort_webui_first">Ordina (prima WebUI)</string>
|
||||
<string name="settings_global_namespace_mode">Modalità Namespace globale</string>
|
||||
<string name="settings_global_namespace_mode_summary">Tutte le sessioni root usano lo spazio di montaggio globale</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,4 +231,6 @@
|
||||
<string name="module_sort_enabled_first">並べ替え (有効を優先)</string>
|
||||
<string name="module_sort_action_first">並べ替え (実行可能を優先)</string>
|
||||
<string name="module_sort_webui_first">並べ替え (WebUIを優先)</string>
|
||||
<string name="settings_global_namespace_mode">グローバル名前空間モード</string>
|
||||
<string name="settings_global_namespace_mode_summary">すべての root セッションがグローバルマウント名前空間を使用します</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,4 +231,6 @@
|
||||
<string name="module_sort_enabled_first">정렬 (활성화됨 우선)</string>
|
||||
<string name="module_sort_action_first">정렬 (동작 우선)</string>
|
||||
<string name="module_sort_webui_first">정렬 (WebUI 우선)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
<string name="module_install_prompt_with_name">Następujące moduły zostaną zainstalowane: %1$s</string>
|
||||
<string name="module_sort_a_to_z">Sortuj (A → Z)</string>
|
||||
<string name="module_sort_z_to_a">Sortuj (Z → A)</string>
|
||||
<string name="module_size_low_to_high">Sortuj (Najmniejszy → Największy)</string>
|
||||
<string name="module_size_high_to_low">Sortuj (Największy → Najmniejszy)</string>
|
||||
<string name="module_size_low_to_high">Sortuj (Małe → Duże)</string>
|
||||
<string name="module_size_high_to_low">Sortuj (Duże → Małe)</string>
|
||||
<string name="uninstall">Odinstaluj</string>
|
||||
<string name="restore">Przywróć</string>
|
||||
<string name="module_install">Zainstaluj</string>
|
||||
@@ -216,19 +216,21 @@
|
||||
<string name="settings_banner_summary">Wyświetlaj banery modułów w tle.</string>
|
||||
<string name="use_webuix">Używaj WebUI X</string>
|
||||
<string name="use_webuix_summary">Używaj WebUI X zamiast WebUI, który obsługuje więcej interfejsów API.</string>
|
||||
<string name="use_webuix_eruda">Wstrzyknij Eruda do WebUI X</string>
|
||||
<string name="use_webuix_eruda">Wstrzykiwanie Eruda do WebUI X</string>
|
||||
<string name="use_webuix_eruda_summary">Wstrzyknij konsolę debugowania do WebUI X, aby ułatwić debugowanie. Wymagane jest aktywne debugowanie WebView.</string>
|
||||
<string name="customization">Personalizacja</string>
|
||||
<string name="developer">Programista</string>
|
||||
<string name="sucompat_disabled">SUCOMPAT NIEAKTYWNY</string>
|
||||
<string name="zygisk_required">Wymagany Zygisk</string>
|
||||
<string name="zygisk_status">Wstrzyknięcie Zygisk</string>
|
||||
<string name="zygisk_status">Wstrzykiwanie Zygisk</string>
|
||||
<string name="home_superuser_count_singular">Superuser</string>
|
||||
<string name="home_superuser_count_plural">Superuserzy</string>
|
||||
<string name="home_module_count_singular">Moduł</string>
|
||||
<string name="home_module_count_plural">Moduły</string>
|
||||
<string name="module_backup_message">Utwórz kopię zapasową obecnie zainstalowanych modułów.</string>
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="module_sort_enabled_first">Sortuj (najpierw włączone)</string>
|
||||
<string name="module_sort_action_first">Sortuj (najpierw z Akcją)</string>
|
||||
<string name="module_sort_webui_first">Sortuj (najpierw z WebUI)</string>
|
||||
<string name="settings_global_namespace_mode">Tryb globalnej przestrzeni nazw</string>
|
||||
<string name="settings_global_namespace_mode_summary">Wszystkie sesje roota używają globalnej przestrzeni nazw montowania</string>
|
||||
</resources>
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<string name="install">Instalar</string>
|
||||
<string name="reboot">Reiniciar</string>
|
||||
<string name="uninstalled">Desinstalado</string>
|
||||
<string name="settings">Configurações</string>
|
||||
<string name="settings">Ajustes</string>
|
||||
<string name="reboot_userspace">Reiniciar</string>
|
||||
<string name="reboot_recovery">Reiniciar em modo Recovery</string>
|
||||
<string name="reboot_bootloader">Reiniciar em modo Bootloader</string>
|
||||
@@ -228,7 +228,9 @@
|
||||
<string name="home_module_count_singular">Módulo</string>
|
||||
<string name="home_module_count_plural">Módulos</string>
|
||||
<string name="module_backup_message">Fazer backup dos módulos instalados.</string>
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="module_sort_enabled_first">Ordenar (Habilitado primeiro)</string>
|
||||
<string name="module_sort_action_first">Ordenar (exceto primeiro)</string>
|
||||
<string name="module_sort_webui_first">Ordenar (WebUI primeiro)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="issue_report_title">Возникли проблемы?</string>
|
||||
<string name="issue_report_body">Обнаружена ошибка или есть обратная связь?</string>
|
||||
<string name="issue_report_body">Обнаружена ошибка или нужна обратная связь?</string>
|
||||
<string name="issue_report_body_2">Сообщите об этом как можно скорее!</string>
|
||||
<string name="issue_report_github">Сообщить на GitHub</string>
|
||||
<string name="issue_report_telegram">Связаться через Telegram</string>
|
||||
@@ -100,7 +100,7 @@
|
||||
<string name="allowlist_backup_message">Резервное копирование текущего списка разрешений.</string>
|
||||
<string name="warning">Предупреждение</string>
|
||||
<string name="warning_message">Эта функция всё ещё находится в стадии бета-тестирования. Пожалуйста, убедитесь, что вы создали резервные копии модулей перед использованием. Используйте это только если понимаете возможные риски. Будьте осторожны.</string>
|
||||
<string name="proceed">В процессе</string>
|
||||
<string name="proceed">Продолжить</string>
|
||||
<string name="cancel">Отмена</string>
|
||||
<string name="later">Позже</string>
|
||||
<string name="lkm_warning_message">Патч LKM использует компоненты с закрытым исходным кодом. Хотите продолжить?</string>
|
||||
@@ -117,7 +117,7 @@
|
||||
<string name="profile">Профиль Приложения</string>
|
||||
<string name="profile_default">По умолчанию</string>
|
||||
<string name="profile_template">Шаблон</string>
|
||||
<string name="profile_custom">Настроить</string>
|
||||
<string name="profile_custom">Пользовательский</string>
|
||||
<string name="profile_name">Имя профиля</string>
|
||||
<string name="profile_namespace">Пространство монтирования</string>
|
||||
<string name="profile_namespace_inherited">Унаследованный</string>
|
||||
@@ -126,14 +126,14 @@
|
||||
<string name="profile_groups">Группы</string>
|
||||
<string name="profile_capabilities">Возможности</string>
|
||||
<string name="profile_selinux_context">Контекст SELinux</string>
|
||||
<string name="profile_umount_modules">Отключить модули</string>
|
||||
<string name="profile_umount_modules">Размонтировать модули</string>
|
||||
<string name="failed_to_update_app_profile">Не удалось обновить Профиль Приложения для %s</string>
|
||||
<string name="require_kernel_version">Текущая версия KernelSU Next %1$d слишком низкая для корректной работы менеджера. Пожалуйста, обновитесь до версии %2$d или выше!</string>
|
||||
<string name="settings_umount_modules_default">Отключить модули</string>
|
||||
<string name="settings_umount_modules_default_summary">Глобальное значение по умолчанию для \"Отключить модули\" в Профиле Приложения. Если включено, это удалит все модификации системы модулями для приложений без установленного профиля.</string>
|
||||
<string name="settings_umount_modules_default">Размонтировать модули</string>
|
||||
<string name="settings_umount_modules_default_summary">По умолчанию включает статус \"Umount\" для приложений. Если эта настройка включена, то все модификации, внесённые модулями, будут удалены для приложений без включённого root-доступа.</string>
|
||||
<string name="settings_susfs_toggle">Скрыть хук kprobes</string>
|
||||
<string name="settings_susfs_toggle_summary">Эта опция отключает хук kprobes, созданный ksu, и вместо него активирует встроенный хук без использования kprobes, реализующий ту же функциональность, которая применяется к ядрам без GKI, не поддерживающим kprobe.</string>
|
||||
<string name="profile_umount_modules_summary">Включение этой опции позволит KernelSU Next восстанавливать любые изменённые модулями файлы для этого приложения.</string>
|
||||
<string name="profile_umount_modules_summary">Если эта настройка включена, то все модификации, внесённые модулями, будут удалены для данного приложения.</string>
|
||||
<string name="profile_selinux_domain">Домен</string>
|
||||
<string name="profile_selinux_rules">Правила</string>
|
||||
<string name="module_update">Обновить</string>
|
||||
@@ -153,8 +153,8 @@
|
||||
<string name="failed_to_update_sepolicy">Не удалось обновить правила SELinux для %s</string>
|
||||
<string name="su_not_allowed">Предоставление прав суперпользователя запрещено для: %s</string>
|
||||
<string name="module_changelog">Журнал изменений</string>
|
||||
<string name="settings_profile_template">Шаблон Профиля Приложений</string>
|
||||
<string name="settings_profile_template_summary">Управление локальными и онлайн шаблонами профилей приложений.</string>
|
||||
<string name="settings_profile_template">Шаблоны доступа</string>
|
||||
<string name="settings_profile_template_summary">Управление локальными и онлайн шаблонами root-доступа.</string>
|
||||
<string name="app_profile_template_create">Создать шаблон</string>
|
||||
<string name="app_profile_template_edit">Изменить шаблон</string>
|
||||
<string name="app_profile_template_id">ID</string>
|
||||
@@ -231,4 +231,6 @@
|
||||
<string name="module_sort_enabled_first">По статусу (Сначала включённые)</string>
|
||||
<string name="module_sort_action_first">По статусу (Сначала со скриптом)</string>
|
||||
<string name="module_sort_webui_first">По статусу (Сначала с WebUI)</string>
|
||||
<string name="settings_global_namespace_mode">Общее пространство имён</string>
|
||||
<string name="settings_global_namespace_mode_summary">Все сессии пользователя root будут использовать общее пространство имён</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,4 +231,6 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,4 +231,6 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="issue_report_title">Sorun mu yaşıyorsunuz?</string>
|
||||
<string name="issue_report_body">Hata veya öneri mi bildirmek istiyorsunuz?</string>
|
||||
<string name="issue_report_body_2">Hemen bildirin!</string>
|
||||
<string name="issue_report_github">GitHub\'de bildirin</string>
|
||||
<string name="issue_report_telegram">Telegram ile iletişim kurun</string>
|
||||
<string name="issue_report_body">Bir hatayla mı karşılaştınız veya geri bildiriminiz mi var?</string>
|
||||
<string name="issue_report_body_2">Mümkün olan en kısa sürede bildirin!</string>
|
||||
<string name="issue_report_github">GitHub’da bildirin</string>
|
||||
<string name="issue_report_telegram">Telegram üzerinden iletişim kurun</string>
|
||||
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
|
||||
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
|
||||
<string name="confirm">Onayla</string>
|
||||
<string name="app_name">KernelSU Next</string>
|
||||
<string name="home">Ana Ekran</string>
|
||||
<string name="home_not_installed">Yüklenmedi</string>
|
||||
<string name="home_click_to_install">Yüklemek için dokunun</string>
|
||||
<string name="lkm_mode_deprecated">LKM modu kullanımdan kaldırıldı!</string>
|
||||
<string name="lkm_alternative_suggestion">GKI kernel yükleyin veya KernelSU Next\'i cihazınıza entegre edin.</string>
|
||||
<string name="home_not_installed">Yüklü değil</string>
|
||||
<string name="home_click_to_install">Yüklemek için tıklayın</string>
|
||||
<string name="lkm_mode_deprecated">LKM modu artık kullanımdan kaldırıldı!</string>
|
||||
<string name="lkm_alternative_suggestion">GKI çekirdeğini yükleyin veya KernelSU Next\'i cihazınıza entegre edin.</string>
|
||||
<string name="home_working">Çalışıyor</string>
|
||||
<string name="home_working_version">Sürüm: %d</string>
|
||||
<string name="home_module_update_count">Güncellemeler: %d</string>
|
||||
<string name="home_failure">KernelSU Next v2 imzası kernelde bulunamadı! [ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure">KernelSU Next v2 imzası çekirdekte bulunamadı! [ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure_tip">Kernel geliştiricinizden KernelSU Next\'i entegre etmelerini isteyin!</string>
|
||||
<string name="home_kernel">Kernel sürümü</string>
|
||||
<string name="hook_mode">Hook modu</string>
|
||||
<string name="home_kernel">Çekirdek sürümü</string>
|
||||
<string name="hook_mode">Kanca modu</string>
|
||||
<string name="enable">Etkinleştir</string>
|
||||
<string name="disable">Devre dışı bırak</string>
|
||||
<string name="enabled">Etkinleştir</string>
|
||||
<string name="disabled">Devre dışı bırak</string>
|
||||
<string name="enabled">Etkin</string>
|
||||
<string name="disabled">Devre dışı</string>
|
||||
<string name="susfs_supported">Destekleniyor</string>
|
||||
<string name="home_susfs">SuSFS: %s</string>
|
||||
<string name="home_susfs_version">SuSFS sürümü</string>
|
||||
<string name="home_susfs_sus_su">SuS SU</string>
|
||||
<string name="home_android">Android sürümü</string>
|
||||
<string name="home_manager_version">Uygulama sürümü</string>
|
||||
<string name="home_manager_version">Yönetici sürümü</string>
|
||||
<string name="home_abi">ABI</string>
|
||||
<string name="home_selinux_status">SELinux durumu</string>
|
||||
<string name="selinux_status_disabled">Devre dışı</string>
|
||||
<string name="selinux_status_enforcing">Zorlanıyor</string>
|
||||
<string name="selinux_status_permissive">Etkin değil</string>
|
||||
<string name="selinux_status_permissive">Permissive (Serbest)</string>
|
||||
<string name="selinux_status_unknown">Bilinmiyor</string>
|
||||
<string name="superuser">Superuser</string>
|
||||
<string name="superuser">Süper Kullanıcı</string>
|
||||
<string name="module_failed_to_enable">Modül etkinleştirilemedi: %s</string>
|
||||
<string name="module_failed_to_disable">Modül devre dışı bırakılamadı: %s</string>
|
||||
<string name="module_empty">Yüklenmiş modül yok</string>
|
||||
<string name="module_empty">Yüklü modül yok</string>
|
||||
<string name="module">Modül</string>
|
||||
<string name="module_install_prompt_with_name">Bu modüller yüklenecektir: %1$s</string>
|
||||
<string name="module_sort_a_to_z">Sırala (A → Z)</string>
|
||||
<string name="module_sort_z_to_a">Sırala (Z → A)</string>
|
||||
<string name="module_size_low_to_high">Sırala (Low → High)</string>
|
||||
<string name="module_size_high_to_low">Sırala (High → Low)</string>
|
||||
<string name="module_size_low_to_high">Sırala (Düşük → Yüksek)</string>
|
||||
<string name="module_size_high_to_low">Sırala (Yüksek → Düşük)</string>
|
||||
<string name="uninstall">Kaldır</string>
|
||||
<string name="restore">Geri yükle</string>
|
||||
<string name="module_install">Yükle</string>
|
||||
@@ -63,9 +63,9 @@
|
||||
<string name="module_uninstall_confirm">%s modülünü kaldırmak istediğinize emin misiniz?</string>
|
||||
<string name="module_uninstall_success">%s kaldırıldı</string>
|
||||
<string name="module_uninstall_failed">Kaldırma başarısız oldu: %s</string>
|
||||
<string name="module_restore_confirm">%s modülünü geri getirmek istediğinize emin misiniz?</string>
|
||||
<string name="module_restore_success">%s geri getirildi</string>
|
||||
<string name="module_restore_failed">Geri getirme başarısız oldu: %s</string>
|
||||
<string name="module_restore_confirm">%s modülünü geri yüklemek istediğinize emin misiniz?</string>
|
||||
<string name="module_restore_success">%s geri yüklendi</string>
|
||||
<string name="module_restore_failed">Geri yükleme başarısız oldu: %s</string>
|
||||
<string name="module_version">Sürüm</string>
|
||||
<string name="module_author">Geliştirici</string>
|
||||
<string name="module_id">Kimlik</string>
|
||||
@@ -74,7 +74,7 @@
|
||||
<string name="module_update_json_empty">Boş</string>
|
||||
<string name="enable_developer_options">Geliştirici seçeneklerini etkinleştir</string>
|
||||
<string name="enable_developer_options_summary">Yalnızca geliştiricilere yönelik gizli ayarları ve hata ayıklama bilgilerini göster.</string>
|
||||
<string name="module_overlay_fs_not_available">OverlayFS çekirdek tarafından devre dışı bırakıldığından modüller kullanılamaz!</string>
|
||||
<string name="module_overlay_fs_not_available">OverlayFS çekirdek tarafından devre dışı bırakıldığı için modüller kullanılamıyor!</string>
|
||||
<string name="refresh">Yenile</string>
|
||||
<string name="show_system_apps">Sistem uygulamalarını göster</string>
|
||||
<string name="hide_system_apps">Sistem uygulamalarını gizle</string>
|
||||
@@ -90,28 +90,28 @@
|
||||
<string name="use_overlay_fs_summary">KernelSU Next\'in bağlama sistemi için Magic Mount üzerinden OverlayFS kullanımı arasında geçiş yapın.</string>
|
||||
<string name="reboot_required">Yeniden başlatma gerekli</string>
|
||||
<string name="reboot_message">Değişiklikler sistem yeniden başlatıldıktan sonra geçerli olacaktır. Şimdi yeniden başlatmak istiyor musunuz?</string>
|
||||
<string name="module_restore">Modülü geri getir</string>
|
||||
<string name="module_restore_message">En yeni yedeklemeden modülleri geri getir.</string>
|
||||
<string name="module_restore">Modülü geri yükle</string>
|
||||
<string name="module_restore_message">Modülleri son yedeklemeden geri yükleyin.</string>
|
||||
<string name="backup_restore">Yedekle & Geri Getir</string>
|
||||
<string name="module_backup">Modülü yedekle</string>
|
||||
<string name="allowlist_restore">İzin verilen listesini geri yükle</string>
|
||||
<string name="allowlist_restore_message">En yeni yedeklemeden modülleri geri getir.</string>
|
||||
<string name="allowlist_backup">İzin verilen listesini yedekle</string>
|
||||
<string name="allowlist_restore">İzin listesini geri yükle</string>
|
||||
<string name="allowlist_restore_message">İzin listesini son yedeklemeden geri yükleyin.</string>
|
||||
<string name="allowlist_backup">İzin listesini yedekle</string>
|
||||
<string name="allowlist_backup_message">Şu anda yapılandırılmış izin listesini yedekleyin.</string>
|
||||
<string name="warning">Uyarı!</string>
|
||||
<string name="warning">Uyarı</string>
|
||||
<string name="warning_message">Bu özellik hala beta aşamasındadır ve geliştirilme aşamasındadır. Lütfen devam etmeden önce modüllerinizi yedeklediğinizden emin olun. Bu özelliği yalnızca potansiyel riskleri anlıyorsanız kullanın. Dikkatli bir şekilde ilerleyin.</string>
|
||||
<string name="proceed">Devam et</string>
|
||||
<string name="cancel">İptal et</string>
|
||||
<string name="later">Sonra</string>
|
||||
<string name="lkm_warning_message">LKM yamaları kapalı kaynak kodludur. Devam etmek istiyor musunuz?</string>
|
||||
<string name="home_next_kernelsu">🔥 Sıradaki yapı</string>
|
||||
<string name="lkm_warning_message">LKM yaması kapalı kaynak bileşenlerine dayanır. Devam etmek istiyor musunuz?</string>
|
||||
<string name="home_next_kernelsu">🔥 Next Yapımı</string>
|
||||
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
|
||||
<string name="home_next_kernelsu_body">Next deneysel sürümü. GitHub\'da göz atın!</string>
|
||||
<string name="home_next_kernelsu_body">Next deneysel dalı. GitHub\'da göz atın!</string>
|
||||
<string name="home_experimental_kernelsu">⚠️ Deneysel geliştirme uyarısı!</string>
|
||||
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
|
||||
<string name="home_experimental_kernelsu_body">KernelSU Next, sürekli geliştirme aşamasında olan resmi olmayan bir sürümdür. Kararlılık, performans veya güvenilirlik garantisi olmadan olduğu gibi sunulur.</string>
|
||||
<string name="home_experimental_kernelsu_body_point_1"> • Risk size aittir: çökmeler, beklenmedik davranışlar veya sistem sorunları meydana gelebilir.</string>
|
||||
<string name="home_experimental_kernelsu_body_point_2"> • Garantili değil: geliştiriciler; kullanımından kaynaklı veri kaybı, sistem hasarı gibi sonuçlardan sorumlu değildir.</string>
|
||||
<string name="home_experimental_kernelsu_body_point_2"> • Garanti yok: geliştiriciler herhangi bir veri kaybından, sistem hasarından veya kullanımından kaynaklanan diğer sonuçlardan sorumlu değildir.</string>
|
||||
<string name="home_experimental_kernelsu_body_point_3"> • Sadece test amaçlı: riskleri anlayan ve sorun giderme konusunda uzman olan kullanıcılar içindir.</string>
|
||||
<string name="about_source_code">Kaynak kodunu görüntüleyin: %1$s</string>
|
||||
<string name="profile">Uygulama Profili</string>
|
||||
@@ -121,42 +121,42 @@
|
||||
<string name="profile_name">Profil ismi</string>
|
||||
<string name="profile_namespace">Bağlama alanadı</string>
|
||||
<string name="profile_namespace_inherited">Inherited</string>
|
||||
<string name="profile_namespace_global">Global</string>
|
||||
<string name="profile_namespace_individual">Bireysel</string>
|
||||
<string name="profile_namespace_global">Genel</string>
|
||||
<string name="profile_namespace_individual">Özel</string>
|
||||
<string name="profile_groups">Gruplar</string>
|
||||
<string name="profile_capabilities">Yetenekler</string>
|
||||
<string name="profile_capabilities">Kabiliyetler</string>
|
||||
<string name="profile_selinux_context">SELinux bağlamı</string>
|
||||
<string name="profile_umount_modules">Modüllerin bağlantısını kes</string>
|
||||
<string name="failed_to_update_app_profile">Uygulama profil güncellemesi %s için başarısız oldu</string>
|
||||
<string name="require_kernel_version">Mecvut KernelSU Next sürümü %1$d, uygulamanın doğru çalışması için çok düşük. Lütfen %2$d ya da daha yüksek bir sürüme yükseltin!</string>
|
||||
<string name="failed_to_update_app_profile">%s için Uygulama Profili güncellenemedi</string>
|
||||
<string name="require_kernel_version">Geçerli KernelSU Next sürümü %1$d, yöneticinin düzgün çalışması için çok düşük. Lütfen %2$d veya daha yüksek bir sürüme yükseltin!</string>
|
||||
<string name="settings_umount_modules_default">Modüllerin bağlantısını kes</string>
|
||||
<string name="settings_umount_modules_default_summary">Uygulama profilinde \"Modüllerin bağlantısını kes\" ayarı için genel varsayılan değer. Etkinleştirilirse, profili ayarlanmamış tüm uygulamalar için sistemdeki tüm modül değişikliklerini kaldırır.</string>
|
||||
<string name="settings_susfs_toggle">kprobes kancasını gizle</string>
|
||||
<string name="settings_susfs_toggle_summary">Bu seçenek, ksu tarafından oluşturulan kprobes kancasını devre dışı bırakır ve bunun yerine gömülü kprobes olmayan kancayı etkinleştirir ve kprobe desteklemeyip GKI olmayan bir çekirdeğe uygulanacak aynı işlevi uygular.</string>
|
||||
<string name="profile_umount_modules_summary">Bu seçeneği etkinleştirmek, KernelSU Next\'in bu uygulama için modüller tarafından değiştirilen dosyaları geri yüklemesine izin verecektir.</string>
|
||||
<string name="settings_susfs_toggle_summary">Bu seçenek, ksu tarafından oluşturulan kprobes kancasını devre dışı bırakır ve bunun yerine, kprobe\'u desteklemeyen GKI olmayan bir çekirdeğe uygulanacak aynı işlevselliği uygulayan gömülü kprobes olmayan kancayı etkinleştirir.</string>
|
||||
<string name="profile_umount_modules_summary">Bu seçeneğin etkinleştirilmesi, KernelSU Next\'in bu uygulama için modüller tarafından değiştirilen tüm dosyaları geri yüklemesine izin verecektir.</string>
|
||||
<string name="profile_selinux_domain">Alan adı</string>
|
||||
<string name="profile_selinux_rules">Kurallar</string>
|
||||
<string name="module_update">Güncelleme</string>
|
||||
<string name="module_update">Güncelle</string>
|
||||
<string name="module_update_available">Güncelleme mevcut</string>
|
||||
<string name="module_updated">Güncellendi</string>
|
||||
<string name="module_downloading">Modül indiriliyor: %s</string>
|
||||
<string name="module_start_downloading">İndirme başlıyor: %s</string>
|
||||
<string name="new_version_available">Yeni sürüm %s mevcut, güncellemek için dokunun.</string>
|
||||
<string name="launch_app">Aç</string>
|
||||
<string name="new_version_available">Yeni sürüm %s mevcut, güncellemek için tıklayın.</string>
|
||||
<string name="launch_app">Başlat</string>
|
||||
<string name="close">Kapat</string>
|
||||
<string name="force_stop_app">Durmaya zorla</string>
|
||||
<string name="restart_app">Yeniden başlat</string>
|
||||
<string name="settings_amoled_mode">AMOLED modu</string>
|
||||
<string name="settings_amoled_mode_summary">AMOLED ekranlar için göz yorgunluğunu azaltmak ve pil tasarrufu sağlamak için kullanışlı saf siyah temayı etkinleştirin.</string>
|
||||
<string name="settings_amoled_mode_summary">Göz yorgunluğunu azaltmak ve pil tasarrufu sağlamak için AMOLED ekranlar için kullanışlı olan saf siyah temayı etkinleştirin.</string>
|
||||
<string name="restart_required">Yeniden başlatma gerekli</string>
|
||||
<string name="restart_app_message">Uygulamanın bu değişikliği uygulaması için yeniden başlatılması gerekiyor.</string>
|
||||
<string name="restart_app_message">Bu değişikliğin etkili olması için uygulamanın yeniden başlatılması gerekiyor.</string>
|
||||
<string name="failed_to_update_sepolicy">%s için SELinux kuralları güncellenemedi</string>
|
||||
<string name="su_not_allowed">%s\'ye Superuser izni verilemedi</string>
|
||||
<string name="su_not_allowed">%s\'ye süper kullanıcı izni verilemedi</string>
|
||||
<string name="module_changelog">Değişiklik Notları</string>
|
||||
<string name="settings_profile_template">Uygulama Profili şablonu</string>
|
||||
<string name="settings_profile_template_summary">Uygulama Profil Şablonunu yerel ve çevrimiçi olarak yönetin</string>
|
||||
<string name="settings_profile_template_summary">Uygulama Profilinin yerel ve çevrimiçi şablonunu yönetme</string>
|
||||
<string name="app_profile_template_create">Şablon oluştur</string>
|
||||
<string name="app_profile_template_edit">Şablonu Düzenle</string>
|
||||
<string name="app_profile_template_edit">Şablonu düzenle</string>
|
||||
<string name="app_profile_template_id">Kimlik</string>
|
||||
<string name="app_profile_template_id_invalid">Geçersiz şablon kimliği</string>
|
||||
<string name="app_profile_template_name">Ad</string>
|
||||
@@ -164,12 +164,12 @@
|
||||
<string name="app_profile_template_save">Kaydet</string>
|
||||
<string name="app_profile_template_delete">Sil</string>
|
||||
<string name="app_profile_template_view">Şablonu görüntüle</string>
|
||||
<string name="app_profile_template_readonly">Sadece okunabilir</string>
|
||||
<string name="app_profile_template_readonly">Salt okunur</string>
|
||||
<string name="app_profile_template_id_exist">Şablon kimliği zaten mevcut!</string>
|
||||
<string name="app_profile_import_export">İçe Aktar / Dışa Aktar</string>
|
||||
<string name="app_profile_import_from_clipboard">Pano\'dan içe aktar</string>
|
||||
<string name="app_profile_export_to_clipboard">Panoya çıkar</string>
|
||||
<string name="app_profile_template_export_empty">Dışa aktarmak için yerel şablon bulunamadı!</string>
|
||||
<string name="app_profile_import_from_clipboard">Panodan içe aktar</string>
|
||||
<string name="app_profile_export_to_clipboard">Panoya aktar</string>
|
||||
<string name="app_profile_template_export_empty">Dışa aktarılacak yerel şablon bulunamıyor!</string>
|
||||
<string name="app_profile_template_import_success">Başarıyla içe aktarıldı</string>
|
||||
<string name="app_profile_template_sync">Çevrimiçi şablonları senkronize et</string>
|
||||
<string name="app_profile_template_save_failed">Şablon kaydedilemedi</string>
|
||||
@@ -177,35 +177,35 @@
|
||||
<string name="module_changelog_failed">Değişiklik günlüğü alınamadı: %s</string>
|
||||
<string name="settings_check_update">Güncellemeleri kontrol et</string>
|
||||
<string name="settings_check_update_summary">Uygulamayı açarken güncellemeleri otomatik denetle</string>
|
||||
<string name="grant_root_failed">Kök yetkisi verilemedi!</string>
|
||||
<string name="action">İşlem</string>
|
||||
<string name="grant_root_failed">Kök izni verilemedi!</string>
|
||||
<string name="action">Eylem</string>
|
||||
<string name="webui">WebUI</string>
|
||||
<string name="open">Aç</string>
|
||||
<string name="enable_web_debugging">WebView hata ayıklama etkinleştir</string>
|
||||
<string name="enable_web_debugging_summary">WebUI\'yi hata ayıklamak için kullanılabilir. Sadece ihtiyaç duyulduğunda etkinleştirin.</string>
|
||||
<string name="enable_web_debugging">WebView hata ayıklamayı etkinleştir</string>
|
||||
<string name="enable_web_debugging_summary">WebUI\'de hata ayıklamak için kullanılabilir. Lütfen yalnızca gerektiğinde etkinleştirin.</string>
|
||||
<string name="direct_install">Doğrudan kurulum (Önerilen)</string>
|
||||
<string name="select_file">Bir dosya seçin</string>
|
||||
<string name="install_inactive_slot">Aktif olmayan yuvaya kur (OTA sonrası)</string>
|
||||
<string name="install_inactive_slot_warning">Cihazınız **ZORUNLU** olarak aktif olmayan yuvadan yeniden başlatılacaktır!\nBunu sadece OTA tamamlandıktan sonra kullanın\nDevam etmek istiyor musunuz?</string>
|
||||
<string name="install_next">Sıradaki</string>
|
||||
<string name="install_inactive_slot_warning">Cihazınız yeniden başlatıldıktan sonra mevcut etkin olmayan yuvaya önyükleme yapmak için **ZORUNLU** olacaktır.\nBu seçeneği yalnızca OTA tamamlandıktan sonra kullanın.\nDevam?</string>
|
||||
<string name="install_next">Sonraki</string>
|
||||
<string name="select_file_tip">%1$s bölüm imajı önerilir</string>
|
||||
<string name="select_kmi">KMI seçin</string>
|
||||
<string name="shrink_sparse_image">Sparse imajını küçültün</string>
|
||||
<string name="shrink_sparse_image_message">Modülün bulunduğu sparse imajını gerçek boyutuna yeniden boyutlandırın. Bunun modülün anormal çalışmasına neden olabileceğini unutmayın, bu nedenle lütfen yalnızca gerekli olduğunda kullanın (yedekleme gibi).</string>
|
||||
<string name="shrink_sparse_image_message">Modülün bulunduğu sparse imajını gerçek boyutuna yeniden boyutlandırın. Bunun modülün anormal çalışmasına neden olabileceğini unutmayın, bu nedenle lütfen yalnızca gerekli olduğunda kullanın (Yedekleme gibi).</string>
|
||||
<string name="settings_uninstall">Kaldır</string>
|
||||
<string name="settings_uninstall_temporary">Geçici olarak kaldır</string>
|
||||
<string name="settings_uninstall_permanent">Kalıcı olarak kaldır</string>
|
||||
<string name="settings_restore_stock_image">Stok imajı geri yükle</string>
|
||||
<string name="settings_uninstall_temporary_message">KernelSU\'yu geçici olarak kaldırın, bir sonraki yeniden başlatmadan sonra orijinal duruma geri dönün.</string>
|
||||
<string name="settings_uninstall_permanent_message">KernelSU Next\'i (Root ve tüm modüller) tamamen ve kalıcı olarak kaldırın.</string>
|
||||
<string name="settings_uninstall_permanent_message">KernelSU Next\'i (Kök ve tüm modüller) tamamen ve kalıcı olarak kaldırın.</string>
|
||||
<string name="settings_restore_stock_image_message">Stok fabrika imajını geri yükler (eğer yedek varsa), genellikle OTA\'dan önce kullanılır; KernelSU\'yu kaldırmanız gerekiyorsa, lütfen \"Kalıcı olarak kaldır\" seçeneğini kullanın.</string>
|
||||
<string name="flashing">Kuruluyor</string>
|
||||
<string name="flash_success">Kurulum başarılı</string>
|
||||
<string name="flash_failed">Kurulum başarısız</string>
|
||||
<string name="selected_lkm">Seçili LKM: %s</string>
|
||||
<string name="save_log">Logları kaydet</string>
|
||||
<string name="log_saved">Loglar kaydedildi</string>
|
||||
<string name="send_log">Logları paylaş</string>
|
||||
<string name="save_log">Günlükleri kaydet</string>
|
||||
<string name="log_saved">Günlükler kaydedildi</string>
|
||||
<string name="send_log">Günlükleri paylaş</string>
|
||||
<string name="settings_disable_su">Su uyumluluğunu devre dışı bırak</string>
|
||||
<string name="settings_disable_su_summary">Geçici olarak uygulamaların su komutu ile kök erişimi kazanmasını devre dışı bırakın (Zaten kök erişimi bulunan işlemler etkilenmez).</string>
|
||||
<string name="settings_language">Dil</string>
|
||||
@@ -223,12 +223,14 @@
|
||||
<string name="sucompat_disabled">SUCOMPAT DEVRE DIŞI</string>
|
||||
<string name="zygisk_required">Zygisk gerekli</string>
|
||||
<string name="zygisk_status">Zygisk enjeksiyonu</string>
|
||||
<string name="home_superuser_count_singular">Superuser</string>
|
||||
<string name="home_superuser_count_plural">Superusers</string>
|
||||
<string name="home_superuser_count_singular">Süper Kullanıcı</string>
|
||||
<string name="home_superuser_count_plural">Süper Kullanıcılar</string>
|
||||
<string name="home_module_count_singular">Modül</string>
|
||||
<string name="home_module_count_plural">Modüller</string>
|
||||
<string name="module_backup_message">Şu anda kurulu olan modülleri yedekleyin.</string>
|
||||
<string name="module_sort_enabled_first">Sırala (Önce Etkin)</string>
|
||||
<string name="module_sort_action_first">Sırala (Önce Eylem)</string>
|
||||
<string name="module_sort_enabled_first">Sırala (Önce etkin)</string>
|
||||
<string name="module_sort_action_first">Sırala (Önce eylem)</string>
|
||||
<string name="module_sort_webui_first">Sırala (Önce WebUI)</string>
|
||||
<string name="settings_global_namespace_mode">Küresel Ad Alanı Modu</string>
|
||||
<string name="settings_global_namespace_mode_summary">Tüm kök oturumları genel bağlama ad alanını kullanır</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,4 +231,6 @@
|
||||
<string name="module_sort_enabled_first">За статусом (Спочатку включені)</string>
|
||||
<string name="module_sort_action_first">За статусом (Спочатку зі скриптом)</string>
|
||||
<string name="module_sort_webui_first">За статусом (Спочатку з WebUI)</string>
|
||||
<string name="settings_global_namespace_mode">Загальний простір імен</string>
|
||||
<string name="settings_global_namespace_mode_summary">Усі сесії користувача root будуть використовувати спільний простір імен</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,4 +231,6 @@
|
||||
<string name="module_sort_enabled_first">Sắp xếp (Bật trước)</string>
|
||||
<string name="module_sort_action_first">Sắp xếp (Khởi chạy trước)</string>
|
||||
<string name="module_sort_webui_first">Sắp xếp (WebUI trước)</string>
|
||||
<string name="settings_global_namespace_mode">Chế độ Namespace chung</string>
|
||||
<string name="settings_global_namespace_mode_summary">Tất cả các phiên root đều sử dụng mount namespace chung</string>
|
||||
</resources>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<string name="lkm_mode_deprecated">LKM 模式已弃用!</string>
|
||||
<string name="lkm_alternative_suggestion">安装 GKI 内核或集成 KernelSU 到你的设备。</string>
|
||||
<string name="home_working">工作中</string>
|
||||
<string name="home_working_version">版本:%d</string>
|
||||
<string name="home_working_version">版本: %d</string>
|
||||
<string name="home_module_update_count">%d 个模块可更新!</string>
|
||||
<string name="home_failure">无法在内核中找到 KernelSU Next v2 签名![ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure_tip">请让你的内核开发人员集成 KernelSU Next!</string>
|
||||
@@ -26,27 +26,27 @@
|
||||
<string name="enabled">已启用</string>
|
||||
<string name="disabled">已禁用</string>
|
||||
<string name="susfs_supported">支持</string>
|
||||
<string name="home_susfs">SuSFS:%s</string>
|
||||
<string name="home_susfs">SuSFS: %s</string>
|
||||
<string name="home_susfs_version">SuSFS 版本</string>
|
||||
<string name="home_susfs_sus_su">SuS SU</string>
|
||||
<string name="home_android">Android 版本</string>
|
||||
<string name="home_manager_version">管理器版本</string>
|
||||
<string name="home_abi">接口</string>
|
||||
<string name="home_abi">ABI 类型</string>
|
||||
<string name="home_selinux_status">SELinux 状态</string>
|
||||
<string name="selinux_status_disabled">禁用</string>
|
||||
<string name="selinux_status_enforcing">严格模式</string>
|
||||
<string name="selinux_status_permissive">宽容模式</string>
|
||||
<string name="selinux_status_unknown">未知</string>
|
||||
<string name="superuser">超级用户</string>
|
||||
<string name="module_failed_to_enable">启用模块失败:%s</string>
|
||||
<string name="module_failed_to_disable">禁用模块失败:%s</string>
|
||||
<string name="module_failed_to_enable">无法启用模块: %s</string>
|
||||
<string name="module_failed_to_disable">无法禁用模块: %s</string>
|
||||
<string name="module_empty">未安装任何模块</string>
|
||||
<string name="module">模块</string>
|
||||
<string name="module_install_prompt_with_name">将安装以下模块:%1$s</string>
|
||||
<string name="module_sort_a_to_z">按 A - Z 排序</string>
|
||||
<string name="module_sort_z_to_a">按 Z - A 排序</string>
|
||||
<string name="module_size_low_to_high">按模块大小正序排序</string>
|
||||
<string name="module_size_high_to_low">按模块大小倒序排序</string>
|
||||
<string name="module_install_prompt_with_name">将安装以下模块: %1$s</string>
|
||||
<string name="module_sort_a_to_z">排序 (A -> Z)</string>
|
||||
<string name="module_sort_z_to_a">排序 (Z -> A)</string>
|
||||
<string name="module_size_low_to_high">排序 (按模块从小到大)</string>
|
||||
<string name="module_size_high_to_low">排序 (按模块从大到小)</string>
|
||||
<string name="uninstall">卸载</string>
|
||||
<string name="restore">还原</string>
|
||||
<string name="module_install">安装</string>
|
||||
@@ -62,10 +62,10 @@
|
||||
<string name="about">关于</string>
|
||||
<string name="module_uninstall_confirm">确定要卸载模块 %s 吗?</string>
|
||||
<string name="module_uninstall_success">已卸载 %s</string>
|
||||
<string name="module_uninstall_failed">卸载失败:%s</string>
|
||||
<string name="module_uninstall_failed">卸载失败: %s</string>
|
||||
<string name="module_restore_confirm">确定要还原模块 %s 吗?</string>
|
||||
<string name="module_restore_success">已还原 %s</string>
|
||||
<string name="module_restore_failed">恢复失败:%s</string>
|
||||
<string name="module_restore_failed">恢复失败: %s</string>
|
||||
<string name="module_version">版本</string>
|
||||
<string name="module_author">作者</string>
|
||||
<string name="module_id">模块标识</string>
|
||||
@@ -82,7 +82,7 @@
|
||||
<string name="safe_mode">安全模式</string>
|
||||
<string name="reboot_to_apply">重启生效</string>
|
||||
<string name="module_magisk_conflict">由于与 Magisk 冲突,模块系统不可用!</string>
|
||||
<string name="home_mount_system">模块系统</string>
|
||||
<string name="home_mount_system">挂载系统</string>
|
||||
<string name="home_magic_mount">Magic Mount</string>
|
||||
<string name="home_overlayfs_mount">OverlayFS</string>
|
||||
<string name="unavailable">不可用</string>
|
||||
@@ -103,10 +103,10 @@
|
||||
<string name="proceed">继续</string>
|
||||
<string name="cancel">取消</string>
|
||||
<string name="later">稍后</string>
|
||||
<string name="lkm_warning_message">此 LKM 补丁依赖于闭源组件,确认操作代表你知晓因继续使用该功能所导致的一切后果与开发团队无关。</string>
|
||||
<string name="home_next_kernelsu">🔥 Next 构建</string>
|
||||
<string name="lkm_warning_message">LKM 补丁依赖于闭源组件。是否继续?</string>
|
||||
<string name="home_next_kernelsu">🔥 下一个版本</string>
|
||||
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
|
||||
<string name="home_next_kernelsu_body">Next 实验性分支。在 GitHub 上查看!</string>
|
||||
<string name="home_next_kernelsu_body">下一个实验性分支。请在 GitHub 上查看!</string>
|
||||
<string name="home_experimental_kernelsu">⚠️ 实验性开发警告!</string>
|
||||
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
|
||||
<string name="home_experimental_kernelsu_body">KernelSU Next 是一个非官方版本,一直处于积极的实验开发阶段。它按原样提供,不保证稳定性、性能或可靠性。</string>
|
||||
@@ -139,9 +139,9 @@
|
||||
<string name="module_update">更新</string>
|
||||
<string name="module_update_available">更新可用</string>
|
||||
<string name="module_updated">重启以应用更新</string>
|
||||
<string name="module_downloading">正在下载模块:%s</string>
|
||||
<string name="module_start_downloading">开始下载:%s</string>
|
||||
<string name="new_version_available">发现新版本:%s,点击升级。</string>
|
||||
<string name="module_downloading">正在下载模块: %s</string>
|
||||
<string name="module_start_downloading">开始下载: %s</string>
|
||||
<string name="new_version_available">发现新版本 %s,点击升级。</string>
|
||||
<string name="launch_app">启动</string>
|
||||
<string name="close">关闭</string>
|
||||
<string name="force_stop_app">强行停止</string>
|
||||
@@ -174,7 +174,7 @@
|
||||
<string name="app_profile_template_sync">同步在线模板</string>
|
||||
<string name="app_profile_template_save_failed">模版保存失败</string>
|
||||
<string name="app_profile_template_import_empty">剪贴板为空!</string>
|
||||
<string name="module_changelog_failed">获取更新日志失败:%s</string>
|
||||
<string name="module_changelog_failed">获取更新日志失败: %s</string>
|
||||
<string name="settings_check_update">检查更新</string>
|
||||
<string name="settings_check_update_summary">在应用启动后自动检查是否有新版本。</string>
|
||||
<string name="grant_root_failed">获取 root 失败!</string>
|
||||
@@ -202,7 +202,7 @@
|
||||
<string name="flashing">刷写中</string>
|
||||
<string name="flash_success">刷写成功</string>
|
||||
<string name="flash_failed">刷写失败</string>
|
||||
<string name="selected_lkm">选择的 LKM:%s</string>
|
||||
<string name="selected_lkm">选择的 LKM: %s</string>
|
||||
<string name="save_log">保存日志</string>
|
||||
<string name="log_saved">日志已保存</string>
|
||||
<string name="send_log">分享日志</string>
|
||||
@@ -220,7 +220,7 @@
|
||||
<string name="use_webuix_eruda_summary">将调试控制台注入 WebUI X 以使调试更容易。需要启用 Web 调试。</string>
|
||||
<string name="customization">界面设置</string>
|
||||
<string name="developer">开发者选项</string>
|
||||
<string name="sucompat_disabled">SU 兼容被禁用</string>
|
||||
<string name="sucompat_disabled">SU 兼容已禁用</string>
|
||||
<string name="zygisk_required">需要 Zygisk</string>
|
||||
<string name="zygisk_status">Zygisk 注入</string>
|
||||
<string name="home_superuser_count_singular">超级用户</string>
|
||||
@@ -228,7 +228,9 @@
|
||||
<string name="home_module_count_singular">模块</string>
|
||||
<string name="home_module_count_plural">模块</string>
|
||||
<string name="module_backup_message">备份当前已安装的模块。</string>
|
||||
<string name="module_sort_enabled_first">按启用状态优先排序</string>
|
||||
<string name="module_sort_action_first">按支持执行脚本的模块优先排序</string>
|
||||
<string name="module_sort_webui_first">按拥有 WebUI 的模块优先排序</string>
|
||||
<string name="module_sort_enabled_first">排序 (已启用优先)</string>
|
||||
<string name="module_sort_action_first">排序 (可执行优先)</string>
|
||||
<string name="module_sort_webui_first">排序 (支持 WebUI 优先)</string>
|
||||
<string name="settings_global_namespace_mode">全局命名空间模式</string>
|
||||
<string name="settings_global_namespace_mode_summary">所有 Root 会话均使用全局挂载命名空间。</string>
|
||||
</resources>
|
||||
|
||||
@@ -229,6 +229,8 @@
|
||||
<string name="home_module_count_plural">模組</string>
|
||||
<string name="module_backup_message">備份當前已安裝的模組。</string>
|
||||
<string name="module_sort_enabled_first">依啟用狀態優先排序</string>
|
||||
<string name="module_sort_action_first">依支援執行腳本的模組優先排序</string>
|
||||
<string name="module_sort_webui_first">依具備 WebUI 的模組優先排序</string>
|
||||
<string name="module_sort_action_first">依支援執行優先排序</string>
|
||||
<string name="module_sort_webui_first">依具備 WebUI 優先排序</string>
|
||||
<string name="settings_global_namespace_mode">全域命名空間模式</string>
|
||||
<string name="settings_global_namespace_mode_summary">所有 Root 工作階段皆使用全域掛載命名空間</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,4 +231,6 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
26
manager/setup.sh
Executable file
26
manager/setup.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
|
||||
> gradle.properties
|
||||
|
||||
{
|
||||
echo 'android.experimental.enableNewResourceShrinker.preciseShrinking=true'
|
||||
echo 'android.enableAppCompileTimeRClass=true'
|
||||
echo 'android.useAndroidX=true'
|
||||
echo KEYSTORE_PASSWORD=$MY_KEYSTORE_PASSWORD
|
||||
echo KEY_ALIAS=$MY_KEY_ALIAS
|
||||
echo KEY_PASSWORD=$MY_KEY_PASSWORD
|
||||
echo KEYSTORE_FILE='key.jks'
|
||||
echo 'org.gradle.parallel=true'
|
||||
echo 'org.gradle.vfs.watch=true'
|
||||
echo 'org.gradle.jvmargs=-Xmx2048m'
|
||||
echo 'android.native.buildOutput=verbose'
|
||||
} >> gradle.properties
|
||||
|
||||
./gradlew clean assembleRelease
|
||||
|
||||
> gradle.properties
|
||||
|
||||
{
|
||||
echo 'android.experimental.enableNewResourceShrinker.preciseShrinking=true'
|
||||
echo 'android.enableAppCompileTimeRClass=true'
|
||||
echo 'android.useAndroidX=true'
|
||||
} >> gradle.properties
|
||||
@@ -31,4 +31,9 @@ if [ -f "./build.gradle.kts" ]; then
|
||||
sed -i 's/\(versionName = managerVersionName\)/versionName = managerVersionNameSpoofed/' ./build.gradle.kts
|
||||
fi
|
||||
|
||||
if [ -f "./app/build.gradle.kts" ]; then
|
||||
sed -i '/val managerVersionName:/a val managerVersionNameSpoofed = "${managerVersionName}-spoofed"' ./app/build.gradle.kts
|
||||
sed -i 's/outputFileName = "KernelSU_Next_${managerVersionName}_${managerVersionCode}-\$name.apk"/outputFileName = "KernelSU_Next_${managerVersionNameSpoofed}_${managerVersionCode}-\$name.apk"/' ./app/build.gradle.kts
|
||||
fi
|
||||
|
||||
echo "Done."
|
||||
|
||||
@@ -310,7 +310,7 @@ pub fn restore(
|
||||
|
||||
let skip_init = kmi.starts_with("android12-");
|
||||
|
||||
let (bootimage, bootdevice) = find_boot_image(&image, skip_init, false, false, workdir)?;
|
||||
let (bootimage, bootdevice) = find_boot_image(&image, skip_init, false, false, workdir, &magiskboot)?;
|
||||
|
||||
println!("- Unpacking boot image");
|
||||
let status = Command::new(&magiskboot)
|
||||
@@ -323,6 +323,7 @@ pub fn restore(
|
||||
ensure!(status.success(), "magiskboot unpack failed");
|
||||
|
||||
let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
|
||||
// let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
|
||||
let no_vendor_init_boot = !workdir
|
||||
.join("vendor_ramdisk")
|
||||
.join("init_boot.cpio")
|
||||
@@ -370,41 +371,78 @@ pub fn restore(
|
||||
}
|
||||
|
||||
if new_boot.is_none() {
|
||||
if no_ramdisk {
|
||||
if !no_vendor_init_boot {
|
||||
// vendor init_boot restore
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
let status =
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio");
|
||||
std::fs::remove_file(vendor_init_boot)?;
|
||||
}
|
||||
} else if !no_vendor_ramdisk {
|
||||
// vendor ramdisk restore
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
let status =
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
let vendor_ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
|
||||
std::fs::remove_file(vendor_ramdisk)?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if !no_ramdisk {
|
||||
println!("- Restoring /ramdisk");
|
||||
println!("- Removing /ramdisk/kernelsu.ko");
|
||||
// remove kernelsu.ko
|
||||
do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
// if init.real exists, restore it
|
||||
println!("- Checking if init.real exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /ramdisk/init.real exists");
|
||||
println!("- Restoring /ramdisk/init.real to init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /ramdisk/init.real not found");
|
||||
println!("- Removing ramdisk.cpio");
|
||||
let ramdisk = workdir.join("ramdisk.cpio");
|
||||
std::fs::remove_file(ramdisk)?;
|
||||
}
|
||||
} else if !no_vendor_init_boot {
|
||||
println!("- Restoring /vendor_ramdisk/init_boot");
|
||||
println!("- Removing /vendor_ramdisk/init_boot/kernelsu.ko");
|
||||
// vendor init_boot restore
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
println!("- Checking if init.real exists");
|
||||
let status =
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /vendor_ramdisk/init_boot/init.real exists");
|
||||
println!("- Restoring /vendor_ramdisk/init_boot/init.real to init");
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /vendor_ramdisk/init_boot/init.real not found");
|
||||
println!("- Removing vendor_ramdisk/init_boot.cpio");
|
||||
let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio");
|
||||
std::fs::remove_file(vendor_init_boot)?;
|
||||
}
|
||||
} else if !no_vendor_ramdisk {
|
||||
println!("- Restoring /vendor_ramdisk/ramdisk");
|
||||
println!("- Removing /vendor_ramdisk/ramdisk/kernelsu.ko");
|
||||
// vendor ramdisk restore
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
let status =
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /vendor_ramdisk/ramdisk/init.real exists");
|
||||
println!("- Restoring /vendor_ramdisk/ramdisk/init.real to init");
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /vendor_ramdisk/ramdisk/init.real not found");
|
||||
println!("- Removing vendor_ramdisk/ramdisk.cpio");
|
||||
let vendor_ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
|
||||
std::fs::remove_file(vendor_ramdisk)?;
|
||||
}
|
||||
} else {
|
||||
println!("- Restoring /ramdisk");
|
||||
println!("- Removing /ramdisk/kernelsu.ko");
|
||||
// remove kernelsu.ko
|
||||
do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
// if init.real exists, restore it
|
||||
println!("- Checking if init.real exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /ramdisk/init.real exists");
|
||||
println!("- Restoring /ramdisk/init.real to init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /ramdisk/init.real not found");
|
||||
println!("- Removing ramdisk.cpio");
|
||||
let ramdisk = workdir.join("ramdisk.cpio");
|
||||
std::fs::remove_file(ramdisk)?;
|
||||
}
|
||||
@@ -536,7 +574,7 @@ fn do_patch(
|
||||
let skip_init = kmi.starts_with("android12-");
|
||||
|
||||
let (bootimage, bootdevice) =
|
||||
find_boot_image(&image, skip_init, ota, is_replace_kernel, workdir)?;
|
||||
find_boot_image(&image, skip_init, ota, is_replace_kernel, workdir, &magiskboot)?;
|
||||
|
||||
let bootimage = bootimage.display().to_string();
|
||||
|
||||
@@ -584,7 +622,8 @@ fn do_patch(
|
||||
.exists();
|
||||
let no_vendor_ramdisk = !workdir.join("vendor_ramdisk").join("ramdisk.cpio").exists();
|
||||
if no_ramdisk && no_vendor_init_boot && no_vendor_ramdisk {
|
||||
bail!("No compatible ramdisk found.");
|
||||
println!("- No compatible ramdisk found.");
|
||||
println!("- Will create our own ramdisk!");
|
||||
}
|
||||
let is_magisk_patched = is_magisk_patched(&magiskboot, workdir)?;
|
||||
let is_magisk_patched_vendor_init_boot =
|
||||
@@ -605,43 +644,59 @@ fn do_patch(
|
||||
is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?;
|
||||
|
||||
let mut need_backup = false;
|
||||
if !is_kernelsu_patched
|
||||
|| (no_ramdisk && !is_kernelsu_patched_vendor_init_boot)
|
||||
if (no_ramdisk && !is_kernelsu_patched_vendor_init_boot)
|
||||
|| (no_ramdisk && no_vendor_init_boot && !is_kernelsu_patched_vendor_ramdisk)
|
||||
|| !is_kernelsu_patched
|
||||
{
|
||||
if no_ramdisk {
|
||||
if !no_vendor_init_boot {
|
||||
// vendor init_boot patching
|
||||
let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
} else if !no_vendor_ramdisk {
|
||||
// vendor ramdisk patching
|
||||
let status = do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// kernelsu.ko is not exist, backup init if necessary
|
||||
if !no_ramdisk {
|
||||
println!("- Checking if /ramdisk/init exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up ramdisk/init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
} else if !no_vendor_init_boot {
|
||||
println!("- Checking if /vendor_ramdisk/init_boot/init exists");
|
||||
let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up vendor_ramdisk/init_boot/init");
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
} else if !no_vendor_ramdisk {
|
||||
println!("- Checking if /vendor_ramdisk/ramdisk/init exists");
|
||||
let status = do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up vendor_ramdisk/ramdisk/init");
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
} else {
|
||||
println!("- Checking if /ramdisk/init exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up ramdisk/init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
}
|
||||
}
|
||||
|
||||
if no_ramdisk {
|
||||
if !no_vendor_init_boot {
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
} else if !no_vendor_ramdisk {
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?;
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?;
|
||||
}
|
||||
if !no_ramdisk {
|
||||
println!("- Patching /ramdisk");
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
} else if !no_vendor_init_boot {
|
||||
println!("- Patching /vendor_ramdisk/init_boot");
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
} else if !no_vendor_ramdisk {
|
||||
println!("- Patching /vendor_ramdisk/ramdisk");
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?;
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?;
|
||||
} else {
|
||||
println!("- Creating and Patching /ramdisk");
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
}
|
||||
@@ -800,16 +855,17 @@ fn find_boot_image(
|
||||
ota: bool,
|
||||
is_replace_kernel: bool,
|
||||
workdir: &Path,
|
||||
magiskboot: &Path,
|
||||
) -> Result<(PathBuf, Option<String>)> {
|
||||
let bootimage;
|
||||
let mut bootdevice = None;
|
||||
if let Some(ref image) = *image {
|
||||
ensure!(image.exists(), "boot image not found");
|
||||
ensure!(image.exists(), "- Boot image not found");
|
||||
bootimage = std::fs::canonicalize(image)?;
|
||||
} else {
|
||||
if cfg!(not(target_os = "android")) {
|
||||
println!("- Current OS is not android, refusing auto bootimage/bootdevice detection");
|
||||
bail!("Please specify a boot image");
|
||||
bail!("- Please specify a boot image");
|
||||
}
|
||||
let mut slot_suffix =
|
||||
utils::getprop("ro.boot.slot_suffix").unwrap_or_else(|| String::from(""));
|
||||
@@ -822,27 +878,104 @@ fn find_boot_image(
|
||||
}
|
||||
};
|
||||
|
||||
let init_boot_exist =
|
||||
Path::new(&format!("/dev/block/by-name/init_boot{slot_suffix}")).exists();
|
||||
let vendor_boot_exist =
|
||||
Path::new(&format!("/dev/block/by-name/vendor_boot{slot_suffix}")).exists();
|
||||
let boot_partition = if !is_replace_kernel && init_boot_exist && !skip_init {
|
||||
format!("/dev/block/by-name/init_boot{slot_suffix}")
|
||||
} else if !is_replace_kernel && vendor_boot_exist && !skip_init {
|
||||
format!("/dev/block/by-name/vendor_boot{slot_suffix}")
|
||||
} else {
|
||||
format!("/dev/block/by-name/boot{slot_suffix}")
|
||||
};
|
||||
let init_boot_partition = format!("/dev/block/by-name/init_boot{slot_suffix}");
|
||||
let vendor_boot_partition = format!("/dev/block/by-name/vendor_boot{slot_suffix}");
|
||||
let boot_partition = format!("/dev/block/by-name/boot{slot_suffix}");
|
||||
|
||||
println!("- Bootdevice: {boot_partition}");
|
||||
let init_boot_exist = Path::new(&init_boot_partition).exists();
|
||||
let vendor_boot_exist = Path::new(&vendor_boot_partition).exists();
|
||||
|
||||
// helper: unpack a partition and check for a ramdisk and init
|
||||
fn unpack_and_check_init(
|
||||
magiskboot: &Path,
|
||||
workdir: &Path,
|
||||
partition: &str,
|
||||
ramdisk_cpio: &str,
|
||||
) -> Result<bool> {
|
||||
let tmp_img = workdir.join("probe.img");
|
||||
dd(partition, &tmp_img)?;
|
||||
let status = Command::new(magiskboot)
|
||||
.current_dir(workdir)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.arg("unpack")
|
||||
.arg(&tmp_img)
|
||||
.status()?;
|
||||
if !status.success() {
|
||||
let _ = std::fs::remove_file(&tmp_img);
|
||||
return Ok(false);
|
||||
}
|
||||
let ramdisk_path = workdir.join(ramdisk_cpio);
|
||||
let has_init = if ramdisk_path.exists() {
|
||||
Command::new(magiskboot)
|
||||
.current_dir(workdir)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.arg("cpio")
|
||||
.arg(ramdisk_cpio)
|
||||
.arg("exists init")
|
||||
.status()
|
||||
.map(|s| s.success())
|
||||
.unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
// Clean up
|
||||
let _ = std::fs::remove_file(&tmp_img);
|
||||
let _ = std::fs::remove_file(workdir.join("ramdisk.cpio"));
|
||||
let _ = std::fs::remove_dir_all(workdir.join("vendor_ramdisk"));
|
||||
Ok(has_init)
|
||||
}
|
||||
|
||||
let mut selected_partition = &boot_partition;
|
||||
|
||||
if !is_replace_kernel && init_boot_exist && !skip_init {
|
||||
// try init_boot/ramdisk.cpio
|
||||
if unpack_and_check_init(magiskboot, workdir, &init_boot_partition, "ramdisk.cpio")? {
|
||||
println!("- Using init_boot partition (ramdisk.cpio).");
|
||||
selected_partition = &init_boot_partition;
|
||||
}
|
||||
}
|
||||
|
||||
// try vendor_boot/vendor_ramdisk/init_boot.cpio
|
||||
if selected_partition == &boot_partition && !is_replace_kernel && vendor_boot_exist && !skip_init {
|
||||
if unpack_and_check_init(
|
||||
magiskboot,
|
||||
workdir,
|
||||
&vendor_boot_partition,
|
||||
"vendor_ramdisk/init_boot.cpio",
|
||||
)? {
|
||||
println!("- Using vendor_boot partition (vendor_ramdisk/init_boot.cpio).");
|
||||
selected_partition = &vendor_boot_partition;
|
||||
}
|
||||
}
|
||||
|
||||
// try vendor_boot/vendor_ramdisk/ramdisk.cpio
|
||||
if selected_partition == &boot_partition && !is_replace_kernel && vendor_boot_exist && !skip_init {
|
||||
if unpack_and_check_init(
|
||||
magiskboot,
|
||||
workdir,
|
||||
&vendor_boot_partition,
|
||||
"vendor_ramdisk/ramdisk.cpio",
|
||||
)? {
|
||||
println!("- Using vendor_boot partition (vendor_ramdisk/ramdisk.cpio).");
|
||||
selected_partition = &vendor_boot_partition;
|
||||
}
|
||||
}
|
||||
|
||||
if selected_partition == &boot_partition {
|
||||
println!("- Using boot partition (ramdisk.cpio).");
|
||||
}
|
||||
|
||||
println!("- Bootdevice: {selected_partition}");
|
||||
let tmp_boot_path = workdir.join("boot.img");
|
||||
|
||||
dd(&boot_partition, &tmp_boot_path)?;
|
||||
dd(selected_partition, &tmp_boot_path)?;
|
||||
|
||||
ensure!(tmp_boot_path.exists(), "boot image not found");
|
||||
ensure!(tmp_boot_path.exists(), "- Tmp boot image not found");
|
||||
|
||||
bootimage = tmp_boot_path;
|
||||
bootdevice = Some(boot_partition);
|
||||
bootdevice = Some(selected_partition.to_string());
|
||||
};
|
||||
Ok((bootimage, bootdevice))
|
||||
}
|
||||
|
||||
@@ -44,3 +44,5 @@ pub const NO_TMPFS_PATH: &str = concatcp!(WORKING_DIR, ".notmpfs");
|
||||
pub const NO_MOUNT_PATH: &str = concatcp!(WORKING_DIR, ".nomount");
|
||||
|
||||
pub const MOUNT_SYSTEM: &str = "Magic_Mount";
|
||||
|
||||
pub const GLOBAL_NAMESPACE_FILE: &str = concatcp!(WORKING_DIR, ".global_mnt");
|
||||
|
||||
@@ -261,7 +261,9 @@ pub fn root_shell() -> Result<()> {
|
||||
|
||||
// switch to global mount namespace
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
if mount_master {
|
||||
let global_namespace_enable =
|
||||
std::fs::read_to_string(defs::GLOBAL_NAMESPACE_FILE).unwrap_or("0".to_string());
|
||||
if global_namespace_enable.trim() == "1" || mount_master {
|
||||
let _ = utils::switch_mnt_ns(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -310,7 +310,7 @@ pub fn restore(
|
||||
|
||||
let skip_init = kmi.starts_with("android12-");
|
||||
|
||||
let (bootimage, bootdevice) = find_boot_image(&image, skip_init, false, false, workdir)?;
|
||||
let (bootimage, bootdevice) = find_boot_image(&image, skip_init, false, false, workdir, &magiskboot)?;
|
||||
|
||||
println!("- Unpacking boot image");
|
||||
let status = Command::new(&magiskboot)
|
||||
@@ -323,6 +323,7 @@ pub fn restore(
|
||||
ensure!(status.success(), "magiskboot unpack failed");
|
||||
|
||||
let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
|
||||
// let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
|
||||
let no_vendor_init_boot = !workdir
|
||||
.join("vendor_ramdisk")
|
||||
.join("init_boot.cpio")
|
||||
@@ -370,41 +371,78 @@ pub fn restore(
|
||||
}
|
||||
|
||||
if new_boot.is_none() {
|
||||
if no_ramdisk {
|
||||
if !no_vendor_init_boot {
|
||||
// vendor init_boot restore
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
let status =
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio");
|
||||
std::fs::remove_file(vendor_init_boot)?;
|
||||
}
|
||||
} else if !no_vendor_ramdisk {
|
||||
// vendor ramdisk restore
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
let status =
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
let vendor_ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
|
||||
std::fs::remove_file(vendor_ramdisk)?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if !no_ramdisk {
|
||||
println!("- Restoring /ramdisk");
|
||||
println!("- Removing /ramdisk/kernelsu.ko");
|
||||
// remove kernelsu.ko
|
||||
do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
// if init.real exists, restore it
|
||||
println!("- Checking if init.real exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /ramdisk/init.real exists");
|
||||
println!("- Restoring /ramdisk/init.real to init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /ramdisk/init.real not found");
|
||||
println!("- Removing ramdisk.cpio");
|
||||
let ramdisk = workdir.join("ramdisk.cpio");
|
||||
std::fs::remove_file(ramdisk)?;
|
||||
}
|
||||
} else if !no_vendor_init_boot {
|
||||
println!("- Restoring /vendor_ramdisk/init_boot");
|
||||
println!("- Removing /vendor_ramdisk/init_boot/kernelsu.ko");
|
||||
// vendor init_boot restore
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
println!("- Checking if init.real exists");
|
||||
let status =
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /vendor_ramdisk/init_boot/init.real exists");
|
||||
println!("- Restoring /vendor_ramdisk/init_boot/init.real to init");
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /vendor_ramdisk/init_boot/init.real not found");
|
||||
println!("- Removing vendor_ramdisk/init_boot.cpio");
|
||||
let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio");
|
||||
std::fs::remove_file(vendor_init_boot)?;
|
||||
}
|
||||
} else if !no_vendor_ramdisk {
|
||||
println!("- Restoring /vendor_ramdisk/ramdisk");
|
||||
println!("- Removing /vendor_ramdisk/ramdisk/kernelsu.ko");
|
||||
// vendor ramdisk restore
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
let status =
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /vendor_ramdisk/ramdisk/init.real exists");
|
||||
println!("- Restoring /vendor_ramdisk/ramdisk/init.real to init");
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /vendor_ramdisk/ramdisk/init.real not found");
|
||||
println!("- Removing vendor_ramdisk/ramdisk.cpio");
|
||||
let vendor_ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
|
||||
std::fs::remove_file(vendor_ramdisk)?;
|
||||
}
|
||||
} else {
|
||||
println!("- Restoring /ramdisk");
|
||||
println!("- Removing /ramdisk/kernelsu.ko");
|
||||
// remove kernelsu.ko
|
||||
do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
// if init.real exists, restore it
|
||||
println!("- Checking if init.real exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /ramdisk/init.real exists");
|
||||
println!("- Restoring /ramdisk/init.real to init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /ramdisk/init.real not found");
|
||||
println!("- Removing ramdisk.cpio");
|
||||
let ramdisk = workdir.join("ramdisk.cpio");
|
||||
std::fs::remove_file(ramdisk)?;
|
||||
}
|
||||
@@ -536,7 +574,7 @@ fn do_patch(
|
||||
let skip_init = kmi.starts_with("android12-");
|
||||
|
||||
let (bootimage, bootdevice) =
|
||||
find_boot_image(&image, skip_init, ota, is_replace_kernel, workdir)?;
|
||||
find_boot_image(&image, skip_init, ota, is_replace_kernel, workdir, &magiskboot)?;
|
||||
|
||||
let bootimage = bootimage.display().to_string();
|
||||
|
||||
@@ -584,7 +622,8 @@ fn do_patch(
|
||||
.exists();
|
||||
let no_vendor_ramdisk = !workdir.join("vendor_ramdisk").join("ramdisk.cpio").exists();
|
||||
if no_ramdisk && no_vendor_init_boot && no_vendor_ramdisk {
|
||||
bail!("No compatible ramdisk found.");
|
||||
println!("- No compatible ramdisk found.");
|
||||
println!("- Will create our own ramdisk!");
|
||||
}
|
||||
let is_magisk_patched = is_magisk_patched(&magiskboot, workdir)?;
|
||||
let is_magisk_patched_vendor_init_boot =
|
||||
@@ -605,43 +644,59 @@ fn do_patch(
|
||||
is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?;
|
||||
|
||||
let mut need_backup = false;
|
||||
if !is_kernelsu_patched
|
||||
|| (no_ramdisk && !is_kernelsu_patched_vendor_init_boot)
|
||||
if (no_ramdisk && !is_kernelsu_patched_vendor_init_boot)
|
||||
|| (no_ramdisk && no_vendor_init_boot && !is_kernelsu_patched_vendor_ramdisk)
|
||||
|| !is_kernelsu_patched
|
||||
{
|
||||
if no_ramdisk {
|
||||
if !no_vendor_init_boot {
|
||||
// vendor init_boot patching
|
||||
let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
} else if !no_vendor_ramdisk {
|
||||
// vendor ramdisk patching
|
||||
let status = do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// kernelsu.ko is not exist, backup init if necessary
|
||||
if !no_ramdisk {
|
||||
println!("- Checking if /ramdisk/init exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up ramdisk/init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
} else if !no_vendor_init_boot {
|
||||
println!("- Checking if /vendor_ramdisk/init_boot/init exists");
|
||||
let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up vendor_ramdisk/init_boot/init");
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
} else if !no_vendor_ramdisk {
|
||||
println!("- Checking if /vendor_ramdisk/ramdisk/init exists");
|
||||
let status = do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up vendor_ramdisk/ramdisk/init");
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
} else {
|
||||
println!("- Checking if /ramdisk/init exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up ramdisk/init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
}
|
||||
}
|
||||
|
||||
if no_ramdisk {
|
||||
if !no_vendor_init_boot {
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
} else if !no_vendor_ramdisk {
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?;
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?;
|
||||
}
|
||||
if !no_ramdisk {
|
||||
println!("- Patching /ramdisk");
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
} else if !no_vendor_init_boot {
|
||||
println!("- Patching /vendor_ramdisk/init_boot");
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
} else if !no_vendor_ramdisk {
|
||||
println!("- Patching /vendor_ramdisk/ramdisk");
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?;
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?;
|
||||
} else {
|
||||
println!("- Creating and Patching /ramdisk");
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
}
|
||||
@@ -800,16 +855,17 @@ fn find_boot_image(
|
||||
ota: bool,
|
||||
is_replace_kernel: bool,
|
||||
workdir: &Path,
|
||||
magiskboot: &Path,
|
||||
) -> Result<(PathBuf, Option<String>)> {
|
||||
let bootimage;
|
||||
let mut bootdevice = None;
|
||||
if let Some(ref image) = *image {
|
||||
ensure!(image.exists(), "boot image not found");
|
||||
ensure!(image.exists(), "- Boot image not found");
|
||||
bootimage = std::fs::canonicalize(image)?;
|
||||
} else {
|
||||
if cfg!(not(target_os = "android")) {
|
||||
println!("- Current OS is not android, refusing auto bootimage/bootdevice detection");
|
||||
bail!("Please specify a boot image");
|
||||
bail!("- Please specify a boot image");
|
||||
}
|
||||
let mut slot_suffix =
|
||||
utils::getprop("ro.boot.slot_suffix").unwrap_or_else(|| String::from(""));
|
||||
@@ -822,27 +878,104 @@ fn find_boot_image(
|
||||
}
|
||||
};
|
||||
|
||||
let init_boot_exist =
|
||||
Path::new(&format!("/dev/block/by-name/init_boot{slot_suffix}")).exists();
|
||||
let vendor_boot_exist =
|
||||
Path::new(&format!("/dev/block/by-name/vendor_boot{slot_suffix}")).exists();
|
||||
let boot_partition = if !is_replace_kernel && init_boot_exist && !skip_init {
|
||||
format!("/dev/block/by-name/init_boot{slot_suffix}")
|
||||
} else if !is_replace_kernel && vendor_boot_exist && !skip_init {
|
||||
format!("/dev/block/by-name/vendor_boot{slot_suffix}")
|
||||
} else {
|
||||
format!("/dev/block/by-name/boot{slot_suffix}")
|
||||
};
|
||||
let init_boot_partition = format!("/dev/block/by-name/init_boot{slot_suffix}");
|
||||
let vendor_boot_partition = format!("/dev/block/by-name/vendor_boot{slot_suffix}");
|
||||
let boot_partition = format!("/dev/block/by-name/boot{slot_suffix}");
|
||||
|
||||
println!("- Bootdevice: {boot_partition}");
|
||||
let init_boot_exist = Path::new(&init_boot_partition).exists();
|
||||
let vendor_boot_exist = Path::new(&vendor_boot_partition).exists();
|
||||
|
||||
// helper: unpack a partition and check for a ramdisk and init
|
||||
fn unpack_and_check_init(
|
||||
magiskboot: &Path,
|
||||
workdir: &Path,
|
||||
partition: &str,
|
||||
ramdisk_cpio: &str,
|
||||
) -> Result<bool> {
|
||||
let tmp_img = workdir.join("probe.img");
|
||||
dd(partition, &tmp_img)?;
|
||||
let status = Command::new(magiskboot)
|
||||
.current_dir(workdir)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.arg("unpack")
|
||||
.arg(&tmp_img)
|
||||
.status()?;
|
||||
if !status.success() {
|
||||
let _ = std::fs::remove_file(&tmp_img);
|
||||
return Ok(false);
|
||||
}
|
||||
let ramdisk_path = workdir.join(ramdisk_cpio);
|
||||
let has_init = if ramdisk_path.exists() {
|
||||
Command::new(magiskboot)
|
||||
.current_dir(workdir)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.arg("cpio")
|
||||
.arg(ramdisk_cpio)
|
||||
.arg("exists init")
|
||||
.status()
|
||||
.map(|s| s.success())
|
||||
.unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
// Clean up
|
||||
let _ = std::fs::remove_file(&tmp_img);
|
||||
let _ = std::fs::remove_file(workdir.join("ramdisk.cpio"));
|
||||
let _ = std::fs::remove_dir_all(workdir.join("vendor_ramdisk"));
|
||||
Ok(has_init)
|
||||
}
|
||||
|
||||
let mut selected_partition = &boot_partition;
|
||||
|
||||
if !is_replace_kernel && init_boot_exist && !skip_init {
|
||||
// try init_boot/ramdisk.cpio
|
||||
if unpack_and_check_init(magiskboot, workdir, &init_boot_partition, "ramdisk.cpio")? {
|
||||
println!("- Using init_boot partition (ramdisk.cpio).");
|
||||
selected_partition = &init_boot_partition;
|
||||
}
|
||||
}
|
||||
|
||||
// try vendor_boot/vendor_ramdisk/init_boot.cpio
|
||||
if selected_partition == &boot_partition && !is_replace_kernel && vendor_boot_exist && !skip_init {
|
||||
if unpack_and_check_init(
|
||||
magiskboot,
|
||||
workdir,
|
||||
&vendor_boot_partition,
|
||||
"vendor_ramdisk/init_boot.cpio",
|
||||
)? {
|
||||
println!("- Using vendor_boot partition (vendor_ramdisk/init_boot.cpio).");
|
||||
selected_partition = &vendor_boot_partition;
|
||||
}
|
||||
}
|
||||
|
||||
// try vendor_boot/vendor_ramdisk/ramdisk.cpio
|
||||
if selected_partition == &boot_partition && !is_replace_kernel && vendor_boot_exist && !skip_init {
|
||||
if unpack_and_check_init(
|
||||
magiskboot,
|
||||
workdir,
|
||||
&vendor_boot_partition,
|
||||
"vendor_ramdisk/ramdisk.cpio",
|
||||
)? {
|
||||
println!("- Using vendor_boot partition (vendor_ramdisk/ramdisk.cpio).");
|
||||
selected_partition = &vendor_boot_partition;
|
||||
}
|
||||
}
|
||||
|
||||
if selected_partition == &boot_partition {
|
||||
println!("- Using boot partition (ramdisk.cpio).");
|
||||
}
|
||||
|
||||
println!("- Bootdevice: {selected_partition}");
|
||||
let tmp_boot_path = workdir.join("boot.img");
|
||||
|
||||
dd(&boot_partition, &tmp_boot_path)?;
|
||||
dd(selected_partition, &tmp_boot_path)?;
|
||||
|
||||
ensure!(tmp_boot_path.exists(), "boot image not found");
|
||||
ensure!(tmp_boot_path.exists(), "- Tmp boot image not found");
|
||||
|
||||
bootimage = tmp_boot_path;
|
||||
bootdevice = Some(boot_partition);
|
||||
bootdevice = Some(selected_partition.to_string());
|
||||
};
|
||||
Ok((bootimage, bootdevice))
|
||||
}
|
||||
|
||||
@@ -47,3 +47,5 @@ pub const KSU_BACKUP_FILE_PREFIX: &str = "ksu_backup_";
|
||||
pub const BACKUP_FILENAME: &str = "stock_image.sha1";
|
||||
|
||||
pub const MOUNT_SYSTEM: &str = "OverlayFS";
|
||||
|
||||
pub const GLOBAL_NAMESPACE_FILE: &str = concatcp!(WORKING_DIR, ".global_mnt");
|
||||
|
||||
@@ -261,7 +261,9 @@ pub fn root_shell() -> Result<()> {
|
||||
|
||||
// switch to global mount namespace
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
if mount_master {
|
||||
let global_namespace_enable =
|
||||
std::fs::read_to_string(defs::GLOBAL_NAMESPACE_FILE).unwrap_or("0".to_string());
|
||||
if global_namespace_enable.trim() == "1" || mount_master {
|
||||
let _ = utils::switch_mnt_ns(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,54 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
|
||||
// This is a simple example. If you want a full-featured "su", please use "/data/adb/ksud debug su".
|
||||
int main(){
|
||||
int32_t result = 0;
|
||||
prctl(0xdeadbeef, 0, 0, 0, &result);
|
||||
system("/system/bin/sh");
|
||||
return 0;
|
||||
#define KERNEL_SU_OPTION 0xDEADBEEF
|
||||
#define CMD_GRANT_ROOT 0
|
||||
#define CMD_ENABLE_SU 15
|
||||
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
unsigned long result = 0;
|
||||
|
||||
if (argc >= 2 && strcmp(argv[1], "--disable-sucompat") == 0) {
|
||||
prctl(KERNEL_SU_OPTION, CMD_ENABLE_SU, 0L, 0L, (unsigned long)&result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
prctl(KERNEL_SU_OPTION, CMD_GRANT_ROOT, 0L, 0L, (unsigned long)&result);
|
||||
if (result != KERNEL_SU_OPTION) {
|
||||
const char *error = "Access Denied: sucompat not permitted\n";
|
||||
write(STDERR_FILENO, error, strlen(error));
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct termios term;
|
||||
if (ioctl(STDIN_FILENO, TCGETS, &term) == 0) {
|
||||
char tty_path[PATH_MAX];
|
||||
ssize_t len = readlink("/proc/self/fd/0", tty_path, sizeof(tty_path) - 1);
|
||||
if (len > 0) {
|
||||
tty_path[len] = '\0';
|
||||
const char *selinux_ctx = "u:object_r:devpts:s0";
|
||||
setxattr(tty_path, "security.selinux", selinux_ctx, strlen(selinux_ctx) + 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
const char *default_args[] = { "/system/bin/su", NULL };
|
||||
if (argc < 1 || !argv) {
|
||||
argv = (char **)default_args;
|
||||
} else {
|
||||
argv[0] = "/system/bin/su";
|
||||
}
|
||||
|
||||
execve("/data/adb/ksud", argv, envp);
|
||||
|
||||
const char *error = "Error: Failed to execve /data/adb/ksud\n";
|
||||
write(STDERR_FILENO, error, strlen(error));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -104,52 +104,77 @@ int main(int argc, char *argv[]) {
|
||||
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_ENABLED_FEATURES, enabled_features, bufsize, &error);
|
||||
printf("%s\n", error || !strlen(enabled_features) ? "Unsupported" : "Supported");
|
||||
free(enabled_features);
|
||||
} else if (argc == 3 && !strcmp(argv[1], "sus_su")) {
|
||||
int last_working_mode = 0;
|
||||
int target_working_mode;
|
||||
char* endptr;
|
||||
} else if (argc >= 2 && !strcmp(argv[1], "sus_su")) {
|
||||
if (argc == 3 && strcmp(argv[2], "support") == 0) {
|
||||
char *enabled_features;
|
||||
size_t bufsize = getpagesize() * 2;
|
||||
enabled_features = (char *)malloc(bufsize);
|
||||
if (!enabled_features) {
|
||||
perror("malloc");
|
||||
return -ENOMEM;
|
||||
}
|
||||
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_ENABLED_FEATURES, enabled_features, bufsize, &error);
|
||||
if (!error && strstr(enabled_features, "CONFIG_KSU_SUSFS_SUS_SU")) {
|
||||
printf("Supported\n");
|
||||
} else {
|
||||
printf("Unsupported\n");
|
||||
}
|
||||
free(enabled_features);
|
||||
return 0;
|
||||
} else if (argc == 3) {
|
||||
int last_working_mode = 0;
|
||||
int target_working_mode;
|
||||
char *endptr;
|
||||
|
||||
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE, &last_working_mode, NULL, &error);
|
||||
if (error)
|
||||
return error;
|
||||
if (!strcmp(argv[2], "mode")) {
|
||||
printf("%d\n", last_working_mode);
|
||||
return 0;
|
||||
}
|
||||
target_working_mode = strtol(argv[2], &endptr, 10);
|
||||
if (*endptr != '\0') {
|
||||
return 1;
|
||||
}
|
||||
if (target_working_mode == SUS_SU_WITH_HOOKS) {
|
||||
bool is_sus_su_ready;
|
||||
prctl(KERNEL_SU_OPTION, CMD_SUSFS_IS_SUS_SU_READY, &is_sus_su_ready, NULL, &error);
|
||||
if (error)
|
||||
return error;
|
||||
if (!is_sus_su_ready) {
|
||||
printf("[-] sus_su mode %d has to be run during or after service stage\n", SUS_SU_WITH_HOOKS);
|
||||
return 1;
|
||||
}
|
||||
if (last_working_mode == SUS_SU_DISABLED) {
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS);
|
||||
} else if (last_working_mode == SUS_SU_WITH_HOOKS) {
|
||||
printf("[-] sus_su is already in mode %d\n", last_working_mode);
|
||||
return 1;
|
||||
} else {
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_DISABLED);
|
||||
if (!error)
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS);
|
||||
}
|
||||
} else if (target_working_mode == SUS_SU_DISABLED) {
|
||||
if (last_working_mode == SUS_SU_DISABLED) {
|
||||
printf("[-] sus_su is already in mode %d\n", last_working_mode);
|
||||
return 1;
|
||||
}
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_DISABLED);
|
||||
}
|
||||
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE, &last_working_mode, NULL, &error);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!strcmp(argv[2], "mode")) {
|
||||
printf("%d\n", last_working_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
target_working_mode = strtol(argv[2], &endptr, 10);
|
||||
if (*endptr != '\0') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (target_working_mode == SUS_SU_WITH_HOOKS) {
|
||||
bool is_sus_su_ready;
|
||||
prctl(KERNEL_SU_OPTION, CMD_SUSFS_IS_SUS_SU_READY, &is_sus_su_ready, NULL, &error);
|
||||
if (error)
|
||||
return error;
|
||||
if (!is_sus_su_ready) {
|
||||
printf("[-] sus_su mode %d has to be run during or after service stage\n", SUS_SU_WITH_HOOKS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (last_working_mode == SUS_SU_DISABLED) {
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS);
|
||||
} else if (last_working_mode == SUS_SU_WITH_HOOKS) {
|
||||
printf("[-] sus_su is already in mode %d\n", last_working_mode);
|
||||
return 1;
|
||||
} else {
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_DISABLED);
|
||||
if (!error)
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS);
|
||||
}
|
||||
} else if (target_working_mode == SUS_SU_DISABLED) {
|
||||
if (last_working_mode == SUS_SU_DISABLED) {
|
||||
printf("[-] sus_su is already in mode %d\n", last_working_mode);
|
||||
return 1;
|
||||
}
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_DISABLED);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Usage: %s sus_su <0|2|mode|support>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Invalid argument: %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user