Compare commits

...

26 Commits
v1.0.9 ... next

Author SHA1 Message Date
Rifat Azad
1de68a8ed2 Revert "userspace: implement OSS ksuinit"
This reverts commit edb99a2c1a.
2025-08-10 13:48:18 +06:00
Rifat Azad
e0c461322b kernel: nest ksun switch manager support under CONFIG_KSU_SWITCH_MANAGER config default as disabled 2025-08-10 12:28:34 +06:00
tiann
edb99a2c1a userspace: implement OSS ksuinit 2025-08-10 10:48:13 +06:00
James McConnell
eaab98b7ec ci(workflows): add artifact caching to build-manager-ci and build-manager-spoofed workflows (#702)
* ci(workflows): add artifact caching to build-manager-ci workflow

Add cache check, save and restore steps to avoid rebuilding artifacts when source files haven't changed. The workflow now checks for cached artifacts first and only rebuilds if cache is invalid or missing.

* ci(workflows): add artifact caching to build-manager-spoofed workflow
Add cache check, save and restore steps to avoid rebuilding artifacts when source files haven't changed. The workflow now checks for cached artifacts first and only rebuilds if cache is invalid or missing.
2025-08-05 09:47:24 +06:00
Rifat Azad
aa37bcc368 New Crowdin updates (#660)
* New translations manager/app/src/main/res/values-zh-rCN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rTW/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl-rPL/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt-rBR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-tr-rTR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rCN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it-rIT/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-in-rID/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es-rEM/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ar-rSA/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bn-rBD/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bg-rBG/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rCN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rTW/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fr-rFR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de-rDE/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hi-rIN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hu-rHU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-in-rID/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it-rIT/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ja-rJP/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ko-rKR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fa-rIR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl-rPL/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt-rBR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru-rRU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es-rEM/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-sv-rSE/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-th-rTH/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-tr-rTR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-uk-rUA/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi-rVN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl-rPL/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru-rRU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-uk-rUA/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi-rVN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rCN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rTW/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-in-rID/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru-rRU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-tr-rTR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rCN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl-rPL/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt-rBR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it-rIT/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it-rIT/strings.xml (bundle: 8)
2025-08-01 16:44:29 +06:00
Rifat Azad
107cd4add0 Update README.md 2025-07-28 19:37:12 +06:00
Rifat Azad
94c4b41ea3 README: updated 2025-07-28 19:36:30 +06:00
Rifat Azad
0bde9047b9 manager: add -spoof string to apk output 2025-07-27 22:42:36 +06:00
Fahrez256Bit
bc9927b9b6 POC: load icon app via ksu://icon/[packageName] (#674)
* manager: load app icons from package name using AppIconUti

Trying basic icon rendering from package via WebView ksu:// scheme.
Includes cache and bitmap scaling.
Still subject to refinement.

* Update WebUIActivity.kt

This proof-of-concept intercepts custom URLs of the form:
  ksu://icon/com.example.app

It fetches the app icon using PackageManager via AppIconUtil,
converts it to PNG, and returns it as a WebResourceResponse.

Used inside shouldInterceptRequest() for early experimentation
with dynamic WebView asset routing.

Fallbacks to WebViewAssetLoader for all other requests.

Notes:
- Icon size currently fixed at 512px
- No error icon or fallback image yet
- No caching headers or mime sniffing implemented

* POC: Handle ksu://icon/[packageName] to serve app icon via WebView

This proof-of-concept intercepts custom URLs of the form:
  ksu://icon/com.example.app

It fetches the app icon using PackageManager via AppIconUtil,
converts it to PNG, and returns it as a WebResourceResponse.

Used inside shouldInterceptRequest() for early experimentation
with dynamic WebView asset routing.

Fallbacks to WebViewAssetLoader for all other requests.

Notes:
- Icon size currently fixed at 512px
- No error icon or fallback image yet
- No caching headers or mime sniffing implemented
2025-07-25 21:23:29 +06:00
James McConnell
d4f4c0a0cc Syscall Hooks (#686)
* Update gki-kernel.yml: Add Syscall Hooks

* Update gki-kernel.yml: Fuzz is needed?

* workflows: apply syscall hook patches and configs only for NON-LKM build

---------

Co-authored-by: Rifat Azad <33044977+rifsxd@users.noreply.github.com>
2025-07-25 19:35:29 +06:00
Rifat Azad
0aaae919c0 userspace/su: add ndk compatible su from kernelnosu
Co-authored-by: nampud <nampud@users.noreply.github.com>
2025-07-25 06:40:48 +06:00
Rifat Azad
3f4c23a34f kernel: allow only perms for /{system | vendor | product | system_ext}/bin/su path
kernel: guard kernelnosu perms if not using KSU_KPROBES_HOOK
2025-07-24 06:44:10 +06:00
Rifat Azad
d69a72c658 src: build script for a full featured manager 2025-07-23 23:02:37 +06:00
Rifat Azad
adbff41a22 ksud: decide best partition to direct flash LKM 2025-07-23 23:02:28 +06:00
Rifat Azad
512f84504e ksud: create our own new ramdisk when no compatible ramdisk found 2025-07-22 07:23:07 +06:00
Rifat Azad
c44f48c8a4 Update README.md 2025-07-21 15:36:05 +06:00
Rifat Azad
5c6c3870a0 ksud_magic: fix rust fmt 2025-07-21 06:59:34 +06:00
Alessandro Paluzzi
c6b5440682 manager | ksud: Add toggle for global mount namespace (#99)
* This is untested, if you facing any issues, open a new issue or comments at our group
* and also, this changes maybe reverted if didn't meet the target.

Taken from Apatch's implementations:
8de6b9d676
57d527a846
f093d6a633

Critics are welcome!

Signed-off-by: rsuntk <90097027+rsuntk@users.noreply.github.com>
2025-07-21 06:34:11 +06:00
Rifat Azad
a917314e84 manager: fixed sus_su features
susfsd: added `sus_su support` command
2025-07-21 06:19:50 +06:00
nampud
948975ba35 kernel: core_hook: add support for KernelNoSU
reorder ksu_handle_prctl checks a bit to allow non-manager to use CMD 15
this allows us to piggyback a small su to KernelSU's permission system after
disabling kernel sucompat

from:
Relax prctl perm check
- 95125c32f9
Allow prctl only for root or manager or su binary
- fa7af67d94
Refine prctl access check, allow /product/bin/su
- dd466dc1b6
Refine prctl check a little bit more
- e7c5b24efa

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-07-21 06:19:34 +06:00
Rifat Azad
45ad73e9dd kernel: guard syscall hook types
- for kernel syscall hooks we need to pass additional guards for ksun (#ifdef CONFIG_KSU -> #if defined(CONFIG_KSU) && !defined(CONFIG_KSU_KPROBES_HOOK)) or else it will fail to build because of undefined symbol

- reference https://github.com/KernelSU-Next/kernel_patches/blob/main/syscall_hook/min_scope_syscall_hooks_v1.4.patch
2025-07-21 02:10:36 +06:00
Rifat Azad
892a62afdf manager: bump MINIMAL_SUPPORTED_KERNEL to 12797 2025-07-19 23:36:00 +06:00
Rifat Azad
d61de07c21 kernel: implement v2_signature size/hash override from userspace through kernel module parameter
- /sys/module/kernelsu/parameters/expected_manager_*
2025-07-19 23:10:48 +06:00
Rifat Azad
4382dca515 ksud: do backup for vendor_boot partition 2025-07-17 23:24:32 +06:00
Rifat Azad
2c9078e038 kernel: use ksu_strncpy_from_user_retry when kprobes hook sucompat pagefaults 2025-07-16 21:06:59 +06:00
Edrick Sinsuan
81f4f09d0c ksud: Address pagefault in ksu_handle_execveat_ksud (#662)
* ksud: Address pagefault in ksu_handle_execveat_ksud

As pointed out by @backslashxx, when strncpy pagefaults, it causes
the first_arg to be completely NULL in some systems. This causes
second_stage initialization to fail hence causing SU to be
non-functional.

This patch copies ksu_strncpy_from_user_retry from @backslashxx's
commit:
e2fe25e485

This adds a fallback to perform a normal strncpy_from_user when nofault
fails which allows us to get the first_arg in such cases.

Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: Edrick Sinsuan <evcsinsuan@gmail.com>

* Revert "ksud: Add second_stage init variant (#653)"

This reverts commit c6b60a24e8.

---------

Signed-off-by: Edrick Sinsuan <evcsinsuan@gmail.com>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-07-15 21:24:20 +06:00
54 changed files with 1381 additions and 443 deletions

View File

@@ -19,12 +19,48 @@ on:
workflow_dispatch: workflow_dispatch:
jobs: 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: build-lkm:
needs: check-cache
if: needs.check-cache.outputs.cache-hit != 'true'
uses: ./.github/workflows/build-lkm.yml uses: ./.github/workflows/build-lkm.yml
secrets: inherit secrets: inherit
build-susfsd: build-susfsd:
needs: build-lkm needs: [check-cache, build-lkm]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy: strategy:
matrix: matrix:
include: include:
@@ -34,7 +70,8 @@ jobs:
os: ${{ matrix.os }} os: ${{ matrix.os }}
build-ksud: build-ksud:
needs: build-susfsd needs: [check-cache, build-susfsd]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy: strategy:
matrix: matrix:
include: include:
@@ -49,8 +86,43 @@ jobs:
target: ${{ matrix.target }} target: ${{ matrix.target }}
os: ${{ matrix.os }} 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: 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 runs-on: ubuntu-latest
defaults: defaults:
run: run:
@@ -92,87 +164,122 @@ jobs:
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 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 - name: Download susfsd
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: susfsd-linux-android name: susfsd-linux-android
path: . path: .
- name: Copy susfsd to app jniLibs # Download fresh ksud artifacts if cache miss
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
- name: Download arm64 ksud_overlayfs - name: Download arm64 ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: ksud_overlayfs-aarch64-linux-android name: ksud_overlayfs-aarch64-linux-android
path: ksud_overlayfs path: ksud_overlayfs
- name: Download arm ksud_overlayfs - name: Download arm ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: ksud_overlayfs-armv7-linux-androideabi name: ksud_overlayfs-armv7-linux-androideabi
path: ksud_overlayfs path: ksud_overlayfs
- name: Download x86_64 ksud_overlayfs - name: Download x86_64 ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: ksud_overlayfs-x86_64-linux-android name: ksud_overlayfs-x86_64-linux-android
path: ksud_overlayfs 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 - name: Download arm64 ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: ksud_magic-aarch64-linux-android name: ksud_magic-aarch64-linux-android
path: ksud_magic path: ksud_magic
- name: Download arm ksud_magic - name: Download arm ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: ksud_magic-armv7-linux-androideabi name: ksud_magic-armv7-linux-androideabi
path: ksud_magic path: ksud_magic
- name: Download x86_64 ksud_magic - name: Download x86_64 ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: ksud_magic-x86_64-linux-android name: ksud_magic-x86_64-linux-android
path: ksud_magic 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 - name: Copy ksud_magic to app jniLibs
run: | run: |
mkdir -p app/src/main/jniLibs/arm64-v8a mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64 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 if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
# Copy from cached artifacts
cp -f ../ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so 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 ../ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/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 - name: Build with Gradle
run: | run: |

View File

@@ -21,12 +21,48 @@ on:
- cron: "0 12 * * *" # 6 PM UTC+6 | 12 PM UTC - cron: "0 12 * * *" # 6 PM UTC+6 | 12 PM UTC
jobs: 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: build-lkm:
needs: check-cache
if: needs.check-cache.outputs.cache-hit != 'true'
uses: ./.github/workflows/build-lkm.yml uses: ./.github/workflows/build-lkm.yml
secrets: inherit secrets: inherit
build-susfsd: build-susfsd:
needs: build-lkm needs: [check-cache, build-lkm]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy: strategy:
matrix: matrix:
include: include:
@@ -36,7 +72,8 @@ jobs:
os: ${{ matrix.os }} os: ${{ matrix.os }}
build-ksud: build-ksud:
needs: build-susfsd needs: [check-cache, build-susfsd]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy: strategy:
matrix: matrix:
include: include:
@@ -51,8 +88,43 @@ jobs:
target: ${{ matrix.target }} target: ${{ matrix.target }}
os: ${{ matrix.os }} 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: 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 runs-on: ubuntu-latest
defaults: defaults:
run: run:
@@ -99,75 +171,122 @@ jobs:
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 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 - name: Download susfsd
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: susfsd-linux-android name: susfsd-linux-android
path: . path: .
- name: Copy susfsd to app jniLibs # Download fresh ksud artifacts if cache miss
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
- name: Download arm64 ksud_overlayfs - name: Download arm64 ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: ksud_overlayfs-aarch64-linux-android name: ksud_overlayfs-aarch64-linux-android
path: ksud_overlayfs path: ksud_overlayfs
- name: Download arm ksud_overlayfs - name: Download arm ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: ksud_overlayfs-armv7-linux-androideabi name: ksud_overlayfs-armv7-linux-androideabi
path: ksud_overlayfs path: ksud_overlayfs
- name: Download x86_64 ksud_overlayfs - name: Download x86_64 ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: ksud_overlayfs-x86_64-linux-android name: ksud_overlayfs-x86_64-linux-android
path: ksud_overlayfs 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 - name: Download arm64 ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: ksud_magic-aarch64-linux-android name: ksud_magic-aarch64-linux-android
path: ksud_magic path: ksud_magic
- name: Download arm ksud_magic - name: Download arm ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: ksud_magic-armv7-linux-androideabi name: ksud_magic-armv7-linux-androideabi
path: ksud_magic path: ksud_magic
- name: Download x86_64 ksud_magic - name: Download x86_64 ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: ksud_magic-x86_64-linux-android name: ksud_magic-x86_64-linux-android
path: ksud_magic 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 - name: Copy ksud_magic to app jniLibs
run: | run: |
cp -f ../ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
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/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 - name: Build with Gradle
run: | run: |

View File

@@ -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" sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' build/kernel/*.sh || echo "No unknown symbol scripts found"
fi 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 - name: Make working directory clean to avoid dirty
working-directory: android-kernel working-directory: android-kernel
run: | run: |

31
build.sh Executable file
View 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

View File

@@ -74,6 +74,7 @@ If youd like to support the project:
- **USDT (BEP20, ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1` - **USDT (BEP20, ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **USDT (TRC20)**: `TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh` - **USDT (TRC20)**: `TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh`
- **USDT (SOL)**: `A4wqBXYd6Ey4nK4SJ2bmjeMgGyaLKT9TwDLh8BEo8Zu6`
- **ETH (ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1` - **ETH (ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **LTC**: `Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL` - **LTC**: `Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL`
- **BTC**: `19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6` - **BTC**: `19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6`
@@ -87,5 +88,4 @@ If youd like to support the project:
- [Genuine](https://github.com/brevent/genuine/) APK v2 signature validation - [Genuine](https://github.com/brevent/genuine/) APK v2 signature validation
- [Diamorphine](https://github.com/m0nad/Diamorphine) Rootkit techniques - [Diamorphine](https://github.com/m0nad/Diamorphine) Rootkit techniques
- [KernelSU](https://github.com/tiann/KernelSU) The original base that made KernelSU Next possible - [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 - [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs) For magic mount support
- [Crowdin Translators](https://crowdin.com/project/kernelsu-next/members) 💬 Thanks to everyone for helping make KernelSU Next multi-lingual!

View File

@@ -40,4 +40,11 @@ config KSU_LSM_SECURITY_HOOKS
Disabling this is mostly only useful for kernel 4.1 and older. Disabling this is mostly only useful for kernel 4.1 and older.
Make sure to implement manual hooks on security/security.c. 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 endmenu

View File

@@ -49,12 +49,12 @@ ifeq ($(shell grep "ssize_t kernel_write" $(srctree)/fs/read_write.c | grep -q "
ccflags-y += -DKSU_KERNEL_WRITE ccflags-y += -DKSU_KERNEL_WRITE
endif endif
ifndef KSU_NEXT_EXPECTED_SIZE ifndef KSU_NEXT_MANAGER_SIZE
KSU_NEXT_EXPECTED_SIZE := 0x3e6 KSU_NEXT_MANAGER_SIZE := 0x3e6
endif endif
ifndef KSU_NEXT_EXPECTED_HASH ifndef KSU_NEXT_MANAGER_HASH
KSU_NEXT_EXPECTED_HASH := 79e590113c4c4c0c222978e413a5faa801666957b1212a328e46c00c69821bf7 KSU_NEXT_MANAGER_HASH := 79e590113c4c4c0c222978e413a5faa801666957b1212a328e46c00c69821bf7
endif endif
ifdef KSU_MANAGER_PACKAGE 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)) $(info -- KernelSU-Next Manager package name: $(KSU_MANAGER_PACKAGE))
endif endif
$(info -- KernelSU-Next Manager signature size: $(KSU_NEXT_EXPECTED_SIZE)) $(info -- KernelSU-Next Manager signature size: $(KSU_NEXT_MANAGER_SIZE))
$(info -- KernelSU-Next Manager signature hash: $(KSU_NEXT_EXPECTED_HASH)) $(info -- KernelSU-Next Manager signature hash: $(KSU_NEXT_MANAGER_HASH))
ccflags-y += -DEXPECTED_NEXT_SIZE=$(KSU_NEXT_EXPECTED_SIZE) ccflags-y += -DEXPECTED_MANAGER_SIZE=$(KSU_NEXT_MANAGER_SIZE)
ccflags-y += -DEXPECTED_NEXT_HASH=\"$(KSU_NEXT_EXPECTED_HASH)\" ccflags-y += -DEXPECTED_MANAGER_HASH=\"$(KSU_NEXT_MANAGER_HASH)\"
ccflags-y += -DKSU_UMOUNT ccflags-y += -DKSU_UMOUNT

View File

@@ -3,10 +3,9 @@
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h>
#include <linux/version.h> #include <linux/version.h>
#ifdef CONFIG_KSU_DEBUG
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#endif
#include <crypto/hash.h> #include <crypto/hash.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
#include <crypto/sha2.h> #include <crypto/sha2.h>
@@ -19,6 +18,8 @@
#include "kernel_compat.h" #include "kernel_compat.h"
#include "throne_tracker.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 sdesc {
struct shash_desc shash; struct shash_desc shash;
@@ -315,6 +316,55 @@ module_param_cb(ksu_debug_manager_uid, &expected_size_ops,
#endif #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) bool is_manager_apk(char *path)
{ {
int tries = 0; int tries = 0;
@@ -333,5 +383,9 @@ bool is_manager_apk(char *path)
return false; 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);
} }

View File

@@ -255,6 +255,34 @@ static void nuke_ext4_sysfs() {
path_put(&path); 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, int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5) 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_root = 0 == current_uid().val;
bool from_manager = is_manager(); 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) { if (!from_root && !from_manager) {
// only root or manager can access this interface // only root or manager can access this interface
return 0; return 0;
} }
#endif
#ifdef CONFIG_KSU_DEBUG #ifdef CONFIG_KSU_DEBUG
pr_info("option: 0x%x, cmd: %ld\n", option, arg2); 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; 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' // all other cmds are for 'root manager'
if (!from_manager) { if (!from_manager) {
return 0; return 0;
@@ -499,7 +561,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
} }
return 0; return 0;
} }
#ifndef CONFIG_KSU_KPROBES_HOOK
if (arg2 == CMD_ENABLE_SU) { if (arg2 == CMD_ENABLE_SU) {
bool enabled = (arg3 != 0); bool enabled = (arg3 != 0);
if (enabled == ksu_su_compat_enabled) { if (enabled == ksu_su_compat_enabled) {
@@ -523,6 +585,8 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
return 0; return 0;
} }
#endif
return 0; return 0;
} }

View File

@@ -173,3 +173,26 @@ long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
return ret; return ret;
} }
#endif #endif
static inline int ksu_access_ok(const void *addr, unsigned long size)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0)
return access_ok(addr, size);
#else
return access_ok(VERIFY_READ, addr, size);
#endif
}
long ksu_strncpy_from_user_retry(char *dst, const void __user *unsafe_addr,
long count)
{
long ret = ksu_strncpy_from_user_nofault(dst, unsafe_addr, count);
if (likely(ret >= 0))
return ret;
// we faulted! fallback to slow path
if (unlikely(!ksu_access_ok(unsafe_addr, count)))
return -EFAULT;
return strncpy_from_user(dst, unsafe_addr, count);
}

View File

@@ -23,6 +23,9 @@
extern long ksu_strncpy_from_user_nofault(char *dst, extern long ksu_strncpy_from_user_nofault(char *dst,
const void __user *unsafe_addr, const void __user *unsafe_addr,
long count); long count);
extern long ksu_strncpy_from_user_retry(char *dst,
const void __user *unsafe_addr,
long count);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
extern struct key *init_session_keyring; extern struct key *init_session_keyring;

View File

@@ -58,12 +58,11 @@ static void stop_input_hook();
static struct work_struct stop_vfs_read_work; static struct work_struct stop_vfs_read_work;
static struct work_struct stop_execve_hook_work; static struct work_struct stop_execve_hook_work;
static struct work_struct stop_input_hook_work; static struct work_struct stop_input_hook_work;
#endif #else
bool ksu_vfs_read_hook __read_mostly = true; bool ksu_vfs_read_hook __read_mostly = true;
bool ksu_execveat_hook __read_mostly = true; bool ksu_execveat_hook __read_mostly = true;
bool ksu_input_hook __read_mostly = true; bool ksu_input_hook __read_mostly = true;
#endif
u32 ksu_devpts_sid; u32 ksu_devpts_sid;
@@ -197,12 +196,11 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
const char __user *p = get_user_arg_ptr(*argv, 1); const char __user *p = get_user_arg_ptr(*argv, 1);
if (p && !IS_ERR(p)) { if (p && !IS_ERR(p)) {
char first_arg[16]; char first_arg[16];
ksu_strncpy_from_user_nofault( ksu_strncpy_from_user_retry(
first_arg, p, sizeof(first_arg)); first_arg, p, sizeof(first_arg));
pr_info("/system/bin/init first arg: %s\n", pr_info("/system/bin/init first arg: %s\n",
first_arg); first_arg);
if (!strcmp(first_arg, "second_stage") || if (!strcmp(first_arg, "second_stage")) {
(argc == 2 && !strcmp(first_arg, ""))) {
pr_info("/system/bin/init second_stage executed\n"); pr_info("/system/bin/init second_stage executed\n");
apply_kernelsu_rules(); apply_kernelsu_rules();
init_second_stage_executed = true; init_second_stage_executed = true;
@@ -223,7 +221,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
const char __user *p = get_user_arg_ptr(*argv, 1); const char __user *p = get_user_arg_ptr(*argv, 1);
if (p && !IS_ERR(p)) { if (p && !IS_ERR(p)) {
char first_arg[16]; char first_arg[16];
ksu_strncpy_from_user_nofault( ksu_strncpy_from_user_retry(
first_arg, p, sizeof(first_arg)); first_arg, p, sizeof(first_arg));
pr_info("/init first arg: %s\n", first_arg); pr_info("/init first arg: %s\n", first_arg);
if (!strcmp(first_arg, "--second-stage")) { if (!strcmp(first_arg, "--second-stage")) {
@@ -248,7 +246,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
} }
char env[256]; char env[256];
// Reading environment variable strings from user space // Reading environment variable strings from user space
if (ksu_strncpy_from_user_nofault( if (ksu_strncpy_from_user_retry(
env, p, sizeof(env)) < 0) env, p, sizeof(env)) < 0)
continue; continue;
// Parsing environment variable names and values // Parsing environment variable names and values
@@ -489,10 +487,12 @@ __maybe_unused int ksu_handle_execve_ksud(const char __user *filename_user,
struct filename filename_in, *filename_p; struct filename filename_in, *filename_p;
char path[32]; char path[32];
#ifndef CONFIG_KSU_KPROBES_HOOK
// return early if disabled. // return early if disabled.
if (!ksu_execveat_hook) { if (!ksu_execveat_hook) {
return 0; return 0;
} }
#endif
if (!filename_user) if (!filename_user)
return 0; return 0;

View File

@@ -179,23 +179,8 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user,
if (unlikely(!filename_user)) if (unlikely(!filename_user))
return 0; return 0;
// nofault variant fails probably due to pagefault_disable memset(path, 0, sizeof(path));
// some cpus dont really have that good speculative execution ksu_strncpy_from_user_retry(path, *filename_user, sizeof(path));
// 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';
if (likely(memcmp(path, su, sizeof(su)))) if (likely(memcmp(path, su, sizeof(su))))
return 0; return 0;

3
manager/.gitignore vendored
View File

@@ -7,5 +7,4 @@ build
captures captures
.cxx .cxx
local.properties local.properties
key.jks key.jks
setup.sh

View File

@@ -16,11 +16,12 @@ object Natives {
// 10946: add capabilities // 10946: add capabilities
// 10977: change groups_count and groups to avoid overflow write // 10977: change groups_count and groups to avoid overflow write
// 11071: Fix the issue of failing to set a custom SELinux type. // 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 // 11640: Support query working mode, LKM or GKI
// when MINIMAL_SUPPORTED_KERNEL > 11640, we can remove this constant. // 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 // 12404: Support disable sucompat mode
const val MINIMAL_SUPPORTED_SU_COMPAT = 12404 const val MINIMAL_SUPPORTED_SU_COMPAT = 12404
@@ -119,6 +120,9 @@ object Natives {
return version < MINIMAL_SUPPORTED_KERNEL return version < MINIMAL_SUPPORTED_KERNEL
} }
val KSU_WORK_DIR = "/data/adb/ksu/"
val GLOBAL_NAMESPACE_FILE = KSU_WORK_DIR + ".global_mnt"
@Immutable @Immutable
@Parcelize @Parcelize
@Keep @Keep

View File

@@ -650,7 +650,7 @@ private fun InfoCard(autoExpand: Boolean = false) {
val suSFS = getSuSFS() val suSFS = getSuSFS()
if (suSFS == "Supported") { 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 susSUMode = if (isSUS_SU) {
val mode = susfsSUS_SU_Mode() val mode = susfsSUS_SU_Mode()
val modeString = val modeString =

View File

@@ -88,6 +88,8 @@ import com.rifsxd.ksunext.ui.component.rememberLoadingDialog
import com.rifsxd.ksunext.ui.util.LocalSnackbarHost import com.rifsxd.ksunext.ui.util.LocalSnackbarHost
import com.rifsxd.ksunext.ui.util.getBugreportFile import com.rifsxd.ksunext.ui.util.getBugreportFile
import com.rifsxd.ksunext.ui.util.* 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.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@@ -101,6 +103,8 @@ import java.time.format.DateTimeFormatter
fun SettingScreen(navigator: DestinationsNavigator) { fun SettingScreen(navigator: DestinationsNavigator) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val snackBarHost = LocalSnackbarHost.current val snackBarHost = LocalSnackbarHost.current
var isGlobalNamespaceEnabled by rememberSaveable { mutableStateOf(false) }
isGlobalNamespaceEnabled = isGlobalNamespaceEnabled()
val isManager = Natives.becomeManager(ksuApp.packageName) val isManager = Natives.becomeManager(ksuApp.packageName)
val ksuVersion = if (isManager) Natives.version else null 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 prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val suSFS = getSuSFS() val suSFS = getSuSFS()
val isSUS_SU = getSuSFSFeatures() val isSUS_SU = hasSuSFs_SUS_SU() == "Supported"
if (suSFS == "Supported") { if (suSFS == "Supported") {
if (isSUS_SU == "CONFIG_KSU_SUSFS_SUS_SU") { if (isSUS_SU) {
var isEnabled by rememberSaveable { var isEnabled by rememberSaveable {
mutableStateOf(susfsSUS_SU_Mode() == "2") mutableStateOf(susfsSUS_SU_Mode() == "2")
} }

View File

@@ -103,7 +103,10 @@ fun Uri.getFileName(context: Context): String? {
fun createRootShell(globalMnt: Boolean = false): Shell { fun createRootShell(globalMnt: Boolean = false): Shell {
Shell.enableVerboseLogging = BuildConfig.DEBUG Shell.enableVerboseLogging = BuildConfig.DEBUG
val builder = Shell.Builder.create() val builder = Shell.Builder.create().apply {
setFlags(Shell.FLAG_MOUNT_MASTER)
}
return try { return try {
if (globalMnt) { if (globalMnt) {
builder.build(ksuDaemonMagicPath(), "debug", "su", "-g") builder.build(ksuDaemonMagicPath(), "debug", "su", "-g")
@@ -403,6 +406,22 @@ fun hasMagisk(): Boolean {
return result.isSuccess 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 { fun isSepolicyValid(rules: String?): Boolean {
if (rules == null) { if (rules == null) {
return true return true
@@ -591,12 +610,19 @@ fun getSuSFSVariant(): String {
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} variant") val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} variant")
return result return result
} }
fun getSuSFSFeatures(): String { fun getSuSFSFeatures(): String {
val shell = getRootShell() val shell = getRootShell()
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} features") val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} features")
return result 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 { fun susfsSUS_SU_0(): String {
val shell = getRootShell() val shell = getRootShell()
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} sus_su 0") val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} sus_su 0")

View File

@@ -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;
}
}

View File

@@ -96,7 +96,23 @@ class WebUIActivity : ComponentActivity() {
view: WebView, view: WebView,
request: WebResourceRequest request: WebResourceRequest
): WebResourceResponse? { ): 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?) { override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url) super.onPageFinished(view, url)
@@ -119,4 +135,4 @@ class WebUIActivity : ComponentActivity() {
super.onDestroy() super.onDestroy()
runCatching { rootShell?.close() } runCatching { rootShell?.close() }
} }
} }

View File

@@ -233,4 +233,6 @@
<string name="module_sort_enabled_first">Sort (Enabled first)</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_action_first">Sort (Action first)</string>
<string name="module_sort_webui_first">Sort (WebUI 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> </resources>

View File

@@ -231,4 +231,6 @@
<string name="module_sort_enabled_first">Сортиране (първо активирани)</string> <string name="module_sort_enabled_first">Сортиране (първо активирани)</string>
<string name="module_sort_action_first">Сортиране (първо действие)</string> <string name="module_sort_action_first">Сортиране (първо действие)</string>
<string name="module_sort_webui_first">Сортиране (първо WebUI)</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> </resources>

View File

@@ -231,4 +231,6 @@
<string name="module_sort_enabled_first">Sort (Enabled first)</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_action_first">Sort (Action first)</string>
<string name="module_sort_webui_first">Sort (WebUI 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> </resources>

View File

@@ -231,4 +231,6 @@
<string name="module_sort_enabled_first">Sortierung (aktivierte zuerst)</string> <string name="module_sort_enabled_first">Sortierung (aktivierte zuerst)</string>
<string name="module_sort_action_first">Sortierung (Aktion zuerst)</string> <string name="module_sort_action_first">Sortierung (Aktion zuerst)</string>
<string name="module_sort_webui_first">Sortierung (WebUI 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> </resources>

View File

@@ -17,7 +17,7 @@
<string name="home_working">Funcionando</string> <string name="home_working">Funcionando</string>
<string name="home_working_version">Versión: %d</string> <string name="home_working_version">Versión: %d</string>
<string name="home_module_update_count">Actualizaciones: %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_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="home_kernel">Versión del kernel</string>
<string name="hook_mode">Método de intercepción</string> <string name="hook_mode">Método de intercepción</string>
@@ -119,7 +119,7 @@
<string name="profile_template">Plantilla</string> <string name="profile_template">Plantilla</string>
<string name="profile_custom">Personalizado</string> <string name="profile_custom">Personalizado</string>
<string name="profile_name">Nombre de perfil</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_inherited">Heredado</string>
<string name="profile_namespace_global">Global</string> <string name="profile_namespace_global">Global</string>
<string name="profile_namespace_individual">Individual</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_singular">Módulo</string>
<string name="home_module_count_plural">Módulos</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_backup_message">Respaldar los módulos actualmente instalados.</string>
<string name="module_sort_enabled_first">Sort (Enabled first)</string> <string name="module_sort_enabled_first">Ordenar (Activados Primero)</string>
<string name="module_sort_action_first">Sort (Action first)</string> <string name="module_sort_action_first">Ordenar (Accionables primero)</string>
<string name="module_sort_webui_first">Sort (WebUI first)</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> </resources>

View File

@@ -232,4 +232,6 @@
<string name="module_sort_enabled_first">Sort (Enabled first)</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_action_first">Sort (Action first)</string>
<string name="module_sort_webui_first">Sort (WebUI 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> </resources>

View File

@@ -233,4 +233,6 @@
<string name="module_sort_enabled_first">Trier (Activé en premier)</string> <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_action_first">Trier (Action en premier)</string>
<string name="module_sort_webui_first">Trier (WebUI 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> </resources>

View File

@@ -233,4 +233,6 @@
<string name="module_sort_enabled_first">Sort (Enabled first)</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_action_first">Sort (Action first)</string>
<string name="module_sort_webui_first">Sort (WebUI 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> </resources>

View File

@@ -231,4 +231,6 @@
<string name="module_sort_enabled_first">Sort (Enabled first)</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_action_first">Sort (Action first)</string>
<string name="module_sort_webui_first">Sort (WebUI 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> </resources>

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="issue_report_title">Ada kendala?</string> <string name="issue_report_title">Memiliki kendala?</string>
<string name="issue_report_body">Menemukan bug atau memiliki umpan balik?</string> <string name="issue_report_body">Mengalami kesalahan atau memiliki umpan balik?</string>
<string name="issue_report_body_2">Laporkan sesegera mungkin!</string> <string name="issue_report_body_2">Laporkan secepatnya!</string>
<string name="issue_report_github">Laporkan di GitHub</string> <string name="issue_report_github">Laporkan di GitHub</string>
<string name="issue_report_telegram">Hubungi melalui Telegram</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_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</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="app_name">KernelSU Next</string>
<string name="home">Beranda</string> <string name="home">Beranda</string>
<string name="home_not_installed">Tidak terpasang</string> <string name="home_not_installed">Tidak terinstal</string>
<string name="home_click_to_install">Klik untuk memasang</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_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="lkm_alternative_suggestion">Pasang kernel GKI atau integrasikan KernelSU Next ke perangkat anda.</string>
<string name="home_working">Berfungsi</string> <string name="home_working">Berfungsi</string>
@@ -32,7 +32,7 @@
<string name="home_android">Versi android</string> <string name="home_android">Versi android</string>
<string name="home_manager_version">Versi manajer</string> <string name="home_manager_version">Versi manajer</string>
<string name="home_abi">ABI</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_disabled">Nonaktif</string>
<string name="selinux_status_enforcing">Enforcing</string> <string name="selinux_status_enforcing">Enforcing</string>
<string name="selinux_status_permissive">Permissive</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_failed_to_disable">Gagal menonaktifkan modul: %s</string>
<string name="module_empty">Tidak ada modul yang terpasang</string> <string name="module_empty">Tidak ada modul yang terpasang</string>
<string name="module">Modul</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_a_to_z">Urutkan (A → Z)</string>
<string name="module_sort_z_to_a">Urutkan (Z → A)</string> <string name="module_sort_z_to_a">Urutkan (Z → A)</string>
<string name="module_size_low_to_high">Urutkan (Kecil → Besar)</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_enabled_first">Urutkan (Diaktifkan lebih dulu)</string>
<string name="module_sort_action_first">Urutkan (Aksi 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="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> </resources>

View File

@@ -9,7 +9,7 @@
<string name="issue_report_telegram_link">https://t.me/ksunext</string> <string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">Conferma</string> <string name="confirm">Conferma</string>
<string name="app_name">KernelSU Next</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_not_installed">Non installato</string>
<string name="home_click_to_install">Clicca per installare</string> <string name="home_click_to_install">Clicca per installare</string>
<string name="lkm_mode_deprecated">La modalità LKM è ora obsoleta!</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">In esecuzione</string>
<string name="home_working_version">Versione: %d</string> <string name="home_working_version">Versione: %d</string>
<string name="home_module_update_count">Aggiornamenti: %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_failure_tip">Chiedi allo sviluppatore del kernel d\'integrare KernelSU Next!</string>
<string name="home_kernel">Versione kernel</string> <string name="home_kernel">Versione kernel</string>
<string name="hook_mode">Modalità Hook</string> <string name="hook_mode">Modalità Hook</string>
@@ -37,7 +37,7 @@
<string name="selinux_status_enforcing">Enforcing</string> <string name="selinux_status_enforcing">Enforcing</string>
<string name="selinux_status_permissive">Permissive</string> <string name="selinux_status_permissive">Permissive</string>
<string name="selinux_status_unknown">Sconosciuto</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_enable">Impossibile abilitare il modulo: %s</string>
<string name="module_failed_to_disable">Impossibile disabilitare il modulo: %s</string> <string name="module_failed_to_disable">Impossibile disabilitare il modulo: %s</string>
<string name="module_empty">Nessun modulo installato</string> <string name="module_empty">Nessun modulo installato</string>
@@ -187,7 +187,7 @@
<string name="select_file">Seleziona un file</string> <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">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_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_file_tip">Immagine partizione %1$s consigliata</string>
<string name="select_kmi">Seleziona KMI</string> <string name="select_kmi">Seleziona KMI</string>
<string name="shrink_sparse_image">Minimizza l\'immagine sparsa</string> <string name="shrink_sparse_image">Minimizza l\'immagine sparsa</string>
@@ -207,7 +207,7 @@
<string name="log_saved">Log salvati</string> <string name="log_saved">Log salvati</string>
<string name="send_log">Condividi i log</string> <string name="send_log">Condividi i log</string>
<string name="settings_disable_su">Disattiva la compatibilità su</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="settings_language">Lingua</string>
<string name="system_default">Default di sistema</string> <string name="system_default">Default di sistema</string>
<string name="settings_legacyui">Usa lo stile d\'interfaccia precedente</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="sucompat_disabled">SUCOMPAT DISABILITATO</string>
<string name="zygisk_required">Zygisk richiesto</string> <string name="zygisk_required">Zygisk richiesto</string>
<string name="zygisk_status">Iniezione Zygisk</string> <string name="zygisk_status">Iniezione Zygisk</string>
<string name="home_superuser_count_singular">Superutente</string> <string name="home_superuser_count_singular">Accesso root</string>
<string name="home_superuser_count_plural">Superutenti</string> <string name="home_superuser_count_plural">Accessi root</string>
<string name="home_module_count_singular">Modulo</string> <string name="home_module_count_singular">Modulo</string>
<string name="home_module_count_plural">Moduli</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_backup_message">Esegue il backup dei moduli attualmente esistenti.</string>
<string name="module_sort_enabled_first">Ordina (prima Abilitato)</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_action_first">Ordina (prima Azione)</string>
<string name="module_sort_webui_first">Ordina (prima WebUI)</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> </resources>

View File

@@ -231,4 +231,6 @@
<string name="module_sort_enabled_first">並べ替え (有効を優先)</string> <string name="module_sort_enabled_first">並べ替え (有効を優先)</string>
<string name="module_sort_action_first">並べ替え (実行可能を優先)</string> <string name="module_sort_action_first">並べ替え (実行可能を優先)</string>
<string name="module_sort_webui_first">並べ替え (WebUIを優先)</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> </resources>

View File

@@ -231,4 +231,6 @@
<string name="module_sort_enabled_first">정렬 (활성화됨 우선)</string> <string name="module_sort_enabled_first">정렬 (활성화됨 우선)</string>
<string name="module_sort_action_first">정렬 (동작 우선)</string> <string name="module_sort_action_first">정렬 (동작 우선)</string>
<string name="module_sort_webui_first">정렬 (WebUI 우선)</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> </resources>

View File

@@ -45,8 +45,8 @@
<string name="module_install_prompt_with_name">Następujące moduły zostaną zainstalowane: %1$s</string> <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_a_to_z">Sortuj (A → Z)</string>
<string name="module_sort_z_to_a">Sortuj (Z → A)</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_low_to_high">Sortuj (Małe → Duże)</string>
<string name="module_size_high_to_low">Sortuj (Największy → Najmniejszy)</string> <string name="module_size_high_to_low">Sortuj (Duże → Małe)</string>
<string name="uninstall">Odinstaluj</string> <string name="uninstall">Odinstaluj</string>
<string name="restore">Przywróć</string> <string name="restore">Przywróć</string>
<string name="module_install">Zainstaluj</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="settings_banner_summary">Wyświetlaj banery modułów w tle.</string>
<string name="use_webuix">Używaj WebUI X</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_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="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="customization">Personalizacja</string>
<string name="developer">Programista</string> <string name="developer">Programista</string>
<string name="sucompat_disabled">SUCOMPAT NIEAKTYWNY</string> <string name="sucompat_disabled">SUCOMPAT NIEAKTYWNY</string>
<string name="zygisk_required">Wymagany Zygisk</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_singular">Superuser</string>
<string name="home_superuser_count_plural">Superuserzy</string> <string name="home_superuser_count_plural">Superuserzy</string>
<string name="home_module_count_singular">Moduł</string> <string name="home_module_count_singular">Moduł</string>
<string name="home_module_count_plural">Moduły</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_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_enabled_first">Sortuj (najpierw włączone)</string>
<string name="module_sort_action_first">Sort (Action first)</string> <string name="module_sort_action_first">Sortuj (najpierw z Akcją)</string>
<string name="module_sort_webui_first">Sort (WebUI first)</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> </resources>

View File

@@ -53,7 +53,7 @@
<string name="install">Instalar</string> <string name="install">Instalar</string>
<string name="reboot">Reiniciar</string> <string name="reboot">Reiniciar</string>
<string name="uninstalled">Desinstalado</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_userspace">Reiniciar</string>
<string name="reboot_recovery">Reiniciar em modo Recovery</string> <string name="reboot_recovery">Reiniciar em modo Recovery</string>
<string name="reboot_bootloader">Reiniciar em modo Bootloader</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_singular">Módulo</string>
<string name="home_module_count_plural">Módulos</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_backup_message">Fazer backup dos módulos instalados.</string>
<string name="module_sort_enabled_first">Sort (Enabled first)</string> <string name="module_sort_enabled_first">Ordenar (Habilitado primeiro)</string>
<string name="module_sort_action_first">Sort (Action first)</string> <string name="module_sort_action_first">Ordenar (exceto primeiro)</string>
<string name="module_sort_webui_first">Sort (WebUI first)</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> </resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="issue_report_title">Возникли проблемы?</string> <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_body_2">Сообщите об этом как можно скорее!</string>
<string name="issue_report_github">Сообщить на GitHub</string> <string name="issue_report_github">Сообщить на GitHub</string>
<string name="issue_report_telegram">Связаться через Telegram</string> <string name="issue_report_telegram">Связаться через Telegram</string>
@@ -100,7 +100,7 @@
<string name="allowlist_backup_message">Резервное копирование текущего списка разрешений.</string> <string name="allowlist_backup_message">Резервное копирование текущего списка разрешений.</string>
<string name="warning">Предупреждение</string> <string name="warning">Предупреждение</string>
<string name="warning_message">Эта функция всё ещё находится в стадии бета-тестирования. Пожалуйста, убедитесь, что вы создали резервные копии модулей перед использованием. Используйте это только если понимаете возможные риски. Будьте осторожны.</string> <string name="warning_message">Эта функция всё ещё находится в стадии бета-тестирования. Пожалуйста, убедитесь, что вы создали резервные копии модулей перед использованием. Используйте это только если понимаете возможные риски. Будьте осторожны.</string>
<string name="proceed">В процессе</string> <string name="proceed">Продолжить</string>
<string name="cancel">Отмена</string> <string name="cancel">Отмена</string>
<string name="later">Позже</string> <string name="later">Позже</string>
<string name="lkm_warning_message">Патч LKM использует компоненты с закрытым исходным кодом. Хотите продолжить?</string> <string name="lkm_warning_message">Патч LKM использует компоненты с закрытым исходным кодом. Хотите продолжить?</string>
@@ -117,7 +117,7 @@
<string name="profile">Профиль Приложения</string> <string name="profile">Профиль Приложения</string>
<string name="profile_default">По умолчанию</string> <string name="profile_default">По умолчанию</string>
<string name="profile_template">Шаблон</string> <string name="profile_template">Шаблон</string>
<string name="profile_custom">Настроить</string> <string name="profile_custom">Пользовательский</string>
<string name="profile_name">Имя профиля</string> <string name="profile_name">Имя профиля</string>
<string name="profile_namespace">Пространство монтирования</string> <string name="profile_namespace">Пространство монтирования</string>
<string name="profile_namespace_inherited">Унаследованный</string> <string name="profile_namespace_inherited">Унаследованный</string>
@@ -126,14 +126,14 @@
<string name="profile_groups">Группы</string> <string name="profile_groups">Группы</string>
<string name="profile_capabilities">Возможности</string> <string name="profile_capabilities">Возможности</string>
<string name="profile_selinux_context">Контекст SELinux</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="failed_to_update_app_profile">Не удалось обновить Профиль Приложения для %s</string>
<string name="require_kernel_version">Текущая версия KernelSU Next %1$d слишком низкая для корректной работы менеджера. Пожалуйста, обновитесь до версии %2$d или выше!</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">Размонтировать модули</string>
<string name="settings_umount_modules_default_summary">Глобальное значение по умолчанию для \"Отключить модули\" в Профиле Приложения. Если включено, это удалит все модификации системы модулями для приложений без установленного профиля.</string> <string name="settings_umount_modules_default_summary">По умолчанию включает статус \"Umount\" для приложений. Если эта настройка включена, то все модификации, внесённые модулями, будут удалены для приложений без включённого root-доступа.</string>
<string name="settings_susfs_toggle">Скрыть хук kprobes</string> <string name="settings_susfs_toggle">Скрыть хук kprobes</string>
<string name="settings_susfs_toggle_summary">Эта опция отключает хук kprobes, созданный ksu, и вместо него активирует встроенный хук без использования kprobes, реализующий ту же функциональность, которая применяется к ядрам без GKI, не поддерживающим kprobe.</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_domain">Домен</string>
<string name="profile_selinux_rules">Правила</string> <string name="profile_selinux_rules">Правила</string>
<string name="module_update">Обновить</string> <string name="module_update">Обновить</string>
@@ -153,8 +153,8 @@
<string name="failed_to_update_sepolicy">Не удалось обновить правила SELinux для %s</string> <string name="failed_to_update_sepolicy">Не удалось обновить правила SELinux для %s</string>
<string name="su_not_allowed">Предоставление прав суперпользователя запрещено для: %s</string> <string name="su_not_allowed">Предоставление прав суперпользователя запрещено для: %s</string>
<string name="module_changelog">Журнал изменений</string> <string name="module_changelog">Журнал изменений</string>
<string name="settings_profile_template">Шаблон Профиля Приложений</string> <string name="settings_profile_template">Шаблоны доступа</string>
<string name="settings_profile_template_summary">Управление локальными и онлайн шаблонами профилей приложений.</string> <string name="settings_profile_template_summary">Управление локальными и онлайн шаблонами root-доступа.</string>
<string name="app_profile_template_create">Создать шаблон</string> <string name="app_profile_template_create">Создать шаблон</string>
<string name="app_profile_template_edit">Изменить шаблон</string> <string name="app_profile_template_edit">Изменить шаблон</string>
<string name="app_profile_template_id">ID</string> <string name="app_profile_template_id">ID</string>
@@ -231,4 +231,6 @@
<string name="module_sort_enabled_first">По статусу (Сначала включённые)</string> <string name="module_sort_enabled_first">По статусу (Сначала включённые)</string>
<string name="module_sort_action_first">По статусу (Сначала со скриптом)</string> <string name="module_sort_action_first">По статусу (Сначала со скриптом)</string>
<string name="module_sort_webui_first">По статусу (Сначала с WebUI)</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> </resources>

View File

@@ -231,4 +231,6 @@
<string name="module_sort_enabled_first">Sort (Enabled first)</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_action_first">Sort (Action first)</string>
<string name="module_sort_webui_first">Sort (WebUI 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> </resources>

View File

@@ -231,4 +231,6 @@
<string name="module_sort_enabled_first">Sort (Enabled first)</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_action_first">Sort (Action first)</string>
<string name="module_sort_webui_first">Sort (WebUI 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> </resources>

View File

@@ -1,52 +1,52 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="issue_report_title">Sorun mu yaşıyorsunuz?</string> <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">Bir hatayla mı karşılaştınız veya geri bildiriminiz mi var?</string>
<string name="issue_report_body_2">Hemen bildirin!</string> <string name="issue_report_body_2">Mümkün olan en kısa sürede bildirin!</string>
<string name="issue_report_github">GitHub\'de bildirin</string> <string name="issue_report_github">GitHubda bildirin</string>
<string name="issue_report_telegram">Telegram ile iletişim kurun</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_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string> <string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">Onayla</string> <string name="confirm">Onayla</string>
<string name="app_name">KernelSU Next</string> <string name="app_name">KernelSU Next</string>
<string name="home">Ana Ekran</string> <string name="home">Ana Ekran</string>
<string name="home_not_installed">Yüklenmedi</string> <string name="home_not_installed">Yüklü değil</string>
<string name="home_click_to_install">Yüklemek için dokunun</string> <string name="home_click_to_install">Yüklemek için tıklayın</string>
<string name="lkm_mode_deprecated">LKM modu kullanımdan kaldırıldı!</string> <string name="lkm_mode_deprecated">LKM modu artık 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="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">Çalışıyor</string>
<string name="home_working_version">Sürüm: %d</string> <string name="home_working_version">Sürüm: %d</string>
<string name="home_module_update_count">Güncellemeler: %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_failure_tip">Kernel geliştiricinizden KernelSU Next\'i entegre etmelerini isteyin!</string>
<string name="home_kernel">Kernel sürümü</string> <string name="home_kernel">Çekirdek sürümü</string>
<string name="hook_mode">Hook modu</string> <string name="hook_mode">Kanca modu</string>
<string name="enable">Etkinleştir</string> <string name="enable">Etkinleştir</string>
<string name="disable">Devre dışı bırak</string> <string name="disable">Devre dışı bırak</string>
<string name="enabled">Etkinleştir</string> <string name="enabled">Etkin</string>
<string name="disabled">Devre dışı bırak</string> <string name="disabled">Devre dışı</string>
<string name="susfs_supported">Destekleniyor</string> <string name="susfs_supported">Destekleniyor</string>
<string name="home_susfs">SuSFS: %s</string> <string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">SuSFS sürümü</string> <string name="home_susfs_version">SuSFS sürümü</string>
<string name="home_susfs_sus_su">SuS SU</string> <string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">Android sürümü</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_abi">ABI</string>
<string name="home_selinux_status">SELinux durumu</string> <string name="home_selinux_status">SELinux durumu</string>
<string name="selinux_status_disabled">Devre dışı</string> <string name="selinux_status_disabled">Devre dışı</string>
<string name="selinux_status_enforcing">Zorlanıyor</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="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_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_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">Modül</string>
<string name="module_install_prompt_with_name">Bu modüller yüklenecektir: %1$s</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_a_to_z">Sırala (A → Z)</string>
<string name="module_sort_z_to_a">Sırala (Z → A)</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_low_to_high">Sırala (Düşük → Yüksek)</string>
<string name="module_size_high_to_low">Sırala (High → Low)</string> <string name="module_size_high_to_low">Sırala (Yüksek → Düşük)</string>
<string name="uninstall">Kaldır</string> <string name="uninstall">Kaldır</string>
<string name="restore">Geri yükle</string> <string name="restore">Geri yükle</string>
<string name="module_install">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_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_success">%s kaldırıldı</string>
<string name="module_uninstall_failed">Kaldırma başarısız oldu: %s</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_confirm">%s modülünü geri yüklemek istediğinize emin misiniz?</string>
<string name="module_restore_success">%s geri getirildi</string> <string name="module_restore_success">%s geri yüklendi</string>
<string name="module_restore_failed">Geri getirme başarısız oldu: %s</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_version">Sürüm</string>
<string name="module_author">Geliştirici</string> <string name="module_author">Geliştirici</string>
<string name="module_id">Kimlik</string> <string name="module_id">Kimlik</string>
@@ -74,7 +74,7 @@
<string name="module_update_json_empty">Boş</string> <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">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="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="refresh">Yenile</string>
<string name="show_system_apps">Sistem uygulamalarını göster</string> <string name="show_system_apps">Sistem uygulamalarını göster</string>
<string name="hide_system_apps">Sistem uygulamalarını gizle</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="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_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="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">Modülü geri yükle</string>
<string name="module_restore_message">En yeni yedeklemeden modülleri geri getir.</string> <string name="module_restore_message">Modülleri son yedeklemeden geri yükleyin.</string>
<string name="backup_restore">Yedekle &amp; Geri Getir</string> <string name="backup_restore">Yedekle &amp; Geri Getir</string>
<string name="module_backup">Modülü yedekle</string> <string name="module_backup">Modülü yedekle</string>
<string name="allowlist_restore">İzin verilen listesini geri yükle</string> <string name="allowlist_restore">İzin listesini geri yükle</string>
<string name="allowlist_restore_message">En yeni yedeklemeden modülleri geri getir.</string> <string name="allowlist_restore_message">İzin listesini son yedeklemeden geri yükleyin.</string>
<string name="allowlist_backup">İzin verilen listesini yedekle</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="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="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="proceed">Devam et</string>
<string name="cancel">İptal et</string> <string name="cancel">İptal et</string>
<string name="later">Sonra</string> <string name="later">Sonra</string>
<string name="lkm_warning_message">LKM yamaları kapalı kaynak kodludur. Devam etmek istiyor musunuz?</string> <string name="lkm_warning_message">LKM yaması kapalı kaynak bileşenlerine dayanır. Devam etmek istiyor musunuz?</string>
<string name="home_next_kernelsu">🔥 Sıradaki yapı</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_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">⚠️ Deneysel geliştirme uyarısı!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</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">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_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="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="about_source_code">Kaynak kodunu görüntüleyin: %1$s</string>
<string name="profile">Uygulama Profili</string> <string name="profile">Uygulama Profili</string>
@@ -121,42 +121,42 @@
<string name="profile_name">Profil ismi</string> <string name="profile_name">Profil ismi</string>
<string name="profile_namespace">Bağlama alanadı</string> <string name="profile_namespace">Bağlama alanadı</string>
<string name="profile_namespace_inherited">Inherited</string> <string name="profile_namespace_inherited">Inherited</string>
<string name="profile_namespace_global">Global</string> <string name="profile_namespace_global">Genel</string>
<string name="profile_namespace_individual">Bireysel</string> <string name="profile_namespace_individual">Özel</string>
<string name="profile_groups">Gruplar</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_selinux_context">SELinux bağlamı</string>
<string name="profile_umount_modules">Modüllerin bağlantısını kes</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="failed_to_update_app_profile">%s için Uygulama Profili güncellenemedi</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="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">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_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">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="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ğ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="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_domain">Alan adı</string>
<string name="profile_selinux_rules">Kurallar</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_update_available">Güncelleme mevcut</string>
<string name="module_updated">Güncellendi</string> <string name="module_updated">Güncellendi</string>
<string name="module_downloading">Modül indiriliyor: %s</string> <string name="module_downloading">Modül indiriliyor: %s</string>
<string name="module_start_downloading">İndirme başlıyor: %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="new_version_available">Yeni sürüm %s mevcut, güncellemek için tıklayın.</string>
<string name="launch_app"></string> <string name="launch_app">Başlat</string>
<string name="close">Kapat</string> <string name="close">Kapat</string>
<string name="force_stop_app">Durmaya zorla</string> <string name="force_stop_app">Durmaya zorla</string>
<string name="restart_app">Yeniden başlat</string> <string name="restart_app">Yeniden başlat</string>
<string name="settings_amoled_mode">AMOLED modu</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_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="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 per kullanıcı izni verilemedi</string>
<string name="module_changelog">Değişiklik Notları</string> <string name="module_changelog">Değişiklik Notları</string>
<string name="settings_profile_template">Uygulama Profili şablonu</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_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">Kimlik</string>
<string name="app_profile_template_id_invalid">Geçersiz şablon kimliği</string> <string name="app_profile_template_id_invalid">Geçersiz şablon kimliği</string>
<string name="app_profile_template_name">Ad</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_save">Kaydet</string>
<string name="app_profile_template_delete">Sil</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_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_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_export">İçe Aktar / Dışa Aktar</string>
<string name="app_profile_import_from_clipboard">Pano\'dan içe aktar</string> <string name="app_profile_import_from_clipboard">Panodan içe aktar</string>
<string name="app_profile_export_to_clipboard">Panoya çıkar</string> <string name="app_profile_export_to_clipboard">Panoya aktar</string>
<string name="app_profile_template_export_empty">Dışa aktarmak için yerel şablon bulunamadı!</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_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_sync">Çevrimiçi şablonları senkronize et</string>
<string name="app_profile_template_save_failed">Şablon kaydedilemedi</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="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">Güncellemeleri kontrol et</string>
<string name="settings_check_update_summary">Uygulamayı açarken güncellemeleri otomatik denetle</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="grant_root_failed">Kök izni verilemedi!</string>
<string name="action">İşlem</string> <string name="action">Eylem</string>
<string name="webui">WebUI</string> <string name="webui">WebUI</string>
<string name="open"></string> <string name="open"></string>
<string name="enable_web_debugging">WebView hata ayıklama etkinleştir</string> <string name="enable_web_debugging">WebView hata ayıklamayı 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_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="direct_install">Doğrudan kurulum (Önerilen)</string>
<string name="select_file">Bir dosya seçin</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">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_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">Sıradaki</string> <string name="install_next">Sonraki</string>
<string name="select_file_tip">%1$s bölüm imajı önerilir</string> <string name="select_file_tip">%1$s bölüm imajı önerilir</string>
<string name="select_kmi">KMI seçin</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">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">Kaldır</string>
<string name="settings_uninstall_temporary">Geçici olarak 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_uninstall_permanent">Kalıcı olarak kaldır</string>
<string name="settings_restore_stock_image">Stok imajı geri yükle</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_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="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="flashing">Kuruluyor</string>
<string name="flash_success">Kurulum başarılı</string> <string name="flash_success">Kurulum başarılı</string>
<string name="flash_failed">Kurulum başarısız</string> <string name="flash_failed">Kurulum başarısız</string>
<string name="selected_lkm">Seçili LKM: %s</string> <string name="selected_lkm">Seçili LKM: %s</string>
<string name="save_log">Logları kaydet</string> <string name="save_log">Günlükleri kaydet</string>
<string name="log_saved">Loglar kaydedildi</string> <string name="log_saved">Günlükler kaydedildi</string>
<string name="send_log">Logları paylaş</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">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_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> <string name="settings_language">Dil</string>
@@ -223,12 +223,14 @@
<string name="sucompat_disabled">SUCOMPAT DEVRE DIŞI</string> <string name="sucompat_disabled">SUCOMPAT DEVRE DIŞI</string>
<string name="zygisk_required">Zygisk gerekli</string> <string name="zygisk_required">Zygisk gerekli</string>
<string name="zygisk_status">Zygisk enjeksiyonu</string> <string name="zygisk_status">Zygisk enjeksiyonu</string>
<string name="home_superuser_count_singular">Superuser</string> <string name="home_superuser_count_singular">Süper Kullanıcı</string>
<string name="home_superuser_count_plural">Superusers</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_singular">Modül</string>
<string name="home_module_count_plural">Modüller</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_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_enabled_first">Sırala (Önce etkin)</string>
<string name="module_sort_action_first">Sırala (Önce Eylem)</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="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> </resources>

View File

@@ -231,4 +231,6 @@
<string name="module_sort_enabled_first">За статусом (Спочатку включені)</string> <string name="module_sort_enabled_first">За статусом (Спочатку включені)</string>
<string name="module_sort_action_first">За статусом (Спочатку зі скриптом)</string> <string name="module_sort_action_first">За статусом (Спочатку зі скриптом)</string>
<string name="module_sort_webui_first">За статусом (Спочатку з WebUI)</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> </resources>

View File

@@ -231,4 +231,6 @@
<string name="module_sort_enabled_first">Sắp xếp (Bật trước)</string> <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_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="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> </resources>

View File

@@ -15,7 +15,7 @@
<string name="lkm_mode_deprecated">LKM 模式已弃用!</string> <string name="lkm_mode_deprecated">LKM 模式已弃用!</string>
<string name="lkm_alternative_suggestion">安装 GKI 内核或集成 KernelSU 到你的设备。</string> <string name="lkm_alternative_suggestion">安装 GKI 内核或集成 KernelSU 到你的设备。</string>
<string name="home_working">工作中</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_module_update_count">%d 个模块可更新!</string>
<string name="home_failure">无法在内核中找到 KernelSU Next v2 签名![ !KSU_NEXT || != size/hash ]</string> <string name="home_failure">无法在内核中找到 KernelSU Next v2 签名![ !KSU_NEXT || != size/hash ]</string>
<string name="home_failure_tip">请让你的内核开发人员集成 KernelSU Next</string> <string name="home_failure_tip">请让你的内核开发人员集成 KernelSU Next</string>
@@ -26,27 +26,27 @@
<string name="enabled">已启用</string> <string name="enabled">已启用</string>
<string name="disabled">已禁用</string> <string name="disabled">已禁用</string>
<string name="susfs_supported">支持</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_version">SuSFS 版本</string>
<string name="home_susfs_sus_su">SuS SU</string> <string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">Android 版本</string> <string name="home_android">Android 版本</string>
<string name="home_manager_version">管理器版本</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="home_selinux_status">SELinux 状态</string>
<string name="selinux_status_disabled">禁用</string> <string name="selinux_status_disabled">禁用</string>
<string name="selinux_status_enforcing">严格模式</string> <string name="selinux_status_enforcing">严格模式</string>
<string name="selinux_status_permissive">宽容模式</string> <string name="selinux_status_permissive">宽容模式</string>
<string name="selinux_status_unknown">未知</string> <string name="selinux_status_unknown">未知</string>
<string name="superuser">超级用户</string> <string name="superuser">超级用户</string>
<string name="module_failed_to_enable">启用模块失败:%s</string> <string name="module_failed_to_enable">无法启用模块: %s</string>
<string name="module_failed_to_disable">禁用模块失败:%s</string> <string name="module_failed_to_disable">无法禁用模块: %s</string>
<string name="module_empty">未安装任何模块</string> <string name="module_empty">未安装任何模块</string>
<string name="module">模块</string> <string name="module">模块</string>
<string name="module_install_prompt_with_name">将安装以下模块%1$s</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_a_to_z">排序 (A -&gt; Z)</string>
<string name="module_sort_z_to_a">按 Z - A 排序</string> <string name="module_sort_z_to_a">排序 (Z -&gt; A)</string>
<string name="module_size_low_to_high">按模块大小正序排序</string> <string name="module_size_low_to_high">排序 (按模块从小到大)</string>
<string name="module_size_high_to_low">按模块大小倒序排序</string> <string name="module_size_high_to_low">排序 (按模块从大到小)</string>
<string name="uninstall">卸载</string> <string name="uninstall">卸载</string>
<string name="restore">还原</string> <string name="restore">还原</string>
<string name="module_install">安装</string> <string name="module_install">安装</string>
@@ -62,10 +62,10 @@
<string name="about">关于</string> <string name="about">关于</string>
<string name="module_uninstall_confirm">确定要卸载模块 %s 吗?</string> <string name="module_uninstall_confirm">确定要卸载模块 %s 吗?</string>
<string name="module_uninstall_success">已卸载 %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_confirm">确定要还原模块 %s 吗?</string>
<string name="module_restore_success">已还原 %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_version">版本</string>
<string name="module_author">作者</string> <string name="module_author">作者</string>
<string name="module_id">模块标识</string> <string name="module_id">模块标识</string>
@@ -82,7 +82,7 @@
<string name="safe_mode">安全模式</string> <string name="safe_mode">安全模式</string>
<string name="reboot_to_apply">重启生效</string> <string name="reboot_to_apply">重启生效</string>
<string name="module_magisk_conflict">由于与 Magisk 冲突,模块系统不可用!</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_magic_mount">Magic Mount</string>
<string name="home_overlayfs_mount">OverlayFS</string> <string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">不可用</string> <string name="unavailable">不可用</string>
@@ -103,10 +103,10 @@
<string name="proceed">继续</string> <string name="proceed">继续</string>
<string name="cancel">取消</string> <string name="cancel">取消</string>
<string name="later">稍后</string> <string name="later">稍后</string>
<string name="lkm_warning_message">LKM 补丁依赖于闭源组件,确认操作代表你知晓因继续使用该功能所导致的一切后果与开发团队无关</string> <string name="lkm_warning_message">LKM 补丁依赖于闭源组件。是否继续?</string>
<string name="home_next_kernelsu">🔥 Next 构建</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_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">⚠️ 实验性开发警告!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string> <string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next 是一个非官方版本,一直处于积极的实验开发阶段。它按原样提供,不保证稳定性、性能或可靠性。</string> <string name="home_experimental_kernelsu_body">KernelSU Next 是一个非官方版本,一直处于积极的实验开发阶段。它按原样提供,不保证稳定性、性能或可靠性。</string>
@@ -139,9 +139,9 @@
<string name="module_update">更新</string> <string name="module_update">更新</string>
<string name="module_update_available">更新可用</string> <string name="module_update_available">更新可用</string>
<string name="module_updated">重启以应用更新</string> <string name="module_updated">重启以应用更新</string>
<string name="module_downloading">正在下载模块%s</string> <string name="module_downloading">正在下载模块: %s</string>
<string name="module_start_downloading">开始下载%s</string> <string name="module_start_downloading">开始下载: %s</string>
<string name="new_version_available">发现新版本%s点击升级。</string> <string name="new_version_available">发现新版本 %s点击升级。</string>
<string name="launch_app">启动</string> <string name="launch_app">启动</string>
<string name="close">关闭</string> <string name="close">关闭</string>
<string name="force_stop_app">强行停止</string> <string name="force_stop_app">强行停止</string>
@@ -174,7 +174,7 @@
<string name="app_profile_template_sync">同步在线模板</string> <string name="app_profile_template_sync">同步在线模板</string>
<string name="app_profile_template_save_failed">模版保存失败</string> <string name="app_profile_template_save_failed">模版保存失败</string>
<string name="app_profile_template_import_empty">剪贴板为空!</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">检查更新</string>
<string name="settings_check_update_summary">在应用启动后自动检查是否有新版本。</string> <string name="settings_check_update_summary">在应用启动后自动检查是否有新版本。</string>
<string name="grant_root_failed">获取 root 失败!</string> <string name="grant_root_failed">获取 root 失败!</string>
@@ -202,7 +202,7 @@
<string name="flashing">刷写中</string> <string name="flashing">刷写中</string>
<string name="flash_success">刷写成功</string> <string name="flash_success">刷写成功</string>
<string name="flash_failed">刷写失败</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="save_log">保存日志</string>
<string name="log_saved">日志已保存</string> <string name="log_saved">日志已保存</string>
<string name="send_log">分享日志</string> <string name="send_log">分享日志</string>
@@ -220,7 +220,7 @@
<string name="use_webuix_eruda_summary">将调试控制台注入 WebUI X 以使调试更容易。需要启用 Web 调试。</string> <string name="use_webuix_eruda_summary">将调试控制台注入 WebUI X 以使调试更容易。需要启用 Web 调试。</string>
<string name="customization">界面设置</string> <string name="customization">界面设置</string>
<string name="developer">开发者选项</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_required">需要 Zygisk</string>
<string name="zygisk_status">Zygisk 注入</string> <string name="zygisk_status">Zygisk 注入</string>
<string name="home_superuser_count_singular">超级用户</string> <string name="home_superuser_count_singular">超级用户</string>
@@ -228,7 +228,9 @@
<string name="home_module_count_singular">模块</string> <string name="home_module_count_singular">模块</string>
<string name="home_module_count_plural">模块</string> <string name="home_module_count_plural">模块</string>
<string name="module_backup_message">备份当前已安装的模块。</string> <string name="module_backup_message">备份当前已安装的模块。</string>
<string name="module_sort_enabled_first">按启用状态优先排序</string> <string name="module_sort_enabled_first">排序 (已启用优先)</string>
<string name="module_sort_action_first">按支持执行脚本的模块优先排序</string> <string name="module_sort_action_first">排序 (可执行优先)</string>
<string name="module_sort_webui_first">按拥有 WebUI 的模块优先排序</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> </resources>

View File

@@ -229,6 +229,8 @@
<string name="home_module_count_plural">模組</string> <string name="home_module_count_plural">模組</string>
<string name="module_backup_message">備份當前已安裝的模組。</string> <string name="module_backup_message">備份當前已安裝的模組。</string>
<string name="module_sort_enabled_first">依啟用狀態優先排序</string> <string name="module_sort_enabled_first">依啟用狀態優先排序</string>
<string name="module_sort_action_first">依支援執行腳本的模組優先排序</string> <string name="module_sort_action_first">依支援執行優先排序</string>
<string name="module_sort_webui_first">依具備 WebUI 的模組優先排序</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> </resources>

View File

@@ -231,4 +231,6 @@
<string name="module_sort_enabled_first">Sort (Enabled first)</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_action_first">Sort (Action first)</string>
<string name="module_sort_webui_first">Sort (WebUI 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> </resources>

26
manager/setup.sh Executable file
View 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

View File

@@ -31,4 +31,9 @@ if [ -f "./build.gradle.kts" ]; then
sed -i 's/\(versionName = managerVersionName\)/versionName = managerVersionNameSpoofed/' ./build.gradle.kts sed -i 's/\(versionName = managerVersionName\)/versionName = managerVersionNameSpoofed/' ./build.gradle.kts
fi 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." echo "Done."

View File

@@ -310,7 +310,7 @@ pub fn restore(
let skip_init = kmi.starts_with("android12-"); 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"); println!("- Unpacking boot image");
let status = Command::new(&magiskboot) let status = Command::new(&magiskboot)
@@ -323,6 +323,7 @@ pub fn restore(
ensure!(status.success(), "magiskboot unpack failed"); ensure!(status.success(), "magiskboot unpack failed");
let no_ramdisk = !workdir.join("ramdisk.cpio").exists(); let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
// let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
let no_vendor_init_boot = !workdir let no_vendor_init_boot = !workdir
.join("vendor_ramdisk") .join("vendor_ramdisk")
.join("init_boot.cpio") .join("init_boot.cpio")
@@ -370,41 +371,78 @@ pub fn restore(
} }
if new_boot.is_none() { if new_boot.is_none() {
if no_ramdisk { if !no_ramdisk {
if !no_vendor_init_boot { println!("- Restoring /ramdisk");
// vendor init_boot restore println!("- Removing /ramdisk/kernelsu.ko");
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 {
// remove kernelsu.ko // remove kernelsu.ko
do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?; do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
// if init.real exists, restore it // if init.real exists, restore it
println!("- Checking if init.real exists");
let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok(); let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
if status { if status {
println!("- /ramdisk/init.real exists");
println!("- Restoring /ramdisk/init.real to init");
do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?; do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
} else { } 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"); let ramdisk = workdir.join("ramdisk.cpio");
std::fs::remove_file(ramdisk)?; std::fs::remove_file(ramdisk)?;
} }
@@ -536,7 +574,7 @@ fn do_patch(
let skip_init = kmi.starts_with("android12-"); let skip_init = kmi.starts_with("android12-");
let (bootimage, bootdevice) = 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(); let bootimage = bootimage.display().to_string();
@@ -584,7 +622,8 @@ fn do_patch(
.exists(); .exists();
let no_vendor_ramdisk = !workdir.join("vendor_ramdisk").join("ramdisk.cpio").exists(); let no_vendor_ramdisk = !workdir.join("vendor_ramdisk").join("ramdisk.cpio").exists();
if no_ramdisk && no_vendor_init_boot && no_vendor_ramdisk { 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 = is_magisk_patched(&magiskboot, workdir)?;
let is_magisk_patched_vendor_init_boot = let is_magisk_patched_vendor_init_boot =
@@ -605,43 +644,59 @@ fn do_patch(
is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?; is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?;
let mut need_backup = false; let mut need_backup = false;
if !is_kernelsu_patched if (no_ramdisk && !is_kernelsu_patched_vendor_init_boot)
|| (no_ramdisk && !is_kernelsu_patched_vendor_init_boot)
|| (no_ramdisk && no_vendor_init_boot && !is_kernelsu_patched_vendor_ramdisk) || (no_ramdisk && no_vendor_init_boot && !is_kernelsu_patched_vendor_ramdisk)
|| !is_kernelsu_patched
{ {
if no_ramdisk { if !no_ramdisk {
if !no_vendor_init_boot { println!("- Checking if /ramdisk/init exists");
// 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
let status = do_cpio_cmd(&magiskboot, workdir, "exists init"); let status = do_cpio_cmd(&magiskboot, workdir, "exists init");
if status.is_ok() { 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")?; do_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
} }
need_backup = flash; need_backup = flash;
} }
} }
if no_ramdisk { if !no_ramdisk {
if !no_vendor_init_boot { println!("- Patching /ramdisk");
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
} else if !no_vendor_ramdisk { } else if !no_vendor_init_boot {
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?; println!("- Patching /vendor_ramdisk/init_boot");
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?; 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 { } else {
println!("- Creating and Patching /ramdisk");
do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
} }
@@ -800,16 +855,17 @@ fn find_boot_image(
ota: bool, ota: bool,
is_replace_kernel: bool, is_replace_kernel: bool,
workdir: &Path, workdir: &Path,
magiskboot: &Path,
) -> Result<(PathBuf, Option<String>)> { ) -> Result<(PathBuf, Option<String>)> {
let bootimage; let bootimage;
let mut bootdevice = None; let mut bootdevice = None;
if let Some(ref image) = *image { 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)?; bootimage = std::fs::canonicalize(image)?;
} else { } else {
if cfg!(not(target_os = "android")) { if cfg!(not(target_os = "android")) {
println!("- Current OS is not android, refusing auto bootimage/bootdevice detection"); 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 = let mut slot_suffix =
utils::getprop("ro.boot.slot_suffix").unwrap_or_else(|| String::from("")); utils::getprop("ro.boot.slot_suffix").unwrap_or_else(|| String::from(""));
@@ -822,27 +878,104 @@ fn find_boot_image(
} }
}; };
let init_boot_exist = let init_boot_partition = format!("/dev/block/by-name/init_boot{slot_suffix}");
Path::new(&format!("/dev/block/by-name/init_boot{slot_suffix}")).exists(); let vendor_boot_partition = format!("/dev/block/by-name/vendor_boot{slot_suffix}");
let vendor_boot_exist = let boot_partition = format!("/dev/block/by-name/boot{slot_suffix}");
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}")
};
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"); 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; bootimage = tmp_boot_path;
bootdevice = Some(boot_partition); bootdevice = Some(selected_partition.to_string());
}; };
Ok((bootimage, bootdevice)) Ok((bootimage, bootdevice))
} }

View File

@@ -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 NO_MOUNT_PATH: &str = concatcp!(WORKING_DIR, ".nomount");
pub const MOUNT_SYSTEM: &str = "Magic_Mount"; pub const MOUNT_SYSTEM: &str = "Magic_Mount";
pub const GLOBAL_NAMESPACE_FILE: &str = concatcp!(WORKING_DIR, ".global_mnt");

View File

@@ -261,7 +261,9 @@ pub fn root_shell() -> Result<()> {
// switch to global mount namespace // switch to global mount namespace
#[cfg(any(target_os = "linux", target_os = "android"))] #[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); let _ = utils::switch_mnt_ns(1);
} }

View File

@@ -310,7 +310,7 @@ pub fn restore(
let skip_init = kmi.starts_with("android12-"); 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"); println!("- Unpacking boot image");
let status = Command::new(&magiskboot) let status = Command::new(&magiskboot)
@@ -323,6 +323,7 @@ pub fn restore(
ensure!(status.success(), "magiskboot unpack failed"); ensure!(status.success(), "magiskboot unpack failed");
let no_ramdisk = !workdir.join("ramdisk.cpio").exists(); let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
// let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
let no_vendor_init_boot = !workdir let no_vendor_init_boot = !workdir
.join("vendor_ramdisk") .join("vendor_ramdisk")
.join("init_boot.cpio") .join("init_boot.cpio")
@@ -370,41 +371,78 @@ pub fn restore(
} }
if new_boot.is_none() { if new_boot.is_none() {
if no_ramdisk { if !no_ramdisk {
if !no_vendor_init_boot { println!("- Restoring /ramdisk");
// vendor init_boot restore println!("- Removing /ramdisk/kernelsu.ko");
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 {
// remove kernelsu.ko // remove kernelsu.ko
do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?; do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
// if init.real exists, restore it // if init.real exists, restore it
println!("- Checking if init.real exists");
let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok(); let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
if status { if status {
println!("- /ramdisk/init.real exists");
println!("- Restoring /ramdisk/init.real to init");
do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?; do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
} else { } 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"); let ramdisk = workdir.join("ramdisk.cpio");
std::fs::remove_file(ramdisk)?; std::fs::remove_file(ramdisk)?;
} }
@@ -536,7 +574,7 @@ fn do_patch(
let skip_init = kmi.starts_with("android12-"); let skip_init = kmi.starts_with("android12-");
let (bootimage, bootdevice) = 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(); let bootimage = bootimage.display().to_string();
@@ -584,7 +622,8 @@ fn do_patch(
.exists(); .exists();
let no_vendor_ramdisk = !workdir.join("vendor_ramdisk").join("ramdisk.cpio").exists(); let no_vendor_ramdisk = !workdir.join("vendor_ramdisk").join("ramdisk.cpio").exists();
if no_ramdisk && no_vendor_init_boot && no_vendor_ramdisk { 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 = is_magisk_patched(&magiskboot, workdir)?;
let is_magisk_patched_vendor_init_boot = let is_magisk_patched_vendor_init_boot =
@@ -605,43 +644,59 @@ fn do_patch(
is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?; is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?;
let mut need_backup = false; let mut need_backup = false;
if !is_kernelsu_patched if (no_ramdisk && !is_kernelsu_patched_vendor_init_boot)
|| (no_ramdisk && !is_kernelsu_patched_vendor_init_boot)
|| (no_ramdisk && no_vendor_init_boot && !is_kernelsu_patched_vendor_ramdisk) || (no_ramdisk && no_vendor_init_boot && !is_kernelsu_patched_vendor_ramdisk)
|| !is_kernelsu_patched
{ {
if no_ramdisk { if !no_ramdisk {
if !no_vendor_init_boot { println!("- Checking if /ramdisk/init exists");
// 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
let status = do_cpio_cmd(&magiskboot, workdir, "exists init"); let status = do_cpio_cmd(&magiskboot, workdir, "exists init");
if status.is_ok() { 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")?; do_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
} }
need_backup = flash; need_backup = flash;
} }
} }
if no_ramdisk { if !no_ramdisk {
if !no_vendor_init_boot { println!("- Patching /ramdisk");
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
} else if !no_vendor_ramdisk { } else if !no_vendor_init_boot {
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?; println!("- Patching /vendor_ramdisk/init_boot");
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?; 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 { } else {
println!("- Creating and Patching /ramdisk");
do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
} }
@@ -800,16 +855,17 @@ fn find_boot_image(
ota: bool, ota: bool,
is_replace_kernel: bool, is_replace_kernel: bool,
workdir: &Path, workdir: &Path,
magiskboot: &Path,
) -> Result<(PathBuf, Option<String>)> { ) -> Result<(PathBuf, Option<String>)> {
let bootimage; let bootimage;
let mut bootdevice = None; let mut bootdevice = None;
if let Some(ref image) = *image { 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)?; bootimage = std::fs::canonicalize(image)?;
} else { } else {
if cfg!(not(target_os = "android")) { if cfg!(not(target_os = "android")) {
println!("- Current OS is not android, refusing auto bootimage/bootdevice detection"); 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 = let mut slot_suffix =
utils::getprop("ro.boot.slot_suffix").unwrap_or_else(|| String::from("")); utils::getprop("ro.boot.slot_suffix").unwrap_or_else(|| String::from(""));
@@ -822,27 +878,104 @@ fn find_boot_image(
} }
}; };
let init_boot_exist = let init_boot_partition = format!("/dev/block/by-name/init_boot{slot_suffix}");
Path::new(&format!("/dev/block/by-name/init_boot{slot_suffix}")).exists(); let vendor_boot_partition = format!("/dev/block/by-name/vendor_boot{slot_suffix}");
let vendor_boot_exist = let boot_partition = format!("/dev/block/by-name/boot{slot_suffix}");
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}")
};
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"); 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; bootimage = tmp_boot_path;
bootdevice = Some(boot_partition); bootdevice = Some(selected_partition.to_string());
}; };
Ok((bootimage, bootdevice)) Ok((bootimage, bootdevice))
} }

View File

@@ -47,3 +47,5 @@ pub const KSU_BACKUP_FILE_PREFIX: &str = "ksu_backup_";
pub const BACKUP_FILENAME: &str = "stock_image.sha1"; pub const BACKUP_FILENAME: &str = "stock_image.sha1";
pub const MOUNT_SYSTEM: &str = "OverlayFS"; pub const MOUNT_SYSTEM: &str = "OverlayFS";
pub const GLOBAL_NAMESPACE_FILE: &str = concatcp!(WORKING_DIR, ".global_mnt");

View File

@@ -261,7 +261,9 @@ pub fn root_shell() -> Result<()> {
// switch to global mount namespace // switch to global mount namespace
#[cfg(any(target_os = "linux", target_os = "android"))] #[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); let _ = utils::switch_mnt_ns(1);
} }

View File

@@ -1,11 +1,54 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h>
#include <sys/prctl.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". #define KERNEL_SU_OPTION 0xDEADBEEF
int main(){ #define CMD_GRANT_ROOT 0
int32_t result = 0; #define CMD_ENABLE_SU 15
prctl(0xdeadbeef, 0, 0, 0, &result);
system("/system/bin/sh"); int main(int argc, char **argv, char **envp) {
return 0; 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;
} }

View File

@@ -104,52 +104,77 @@ int main(int argc, char *argv[]) {
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_ENABLED_FEATURES, enabled_features, bufsize, &error); prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_ENABLED_FEATURES, enabled_features, bufsize, &error);
printf("%s\n", error || !strlen(enabled_features) ? "Unsupported" : "Supported"); printf("%s\n", error || !strlen(enabled_features) ? "Unsupported" : "Supported");
free(enabled_features); free(enabled_features);
} else if (argc == 3 && !strcmp(argv[1], "sus_su")) { } else if (argc >= 2 && !strcmp(argv[1], "sus_su")) {
int last_working_mode = 0; if (argc == 3 && strcmp(argv[2], "support") == 0) {
int target_working_mode; char *enabled_features;
char* endptr; 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); prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE, &last_working_mode, NULL, &error);
if (error) if (error)
return error; return error;
if (!strcmp(argv[2], "mode")) {
printf("%d\n", last_working_mode); if (!strcmp(argv[2], "mode")) {
return 0; printf("%d\n", last_working_mode);
} return 0;
target_working_mode = strtol(argv[2], &endptr, 10); }
if (*endptr != '\0') {
return 1; target_working_mode = strtol(argv[2], &endptr, 10);
} if (*endptr != '\0') {
if (target_working_mode == SUS_SU_WITH_HOOKS) { return 1;
bool is_sus_su_ready; }
prctl(KERNEL_SU_OPTION, CMD_SUSFS_IS_SUS_SU_READY, &is_sus_su_ready, NULL, &error);
if (error) if (target_working_mode == SUS_SU_WITH_HOOKS) {
return error; bool is_sus_su_ready;
if (!is_sus_su_ready) { prctl(KERNEL_SU_OPTION, CMD_SUSFS_IS_SUS_SU_READY, &is_sus_su_ready, NULL, &error);
printf("[-] sus_su mode %d has to be run during or after service stage\n", SUS_SU_WITH_HOOKS); if (error)
return 1; return error;
} if (!is_sus_su_ready) {
if (last_working_mode == SUS_SU_DISABLED) { printf("[-] sus_su mode %d has to be run during or after service stage\n", SUS_SU_WITH_HOOKS);
error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS); return 1;
} else if (last_working_mode == SUS_SU_WITH_HOOKS) { }
printf("[-] sus_su is already in mode %d\n", last_working_mode);
return 1; if (last_working_mode == SUS_SU_DISABLED) {
} else { error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS);
error = enable_sus_su(last_working_mode, SUS_SU_DISABLED); } else if (last_working_mode == SUS_SU_WITH_HOOKS) {
if (!error) printf("[-] sus_su is already in mode %d\n", last_working_mode);
error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS); return 1;
} } else {
} else if (target_working_mode == SUS_SU_DISABLED) { error = enable_sus_su(last_working_mode, SUS_SU_DISABLED);
if (last_working_mode == SUS_SU_DISABLED) { if (!error)
printf("[-] sus_su is already in mode %d\n", last_working_mode); error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS);
return 1; }
} } else if (target_working_mode == SUS_SU_DISABLED) {
error = enable_sus_su(last_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 { } else {
fprintf(stderr, "Invalid argument: %s\n", argv[1]); fprintf(stderr, "Invalid argument: %s\n", argv[1]);
return 1; return 1;
} }
return 0; return 0;
} }