mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-08-14 07:27:28 +00:00
Compare commits
51 Commits
canary-270
...
canary-270
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8e82113bce | ||
![]() |
f723ef153b | ||
![]() |
1dc723fb6d | ||
![]() |
8f271c2575 | ||
![]() |
7cf56b4406 | ||
![]() |
c2eb603957 | ||
![]() |
e6bd2ff60f | ||
![]() |
5604074eba | ||
![]() |
3f061c1a1e | ||
![]() |
55e78a7b1a | ||
![]() |
000f1d6041 | ||
![]() |
2cbec20238 | ||
![]() |
4b724c7257 | ||
![]() |
ab04c6ab39 | ||
![]() |
821a6c6954 | ||
![]() |
5f27a62221 | ||
![]() |
c76cc4c6bd | ||
![]() |
52b75c53b6 | ||
![]() |
9db2e99086 | ||
![]() |
e9e2ecf2dd | ||
![]() |
9a9e617c35 | ||
![]() |
3a0becc783 | ||
![]() |
1f974cb220 | ||
![]() |
1db80228e8 | ||
![]() |
838e1e254d | ||
![]() |
554eda8fe1 | ||
![]() |
2bdc047c4d | ||
![]() |
e64f59ce5b | ||
![]() |
b8140ad4e6 | ||
![]() |
5a55483698 | ||
![]() |
2d341863f5 | ||
![]() |
278046becb | ||
![]() |
5c0497354f | ||
![]() |
98c258df93 | ||
![]() |
c578cccfd5 | ||
![]() |
07835a3e0e | ||
![]() |
09131aca89 | ||
![]() |
9ce998a6df | ||
![]() |
ca36b42d79 | ||
![]() |
37df39ec37 | ||
![]() |
1701361a73 | ||
![]() |
4c14ae33f5 | ||
![]() |
d4a9ef7b7f | ||
![]() |
1539cfe888 | ||
![]() |
9093be1329 | ||
![]() |
606d076251 | ||
![]() |
46a34e19bc | ||
![]() |
5ac7dc0b37 | ||
![]() |
3b27de3715 | ||
![]() |
939bfac920 | ||
![]() |
f601bf12d5 |
90
.github/actions/setup/action.yml
vendored
90
.github/actions/setup/action.yml
vendored
@@ -1,4 +1,8 @@
|
||||
name: Magisk Setup
|
||||
inputs:
|
||||
is-asset-build:
|
||||
required: false
|
||||
default: false
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
@@ -13,32 +17,84 @@ runs:
|
||||
with:
|
||||
python-version: "3.x"
|
||||
|
||||
- name: Set up sccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
- name: Install GNU make
|
||||
if: runner.os == 'macOS'
|
||||
shell: bash
|
||||
run: |
|
||||
brew install make
|
||||
echo 'GNUMAKE=gmake' >> "$GITHUB_ENV"
|
||||
|
||||
- name: Cache sccache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
variant: sccache
|
||||
key: ${{ runner.os }}-${{ github.sha }}
|
||||
restore-keys: ${{ runner.os }}
|
||||
max-size: 10000M
|
||||
path: .sccache
|
||||
key: sccache-${{ runner.os }}-${{ github.sha }}
|
||||
restore-keys: sccache-${{ runner.os }}-
|
||||
|
||||
- name: Set up sccache
|
||||
shell: bash
|
||||
env:
|
||||
SCCACHE_DIRECT: false
|
||||
SCCACHE_DIR: ${{ github.workspace }}/.sccache
|
||||
SCCACHE_CACHE_SIZE: 2G
|
||||
SCCACHE_IDLE_TIMEOUT: 0
|
||||
run: |
|
||||
bash $GITHUB_ACTION_PATH/sccache.sh
|
||||
sccache --start-server
|
||||
sccache -z
|
||||
|
||||
- name: Show sccache stats
|
||||
uses: gacts/run-and-post-run@v1
|
||||
with:
|
||||
run: sccache -s
|
||||
post: sccache -s
|
||||
|
||||
- name: Set GRADLE_USER_HOME
|
||||
shell: bash
|
||||
run: echo "GRADLE_USER_HOME=$GITHUB_WORKSPACE/.gradle" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Cache Gradle dependencies
|
||||
uses: actions/cache@v4
|
||||
if: inputs.is-asset-build == 'true'
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
!~/.gradle/caches/build-cache-*
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: ${{ runner.os }}-gradle-
|
||||
.gradle/caches
|
||||
.gradle/wrapper
|
||||
!.gradle/caches/build-cache-*
|
||||
key: gradle-cache-${{ hashFiles('gradle/**') }}
|
||||
restore-keys: gradle-cache-
|
||||
|
||||
- name: Cache build cache
|
||||
uses: actions/cache@v4
|
||||
- name: Restore Gradle dependencies
|
||||
uses: actions/cache/restore@v4
|
||||
if: inputs.is-asset-build == 'false'
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches/build-cache-*
|
||||
key: ${{ runner.os }}-build-cache-${{ github.sha }}
|
||||
restore-keys: ${{ runner.os }}-build-cache-
|
||||
.gradle/caches
|
||||
.gradle/wrapper
|
||||
!.gradle/caches/build-cache-*
|
||||
key: gradle-cache-${{ hashFiles('gradle/**') }}
|
||||
restore-keys: gradle-cache-
|
||||
enableCrossOsArchive: true
|
||||
|
||||
- name: Cache Gradle build cache
|
||||
uses: actions/cache@v4
|
||||
if: inputs.is-asset-build == 'true'
|
||||
with:
|
||||
path: |
|
||||
.gradle/caches/build-cache-*
|
||||
key: gradle-build-cache-${{ github.sha }}
|
||||
restore-keys: gradle-build-cache-
|
||||
|
||||
- name: Restore Gradle build cache
|
||||
uses: actions/cache/restore@v4
|
||||
if: inputs.is-asset-build == 'false'
|
||||
with:
|
||||
path: |
|
||||
.gradle/caches/build-cache-*
|
||||
key: gradle-build-cache-${{ github.sha }}
|
||||
restore-keys: gradle-build-cache-
|
||||
enableCrossOsArchive: true
|
||||
|
||||
- name: Set up NDK
|
||||
run: python build.py -v ndk
|
||||
shell: bash
|
||||
run: python build.py -v ndk
|
||||
|
25
.github/actions/setup/sccache.sh
vendored
Executable file
25
.github/actions/setup/sccache.sh
vendored
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Get latest sccache version
|
||||
get_sccache_ver() {
|
||||
curl -sL 'https://api.github.com/repos/mozilla/sccache/releases/latest' | jq -r .name
|
||||
}
|
||||
|
||||
# $1=variant
|
||||
# $2=install_dir
|
||||
# $3=exe
|
||||
install_from_gh() {
|
||||
local ver=$(curl -sL 'https://api.github.com/repos/mozilla/sccache/releases/latest' | jq -r .name)
|
||||
local url="https://github.com/mozilla/sccache/releases/download/${ver}/sccache-${ver}-$1.tar.gz"
|
||||
local dest="$2/$3"
|
||||
curl -L "$url" | tar xz -O --wildcards "*/$3" > $dest
|
||||
chmod +x $dest
|
||||
}
|
||||
|
||||
if [ $RUNNER_OS = "macOS" ]; then
|
||||
brew install sccache
|
||||
elif [ $RUNNER_OS = "Linux" ]; then
|
||||
install_from_gh x86_64-unknown-linux-musl /usr/local/bin sccache
|
||||
elif [ $RUNNER_OS = "Windows" ]; then
|
||||
install_from_gh x86_64-pc-windows-msvc $USERPROFILE/.cargo/bin sccache.exe
|
||||
fi
|
1
.github/ci.prop
vendored
Normal file
1
.github/ci.prop
vendored
Normal file
@@ -0,0 +1 @@
|
||||
abiList=arm64-v8a
|
54
.github/workflows/build.yml
vendored
54
.github/workflows/build.yml
vendored
@@ -17,9 +17,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
name: Build Magisk artifacts
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
SCCACHE_DIRECT: false
|
||||
runs-on: macos-14
|
||||
strategy:
|
||||
fail-fast: false
|
||||
steps:
|
||||
@@ -27,10 +25,11 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: "recursive"
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
is-asset-build: true
|
||||
|
||||
- name: Build release
|
||||
run: ./build.py -vr all
|
||||
@@ -58,24 +57,21 @@ jobs:
|
||||
test-build:
|
||||
name: Test building on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
SCCACHE_DIRECT: false
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-latest, macos-14]
|
||||
os: [windows-latest, ubuntu-latest]
|
||||
steps:
|
||||
- name: Check out
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: "recursive"
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
- name: Build debug
|
||||
run: python build.py -v all
|
||||
- name: Test build
|
||||
run: python build.py -v -c .github/ci.prop all
|
||||
|
||||
- name: Stop gradle daemon
|
||||
run: ./gradlew --stop
|
||||
@@ -96,8 +92,6 @@ jobs:
|
||||
steps:
|
||||
- name: Check out
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -114,9 +108,18 @@ jobs:
|
||||
- name: Run AVD test
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
AVD_TEST_VERBOSE: 1
|
||||
AVD_TEST_LOG: 1
|
||||
run: scripts/avd_test.sh ${{ matrix.version }} ${{ matrix.type }}
|
||||
|
||||
- name: Upload logs on error
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "avd-logs-${{ matrix.version }}"
|
||||
path: |
|
||||
kernel.log
|
||||
logcat.log
|
||||
|
||||
avd-test-32:
|
||||
name: Test API ${{ matrix.version }} (x86)
|
||||
runs-on: ubuntu-latest
|
||||
@@ -129,8 +132,6 @@ jobs:
|
||||
steps:
|
||||
- name: Check out
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -148,11 +149,20 @@ jobs:
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
FORCE_32_BIT: 1
|
||||
AVD_TEST_VERBOSE: 1
|
||||
AVD_TEST_LOG: 1
|
||||
run: scripts/avd_test.sh ${{ matrix.version }}
|
||||
|
||||
- name: Upload logs on error
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "avd32-logs-${{ matrix.version }}"
|
||||
path: |
|
||||
kernel.log
|
||||
logcat.log
|
||||
|
||||
cf_test:
|
||||
name: Test ${{ matrix.branch }} (${{ matrix.target }})
|
||||
name: Test ${{ matrix.device }}
|
||||
runs-on: ubuntu-24.04
|
||||
needs: build
|
||||
env:
|
||||
@@ -162,13 +172,13 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- branch: "aosp-main"
|
||||
target: "aosp_cf_x86_64_phone-trunk_staging-userdebug"
|
||||
device: "aosp_cf_x86_64_phone"
|
||||
- branch: "aosp-main-throttled"
|
||||
device: "aosp_cf_x86_64_phone_pgagnostic"
|
||||
|
||||
steps:
|
||||
- name: Check out
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -179,7 +189,7 @@ jobs:
|
||||
- name: Setup Cuttlefish environment
|
||||
run: |
|
||||
scripts/cuttlefish.sh setup
|
||||
scripts/cuttlefish.sh download ${{ matrix.branch }} ${{ matrix.target }}
|
||||
scripts/cuttlefish.sh download ${{ matrix.branch }} ${{ matrix.device }}
|
||||
|
||||
- name: Run Cuttlefish test
|
||||
timeout-minutes: 10
|
||||
@@ -189,7 +199,7 @@ jobs:
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "cvd-logs"
|
||||
name: "cvd-logs-${{ matrix.device }}"
|
||||
path: |
|
||||
/home/runner/aosp_cf_phone/cuttlefish/instances/cvd-1/logs
|
||||
/home/runner/aosp_cf_phone/cuttlefish/instances/cvd-1/cuttlefish_config.json
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -13,7 +13,7 @@ native/out
|
||||
# Android Studio / Gradle
|
||||
*.iml
|
||||
.gradle
|
||||
.idea
|
||||
/local.properties
|
||||
/.idea
|
||||
/build
|
||||
/captures
|
||||
|
@@ -22,7 +22,7 @@ Click the icon below to download Magisk apk.
|
||||
|
||||
[](https://github.com/topjohnwu/Magisk/releases/tag/v27.0)
|
||||
[](https://github.com/topjohnwu/Magisk/releases/tag/v27.0)
|
||||
[](https://github.com/topjohnwu/Magisk/releases/tag/canary-27006)
|
||||
[](https://github.com/topjohnwu/Magisk/releases/tag/canary-27007)
|
||||
|
||||
## Useful Links
|
||||
|
||||
|
@@ -47,22 +47,21 @@ android {
|
||||
dependencies {
|
||||
implementation(project(":app:core"))
|
||||
|
||||
implementation("com.github.topjohnwu:indeterminate-checkbox:1.0.7")
|
||||
implementation("dev.rikka.rikkax.layoutinflater:layoutinflater:1.3.0")
|
||||
implementation("dev.rikka.rikkax.insets:insets:1.3.0")
|
||||
implementation("dev.rikka.rikkax.recyclerview:recyclerview-ktx:1.3.2")
|
||||
implementation(libs.indeterminate.checkbox)
|
||||
implementation(libs.rikka.layoutinflater)
|
||||
implementation(libs.rikka.insets)
|
||||
implementation(libs.rikka.recyclerview)
|
||||
|
||||
val vNav = "2.7.7"
|
||||
implementation("androidx.navigation:navigation-fragment-ktx:${vNav}")
|
||||
implementation("androidx.navigation:navigation-ui-ktx:${vNav}")
|
||||
implementation(libs.navigation.fragment.ktx)
|
||||
implementation(libs.navigation.ui.ktx)
|
||||
|
||||
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
|
||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
||||
implementation("androidx.recyclerview:recyclerview:1.3.2")
|
||||
implementation("androidx.transition:transition:1.5.1")
|
||||
implementation("androidx.fragment:fragment-ktx:1.8.2")
|
||||
implementation("androidx.appcompat:appcompat:1.7.0")
|
||||
implementation("com.google.android.material:material:1.12.0")
|
||||
implementation(libs.constraintlayout)
|
||||
implementation(libs.swiperefreshlayout)
|
||||
implementation(libs.recyclerview)
|
||||
implementation(libs.transition)
|
||||
implementation(libs.fragment.ktx)
|
||||
implementation(libs.appcompat)
|
||||
implementation(libs.material)
|
||||
|
||||
// Make sure kapt runs with a proper kotlin-stdlib
|
||||
kapt(kotlin("stdlib"))
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package com.topjohnwu.magisk.dialog
|
||||
|
||||
import android.content.Context
|
||||
import com.topjohnwu.magisk.core.R
|
||||
import com.topjohnwu.magisk.core.di.ServiceLocator
|
||||
import com.topjohnwu.magisk.core.download.DownloadEngine
|
||||
@@ -7,6 +8,8 @@ import com.topjohnwu.magisk.core.download.Subject
|
||||
import com.topjohnwu.magisk.core.model.module.OnlineModule
|
||||
import com.topjohnwu.magisk.ui.flash.FlashFragment
|
||||
import com.topjohnwu.magisk.view.MagiskDialog
|
||||
import com.topjohnwu.magisk.view.Notifications
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
class OnlineModuleInstallDialog(private val item: OnlineModule) : MarkDownDialog() {
|
||||
|
||||
@@ -17,14 +20,21 @@ class OnlineModuleInstallDialog(private val item: OnlineModule) : MarkDownDialog
|
||||
return if (str.length > 1000) str.substring(0, 1000) else str
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
class Module(
|
||||
override val module: OnlineModule,
|
||||
override val autoLaunch: Boolean,
|
||||
override val notifyId: Int = Notifications.nextId()
|
||||
) : Subject.Module() {
|
||||
override fun pendingIntent(context: Context) = FlashFragment.installIntent(context, file)
|
||||
}
|
||||
|
||||
override fun build(dialog: MagiskDialog) {
|
||||
super.build(dialog)
|
||||
dialog.apply {
|
||||
|
||||
fun download(install: Boolean) {
|
||||
val module = Subject.Module(item, install)
|
||||
module.piCreator = FlashFragment::installIntent
|
||||
DownloadEngine.startWithActivity(activity, module)
|
||||
DownloadEngine.startWithActivity(activity, Module(item, install))
|
||||
}
|
||||
|
||||
val title = context.getString(R.string.repo_install_title,
|
||||
|
@@ -30,39 +30,34 @@ android {
|
||||
dependencies {
|
||||
api(project(":app:shared"))
|
||||
|
||||
api("com.jakewharton.timber:timber:5.0.1")
|
||||
api("io.noties.markwon:core:4.6.2")
|
||||
implementation("org.bouncycastle:bcpkix-jdk18on:1.78.1")
|
||||
implementation("org.apache.commons:commons-compress:1.26.2")
|
||||
api(libs.timber)
|
||||
api(libs.markwon.core)
|
||||
implementation(libs.bcpkix)
|
||||
implementation(libs.commons.compress)
|
||||
|
||||
val vLibsu = "6.0.0"
|
||||
api("com.github.topjohnwu.libsu:core:${vLibsu}")
|
||||
api("com.github.topjohnwu.libsu:service:${vLibsu}")
|
||||
api("com.github.topjohnwu.libsu:nio:${vLibsu}")
|
||||
api(libs.libsu.core)
|
||||
api(libs.libsu.service)
|
||||
api(libs.libsu.nio)
|
||||
|
||||
val vRetrofit = "2.11.0"
|
||||
implementation("com.squareup.retrofit2:retrofit:${vRetrofit}")
|
||||
implementation("com.squareup.retrofit2:converter-moshi:${vRetrofit}")
|
||||
implementation("com.squareup.retrofit2:converter-scalars:${vRetrofit}")
|
||||
implementation(libs.retrofit)
|
||||
implementation(libs.retrofit.moshi)
|
||||
implementation(libs.retrofit.scalars)
|
||||
|
||||
val vOkHttp = "4.12.0"
|
||||
implementation("com.squareup.okhttp3:okhttp:${vOkHttp}")
|
||||
implementation("com.squareup.okhttp3:logging-interceptor:${vOkHttp}")
|
||||
implementation("com.squareup.okhttp3:okhttp-dnsoverhttps:${vOkHttp}")
|
||||
implementation(libs.okhttp)
|
||||
implementation(libs.okhttp.logging)
|
||||
implementation(libs.okhttp.dnsoverhttps)
|
||||
|
||||
val vMoshi = "1.15.1"
|
||||
implementation("com.squareup.moshi:moshi:${vMoshi}")
|
||||
ksp("com.squareup.moshi:moshi-kotlin-codegen:${vMoshi}")
|
||||
implementation(libs.moshi)
|
||||
ksp(libs.moshi.codegen)
|
||||
|
||||
val vRoom = "2.6.1"
|
||||
implementation("androidx.room:room-runtime:${vRoom}")
|
||||
implementation("androidx.room:room-ktx:${vRoom}")
|
||||
ksp("androidx.room:room-compiler:${vRoom}")
|
||||
implementation(libs.room.runtime)
|
||||
implementation(libs.room.ktx)
|
||||
ksp(libs.room.compiler)
|
||||
|
||||
implementation("androidx.core:core-splashscreen:1.0.1")
|
||||
implementation("androidx.core:core-ktx:1.13.1")
|
||||
implementation("androidx.activity:activity:1.9.1")
|
||||
implementation("androidx.collection:collection-ktx:1.4.2")
|
||||
implementation("androidx.profileinstaller:profileinstaller:1.3.1")
|
||||
implementation("androidx.lifecycle:lifecycle-process:2.8.4")
|
||||
implementation(libs.core.splashscreen)
|
||||
implementation(libs.core.ktx)
|
||||
implementation(libs.activity)
|
||||
implementation(libs.collection.ktx)
|
||||
implementation(libs.profileinstaller)
|
||||
implementation(libs.lifecycle.process)
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ import kotlinx.parcelize.Parcelize
|
||||
import java.io.File
|
||||
import java.util.UUID
|
||||
|
||||
sealed class Subject : Parcelable {
|
||||
abstract class Subject : Parcelable {
|
||||
|
||||
abstract val url: String
|
||||
abstract val file: Uri
|
||||
@@ -27,24 +27,13 @@ sealed class Subject : Parcelable {
|
||||
|
||||
open fun pendingIntent(context: Context): PendingIntent? = null
|
||||
|
||||
@Parcelize
|
||||
class Module(
|
||||
private val module: OnlineModule,
|
||||
override val autoLaunch: Boolean,
|
||||
override val notifyId: Int = Notifications.nextId()
|
||||
) : Subject() {
|
||||
override val url: String get() = module.zipUrl
|
||||
override val title: String get() = module.downloadFilename
|
||||
|
||||
@IgnoredOnParcel
|
||||
override val file by lazy {
|
||||
abstract class Module : Subject() {
|
||||
abstract val module: OnlineModule
|
||||
final override val url: String get() = module.zipUrl
|
||||
final override val title: String get() = module.downloadFilename
|
||||
final override val file by lazy {
|
||||
MediaStoreUtils.getFile(title).uri
|
||||
}
|
||||
|
||||
@IgnoredOnParcel
|
||||
var piCreator: ((Context, Uri) -> PendingIntent)? = null
|
||||
|
||||
override fun pendingIntent(context: Context) = piCreator?.invoke(context, file)
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
|
@@ -134,10 +134,12 @@ abstract class MagiskInstallImpl protected constructor(
|
||||
|
||||
val abi32 = Const.CPU_ABI_32
|
||||
if (Process.is64Bit() && abi32 != null) {
|
||||
val magisk32 = File(installDir, "magisk32")
|
||||
val entry = zf.getEntry("lib/$abi32/libmagisk.so")
|
||||
zf.getInputStream(entry).writeTo(magisk32)
|
||||
magisk32.setExecutable(true)
|
||||
if (entry != null) {
|
||||
val magisk32 = File(installDir, "magisk32")
|
||||
zf.getInputStream(entry).writeTo(magisk32)
|
||||
magisk32.setExecutable(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@@ -2,130 +2,154 @@
|
||||
|
||||
<!--Sections-->
|
||||
<string name="modules">الإضافات</string>
|
||||
<string name="superuser">صلاحية الروت</string>
|
||||
<string name="superuser">المستخدم الخارق</string>
|
||||
<string name="logs">السجلات</string>
|
||||
<string name="settings">الإعدادات</string>
|
||||
<string name="install">تثبيت</string>
|
||||
<string name="section_home">الأساسي</string>
|
||||
<string name="section_theme">السِمات</string>
|
||||
<string name="install">التثبيت</string>
|
||||
<string name="section_home">الرئيسية</string>
|
||||
<string name="section_theme">المظهر</string>
|
||||
<string name="denylist">القائمة السوداء</string>
|
||||
|
||||
<!--Home-->
|
||||
<string name="no_connection">لا يوجد إتصال</string>
|
||||
<string name="app_changelog">تفاصيل التحديث</string>
|
||||
<string name="no_connection">لا يوجد اتصال متاح</string>
|
||||
<string name="app_changelog">سجل التغييرات</string>
|
||||
<string name="loading">جارٍ التحميل...</string>
|
||||
<string name="update">تحديث</string>
|
||||
<string name="not_available">غير/متوفر</string>
|
||||
<string name="not_available">غير متاح</string>
|
||||
<string name="hide">إخفاء</string>
|
||||
<string name="home_package">الحزمة</string>
|
||||
<string name="home_app_title">التطبيق</string>
|
||||
|
||||
<string name="home_support_title">تبرع لنا</string>
|
||||
<string name="home_item_source">الكود المصدري للتطبيق</string>
|
||||
<string name="home_support_content">مـاجـيسك هي، وستظل دوماً، مجانيةً و مفتوحة المصدر، اظهر اهتمامك لنا لكي نبقيها هكذا بدعم مالي صغير</string>
|
||||
<string name="home_installed_version">تم التثبيت</string>
|
||||
<string name="home_latest_version">آخر إصدار</string>
|
||||
<string name="invalid_update_channel">مصدر التحديث غير صالح</string>
|
||||
<string name="home_notice_content">قم بتحميل Magisk فقط من صفحة GitHub الرسمية. الملفات من مصادر غير معروفة قد تكون ضارة!</string>
|
||||
<string name="home_support_title">ادعمنا</string>
|
||||
<string name="home_follow_title">تابعنا</string>
|
||||
<string name="home_item_source">المصدر</string>
|
||||
<string name="home_support_content">Magisk مجاني ومفتوح المصدر وسيظل كذلك دائمًا. يمكنك إظهار دعمك لنا من خلال التبرع.</string>
|
||||
<string name="home_installed_version">المثبتة</string>
|
||||
<string name="home_latest_version">الأحدث</string>
|
||||
<string name="invalid_update_channel">قناة التحديث غير صالحة</string>
|
||||
<string name="uninstall_magisk_title">إلغاء تثبيت Magisk</string>
|
||||
<string name="uninstall_magisk_msg">ستُعطل/ستُحذف جميع الإضافات. سيُحذف الروت، وربما ستشفر بياناتك إذا لم تكن غير مشفرة حالياً.</string>
|
||||
<string name="uninstall_magisk_msg">ستتم إزالة جميع الوحدات / تعطيلها!\nسيتم إزالة الروت!\nأي تخزين داخلي تم فك تشفيره باستخدام Magisk سيتم إعادة تشفيره!</string>
|
||||
|
||||
<!--Install-->
|
||||
<string name="keep_force_encryption">فرض التشفير الإجباري</string>
|
||||
<string name="keep_dm_verity">فرض تشفيرات AVB2.0/dm-verity</string>
|
||||
<string name="recovery_mode">وضـع الريكفري</string>
|
||||
<string name="keep_force_encryption">الحفاظ على التشفير الإجباري</string>
|
||||
<string name="keep_dm_verity">الحفاظ على AVB 2.0/dm-verity</string>
|
||||
<string name="recovery_mode">وضع الاسترداد</string>
|
||||
<string name="install_options_title">الخيارات</string>
|
||||
<string name="install_method_title">الطريقة</string>
|
||||
<string name="install_next">التالي</string>
|
||||
<string name="install_start">هيا، بنا</string>
|
||||
<string name="manager_download_install">اضغط للتنزيل و التثبيت</string>
|
||||
<string name="direct_install">تثبيت مباشر (موصى بها)</string>
|
||||
<string name="install_inactive_slot">التثبيت على المنطقة الغير نشطة (بعد OTA)</string>
|
||||
<string name="install_inactive_slot_msg">سيُجبر جهازك للاقلاع على المنطقة الغير النشطة بعد إعادة التشغيل!\n استخدم هذا الخيار فقط بعد الانتهاء من OTA. استمرار؟</string>
|
||||
<string name="setup_title">إعدادات إضافية</string>
|
||||
<string name="select_patch_file">حدد و عدل ملفاً</string>
|
||||
<string name="patch_file_msg">اختر ملف (*.img) أو ملف odin (*.tar)</string>
|
||||
<string name="reboot_delay_toast">إعادة التشغيل بعد ٥ ثواني…</string>
|
||||
<string name="install_start">هيا بنا</string>
|
||||
<string name="manager_download_install">اضغط للتنزيل والتثبيت</string>
|
||||
<string name="direct_install">التثبيت المباشر (موصى به)</string>
|
||||
<string name="install_inactive_slot">التثبيت على الشريحة غير النشطة (بعد OTA)</string>
|
||||
<string name="install_inactive_slot_msg">سيتم إجبار جهازك على التمهيد إلى الشريحة غير النشطة الحالية بعد إعادة التشغيل!\nاستخدم هذا الخيار فقط بعد الانتهاء من OTA.\nهل تود المتابعة؟</string>
|
||||
<string name="setup_title">إعداد إضافي</string>
|
||||
<string name="select_patch_file">اختر وقم بعمل باتش ملف</string>
|
||||
<string name="patch_file_msg">اختر صورة خام (*.img) أو ملف ODIN tarfile (*.tar) أو payload.bin (*.bin)</string>
|
||||
<string name="reboot_delay_toast">سيتم إعادة التشغيل في 5 ثوانٍ...</string>
|
||||
<string name="flash_screen_title">التثبيت</string>
|
||||
|
||||
<!--Superuser-->
|
||||
<string name="su_request_title">طلبات صلاحية الروت</string>
|
||||
<string name="su_request_title">طلب المستخدم الخارق</string>
|
||||
<string name="touch_filtered_warning">نظرًا لأن تطبيقًا ما يحجب طلب المستخدم الخارق، لا يمكن لـ Magisk التحقق من استجابتك</string>
|
||||
<string name="deny">رفض</string>
|
||||
<string name="prompt">طلب</string>
|
||||
<string name="grant">سماح</string>
|
||||
<string name="su_warning">يمنح حق الوصول الكامل إلى جهازك. ارفض إذا كنت غير متأكد!</string>
|
||||
<string name="forever">للأبد</string>
|
||||
<string name="prompt">إشعار</string>
|
||||
<string name="grant">منح</string>
|
||||
<string name="su_warning">يمنح حق الوصول الكامل لجهازك.\nارفض إذا لم تكن متأكدًا!</string>
|
||||
<string name="forever">دائمًا</string>
|
||||
<string name="once">مرة واحدة</string>
|
||||
<string name="tenmin">10 دقائق</string>
|
||||
<string name="tenmin">جار0 دقائق</string>
|
||||
<string name="twentymin">20 دقيقة</string>
|
||||
<string name="thirtymin">30 دقيقة</string>
|
||||
<string name="sixtymin">60 دقيقة</string>
|
||||
<string name="su_allow_toast">تم منح صلاحيات الروت لـ%1$s</string>
|
||||
<string name="su_deny_toast">تم رفض صلاحيات الروت لـ%1$s </string>
|
||||
<string name="su_snack_grant">تم منح صلاحيات الروت لـ%1$s</string>
|
||||
<string name="su_snack_deny">تم رفض صلاحيات الروت لـ%1$s</string>
|
||||
<string name="su_snack_notif_on">تم تفعيل الإشعارات لـ%1$s</string>
|
||||
<string name="su_snack_notif_off">تم تعطيل الإشعارات لـ%1$s</string>
|
||||
<string name="su_snack_log_on">تم تفعيل السجلات لـ%1$s</string>
|
||||
<string name="su_snack_log_off">تم تعطيل السجلات لـ%1$s</string>
|
||||
<string name="su_revoke_title">منع؟</string>
|
||||
<string name="su_revoke_msg">هل تريد منع صلاحية %1$s?</string>
|
||||
<string name="toast">اشعار</string>
|
||||
<string name="none">بدون</string>
|
||||
<string name="su_allow_toast">%جار$s تم منحه حقوق المستخدم الخارق</string>
|
||||
<string name="su_deny_toast">%جار$s تم رفض حقوق المستخدم الخارق</string>
|
||||
<string name="su_snack_grant">تم منح حقوق المستخدم الخارق لـ %جار$s</string>
|
||||
<string name="su_snack_deny">تم رفض حقوق المستخدم الخارق لـ %جار$s</string>
|
||||
<string name="su_snack_notif_on">تم تفعيل الإشعارات لـ %جار$s</string>
|
||||
<string name="su_snack_notif_off">تم تعطيل الإشعارات لـ %جار$s</string>
|
||||
<string name="su_snack_log_on">تم تفعيل السجلات لـ %جار$s</string>
|
||||
<string name="su_snack_log_off">تم تعطيل السجلات لـ %جار$s</string>
|
||||
<string name="su_revoke_title">إلغاء؟</string>
|
||||
<string name="su_revoke_msg">تأكيد لإلغاء حقوق المستخدم الخارق لـ %جار$s</string>
|
||||
<string name="toast">إشعار</string>
|
||||
<string name="none">لا شيء</string>
|
||||
|
||||
<string name="superuser_toggle_notification">الإشعارات</string>
|
||||
<string name="superuser_toggle_revoke">منع</string>
|
||||
<string name="superuser_policy_none">لم يسأل آية تطبيق لصلاحيات الروت</string>
|
||||
<string name="superuser_toggle_revoke">إلغاء</string>
|
||||
<string name="superuser_policy_none">لم يطلب أي تطبيق بعد إذن المستخدم الخارق.</string>
|
||||
|
||||
<!--Logs-->
|
||||
<string name="log_data_none">لا يوجد أية سجلات هنا :-:، حاول استعمال تطبيقات روت اكثر</string>
|
||||
<string name="log_data_magisk_none">لا توجد أيةَ سجلات ⊙_⊙</string>
|
||||
<string name="menuSaveLog">حفظ السجلات</string>
|
||||
<string name="menuClearLog">حذف السجلات</string>
|
||||
<string name="logs_cleared">تم الحذف بنجاح</string>
|
||||
<string name="pid">PID: %1$d</string>
|
||||
<string name="target_uid">UID: %1$d</string>
|
||||
<string name="log_data_none">أنت خالٍ من السجلات، جرب استخدام تطبيقات الروت الخاصة بك أكثر</string>
|
||||
<string name="log_data_magisk_none">سجلات Magisk فارغة، هذا غريب</string>
|
||||
<string name="menuSaveLog">حفظ السجل</string>
|
||||
<string name="menuClearLog">مسح السجل الآن</string>
|
||||
<string name="logs_cleared">تم مسح السجل بنجاح</string>
|
||||
<string name="pid">PID: %جار$d</string>
|
||||
<string name="target_uid">UID الهدف: %جار$d</string>
|
||||
<string name="target_pid">PID هدف النطاق المركب: %s</string>
|
||||
<string name="selinux_context">سياق SELinux: %s</string>
|
||||
<string name="supp_group">المجموعة التكميلية: %s</string>
|
||||
|
||||
<!--SafetyNet-->
|
||||
|
||||
<!-- MagiskHide -->
|
||||
<string name="show_system_app">إظهار برامج النظام</string>
|
||||
<string name="hide_filter_hint">البحث بالإسم</string>
|
||||
<string name="hide_search">ابحث</string>
|
||||
<!--MagiskHide-->
|
||||
<string name="show_system_app">عرض تطبيقات النظام</string>
|
||||
<string name="show_os_app">عرض تطبيقات نظام التشغيل</string>
|
||||
<string name="hide_filter_hint">التصفية بالاسم</string>
|
||||
<string name="hide_search">بحث</string>
|
||||
|
||||
<!--Module Fragment-->
|
||||
<string name="no_info_provided">(لم توفر معلومات)</string>
|
||||
<string name="reboot_recovery">إعادة التشغيل إلى Recovery</string>
|
||||
<string name="reboot_bootloader">إعادة التشغيل إلى Bootloader</string>
|
||||
<string name="reboot_download">إعادة التشغيل إلى وضـع Odin</string>
|
||||
<string name="reboot_edl">إعادة التشغيل إلى وضـعية EDL</string>
|
||||
<string name="module_version_author">%1$sبواسطة%2$s</string>
|
||||
<string name="module_state_remove">إزالة </string>
|
||||
<string name="module_state_restore">إسترجاع</string>
|
||||
<string name="module_action_install_external">اختر من الذاكرة الداخلية</string>
|
||||
<string name="update_available">التحديث متوفر</string>
|
||||
<string name="external_rw_permission_denied">امنحني إذن الولوج للذاكرة الداخلية</string>
|
||||
<!--Module-->
|
||||
<string name="no_info_provided">(لم يتم تقديم معلومات)</string>
|
||||
<string name="reboot_userspace">إعادة تشغيل ناعمة</string>
|
||||
<string name="reboot_recovery">إعادة التشغيل إلى وضع الاسترداد</string>
|
||||
<string name="reboot_bootloader">إعادة التشغيل إلى محمل الإقلاع</string>
|
||||
<string name="reboot_download">إعادة التشغيل إلى وضع التنزيل</string>
|
||||
<string name="reboot_edl">إعادة التشغيل إلى وضع EDL</string>
|
||||
<string name="reboot_safe_mode">وضع الآمن</string>
|
||||
<string name="module_state_remove">إزالة</string>
|
||||
<string name="module_state_restore">استعادة</string>
|
||||
<string name="module_action_install_external">التثبيت من التخزين</string>
|
||||
<string name="update_available">تحديث متاح</string>
|
||||
<string name="suspend_text_riru">تم تعليق الإضافةة لأن %جار$s مفعّل</string>
|
||||
<string name="suspend_text_zygisk">تم تعليق الإضافةة لأن %جار$s غير مفعّل</string>
|
||||
<string name="zygisk_module_unloaded">لم يتم تحميل إضافة Zygisk بسبب عدم التوافق</string>
|
||||
<string name="module_empty">لم يتم تثبيت أي إضافة</string>
|
||||
<string name="confirm_install">هل تريد تثبيت الإضافة %جار$s؟</string>
|
||||
<string name="confirm_install_title">تأكيد التثبيت</string>
|
||||
|
||||
<!--Settings -->
|
||||
<string name="settings_dark_mode_title">وضـعية الِسمات</string>
|
||||
<string name="settings_dark_mode_message">حدد الوضـع الذي يناسب ذوقك</string>
|
||||
<string name="settings_dark_mode_light">الوضـع المضيء</string>
|
||||
<string name="settings_dark_mode_system">اتبّع النظام</string>
|
||||
<string name="settings_dark_mode_dark">وضـع الظلام</string>
|
||||
<string name="settings_download_path_title">مسار التحميل</string>
|
||||
<string name="settings_download_path_message">ستحمل الملفات إلى %1$s</string>
|
||||
<!--Settings-->
|
||||
<string name="settings_dark_mode_title">وضع الثيم</string>
|
||||
<string name="settings_dark_mode_message">اختر الوضع الذي يناسب نمطك!</string>
|
||||
<string name="settings_dark_mode_light">دائمًا فاتح</string>
|
||||
<string name="settings_dark_mode_system">تابع النظام</string>
|
||||
<string name="settings_dark_mode_dark">دائمًا داكن</string>
|
||||
<string name="settings_download_path_title">مسار التنزيل</string>
|
||||
<string name="settings_download_path_message">سيتم حفظ الملفات في %جار$s</string>
|
||||
<string name="settings_hide_app_title">إخفاء تطبيق Magisk</string>
|
||||
<string name="settings_hide_app_summary">تثبيت تطبيق وكيل بمعرف حزمة عشوائي واسم تطبيق مخصص</string>
|
||||
<string name="settings_restore_app_title">استعادة تطبيق Magisk</string>
|
||||
<string name="settings_restore_app_summary">إظهار التطبيق واستعادة APK الأصلي</string>
|
||||
<string name="language">اللغة</string>
|
||||
<string name="system_default">(الأفتراضي)</string>
|
||||
<string name="system_default">(افتراضي النظام)</string>
|
||||
<string name="settings_check_update_title">تحقق من التحديثات</string>
|
||||
<string name="settings_check_update_summary">التحقق من التحديثات في الخلفية بشكل دوري</string>
|
||||
<string name="settings_update_channel_title">مصدر التحديثات</string>
|
||||
<string name="settings_check_update_summary">التحقق دوريًا من التحديثات في الخلفية</string>
|
||||
<string name="settings_update_channel_title">قناة التحديث</string>
|
||||
<string name="settings_update_stable">مستقر</string>
|
||||
<string name="settings_update_beta">تجريبي</string>
|
||||
<string name="settings_update_beta">بيتا</string>
|
||||
<string name="settings_update_custom">مخصص</string>
|
||||
<string name="settings_update_custom_msg">أدخل الرابط لمصدرك المخصص</string>
|
||||
<string name="settings_hosts_title">موانع الاعلانات</string>
|
||||
<string name="settings_hosts_summary">حجب الاعلانات دون تعديل النظام</string>
|
||||
<string name="settings_hosts_toast">تم تمكين خاصية حجب الاعلانات</string>
|
||||
<string name="settings_app_name_hint">الإسم الجديد</string>
|
||||
<string name="settings_app_name_helper">التطبيق الجديد سوف يملك هذا الإسم</string>
|
||||
<string name="settings_app_name_error">الصيغة غير مقبولة</string>
|
||||
<string name="settings_update_custom_msg">أدخل عنوان URL لقناة مخصصة</string>
|
||||
<string name="settings_zygisk_summary">تشغيل أجزاء من Magisk في خدمة zygote</string>
|
||||
<string name="settings_denylist_title">تفعيل القائمة السوداء</string>
|
||||
<string name="settings_denylist_summary">سيتم إرجاع جميع تعديلات Magisk للعمليات الموجودة في القائمة السوداء</string>
|
||||
<string name="settings_denylist_config_title">تكوين القائمة السوداء</string>
|
||||
<string name="settings_denylist_config_summary">اختر العمليات التي سيتم تضمينها في القائمة السوداء</string>
|
||||
<string name="settings_hosts_title">مضيفين بدون نظام</string>
|
||||
<string name="settings_hosts_summary">دعم المضيفين بدون نظام لتطبيقات حظر الإعلانات</string>
|
||||
<string name="settings_hosts_toast">تم إضافة إضافة المضيفين بدون نظام</string>
|
||||
<string name="settings_app_name_hint">اسم جديد</string>
|
||||
<string name="settings_app_name_helper">سيتم إعادة تغليف التطبيق بهذا الاسم</string>
|
||||
<string name="settings_app_name_error">تنسيق غير صالح</string>
|
||||
<string name="settings_su_app_adb">التطبيقات و ADB</string>
|
||||
<string name="settings_su_app">التطبيقات فقط</string>
|
||||
<string name="settings_su_adb">ADB فقط</string>
|
||||
@@ -136,55 +160,86 @@
|
||||
<string name="settings_su_request_30">30 ثانية</string>
|
||||
<string name="settings_su_request_45">45 ثانية</string>
|
||||
<string name="settings_su_request_60">60 ثانية</string>
|
||||
<string name="superuser_access">صلاحيات الروت</string>
|
||||
<string name="auto_response">الفعل التلقائي</string>
|
||||
<string name="request_timeout">المهلة قبل الفعل التلقائي</string>
|
||||
<string name="superuser_notification">إشعارات طلبات الروت</string>
|
||||
<string name="settings_su_reauth_title">إعادة المصادقة بعد الترقية</string>
|
||||
<string name="settings_su_reauth_summary">أعد مصادقة صلاحيات الروت بعد إجراء ترقيات للتطبيق</string>
|
||||
<string name="settings_customization">تخصيص</string>
|
||||
<string name="superuser_access">وصول المستخدم الخارق</string>
|
||||
<string name="auto_response">استجابة تلقائية</string>
|
||||
<string name="request_timeout">انتهاء مهلة الطلب</string>
|
||||
<string name="superuser_notification">إشعار المستخدم الخارق</string>
|
||||
<string name="settings_su_reauth_title">إعادة التوثيق بعد الترقية</string>
|
||||
<string name="settings_su_reauth_summary">طلب أذونات المستخدم الخارق مرة أخرى بعد ترقية التطبيقات</string>
|
||||
<string name="settings_su_tapjack_title">حماية من اختراق النقرات</string>
|
||||
<string name="settings_su_tapjack_summary">لن يستجيب مربع حوار طلب المستخدم الخارق لأي إدخال أثناء تغطيته بواسطة أي نافذة أو تراكب آخر</string>
|
||||
<string name="settings_su_auth_title">توثيق المستخدم</string>
|
||||
<string name="settings_su_auth_summary">طلب توثيق المستخدم أثناء طلبات المستخدم الخارق</string>
|
||||
<string name="settings_su_auth_insecure">لا توجد طريقة توثيق مهيأة على الجهاز</string>
|
||||
<string name="settings_customization">التخصيص</string>
|
||||
<string name="setting_add_shortcut_summary">إضافة اختصار جميل إلى الشاشة الرئيسية في حالة كان الاسم والأيقونة صعب التعرف عليهما بعد إخفاء التطبيق</string>
|
||||
<string name="settings_doh_title">DNS عبر HTTPS</string>
|
||||
<string name="settings_doh_description">الحل لمشكلة تسميم DNS في بعض الدول</string>
|
||||
<string name="settings_random_name_title">تغيير الاسم عشوائيًا</string>
|
||||
<string name="settings_random_name_description">تغيير اسم ملف الخرج عشوائيًا لصور وملفات tar المصححة لمنع الاكتشاف</string>
|
||||
|
||||
<string name="multiuser_mode">نمط مستخدمين متعددين</string>
|
||||
<string name="multiuser_mode">وضع المستخدمين المتعددين</string>
|
||||
<string name="settings_owner_only">مالك الجهاز فقط</string>
|
||||
<string name="settings_owner_manage">المالك هو من يحدد</string>
|
||||
<string name="settings_user_independent">مستقل </string>
|
||||
<string name="owner_only_summary">للمالك فقط له صلاحيات الروت</string>
|
||||
<string name="owner_manage_summary">فقط المالك من يرفض و يمنح صلاحيات الروت</string>
|
||||
<string name="user_independent_summary">كل مستخدم له قواعد روت خاصة به</string>
|
||||
<string name="settings_owner_manage">يديرها مالك الجهاز</string>
|
||||
<string name="settings_user_independent">مستقل عن المستخدم</string>
|
||||
<string name="owner_only_summary">فقط المالك له وصول روت</string>
|
||||
<string name="owner_manage_summary">فقط المالك يمكنه إدارة وصول الروت وتلقي طلبات الإذن</string>
|
||||
<string name="user_independent_summary">كل مستخدم لديه قواعد الروت الخاصة به</string>
|
||||
|
||||
<string name="mount_namespace_mode">نمط Mount Namespace</string>
|
||||
<string name="settings_ns_global">نمط Namespace العام</string>
|
||||
<string name="settings_ns_requester">نمط NameSpace المتوارث</string>
|
||||
<string name="settings_ns_isolate">نمط NameSpace المعزول</string>
|
||||
<string name="global_summary">جميع الجلسات الروت تستخدم NameSpace العام</string>
|
||||
<string name="requester_summary">جميع الجلسات الروت تستخدم NameSpace المتوارث</string>
|
||||
<string name="isolate_summary">جميع الجلسات الروت تستخدم NameSpace المعزول</string>
|
||||
<string name="mount_namespace_mode">وضع مساحة التثبيت</string>
|
||||
<string name="settings_ns_global">مساحة أسماء عامة</string>
|
||||
<string name="settings_ns_requester">وراثة مساحة الأسماء</string>
|
||||
<string name="settings_ns_isolate">مساحة أسماء معزولة</string>
|
||||
<string name="global_summary">جميع جلسات الروت تستخدم مساحة التثبيت العامة</string>
|
||||
<string name="requester_summary">جلسات الروت سترث مساحة الأسماء من طالب الروت</string>
|
||||
<string name="isolate_summary">كل جلسة روت سيكون لها مساحة أسماء معزولة خاصة بها</string>
|
||||
|
||||
<!--Notifications-->
|
||||
<string name="update_channel">تحديثات Magisk</string>
|
||||
<string name="progress_channel">إشعارات التقدم</string>
|
||||
<string name="updated_channel">اكتمل التحديث</string>
|
||||
<string name="download_complete">اكتمل التنزيل</string>
|
||||
<string name="download_file_error">فشل تنزيل الملف</string>
|
||||
<string name="magisk_update_title">تحديث مـاجـيسك متوفر!</string>
|
||||
<string name="download_file_error">خطأ في تنزيل الملف</string>
|
||||
<string name="magisk_update_title">تحديث Magisk متاح!</string>
|
||||
<string name="updated_title">تم تحديث Magisk</string>
|
||||
<string name="updated_text">اضغط لفتح التطبيق</string>
|
||||
|
||||
<!--Toasts, Dialogs-->
|
||||
<string name="yes">نعم</string>
|
||||
<string name="no">لا</string>
|
||||
<string name="download">تنزيل</string>
|
||||
<string name="reboot">إعادة التشغيل</string>
|
||||
<string name="release_notes">معلومات الأصدار الجديد</string>
|
||||
<string name="flashing">يتم الحرق...</string>
|
||||
<string name="release_notes">ملاحظات الإصدار</string>
|
||||
<string name="flashing">جارٍ التثبيت...</string>
|
||||
<string name="done">تم!</string>
|
||||
<string name="failure">فشل!</string>
|
||||
<string name="open_link_failed_toast">لم يُعثر على تطبيق لفتح الرابط …</string>
|
||||
<string name="complete_uninstall">إلغاء التثبيت بالكامل</string>
|
||||
<string name="hide_app_title">جارٍ إخفاء تطبيق Magisk...</string>
|
||||
<string name="open_link_failed_toast">لم يتم العثور على تطبيق لفتح الرابط</string>
|
||||
<string name="complete_uninstall">إلغاء التثبيت الكامل</string>
|
||||
<string name="restore_img">استعادة الصور</string>
|
||||
<string name="restore_img_msg">جار الأستعادة…</string>
|
||||
<string name="restore_done">تم الأستعادة</string>
|
||||
<string name="restore_fail">النسخة الاحتياطية الأصلية غير موجودة!</string>
|
||||
<string name="setup_fail">فشل التضبيط</string>
|
||||
<string name="env_fix_title"> الإعداد الأضافي مطلوب</string>
|
||||
<string name="setup_msg">جار تضبيت البيئة</string>
|
||||
<string name="unsupport_magisk_title">إصدار مـاجـيسك غير مدعوم</string>
|
||||
<string name="restore_img_msg">جارٍ الاستعادة...</string>
|
||||
<string name="restore_done">اكتملت الاستعادة!</string>
|
||||
<string name="restore_fail">لا يوجد نسخة احتياطية أصلية!</string>
|
||||
<string name="setup_fail">فشل الإعداد</string>
|
||||
<string name="env_fix_title">يتطلب إعداد إضافي</string>
|
||||
<string name="env_fix_msg">يحتاج جهازك إلى إعداد إضافي ليعمل Magisk بشكل صحيح. هل تريد المتابعة وإعادة التشغيل؟</string>
|
||||
<string name="env_full_fix_msg">يحتاج جهازك إلى إعادة تثبيت Magisk ليعمل بشكل صحيح. يرجى إعادة تثبيت Magisk من داخل التطبيق، لا يمكن لوضع الاسترداد الحصول على معلومات الجهاز الصحيحة.</string>
|
||||
<string name="setup_msg">جارٍ تشغيل إعداد البيئة...</string>
|
||||
<string name="unsupport_magisk_title">إصدار Magisk غير مدعوم</string>
|
||||
<string name="unsupport_magisk_msg">هذا الإصدار من التطبيق لا يدعم إصدارات Magisk الأقل من %جار$s.\n\nسيعمل التطبيق كما لو أن Magisk غير مثبت، يرجى ترقية Magisk في أقرب وقت ممكن.</string>
|
||||
<string name="unsupport_general_title">حالة غير طبيعية</string>
|
||||
<string name="unsupport_system_app_msg">تشغيل هذا التطبيق كتطبيق نظام غير مدعوم. يرجى إعادة التطبيق إلى تطبيق مستخدم.</string>
|
||||
<string name="unsupport_other_su_msg">تم اكتشاف "su" ثنائي ليس من Magisk. يرجى إزالة أي حل روت منافس و/أو إعادة تثبيت Magisk.</string>
|
||||
<string name="unsupport_external_storage_msg">تم تثبيت Magisk في التخزين الخارجي. يرجى نقل التطبيق إلى التخزين الداخلي.</string>
|
||||
<string name="unsupport_nonroot_stub_msg">لا يمكن للتطبيق المخفي Magisk الاستمرار في العمل لأن الروت قد فقد. يرجى استعادة APK الأصلي.</string>
|
||||
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
|
||||
<string name="external_rw_permission_denied">امنح إذن التخزين لتمكين هذه الوظيفة</string>
|
||||
<string name="post_notifications_denied">امنح إذن الإشعارات لتمكين هذه الوظيفة</string>
|
||||
<string name="install_unknown_denied">اسمح بتثبيت "التطبيقات غير المعروفة" لتمكين هذه الوظيفة</string>
|
||||
<string name="add_shortcut_title">إضافة اختصار إلى الشاشة الرئيسية</string>
|
||||
<string name="add_shortcut_msg">بعد إخفاء هذا التطبيق، قد يصبح من الصعب التعرف على اسمه ورمزه. هل تريد إضافة اختصار جميل إلى الشاشة الرئيسية؟</string>
|
||||
<string name="app_not_found">لم يتم العثور على تطبيق لمعالجة هذا الإجراء</string>
|
||||
<string name="reboot_apply_change">إعادة التشغيل لتطبيق التغييرات</string>
|
||||
<string name="restore_app_confirmation">سيؤدي هذا إلى استعادة التطبيق المخفي إلى التطبيق الأصلي. هل تريد حقًا القيام بذلك؟</string>
|
||||
|
||||
</resources>
|
||||
|
@@ -12,21 +12,21 @@
|
||||
|
||||
<!--Home-->
|
||||
<string name="no_connection">Bağlantı yok</string>
|
||||
<string name="app_changelog">Değişiklik günlüğü</string>
|
||||
<string name="app_changelog">Değişiklik Günlüğü</string>
|
||||
<string name="loading">Yükleniyor…</string>
|
||||
<string name="update">Güncelle</string>
|
||||
<string name="not_available">Yüklü değil</string>
|
||||
<string name="not_available">Yok</string>
|
||||
<string name="hide">Gizle</string>
|
||||
<string name="home_package">Paket</string>
|
||||
<string name="home_app_title">Uygulama</string>
|
||||
|
||||
<string name="home_notice_content">Magisk\'i YALNIZCA resmi GitHub sayfasından indirin. Bilinmeyen kaynaklardan gelen dosyalar kötü amaçlı olabilir!</string>
|
||||
<string name="home_notice_content">Magisk\'i YALNIZCA resmi GitHub sayfasından indirin. Bilinmeyen kaynaklardan gelen dosyalar zararlı olabilir!</string>
|
||||
<string name="home_support_title">Bizi Destekleyin</string>
|
||||
<string name="home_follow_title">Bizi Takip Edin</string>
|
||||
<string name="home_item_source">Kaynak</string>
|
||||
<string name="home_support_content">Magisk ücretsiz ve açık kaynaktır ve her zaman öyle kalacaktır. Ancak bir bağış yaparak bize destek olduğunuzu gösterebilirsiniz.</string>
|
||||
<string name="home_installed_version">Durum</string>
|
||||
<string name="home_latest_version">En son sürüm</string>
|
||||
<string name="home_support_content">Magisk her zaman ücretsiz ve açık kaynak olacaktır. Ancak, bir bağış yaparak bize destek olabilirsiniz.</string>
|
||||
<string name="home_installed_version">Yüklü Sürüm</string>
|
||||
<string name="home_latest_version">En Son Sürüm</string>
|
||||
<string name="invalid_update_channel">Geçersiz Güncelleme Kanalı</string>
|
||||
<string name="uninstall_magisk_title">Magisk\'i Kaldır</string>
|
||||
<string name="uninstall_magisk_msg">Tüm modüller devre dışı bırakılacak/kaldırılacak!\nKök kaldırılacak!\nMagisk kullanılarak şifrelenmemiş herhangi bir dahili depolama yeniden şifrelenecek!</string>
|
||||
@@ -38,14 +38,14 @@
|
||||
<string name="install_options_title">Seçenekler</string>
|
||||
<string name="install_method_title">Yöntem</string>
|
||||
<string name="install_next">Sonraki</string>
|
||||
<string name="install_start">Haydi başlayalım</string>
|
||||
<string name="install_start">Hadi başlayalım</string>
|
||||
<string name="manager_download_install">İndirmek ve yüklemek için basın</string>
|
||||
<string name="direct_install">Doğrudan Kurulum (Önerilir)</string>
|
||||
<string name="install_inactive_slot">Etkin Olmayan Yuvaya Yükle (OTA\'dan Sonra)</string>
|
||||
<string name="install_inactive_slot_msg">Yeniden başlatmanın ardından cihazınız mevcut etkin olmayan yuvaya önyükleme yapmaya ZORLANACAK!\nBu seçeneği yalnızca OTA tamamlandıktan sonra kullanın.\nDevam edilsin mi?</string>
|
||||
<string name="direct_install">Doğrudan Yükleme (Önerilir)</string>
|
||||
<string name="install_inactive_slot">Etkin Olmayan Slot\'a Yükle (OTA Sonrası)</string>
|
||||
<string name="install_inactive_slot_msg">Cihazınız yeniden başlatıldıktan sonra zorunlu olarak mevcut etkin olmayan slota önyükleme yapılacaktır!\nBu seçeneği yalnızca OTA tamamlandıktan sonra kullanın.\nDevam etmek istiyor musunuz?</string>
|
||||
<string name="setup_title">Ek Kurulum</string>
|
||||
<string name="select_patch_file">Bir Dosya Seç ve Yama Yap</string>
|
||||
<string name="patch_file_msg">Bir ham görüntü (*.img) veya bir ODIN tar dosyası (*.tar) veya bir payload.bin (*.bin) seçin</string>
|
||||
<string name="patch_file_msg">Ham bir görüntü (*.img) veya bir ODIN tar dosyası (*.tar) veya bir payload.bin (*.bin) seçin</string>
|
||||
<string name="reboot_delay_toast">5 saniye içinde yeniden başlatılıyor…</string>
|
||||
<string name="flash_screen_title">Yükleniyor</string>
|
||||
|
||||
@@ -53,42 +53,42 @@
|
||||
<string name="su_request_title">Süper Kullanıcı İsteği</string>
|
||||
<string name="touch_filtered_warning">Bir uygulama bir Süper Kullanıcı isteğini engellediği için Magisk yanıtınızı doğrulayamıyor</string>
|
||||
<string name="deny">Reddet</string>
|
||||
<string name="prompt">Sor</string>
|
||||
<string name="grant">İzin ver</string>
|
||||
<string name="su_warning">Cihazınıza tam erişim sağlar.\nEğer emin değilseniz reddedin!</string>
|
||||
<string name="prompt">İstem</string>
|
||||
<string name="grant">İzin Ver</string>
|
||||
<string name="su_warning">Cihazınıza tam erişim sağlar.\nEmin değilseniz reddedin!</string>
|
||||
<string name="forever">Daima</string>
|
||||
<string name="once">Bir kez</string>
|
||||
<string name="tenmin">10 dakika</string>
|
||||
<string name="twentymin">20 dakika</string>
|
||||
<string name="thirtymin">30 dakika</string>
|
||||
<string name="sixtymin">60 dakika</string>
|
||||
<string name="su_allow_toast">%1$s uygulamasının Süper Kullanıcı izni verildi</string>
|
||||
<string name="su_deny_toast">%1$s uygulamasının Süper Kullanıcı izni reddedildi</string>
|
||||
<string name="su_snack_grant">%1$s uygulamasının Süper Kullanıcı izni verildi</string>
|
||||
<string name="su_snack_deny">%1$s uygulamasının Süper Kullanıcı izni reddedildi</string>
|
||||
<string name="su_allow_toast">%1$s uygulamasının süper kullanıcı hakları verildi</string>
|
||||
<string name="su_deny_toast">%1$s uygulamasının süper kullanıcı hakları reddedildi</string>
|
||||
<string name="su_snack_grant">%1$s uygulamasının süper kullanıcı hakları verildi</string>
|
||||
<string name="su_snack_deny">%1$s uygulamasının süper kullanıcı hakları reddedildi</string>
|
||||
<string name="su_snack_notif_on">%1$s uygulamasının bildirimleri etkinleştirildi</string>
|
||||
<string name="su_snack_notif_off">%1$s uygulamasının bildirimleri devre dışı bırakıldı</string>
|
||||
<string name="su_snack_log_on">%1$s uygulamasının günlüğü etkinleştirildi</string>
|
||||
<string name="su_snack_log_off">%1$s uygulamasının günlüğü devre dışı bırakıldı</string>
|
||||
<string name="su_revoke_title">İptal et?</string>
|
||||
<string name="su_revoke_msg">%1$s uygulamasının Süper Kullanıcı haklarını iptal etmeyi onaylayın</string>
|
||||
<string name="toast">Tost</string>
|
||||
<string name="none">Hiçbiri</string>
|
||||
<string name="su_revoke_title">İptal Et?</string>
|
||||
<string name="su_revoke_msg">%1$s uygulamasının süper kullanıcı haklarını iptal etmek istediğinize emin misiniz?</string>
|
||||
<string name="toast">Bildirim</string>
|
||||
<string name="none">Yok</string>
|
||||
|
||||
<string name="superuser_toggle_notification">Bildirimler</string>
|
||||
<string name="superuser_toggle_revoke">İptal et</string>
|
||||
<string name="superuser_toggle_revoke">İptal Et</string>
|
||||
<string name="superuser_policy_none">Henüz hiçbir uygulama Süper Kullanıcı izni istemedi.</string>
|
||||
|
||||
<!--Logs-->
|
||||
<string name="log_data_none">Günlük kullanmıyorsunuz, kök uygulamalarınızı daha fazla kullanmayı deneyin</string>
|
||||
<string name="log_data_magisk_none">Magisk günlükleri boş, bu garip</string>
|
||||
<string name="log_data_none">Günlük kullanmıyorsunuz, root (kök) uygulamalarınızı daha çok kullanmayı deneyin</string>
|
||||
<string name="log_data_magisk_none">Magisk günlükleri boş, bu tuhaf</string>
|
||||
<string name="menuSaveLog">Günlüğü kaydet</string>
|
||||
<string name="menuClearLog">Günlüğü şimdi temizle</string>
|
||||
<string name="logs_cleared">Günlük kaydı başarıyla temizlendi</string>
|
||||
<string name="pid">PID: %1$d</string>
|
||||
<string name="target_uid">Hedef UID: %1$d</string>
|
||||
<string name="target_pid">Ns hedef PID\'sini bağla: %s</string>
|
||||
<string name="selinux_context">SELinux içeriği: %s</string>
|
||||
<string name="target_pid">Mount ns hedef PID: %s</string>
|
||||
<string name="selinux_context">SELinux bağlamı: %s</string>
|
||||
<string name="supp_group">Ek grup: %s</string>
|
||||
|
||||
<!--SafetyNet-->
|
||||
@@ -96,7 +96,7 @@
|
||||
<!--MagiskHide-->
|
||||
<string name="show_system_app">Sistem uygulamalarını göster</string>
|
||||
<string name="show_os_app">İşletim sistemi uygulamalarını göster</string>
|
||||
<string name="hide_filter_hint">Ada göre filtrele</string>
|
||||
<string name="hide_filter_hint">İsme göre filtrele</string>
|
||||
<string name="hide_search">Ara</string>
|
||||
|
||||
<!--Module-->
|
||||
@@ -106,13 +106,14 @@
|
||||
<string name="reboot_bootloader">Önyükleyici modunda yeniden başlat</string>
|
||||
<string name="reboot_download">İndirme modunda yeniden başlat</string>
|
||||
<string name="reboot_edl">EDL modunda yeniden başlat</string>
|
||||
<string name="reboot_safe_mode">Güvenli mod</string>
|
||||
<string name="module_version_author">%1$s / %2$s</string>
|
||||
<string name="module_state_remove">Kaldır</string>
|
||||
<string name="module_state_restore">Geri yükle</string>
|
||||
<string name="module_state_restore">Geri Yükle</string>
|
||||
<string name="module_action_install_external">Depolamadan yükle</string>
|
||||
<string name="update_available">Güncelleme Mevcut</string>
|
||||
<string name="suspend_text_riru">%1$s etkinleştirildiği için modül askıya alındı</string>
|
||||
<string name="suspend_text_zygisk">%1$s etkinleştirilmediği için modül askıya alındı</string>
|
||||
<string name="suspend_text_riru">Modül, %1$s etkin olduğu için askıya alındı</string>
|
||||
<string name="suspend_text_zygisk">Modül, %1$s etkin olmadığı için askıya alındı</string>
|
||||
<string name="zygisk_module_unloaded">Uyumsuzluk nedeniyle Zygisk modülü yüklenmedi</string>
|
||||
<string name="module_empty">Yüklü modül yok</string>
|
||||
<string name="confirm_install">%1$s modülü yüklensin mi?</string>
|
||||
@@ -121,39 +122,39 @@
|
||||
<!--Settings-->
|
||||
<string name="settings_dark_mode_title">Tema Modu</string>
|
||||
<string name="settings_dark_mode_message">Tarzınıza en uygun modu seçin!</string>
|
||||
<string name="settings_dark_mode_light">Daima Açık</string>
|
||||
<string name="settings_dark_mode_light">Her Zaman Aydınlık</string>
|
||||
<string name="settings_dark_mode_system">Sistemi Takip Et</string>
|
||||
<string name="settings_dark_mode_dark">Daima Koyu</string>
|
||||
<string name="settings_download_path_title">İndirme yolu</string>
|
||||
<string name="settings_dark_mode_dark">Her Zaman Karanlık</string>
|
||||
<string name="settings_download_path_title">İndirme Yolu</string>
|
||||
<string name="settings_download_path_message">Dosyalar %1$s konumuna kaydedilecek</string>
|
||||
<string name="settings_hide_app_title">Magisk uygulamasını gizle</string>
|
||||
<string name="settings_hide_app_summary">Rastgele bir paket kimliği ve özel uygulama etiketi olan bir proxy uygulaması yükleyin</string>
|
||||
<string name="settings_hide_app_summary">Rastgele bir paket kimliği ve özel uygulama etiketi olan bir vekil (proxy) uygulaması yükleyin</string>
|
||||
<string name="settings_restore_app_title">Magisk uygulamasını geri yükle</string>
|
||||
<string name="settings_restore_app_summary">Uygulamayı göster ve orijinal APK\'yı geri yükle</string>
|
||||
<string name="language">Dil</string>
|
||||
<string name="system_default">(Sistem Varsayılanı)</string>
|
||||
<string name="settings_check_update_title">Güncellemeleri Kontrol Et</string>
|
||||
<string name="settings_check_update_summary">Arka plandaki güncellemeleri düzenli olarak kontrol et</string>
|
||||
<string name="settings_check_update_summary">Arka planda düzenli olarak güncellemeleri kontrol et</string>
|
||||
<string name="settings_update_channel_title">Güncelleme Kanalı</string>
|
||||
<string name="settings_update_stable">Stabil</string>
|
||||
<string name="settings_update_stable">Kararlı</string>
|
||||
<string name="settings_update_beta">Beta</string>
|
||||
<string name="settings_update_custom">Özel</string>
|
||||
<string name="settings_update_custom_msg">Özel bir kanal bağlantısı ekle</string>
|
||||
<string name="settings_zygisk_summary">Zygisk arka plan programında Magisk\'in bazı bölümlerini çalıştır</string>
|
||||
<string name="settings_update_custom_msg">Özel kanal URL\'si girin</string>
|
||||
<string name="settings_zygisk_summary">Magisk\'in bazı bölümlerini zygote daemon\'unda çalıştır</string>
|
||||
<string name="settings_denylist_title">Reddetme Listesini Zorla</string>
|
||||
<string name="settings_denylist_summary">Reddetme listesindeki işlemlerde tüm Magisk değişiklikleri geri alınır</string>
|
||||
<string name="settings_denylist_summary">Reddetme Listesindeki işlemler tüm Magisk değişikliklerini geri alacak</string>
|
||||
<string name="settings_denylist_config_title">Reddetme Listesini Yapılandır</string>
|
||||
<string name="settings_denylist_config_summary">Reddetme listesine dahil edilecek işlemleri seç</string>
|
||||
<string name="settings_denylist_config_summary">Reddetme Listesine dahil edilecek işlemleri seçin</string>
|
||||
<string name="settings_hosts_title">Sistemsiz ana makineler (systemless hosts)</string>
|
||||
<string name="settings_hosts_summary">Reklam engelleme uygulamaları için sistemsiz ana makineler (systemless hosts) desteği</string>
|
||||
<string name="settings_hosts_toast">Sistemsiz ana makineler (systemless hosts) modülü eklendi</string>
|
||||
<string name="settings_app_name_hint">Yeni ad</string>
|
||||
<string name="settings_app_name_helper">Uygulama bu adla yeniden paketlenecek</string>
|
||||
<string name="settings_app_name_helper">Uygulama bu isimle yeniden paketlenecek</string>
|
||||
<string name="settings_app_name_error">Geçersiz format</string>
|
||||
<string name="settings_su_app_adb">Uygulamalar ve ADB</string>
|
||||
<string name="settings_su_app">Yalnızca uygulamalar</string>
|
||||
<string name="settings_su_adb">Yalnızca ADB</string>
|
||||
<string name="settings_su_disable">Devre dışı</string>
|
||||
<string name="settings_su_app">Sadece Uygulamalar</string>
|
||||
<string name="settings_su_adb">Sadece ADB</string>
|
||||
<string name="settings_su_disable">Devre Dışı</string>
|
||||
<string name="settings_su_request_10">10 saniye</string>
|
||||
<string name="settings_su_request_15">15 saniye</string>
|
||||
<string name="settings_su_request_20">20 saniye</string>
|
||||
@@ -164,39 +165,41 @@
|
||||
<string name="auto_response">Otomatik Yanıt</string>
|
||||
<string name="request_timeout">İstek Zaman Aşımı</string>
|
||||
<string name="superuser_notification">Süper Kullanıcı Bildirimi</string>
|
||||
<string name="settings_su_reauth_title">Yükseltmeden sonra yeniden kimlik doğrulaması yap</string>
|
||||
<string name="settings_su_reauth_summary">Uygulamaları yükselttikten sonra Süper Kullanıcı izinlerini tekrar iste</string>
|
||||
<string name="settings_su_tapjack_title">Sahte Ekran (Tapjacking) Koruması</string>
|
||||
<string name="settings_su_tapjack_summary">Süper Kullanıcı bilgi istemi iletişim kutusu, herhangi bir başka pencere veya yer paylaşımı tarafından engellendiğinde girişe yanıt vermeyecektir.</string>
|
||||
<string name="settings_su_auth_title">Kullanıcı Kimlik Doğrulaması</string>
|
||||
<string name="settings_su_auth_summary">Süper Kullanıcı istekleri sırasında kullanıcı kimlik doğrulaması iste</string>
|
||||
<string name="settings_su_auth_insecure">Cihazda hiçbir kimlik doğrulama yöntemi yapılandırılmamış</string>
|
||||
<string name="settings_su_reauth_title">Yükseltme sonrası yeniden doğrulama yap</string>
|
||||
<string name="settings_su_reauth_summary">Uygulama güncellemelerinden sonra Süper Kullanıcı izinlerini tekrar iste</string>
|
||||
<string name="settings_su_tapjack_title">Tapjacking Koruması</string>
|
||||
<string name="settings_su_tapjack_summary">Süper Kullanıcı istemi diyalogu, başka bir pencere veya katman tarafından gizlendiğinde girdilere yanıt vermeyecektir</string>
|
||||
<string name="settings_su_auth_title">Kullanıcı Kimlik Doğrulama</string>
|
||||
<string name="settings_su_auth_summary">Süper Kullanıcı isteklerinde kullanıcı kimlik doğrulaması iste</string>
|
||||
<string name="settings_su_auth_insecure">Cihazda yapılandırılmış bir kimlik doğrulama yöntemi yok</string>
|
||||
<string name="settings_customization">Özelleştir</string>
|
||||
<string name="setting_add_shortcut_summary">Uygulamayı gizledikten sonra adın ve simgenin tanınmasının zor olması durumunda ana ekrana güzel bir kısayol ekle</string>
|
||||
<string name="settings_doh_title">HTTPS üzerinden DNS</string>
|
||||
<string name="settings_doh_description">Bazı ülkelerde DNS zehirlenmesine geçici çözüm</string>
|
||||
<string name="setting_add_shortcut_summary">Uygulamayı gizledikten sonra adı ve simgeyi tanımakta zorlanıyorsanız ana ekrana güzel bir kısayol ekle</string>
|
||||
<string name="settings_doh_title">DNS üzerinden HTTPS</string>
|
||||
<string name="settings_doh_description">Bazı ülkelerde DNS zehirlemesine karşı geçici çözüm</string>
|
||||
<string name="settings_random_name_title">Çıkış adını rastgele seç</string>
|
||||
<string name="settings_random_name_description">Algılamayı önlemek için yamalı resimlerin ve tar dosyalarının çıkış dosya adını rastgele seç</string>
|
||||
|
||||
<string name="multiuser_mode">Çok Kullanıcılı Mod</string>
|
||||
<string name="settings_owner_only">Yalnızca Cihaz Sahibi</string>
|
||||
<string name="settings_owner_manage">Cihaz Sahibi Tarafından Yönetildi</string>
|
||||
<string name="settings_owner_manage">Cihaz Sahibi Yönetiminde</string>
|
||||
<string name="settings_user_independent">Kullanıcıdan Bağımsız</string>
|
||||
<string name="owner_only_summary">Kök erişimi yalnızca sahibine aittir</string>
|
||||
<string name="owner_manage_summary">Kök erişimini yalnızca sahip yönetebilir ve istek istemlerini alabilir</string>
|
||||
<string name="user_independent_summary">Her kullanıcının kendi ayrı kök kuralları vardır</string>
|
||||
<string name="owner_only_summary">Yalnızca sahip kök (root) erişimine sahiptir</string>
|
||||
<string name="owner_manage_summary">Yalnızca sahip kök (root) erişimini yönetebilir ve istek uyarılarını alabilir</string>
|
||||
<string name="user_independent_summary">Her kullanıcının kendi ayrı kök (root) kuralları vardır</string>
|
||||
|
||||
<string name="mount_namespace_mode">Bağlama Ad Alanı Modu</string>
|
||||
<string name="settings_ns_global">Küresel Ad Alanı</string>
|
||||
<string name="settings_ns_requester">Ad Alanını Devral</string>
|
||||
<string name="settings_ns_isolate">İzole Edilmiş Ad Alanı</string>
|
||||
<string name="global_summary">Tüm kök oturumları, global bağlama ad alanını kullanır</string>
|
||||
<string name="requester_summary">Kök oturumları, istek sahibinin ad alanını devralır</string>
|
||||
<string name="isolate_summary">Her kök oturumun kendi izole edilmiş ad alanı olacaktır</string>
|
||||
<string name="settings_ns_isolate">İzolasyon Ad Alanı</string>
|
||||
<string name="global_summary">Tüm kök (root) oturumları küresel bağlama ad alanını kullanır</string>
|
||||
<string name="requester_summary">Kök (root) oturumları isteyicisinin ad alanını devralacak</string>
|
||||
<string name="isolate_summary">Her kök (root) oturumu kendi izole ad alanına sahip olacak</string>
|
||||
|
||||
<!--Notifications-->
|
||||
<string name="update_channel">Magisk Güncellemeleri</string>
|
||||
<string name="progress_channel">İlerleme Bildirimleri</string>
|
||||
<string name="updated_channel">Güncelleme Tamamlandı</string>
|
||||
<string name="download_complete">İndirme Tamamlandı</string>
|
||||
<string name="download_complete">İndirme tamamlandı</string>
|
||||
<string name="download_file_error">Dosya indirilirken hata oluştu</string>
|
||||
<string name="magisk_update_title">Magisk Güncellemesi Mevcut!</string>
|
||||
<string name="updated_title">Magisk Güncellendi</string>
|
||||
@@ -204,41 +207,41 @@
|
||||
|
||||
<!--Toasts, Dialogs-->
|
||||
<string name="yes">Mevcut</string>
|
||||
<string name="no">Mevcut değil</string>
|
||||
<string name="repo_install_title">%1$s %2$s(%3$d) yükle</string>
|
||||
<string name="no">Mevcut Değil</string>
|
||||
<string name="repo_install_title">%1$s %2$s(%3$d) Kur</string>
|
||||
<string name="download">İndir</string>
|
||||
<string name="reboot">Yeniden başlat</string>
|
||||
<string name="release_notes">Sürüm notları</string>
|
||||
<string name="flashing">Flaşlanıyor…</string>
|
||||
<string name="reboot">Yeniden Başlat</string>
|
||||
<string name="release_notes">Sürüm Notları</string>
|
||||
<string name="flashing">Yükleniyor...</string>
|
||||
<string name="done">Tamamlandı!</string>
|
||||
<string name="failure">Başarısız!</string>
|
||||
<string name="hide_app_title">Magisk uygulaması gizleniyor…</string>
|
||||
<string name="open_link_failed_toast">Bağlantıyı açacak uygulama bulunamadı</string>
|
||||
<string name="complete_uninstall">Kaldırmayı Tamamla</string>
|
||||
<string name="open_link_failed_toast">Bağlantıyı açmak için uygulama bulunamadı</string>
|
||||
<string name="complete_uninstall">Tamamen Kaldır</string>
|
||||
<string name="restore_img">Görüntüleri Geri Yükle</string>
|
||||
<string name="restore_img_msg">Geri yükleniyor…</string>
|
||||
<string name="restore_img_msg">Geri Yükleniyor...</string>
|
||||
<string name="restore_done">Geri yükleme tamamlandı!</string>
|
||||
<string name="restore_fail">Stok yedeği mevcut değil!</string>
|
||||
<string name="setup_fail">Kurulum başarısız oldu</string>
|
||||
<string name="env_fix_title">Ek Kurulum Gerekiyor</string>
|
||||
<string name="env_fix_msg">Magisk\'in düzgün çalışması için cihazınızın ek kuruluma ihtiyacı var. Devam etmek ve yeniden başlatmak istiyor musunuz?</string>
|
||||
<string name="env_full_fix_msg">Cihazınızın düzgün çalışması için Magisk\'in yeniden başlatılması gerekiyor. Lütfen Magisk\'i uygulama içinden yeniden yükleyin, kurtarma modu doğru cihaz bilgilerini alamıyor.</string>
|
||||
<string name="setup_msg">Ortam kurulumu çalıştırılıyor…</string>
|
||||
<string name="env_fix_title">Ek Ayar Gerekiyor</string>
|
||||
<string name="env_fix_msg">Magisk\'in düzgün çalışabilmesi için cihazınızın ek ayarlar yapması gerekiyor. Devam etmek ve yeniden başlatmak istiyor musunuz?</string>
|
||||
<string name="env_full_fix_msg">Cihazınızın düzgün çalışabilmesi için Magisk\'in yeniden yüklenmesi gerekiyor. Lütfen Magisk\'i uygulama içinde yeniden yükleyin, kurtarma modu doğru cihaz bilgilerini alamaz.</string>
|
||||
<string name="setup_msg">Ortam kurulumu yapılıyor...</string>
|
||||
<string name="unsupport_magisk_title">Desteklenmeyen Magisk Sürümü</string>
|
||||
<string name="unsupport_magisk_msg">Uygulamanın bu sürümü %1$s altındaki Magisk sürümlerini desteklemiyor.\n\nUygulama Magisk yüklenmemiş gibi davranacak, lütfen en kısa sürede Magisk\'i yükseltin.</string>
|
||||
<string name="unsupport_magisk_msg">Bu uygulama sürümü, %1$s altındaki Magisk sürümlerini desteklemiyor.\n\nUygulama, Magisk yüklü değilmiş gibi davranacaktır, lütfen en kısa sürede Magisk\'i güncelleyin.</string>
|
||||
<string name="unsupport_general_title">Anormal Durum</string>
|
||||
<string name="unsupport_system_app_msg">Bu uygulamanın sistem uygulaması olarak çalıştırılması desteklenmiyor. Lütfen uygulamayı bir kullanıcı uygulamasına geri yükleyin.</string>
|
||||
<string name="unsupport_other_su_msg">Magisk\'ten olmayan bir \"su\" ikilisi algılandı. Lütfen rakip kök çözümlerini kaldırın ve/veya Magisk\'i yeniden yükleyin.</string>
|
||||
<string name="unsupport_external_storage_msg">Magisk harici depolamaya yüklenmiş. Lütfen uygulamayı dahili depolamaya taşıyın.</string>
|
||||
<string name="unsupport_nonroot_stub_msg">Kök (root) kaybolduğu için gizli Magisk uygulaması çalışmaya devam edemiyor. Lütfen orijinal APK\'yı geri yükleyin.</string>
|
||||
<string name="unsupport_system_app_msg">Bu uygulamanın sistem uygulaması olarak çalıştırılması desteklenmiyor. Lütfen uygulamayı kullanıcı uygulamasına geri döndürün.</string>
|
||||
<string name="unsupport_other_su_msg">Magisk\'ten gelmeyen bir "su" ikili dosyası tespit edildi. Lütfen herhangi bir rakip kök (root) çözümünü kaldırın ve/veya Magisk\'i yeniden yükleyin.</string>
|
||||
<string name="unsupport_external_storage_msg">Magisk harici depolamaya yüklendi. Lütfen uygulamayı dahili depolamaya taşıyın.</string>
|
||||
<string name="unsupport_nonroot_stub_msg">Gizli Magisk uygulaması kök (root) erişimi kaybolduğu için çalışmaya devam edemez. Lütfen orijinal APK\'yı geri yükleyin.</string>
|
||||
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
|
||||
<string name="external_rw_permission_denied">Bu işlevi etkinleştirmek için depolama izni veriniz.</string>
|
||||
<string name="post_notifications_denied">Bu işlevi etkinleştirmek için bildirim izni veriniz.</string>
|
||||
<string name="install_unknown_denied">Bu işlevi etkinleştirmek için "Bilinmeyen uygulamaları yükle" ayarına izin veriniz.</string>
|
||||
<string name="external_rw_permission_denied">Bu işlevselliği etkinleştirmek için depolama izni verin</string>
|
||||
<string name="post_notifications_denied">Bu işlevselliği etkinleştirmek için bildirim izni verin</string>
|
||||
<string name="install_unknown_denied">Bu işlevselliği etkinleştirmek için "bilinmeyen uygulamaları yükle" iznini verin</string>
|
||||
<string name="add_shortcut_title">Ana ekrana kısayol ekle</string>
|
||||
<string name="add_shortcut_msg">Bu uygulamayı gizledikten sonra adını ve simgesini tanımak zorlaşabilir. Ana ekrana güzel bir kısayol eklemek ister misiniz?</string>
|
||||
<string name="app_not_found">Bu eylemi gerçekleştirecek uygulama bulunamadı</string>
|
||||
<string name="add_shortcut_msg">Bu uygulamayı gizledikten sonra adı ve simgesi tanınmayabilir. Ana ekrana güzel bir kısayol eklemek ister misiniz?</string>
|
||||
<string name="app_not_found">Bu işlemi gerçekleştirecek uygulama bulunamadı</string>
|
||||
<string name="reboot_apply_change">Değişiklikleri uygulamak için yeniden başlatın</string>
|
||||
<string name="restore_app_confirmation">Bu işlem, gizli uygulamayı orijinal uygulama ile değiştirecektir. Bu işlemi yapmak istediğinizden emin misiniz?</string>
|
||||
<string name="restore_app_confirmation">Bu, gizli uygulamayı orijinal uygulamaya geri yükleyecektir. Gerçekten bunu yapmak istiyor musunuz?</string>
|
||||
|
||||
</resources>
|
||||
|
@@ -1,13 +1,22 @@
|
||||
package com.topjohnwu.magisk;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
|
||||
public class ProviderInstaller {
|
||||
|
||||
private static final String GMS_PACKAGE_NAME = "com.google.android.gms";
|
||||
|
||||
public static boolean install(Context context) {
|
||||
try {
|
||||
// Check if gms is a system app
|
||||
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(GMS_PACKAGE_NAME, 0);
|
||||
if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try installing new SSL provider from Google Play Service
|
||||
Context gms = context.createPackageContext("com.google.android.gms",
|
||||
Context gms = context.createPackageContext(GMS_PACKAGE_NAME,
|
||||
Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
|
||||
gms.getClassLoader()
|
||||
.loadClass("com.google.android.gms.common.security.ProviderInstallerImpl")
|
||||
|
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="upgrade_msg">عليك الترقية ماجـيسك Manager لإكمال تهيئة التطبيق.هل اكمل؟</string>
|
||||
<string name="no_internet_msg">يرجى الاتصال بالانترنيت! ترقية ماجـيسك مطلوب...</string>
|
||||
<string name="upgrade_msg">عليك الترقية Magisk لإكمال تهيئة التطبيق. هل تريد التنزيل والتثبيت؟</string>
|
||||
<string name="no_internet_msg">يرجى اللإتصال بالإنترنت! ترقية Magisk مطلوبة.</string>
|
||||
<string name="dling">جارٍ التنزيل</string>
|
||||
<string name="relaunch_app">يرجى إعادة تشغيل التطبيق يدوياً</string>
|
||||
</resources>
|
||||
|
510
build.py
510
build.py
@@ -5,6 +5,7 @@ import lzma
|
||||
import multiprocessing
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
@@ -38,6 +39,7 @@ def vprint(str):
|
||||
print(str)
|
||||
|
||||
|
||||
# Environment checks and detection
|
||||
is_windows = os.name == "nt"
|
||||
EXE_EXT = ".exe" if is_windows else ""
|
||||
|
||||
@@ -51,7 +53,6 @@ if is_windows:
|
||||
# We can't do ANSI color codes in terminal on Windows without colorama
|
||||
no_color = True
|
||||
|
||||
# Environment checks
|
||||
if not sys.version_info >= (3, 8):
|
||||
error("Requires Python 3.8+")
|
||||
|
||||
@@ -63,42 +64,40 @@ except KeyError:
|
||||
except KeyError:
|
||||
error("Please set Android SDK path to environment variable ANDROID_HOME")
|
||||
|
||||
if shutil.which("sccache") is not None:
|
||||
os.environ["RUSTC_WRAPPER"] = "sccache"
|
||||
os.environ["NDK_CCACHE"] = "sccache"
|
||||
os.environ["CARGO_INCREMENTAL"] = "0"
|
||||
if shutil.which("ccache") is not None:
|
||||
os.environ["NDK_CCACHE"] = "ccache"
|
||||
|
||||
cpu_count = multiprocessing.cpu_count()
|
||||
os_name = platform.system().lower()
|
||||
|
||||
archs = ["armeabi-v7a", "x86", "arm64-v8a", "x86_64", "riscv64"]
|
||||
triples = [
|
||||
"armv7a-linux-androideabi",
|
||||
"i686-linux-android",
|
||||
"aarch64-linux-android",
|
||||
"x86_64-linux-android",
|
||||
"riscv64-linux-android",
|
||||
]
|
||||
# Common constants
|
||||
support_abis = {
|
||||
"armeabi-v7a": "thumbv7neon-linux-androideabi",
|
||||
"x86": "i686-linux-android",
|
||||
"arm64-v8a": "aarch64-linux-android",
|
||||
"x86_64": "x86_64-linux-android",
|
||||
"riscv64": "riscv64-linux-android",
|
||||
}
|
||||
default_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"}
|
||||
support_targets = default_targets | {"resetprop"}
|
||||
rust_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"}
|
||||
|
||||
# Common paths
|
||||
ndk_root = sdk_path / "ndk"
|
||||
ndk_path = ndk_root / "magisk"
|
||||
ndk_build = ndk_path / "ndk-build"
|
||||
rust_bin = ndk_path / "toolchains" / "rust" / "bin"
|
||||
llvm_bin = ndk_path / "toolchains" / "llvm" / "prebuilt" / f"{os_name}-x86_64" / "bin"
|
||||
cargo = rust_bin / f"cargo{EXE_EXT}"
|
||||
gradlew = Path("gradlew" + (".bat" if is_windows else "")).resolve()
|
||||
adb_path = sdk_path / "platform-tools" / f"adb{EXE_EXT}"
|
||||
cargo = rust_bin / "cargo"
|
||||
gradlew = Path.cwd() / "gradlew"
|
||||
adb_path = sdk_path / "platform-tools" / "adb"
|
||||
native_gen_path = Path("native", "out", "generated").resolve()
|
||||
|
||||
# Global vars
|
||||
config = {}
|
||||
STDOUT = None
|
||||
build_tools = None
|
||||
args = {}
|
||||
build_abis = {}
|
||||
|
||||
###################
|
||||
# Helper functions
|
||||
###################
|
||||
|
||||
|
||||
def mv(source: Path, target: Path):
|
||||
@@ -137,20 +136,26 @@ def rm_on_error(func, path, _):
|
||||
|
||||
def rm_rf(path: Path):
|
||||
vprint(f"rm -rf {path}")
|
||||
shutil.rmtree(path, ignore_errors=False, onerror=rm_on_error)
|
||||
if sys.version_info >= (3, 12):
|
||||
shutil.rmtree(path, ignore_errors=False, onexc=rm_on_error)
|
||||
else:
|
||||
shutil.rmtree(path, ignore_errors=False, onerror=rm_on_error)
|
||||
|
||||
|
||||
def execv(cmd, env=None):
|
||||
return subprocess.run(cmd, stdout=STDOUT, env=env)
|
||||
def execv(cmds: list, env=None):
|
||||
out = None if args.force_out or args.verbose > 0 else subprocess.DEVNULL
|
||||
# Use shell on Windows to support PATHEXT
|
||||
return subprocess.run(cmds, stdout=out, env=env, shell=is_windows)
|
||||
|
||||
|
||||
def system(cmd):
|
||||
return subprocess.run(cmd, shell=True, stdout=STDOUT)
|
||||
|
||||
|
||||
def cmd_out(cmd, env=None):
|
||||
def cmd_out(cmds: list):
|
||||
return (
|
||||
subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, env=env)
|
||||
subprocess.run(
|
||||
cmds,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL,
|
||||
shell=is_windows,
|
||||
)
|
||||
.stdout.strip()
|
||||
.decode("utf-8")
|
||||
)
|
||||
@@ -160,51 +165,9 @@ def xz(data):
|
||||
return lzma.compress(data, preset=9, check=lzma.CHECK_NONE)
|
||||
|
||||
|
||||
def parse_props(file):
|
||||
props = {}
|
||||
with open(file, "r") as f:
|
||||
for line in [l.strip(" \t\r\n") for l in f]:
|
||||
if line.startswith("#") or len(line) == 0:
|
||||
continue
|
||||
prop = line.split("=")
|
||||
if len(prop) != 2:
|
||||
continue
|
||||
value = prop[1].strip(" \t\r\n")
|
||||
if len(value) == 0:
|
||||
continue
|
||||
props[prop[0].strip(" \t\r\n")] = value
|
||||
return props
|
||||
|
||||
|
||||
def load_config(args):
|
||||
commit_hash = cmd_out(["git", "rev-parse", "--short=8", "HEAD"])
|
||||
|
||||
# Default values
|
||||
config["version"] = commit_hash
|
||||
config["versionCode"] = 1000000
|
||||
config["outdir"] = "out"
|
||||
|
||||
args.config = Path(args.config)
|
||||
|
||||
# Load prop files
|
||||
if args.config.exists():
|
||||
config.update(parse_props(args.config))
|
||||
|
||||
if Path("gradle.properties").exists():
|
||||
for key, value in parse_props("gradle.properties").items():
|
||||
if key.startswith("magisk."):
|
||||
config[key[7:]] = value
|
||||
|
||||
try:
|
||||
config["versionCode"] = int(config["versionCode"])
|
||||
except ValueError:
|
||||
error('Config error: "versionCode" is required to be an integer')
|
||||
|
||||
config["outdir"] = Path(config["outdir"])
|
||||
|
||||
config["outdir"].mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
global STDOUT
|
||||
STDOUT = None if args.verbose > 0 else subprocess.DEVNULL
|
||||
###############
|
||||
# Build Native
|
||||
###############
|
||||
|
||||
|
||||
def clean_elf():
|
||||
@@ -225,26 +188,28 @@ def clean_elf():
|
||||
elf_cleaner,
|
||||
]
|
||||
)
|
||||
args = [elf_cleaner, "--api-level", "23"]
|
||||
args.extend(
|
||||
Path("native", "out", arch, bin)
|
||||
for arch in archs
|
||||
for bin in ["magisk", "magiskpolicy"]
|
||||
)
|
||||
execv(args)
|
||||
cmds = [elf_cleaner, "--api-level", "23"]
|
||||
cmds.extend(glob.glob("native/out/*/magisk"))
|
||||
cmds.extend(glob.glob("native/out/*/magiskpolicy"))
|
||||
execv(cmds)
|
||||
|
||||
|
||||
def run_ndk_build(args, flags):
|
||||
def run_ndk_build(cmds: list):
|
||||
os.chdir("native")
|
||||
flags = "NDK_PROJECT_PATH=. NDK_APPLICATION_MK=src/Application.mk " + flags
|
||||
cmds.append("NDK_PROJECT_PATH=.")
|
||||
cmds.append("NDK_APPLICATION_MK=src/Application.mk")
|
||||
cmds.append(f"APP_ABI={' '.join(build_abis.keys())}")
|
||||
cmds.append(f"-j{cpu_count}")
|
||||
if args.verbose > 1:
|
||||
flags = "V=1 " + flags
|
||||
proc = system(f"{ndk_build} {flags} -j{cpu_count}")
|
||||
cmds.append("V=1")
|
||||
if not args.release:
|
||||
cmds.append("MAGISK_DEBUG=1")
|
||||
proc = execv([ndk_build, *cmds])
|
||||
if proc.returncode != 0:
|
||||
error("Build binary failed!")
|
||||
os.chdir("..")
|
||||
|
||||
for arch in archs:
|
||||
for arch in build_abis.keys():
|
||||
arch_dir = Path("native", "libs", arch)
|
||||
out_dir = Path("native", "out", arch)
|
||||
for source in arch_dir.iterdir():
|
||||
@@ -252,40 +217,40 @@ def run_ndk_build(args, flags):
|
||||
mv(source, target)
|
||||
|
||||
|
||||
def build_cpp_src(args, targets: set):
|
||||
def build_cpp_src(targets: set):
|
||||
dump_flag_header()
|
||||
|
||||
flags = ""
|
||||
cmds = []
|
||||
clean = False
|
||||
|
||||
if "magisk" in targets:
|
||||
flags += " B_MAGISK=1"
|
||||
cmds.append("B_MAGISK=1")
|
||||
clean = True
|
||||
|
||||
if "magiskpolicy" in targets:
|
||||
flags += " B_POLICY=1"
|
||||
cmds.append("B_POLICY=1")
|
||||
clean = True
|
||||
|
||||
if "magiskinit" in targets:
|
||||
flags += " B_PRELOAD=1"
|
||||
cmds.append("B_PRELOAD=1")
|
||||
|
||||
if "resetprop" in targets:
|
||||
flags += " B_PROP=1"
|
||||
cmds.append("B_PROP=1")
|
||||
|
||||
if flags:
|
||||
run_ndk_build(args, flags)
|
||||
if cmds:
|
||||
run_ndk_build(cmds)
|
||||
|
||||
flags = ""
|
||||
cmds.clear()
|
||||
|
||||
if "magiskinit" in targets:
|
||||
flags += " B_INIT=1"
|
||||
cmds.append("B_INIT=1")
|
||||
|
||||
if "magiskboot" in targets:
|
||||
flags += " B_BOOT=1"
|
||||
cmds.append("B_BOOT=1")
|
||||
|
||||
if flags:
|
||||
flags += " B_CRT0=1"
|
||||
run_ndk_build(args, flags)
|
||||
if cmds:
|
||||
cmds.append("B_CRT0=1")
|
||||
run_ndk_build(cmds)
|
||||
|
||||
if clean:
|
||||
clean_elf()
|
||||
@@ -295,11 +260,11 @@ def run_cargo(cmds):
|
||||
env = os.environ.copy()
|
||||
env["PATH"] = f'{rust_bin}{os.pathsep}{env["PATH"]}'
|
||||
env["CARGO_BUILD_RUSTC"] = str(rust_bin / f"rustc{EXE_EXT}")
|
||||
env["RUSTFLAGS"] = f"-Clinker-plugin-lto -Zthreads={min(8, cpu_count)}"
|
||||
env["CARGO_BUILD_RUSTFLAGS"] = f"-Z threads={min(8, cpu_count)}"
|
||||
return execv([cargo, *cmds], env)
|
||||
|
||||
|
||||
def build_rust_src(args, targets: set):
|
||||
def build_rust_src(targets: set):
|
||||
targets = targets.copy()
|
||||
if "resetprop" in targets:
|
||||
targets.add("magisk")
|
||||
@@ -309,54 +274,40 @@ def build_rust_src(args, targets: set):
|
||||
|
||||
os.chdir(Path("native", "src"))
|
||||
|
||||
native_out = Path("..", "out")
|
||||
native_out.mkdir(mode=0o755, exist_ok=True)
|
||||
|
||||
# Start building the actual build commands
|
||||
# Start building the build commands
|
||||
cmds = ["build", "-p", ""]
|
||||
rust_out = "debug"
|
||||
if args.release:
|
||||
cmds.append("-r")
|
||||
rust_out = "release"
|
||||
profile = "release"
|
||||
else:
|
||||
profile = "debug"
|
||||
if args.verbose == 0:
|
||||
cmds.append("-q")
|
||||
elif args.verbose > 1:
|
||||
cmds.append("--verbose")
|
||||
|
||||
cmds.append("--target")
|
||||
cmds.append("")
|
||||
for triple in build_abis.values():
|
||||
cmds.append("--target")
|
||||
cmds.append(triple)
|
||||
|
||||
for arch, triple in zip(archs, triples):
|
||||
rust_triple = (
|
||||
"thumbv7neon-linux-androideabi" if triple.startswith("armv7") else triple
|
||||
)
|
||||
cmds[-1] = rust_triple
|
||||
for tgt in targets:
|
||||
cmds[2] = tgt
|
||||
proc = run_cargo(cmds)
|
||||
if proc.returncode != 0:
|
||||
error("Build binary failed!")
|
||||
|
||||
for tgt in targets:
|
||||
cmds[2] = tgt
|
||||
proc = run_cargo(cmds)
|
||||
if proc.returncode != 0:
|
||||
error("Build binary failed!")
|
||||
os.chdir(Path("..", ".."))
|
||||
|
||||
native_out = Path("native", "out")
|
||||
rust_out = native_out / "rust"
|
||||
for arch, triple in build_abis.items():
|
||||
arch_out = native_out / arch
|
||||
arch_out.mkdir(mode=0o755, exist_ok=True)
|
||||
for tgt in targets:
|
||||
source = Path("target", rust_triple, rust_out, f"lib{tgt}.a")
|
||||
source = rust_out / triple / profile / f"lib{tgt}.a"
|
||||
target = arch_out / f"lib{tgt}-rs.a"
|
||||
mv(source, target)
|
||||
|
||||
os.chdir(Path("..", ".."))
|
||||
|
||||
|
||||
def run_cargo_cmd(args):
|
||||
global STDOUT
|
||||
STDOUT = None
|
||||
if len(args.commands) >= 1 and args.commands[0] == "--":
|
||||
args.commands = args.commands[1:]
|
||||
os.chdir(Path("native", "src"))
|
||||
run_cargo(args.commands)
|
||||
os.chdir(Path("..", ".."))
|
||||
|
||||
|
||||
def write_if_diff(file_name: Path, text: str):
|
||||
do_write = True
|
||||
@@ -387,7 +338,7 @@ def dump_flag_header():
|
||||
write_if_diff(Path(native_gen_path, "flags.h"), flag_txt)
|
||||
|
||||
|
||||
def build_binary(args):
|
||||
def build_native():
|
||||
# Verify NDK install
|
||||
try:
|
||||
with open(Path(ndk_path, "ONDK_VERSION"), "r") as ondk_ver:
|
||||
@@ -402,10 +353,22 @@ def build_binary(args):
|
||||
if not targets:
|
||||
return
|
||||
|
||||
header("* Building binaries: " + " ".join(targets))
|
||||
header("* Building: " + " ".join(targets))
|
||||
|
||||
build_rust_src(args, targets)
|
||||
build_cpp_src(args, targets)
|
||||
if sccache := shutil.which("sccache"):
|
||||
os.environ["RUSTC_WRAPPER"] = sccache
|
||||
os.environ["NDK_CCACHE"] = sccache
|
||||
os.environ["CARGO_INCREMENTAL"] = "0"
|
||||
if ccache := shutil.which("ccache"):
|
||||
os.environ["NDK_CCACHE"] = ccache
|
||||
|
||||
build_rust_src(targets)
|
||||
build_cpp_src(targets)
|
||||
|
||||
|
||||
############
|
||||
# Build App
|
||||
############
|
||||
|
||||
|
||||
def find_jdk():
|
||||
@@ -440,7 +403,7 @@ def find_jdk():
|
||||
return env
|
||||
|
||||
|
||||
def build_apk(args, module):
|
||||
def build_apk(module: str):
|
||||
env = find_jdk()
|
||||
|
||||
build_type = "Release" if args.release else "Debug"
|
||||
@@ -466,9 +429,9 @@ def build_apk(args, module):
|
||||
header(f"Output: {target}")
|
||||
|
||||
|
||||
def build_app(args):
|
||||
def build_app():
|
||||
header("* Building the Magisk app")
|
||||
build_apk(args, ":app:apk")
|
||||
build_apk(":app:apk")
|
||||
|
||||
build_type = "release" if args.release else "debug"
|
||||
|
||||
@@ -484,13 +447,18 @@ def build_app(args):
|
||||
cp(source, target)
|
||||
|
||||
|
||||
def build_stub(args):
|
||||
def build_stub():
|
||||
header("* Building the stub app")
|
||||
build_apk(args, ":app:stub")
|
||||
build_apk(":app:stub")
|
||||
|
||||
|
||||
def cleanup(args):
|
||||
support_targets = {"native", "cpp", "rust", "java"}
|
||||
################
|
||||
# Build General
|
||||
################
|
||||
|
||||
|
||||
def cleanup():
|
||||
support_targets = {"native", "cpp", "rust", "app"}
|
||||
if args.targets:
|
||||
targets = set(args.targets) & support_targets
|
||||
if "native" in targets:
|
||||
@@ -503,7 +471,6 @@ def cleanup(args):
|
||||
header("* Cleaning C++")
|
||||
rm_rf(Path("native", "libs"))
|
||||
rm_rf(Path("native", "obj"))
|
||||
rm_rf(Path("native", "out"))
|
||||
|
||||
if "rust" in targets:
|
||||
header("* Cleaning Rust")
|
||||
@@ -513,12 +480,34 @@ def cleanup(args):
|
||||
for rs_gen in glob.glob("native/**/*-rs.*pp", recursive=True):
|
||||
rm(rs_gen)
|
||||
|
||||
if "java" in targets:
|
||||
header("* Cleaning java")
|
||||
if "native" in targets:
|
||||
rm_rf(Path("native", "out"))
|
||||
|
||||
if "app" in targets:
|
||||
header("* Cleaning app")
|
||||
execv([gradlew, ":app:clean"], env=find_jdk())
|
||||
|
||||
|
||||
def setup_ndk(args):
|
||||
def build_all():
|
||||
build_native()
|
||||
build_app()
|
||||
|
||||
|
||||
############
|
||||
# Utilities
|
||||
############
|
||||
|
||||
|
||||
def cargo_cli():
|
||||
args.force_out = True
|
||||
if len(args.commands) >= 1 and args.commands[0] == "--":
|
||||
args.commands = args.commands[1:]
|
||||
os.chdir(Path("native", "src"))
|
||||
run_cargo(args.commands)
|
||||
os.chdir(Path("..", ".."))
|
||||
|
||||
|
||||
def setup_ndk():
|
||||
ndk_ver = config["ondkVersion"]
|
||||
url = f"https://github.com/topjohnwu/ondk/releases/download/{ndk_ver}/ondk-{ndk_ver}-{os_name}.tar.xz"
|
||||
ndk_archive = url.split("/")[-1]
|
||||
@@ -537,7 +526,7 @@ def setup_ndk(args):
|
||||
mv(ondk_path, ndk_path)
|
||||
|
||||
|
||||
def push_files(args, script):
|
||||
def push_files(script):
|
||||
abi = cmd_out([adb_path, "shell", "getprop", "ro.product.cpu.abi"])
|
||||
if not abi:
|
||||
error("Cannot detect emulator ABI")
|
||||
@@ -565,22 +554,22 @@ def push_files(args, script):
|
||||
error("adb push failed!")
|
||||
|
||||
|
||||
def setup_avd(args):
|
||||
def setup_avd():
|
||||
if not args.skip:
|
||||
build_all(args)
|
||||
build_all()
|
||||
|
||||
header("* Setting up emulator")
|
||||
|
||||
push_files(args, Path("scripts", "avd_magisk.sh"))
|
||||
push_files(Path("scripts", "avd_magisk.sh"))
|
||||
|
||||
proc = execv([adb_path, "shell", "sh", "/data/local/tmp/avd_magisk.sh"])
|
||||
if proc.returncode != 0:
|
||||
error("avd_magisk.sh failed!")
|
||||
|
||||
|
||||
def patch_avd_file(args):
|
||||
def patch_avd_file():
|
||||
if not args.skip:
|
||||
build_all(args)
|
||||
build_all()
|
||||
|
||||
input = Path(args.image)
|
||||
if args.output:
|
||||
@@ -593,7 +582,7 @@ def patch_avd_file(args):
|
||||
|
||||
header(f"* Patching {input.name}")
|
||||
|
||||
push_files(args, Path("scripts", "avd_patch.sh"))
|
||||
push_files(Path("scripts", "avd_patch.sh"))
|
||||
|
||||
proc = execv([adb_path, "push", input, "/data/local/tmp"])
|
||||
if proc.returncode != 0:
|
||||
@@ -610,12 +599,7 @@ def patch_avd_file(args):
|
||||
header(f"Output: {output}")
|
||||
|
||||
|
||||
def build_all(args):
|
||||
build_binary(args)
|
||||
build_app(args)
|
||||
|
||||
|
||||
def setup_rustup(args):
|
||||
def setup_rustup():
|
||||
wrapper_dir = Path(args.wrapper_dir)
|
||||
rm_rf(wrapper_dir)
|
||||
wrapper_dir.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
@@ -631,10 +615,10 @@ def setup_rustup(args):
|
||||
# Build rustup_wrapper
|
||||
wrapper_src = Path("tools", "rustup_wrapper")
|
||||
cargo_toml = wrapper_src / "Cargo.toml"
|
||||
execv(
|
||||
[cargo, "build", "--release", f"--manifest-path={cargo_toml}"]
|
||||
+ (["--verbose"] if args.verbose > 1 else [])
|
||||
)
|
||||
cmds = ["build", "--release", f"--manifest-path={cargo_toml}"]
|
||||
if args.verbose > 1:
|
||||
cmds.append("--verbose")
|
||||
run_cargo(cmds)
|
||||
|
||||
# Replace rustup with wrapper
|
||||
wrapper = wrapper_dir / (f"rustup{EXE_EXT}")
|
||||
@@ -643,77 +627,149 @@ def setup_rustup(args):
|
||||
wrapper.chmod(0o755)
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description="Magisk build script")
|
||||
parser.set_defaults(func=lambda x: None)
|
||||
parser.add_argument(
|
||||
"-r", "--release", action="store_true", help="compile in release mode"
|
||||
)
|
||||
parser.add_argument("-v", "--verbose", action="count", default=0, help="verbose output")
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
"--config",
|
||||
default="config.prop",
|
||||
help="custom config file (default: config.prop)",
|
||||
)
|
||||
subparsers = parser.add_subparsers(title="actions")
|
||||
##################
|
||||
# Config and args
|
||||
##################
|
||||
|
||||
all_parser = subparsers.add_parser("all", help="build everything")
|
||||
all_parser.set_defaults(func=build_all)
|
||||
|
||||
binary_parser = subparsers.add_parser("binary", help="build binaries")
|
||||
binary_parser.add_argument(
|
||||
"targets",
|
||||
nargs="*",
|
||||
help=f"{', '.join(support_targets)}, \
|
||||
or empty for defaults ({', '.join(default_targets)})",
|
||||
)
|
||||
binary_parser.set_defaults(func=build_binary)
|
||||
def parse_props(file):
|
||||
props = {}
|
||||
with open(file, "r") as f:
|
||||
for line in [l.strip(" \t\r\n") for l in f]:
|
||||
if line.startswith("#") or len(line) == 0:
|
||||
continue
|
||||
prop = line.split("=")
|
||||
if len(prop) != 2:
|
||||
continue
|
||||
key = prop[0].strip(" \t\r\n")
|
||||
value = prop[1].strip(" \t\r\n")
|
||||
if not key or not value:
|
||||
continue
|
||||
props[key] = value
|
||||
return props
|
||||
|
||||
cargo_parser = subparsers.add_parser("cargo", help="run cargo with proper environment")
|
||||
cargo_parser.add_argument("commands", nargs=argparse.REMAINDER)
|
||||
cargo_parser.set_defaults(func=run_cargo_cmd)
|
||||
|
||||
rustup_parser = subparsers.add_parser("rustup", help="setup rustup wrapper")
|
||||
rustup_parser.add_argument("wrapper_dir", help="path to setup rustup wrapper binaries")
|
||||
rustup_parser.set_defaults(func=setup_rustup)
|
||||
def load_config():
|
||||
commit_hash = cmd_out(["git", "rev-parse", "--short=8", "HEAD"])
|
||||
|
||||
app_parser = subparsers.add_parser("app", help="build the Magisk app")
|
||||
app_parser.set_defaults(func=build_app)
|
||||
# Default values
|
||||
config["version"] = commit_hash
|
||||
config["versionCode"] = 1000000
|
||||
config["outdir"] = "out"
|
||||
|
||||
stub_parser = subparsers.add_parser("stub", help="build the stub app")
|
||||
stub_parser.set_defaults(func=build_stub)
|
||||
args.config = Path(args.config)
|
||||
|
||||
avd_parser = subparsers.add_parser("emulator", help="setup AVD for development")
|
||||
avd_parser.add_argument(
|
||||
"-s", "--skip", action="store_true", help="skip building binaries and the app"
|
||||
)
|
||||
avd_parser.set_defaults(func=setup_avd)
|
||||
# Load prop files
|
||||
if args.config.exists():
|
||||
config.update(parse_props(args.config))
|
||||
|
||||
avd_patch_parser = subparsers.add_parser(
|
||||
"avd_patch", help="patch AVD ramdisk.img or init_boot.img"
|
||||
)
|
||||
avd_patch_parser.add_argument("image", help="path to ramdisk.img or init_boot.img")
|
||||
avd_patch_parser.add_argument("output", help="optional output file name", nargs="?")
|
||||
avd_patch_parser.add_argument(
|
||||
"-s", "--skip", action="store_true", help="skip building binaries and the app"
|
||||
)
|
||||
avd_patch_parser.set_defaults(func=patch_avd_file)
|
||||
if Path("gradle.properties").exists():
|
||||
for key, value in parse_props("gradle.properties").items():
|
||||
if key.startswith("magisk."):
|
||||
config[key[7:]] = value
|
||||
|
||||
clean_parser = subparsers.add_parser("clean", help="cleanup")
|
||||
clean_parser.add_argument(
|
||||
"targets", nargs="*", help="native, cpp, rust, java, or empty to clean all"
|
||||
)
|
||||
clean_parser.set_defaults(func=cleanup)
|
||||
try:
|
||||
config["versionCode"] = int(config["versionCode"])
|
||||
except ValueError:
|
||||
error('Config error: "versionCode" is required to be an integer')
|
||||
|
||||
ndk_parser = subparsers.add_parser("ndk", help="setup Magisk NDK")
|
||||
ndk_parser.set_defaults(func=setup_ndk)
|
||||
config["outdir"] = Path(config["outdir"])
|
||||
config["outdir"].mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
if "abiList" in config:
|
||||
abiList = re.split("\\s*,\\s*", config["abiList"])
|
||||
archs = set(abiList) & support_abis.keys()
|
||||
else:
|
||||
archs = {"armeabi-v7a", "x86", "arm64-v8a", "x86_64"}
|
||||
|
||||
args = parser.parse_args()
|
||||
load_config(args)
|
||||
triples = map(support_abis.get, archs)
|
||||
|
||||
# Call corresponding functions
|
||||
args.func(args)
|
||||
global build_abis
|
||||
build_abis = dict(zip(archs, triples))
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description="Magisk build script")
|
||||
parser.set_defaults(func=lambda x: None)
|
||||
parser.add_argument(
|
||||
"-r", "--release", action="store_true", help="compile in release mode"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v", "--verbose", action="count", default=0, help="verbose output"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
"--config",
|
||||
default="config.prop",
|
||||
help="custom config file (default: config.prop)",
|
||||
)
|
||||
subparsers = parser.add_subparsers(title="actions")
|
||||
|
||||
all_parser = subparsers.add_parser("all", help="build everything")
|
||||
|
||||
native_parser = subparsers.add_parser("native", help="build native binaries")
|
||||
native_parser.add_argument(
|
||||
"targets",
|
||||
nargs="*",
|
||||
help=f"{', '.join(support_targets)}, \
|
||||
or empty for defaults ({', '.join(default_targets)})",
|
||||
)
|
||||
|
||||
app_parser = subparsers.add_parser("app", help="build the Magisk app")
|
||||
|
||||
stub_parser = subparsers.add_parser("stub", help="build the stub app")
|
||||
|
||||
clean_parser = subparsers.add_parser("clean", help="cleanup")
|
||||
clean_parser.add_argument(
|
||||
"targets", nargs="*", help="native, cpp, rust, java, or empty to clean all"
|
||||
)
|
||||
|
||||
ndk_parser = subparsers.add_parser("ndk", help="setup Magisk NDK")
|
||||
|
||||
emu_parser = subparsers.add_parser("emulator", help="setup AVD for development")
|
||||
emu_parser.add_argument(
|
||||
"-s", "--skip", action="store_true", help="skip building binaries and the app"
|
||||
)
|
||||
|
||||
avd_patch_parser = subparsers.add_parser(
|
||||
"avd_patch", help="patch AVD ramdisk.img or init_boot.img"
|
||||
)
|
||||
avd_patch_parser.add_argument("image", help="path to ramdisk.img or init_boot.img")
|
||||
avd_patch_parser.add_argument("output", help="optional output file name", nargs="?")
|
||||
avd_patch_parser.add_argument(
|
||||
"-s", "--skip", action="store_true", help="skip building binaries and the app"
|
||||
)
|
||||
|
||||
cargo_parser = subparsers.add_parser(
|
||||
"cargo", help="call 'cargo' commands against the project"
|
||||
)
|
||||
cargo_parser.add_argument("commands", nargs=argparse.REMAINDER)
|
||||
|
||||
rustup_parser = subparsers.add_parser("rustup", help="setup rustup wrapper")
|
||||
rustup_parser.add_argument(
|
||||
"wrapper_dir", help="path to setup rustup wrapper binaries"
|
||||
)
|
||||
|
||||
# Set callbacks
|
||||
all_parser.set_defaults(func=build_all)
|
||||
native_parser.set_defaults(func=build_native)
|
||||
cargo_parser.set_defaults(func=cargo_cli)
|
||||
rustup_parser.set_defaults(func=setup_rustup)
|
||||
app_parser.set_defaults(func=build_app)
|
||||
stub_parser.set_defaults(func=build_stub)
|
||||
emu_parser.set_defaults(func=setup_avd)
|
||||
avd_patch_parser.set_defaults(func=patch_avd_file)
|
||||
clean_parser.set_defaults(func=cleanup)
|
||||
ndk_parser.set_defaults(func=setup_ndk)
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
args = parse_args()
|
||||
load_config()
|
||||
vars(args)["force_out"] = False
|
||||
args.func()
|
||||
|
@@ -25,10 +25,10 @@ tasks.withType<KotlinCompile>().configureEach {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(kotlin("gradle-plugin", "2.0.0"))
|
||||
implementation("com.android.tools.build:gradle:8.5.1")
|
||||
implementation("com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:2.0.0-1.0.23")
|
||||
implementation("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.7")
|
||||
implementation("org.lsposed.lsparanoid:gradle-plugin:0.6.0")
|
||||
implementation("org.eclipse.jgit:org.eclipse.jgit:6.10.0.202406032230-r")
|
||||
implementation(kotlin("gradle-plugin", libs.versions.kotlin.get()))
|
||||
implementation(libs.android.gradle.plugin)
|
||||
implementation(libs.ksp.plugin)
|
||||
implementation(libs.navigation.safe.args.plugin)
|
||||
implementation(libs.lsparanoid.plugin)
|
||||
implementation(libs.jgit)
|
||||
}
|
||||
|
7
buildSrc/settings.gradle.kts
Normal file
7
buildSrc/settings.gradle.kts
Normal file
@@ -0,0 +1,7 @@
|
||||
dependencyResolutionManagement {
|
||||
versionCatalogs {
|
||||
create("libs") {
|
||||
from(files("../gradle/libs.versions.toml"))
|
||||
}
|
||||
}
|
||||
}
|
@@ -8,6 +8,8 @@ import java.util.Properties
|
||||
|
||||
private val props = Properties()
|
||||
private var commitHash = ""
|
||||
private val supportAbis = setOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64", "riscv64")
|
||||
private val defaultAbis = setOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64")
|
||||
|
||||
object Config {
|
||||
operator fun get(key: String): String? {
|
||||
@@ -20,6 +22,10 @@ object Config {
|
||||
val version: String get() = get("version") ?: commitHash
|
||||
val versionCode: Int get() = get("magisk.versionCode")!!.toInt()
|
||||
val stubVersion: String get() = get("magisk.stubVersion")!!
|
||||
val abiList: Set<String> get() {
|
||||
val abiList = get("abiList") ?: return defaultAbis
|
||||
return abiList.split(Regex("\\s*,\\s*")).toSet() intersect supportAbis
|
||||
}
|
||||
}
|
||||
|
||||
class MagiskPlugin : Plugin<Project> {
|
||||
|
@@ -72,7 +72,7 @@ fun Project.setupCommon() {
|
||||
compileSdkVersion(34)
|
||||
buildToolsVersion = "34.0.0"
|
||||
ndkPath = "$sdkDirectory/ndk/magisk"
|
||||
ndkVersion = "27.0.11902837"
|
||||
ndkVersion = "27.0.12077973"
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 23
|
||||
@@ -121,9 +121,11 @@ const val BUSYBOX_ZIP_CHECKSUM =
|
||||
fun Project.setupCoreLib() {
|
||||
setupCommon()
|
||||
|
||||
val abiList = Config.abiList
|
||||
|
||||
val syncLibs by tasks.registering(Sync::class) {
|
||||
into("src/main/jniLibs")
|
||||
for (abi in arrayOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64", "riscv64")) {
|
||||
for (abi in abiList) {
|
||||
into(abi) {
|
||||
from(rootProject.file("native/out/$abi")) {
|
||||
include("magiskboot", "magiskinit", "magiskpolicy", "magisk", "libinit-ld.so")
|
||||
@@ -132,7 +134,7 @@ fun Project.setupCoreLib() {
|
||||
}
|
||||
}
|
||||
onlyIf {
|
||||
if (inputs.sourceFiles.files.size != 25)
|
||||
if (inputs.sourceFiles.files.size != abiList.size * 5)
|
||||
throw StopExecutionException("Please build binaries first! (./build.py binary)")
|
||||
true
|
||||
}
|
||||
@@ -158,6 +160,7 @@ fun Project.setupCoreLib() {
|
||||
}
|
||||
}
|
||||
from(zipTree(bb))
|
||||
include(abiList.map { "$it/libbusybox.so" })
|
||||
into("src/main/jniLibs")
|
||||
}
|
||||
|
||||
|
@@ -9,6 +9,10 @@ version=string
|
||||
# Output path. Default: out
|
||||
outdir=string
|
||||
|
||||
# List of ABIs to build, separated with ','
|
||||
# Default: armeabi-v7a,x86,arm64-v8a,x86_64
|
||||
abiList=[string]
|
||||
|
||||
#####################################################
|
||||
# Signing configs for signing zips and APKs
|
||||
# These 4 variables has to be either all set or not
|
||||
|
@@ -30,5 +30,5 @@ android.nonFinalResIds=false
|
||||
|
||||
# Magisk
|
||||
magisk.stubVersion=40
|
||||
magisk.versionCode=27006
|
||||
magisk.ondkVersion=r27.2
|
||||
magisk.versionCode=27007
|
||||
magisk.ondkVersion=r27.4
|
||||
|
65
gradle/libs.versions.toml
Normal file
65
gradle/libs.versions.toml
Normal file
@@ -0,0 +1,65 @@
|
||||
[versions]
|
||||
kotlin = "2.0.10"
|
||||
android = "8.5.2"
|
||||
ksp = "2.0.10-1.0.24"
|
||||
rikka = "1.3.0"
|
||||
navigation = "2.7.7"
|
||||
libsu = "6.0.0"
|
||||
moshi = "1.15.1"
|
||||
okhttp = "4.12.0"
|
||||
retrofit = "2.11.0"
|
||||
room = "2.6.1"
|
||||
|
||||
[libraries]
|
||||
bcpkix = { module = "org.bouncycastle:bcpkix-jdk18on", version = "1.78.1" }
|
||||
commons-compress = { module = "org.apache.commons:commons-compress", version = "1.27.0" }
|
||||
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
|
||||
retrofit-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" }
|
||||
retrofit-scalars = { module = "com.squareup.retrofit2:converter-scalars", version.ref = "retrofit" }
|
||||
markwon-core = { module = "io.noties.markwon:core", version = "4.6.2" }
|
||||
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
||||
okhttp-dnsoverhttps = { module = "com.squareup.okhttp3:okhttp-dnsoverhttps", version.ref = "okhttp" }
|
||||
okhttp-logging = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" }
|
||||
moshi = { module = "com.squareup.moshi:moshi", version.ref = "moshi" }
|
||||
moshi-codegen = { module = "com.squareup.moshi:moshi-kotlin-codegen", version.ref = "moshi" }
|
||||
timber = { module = "com.jakewharton.timber:timber", version = "5.0.1" }
|
||||
jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version = "6.10.0.202406032230-r" }
|
||||
|
||||
# AndroidX
|
||||
activity = { module = "androidx.activity:activity", version = "1.9.1" }
|
||||
appcompat = { module = "androidx.appcompat:appcompat", version = "1.7.0" }
|
||||
core-ktx = { module = "androidx.core:core-ktx", version = "1.13.1" }
|
||||
core-splashscreen = { module = "androidx.core:core-splashscreen", version = "1.0.1" }
|
||||
constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.1.4" }
|
||||
fragment-ktx = { module = "androidx.fragment:fragment-ktx", version = "1.8.2" }
|
||||
navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "navigation" }
|
||||
navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version.ref = "navigation" }
|
||||
profileinstaller = { module = "androidx.profileinstaller:profileinstaller", version = "1.3.1" }
|
||||
recyclerview = { module = "androidx.recyclerview:recyclerview", version = "1.3.2" }
|
||||
room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
|
||||
room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
|
||||
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
|
||||
swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version = "1.1.0" }
|
||||
transition = { module = "androidx.transition:transition", version = "1.5.1" }
|
||||
collection-ktx = { module = "androidx.collection:collection-ktx", version = "1.4.3" }
|
||||
lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version = "2.8.4" }
|
||||
material = { module = "com.google.android.material:material", version = "1.12.0" }
|
||||
|
||||
# topjohnwu
|
||||
indeterminate-checkbox = { module = "com.github.topjohnwu:indeterminate-checkbox", version = "1.0.7" }
|
||||
libsu-core = { module = "com.github.topjohnwu.libsu:core", version.ref = "libsu" }
|
||||
libsu-service = { module = "com.github.topjohnwu.libsu:service", version.ref = "libsu" }
|
||||
libsu-nio = { module = "com.github.topjohnwu.libsu:nio", version.ref = "libsu" }
|
||||
|
||||
# Rikka
|
||||
rikka-recyclerview = { module = "dev.rikka.rikkax.recyclerview:recyclerview-ktx", version = "1.3.2" }
|
||||
rikka-layoutinflater = { module = "dev.rikka.rikkax.layoutinflater:layoutinflater", version.ref = "rikka" }
|
||||
rikka-insets = { module = "dev.rikka.rikkax.insets:insets", version.ref = "rikka" }
|
||||
|
||||
# Build plugins
|
||||
android-gradle-plugin = { module = "com.android.tools.build:gradle", version.ref = "android" }
|
||||
ksp-plugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
|
||||
navigation-safe-args-plugin = { module = "androidx.navigation:navigation-safe-args-gradle-plugin", version.ref = "navigation" }
|
||||
lsparanoid-plugin = { module = "org.lsposed.lsparanoid:gradle-plugin", version = "0.6.0" }
|
||||
|
||||
[plugins]
|
@@ -1,7 +1,10 @@
|
||||
[build]
|
||||
# Choose arm64 as the default target to make the IDE happy.
|
||||
# Set arm64 as the default target
|
||||
# The actual compilation will have the target overriden by command-line.
|
||||
target = "aarch64-linux-android"
|
||||
# Enable cross language LTO, and explicitly set dwarf-version for ThinLTO
|
||||
rustflags = ["-Z", "dwarf-version=4", "-C", "linker-plugin-lto"]
|
||||
target-dir = "../out/rust"
|
||||
|
||||
[unstable]
|
||||
build-std = ["std", "panic_abort"]
|
||||
|
2
native/src/.gitignore
vendored
2
native/src/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
test.cpp
|
||||
target/
|
@@ -1,7 +1,5 @@
|
||||
APP_BUILD_SCRIPT := src/Android.mk
|
||||
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 riscv64
|
||||
APP_CFLAGS := -Wall -Oz -fomit-frame-pointer -flto
|
||||
APP_LDFLAGS := -flto -Wl,--icf=all
|
||||
APP_CFLAGS := -Wall -Oz -fomit-frame-pointer
|
||||
APP_CPPFLAGS := -std=c++23
|
||||
APP_STL := none
|
||||
APP_PLATFORM := android-23
|
||||
@@ -9,11 +7,25 @@ APP_THIN_ARCHIVE := true
|
||||
APP_STRIP_MODE := none
|
||||
APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true
|
||||
|
||||
ifdef MAGISK_DEBUG
|
||||
|
||||
NDK_APP_OUT := ./obj/debug
|
||||
APP_CFLAGS += -flto=thin -gdwarf-4
|
||||
APP_LDFLAGS += -flto=thin
|
||||
|
||||
else
|
||||
|
||||
NDK_APP_OUT := ./obj/release
|
||||
APP_CFLAGS += -flto
|
||||
APP_LDFLAGS += -flto -Wl,--icf=all
|
||||
|
||||
endif
|
||||
|
||||
ifdef B_CRT0
|
||||
|
||||
# Disable all security and debugging features
|
||||
APP_CFLAGS += -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-stack-protector -U_FORTIFY_SOURCE
|
||||
APP_CFLAGS += -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-stack-protector -fno-threadsafe-statics -U_FORTIFY_SOURCE
|
||||
# Override output folder to make sure all dependencies are rebuilt with new CFLAGS
|
||||
NDK_APP_OUT := ./obj/nolibc
|
||||
NDK_APP_OUT := $(NDK_APP_OUT)-nolibc
|
||||
|
||||
endif
|
||||
|
340
native/src/Cargo.lock
generated
340
native/src/Cargo.lock
generated
@@ -32,9 +32,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.2.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "base"
|
||||
@@ -66,27 +66,27 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.11.0-pre.5"
|
||||
version = "0.11.0-rc.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ded684142010808eb980d9974ef794da2bcf97d13396143b1515e9f0fb4a10e"
|
||||
checksum = "17092d478f4fadfb35a7e082f62e49f0907fdf048801d9d706277e34f9df8a78"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.15.0"
|
||||
version = "1.16.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15"
|
||||
checksum = "102087e286b4677862ea56cf8fc58bb2cdfa8725c40ffb80fe3a008eb7f2fc83"
|
||||
dependencies = [
|
||||
"bytemuck_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck_derive"
|
||||
version = "1.6.0"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60"
|
||||
checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -101,9 +101,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.90"
|
||||
version = "1.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
|
||||
checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@@ -123,9 +123,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.10.0-pre.2"
|
||||
version = "0.10.0-rc.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7e3352a27098ba6b09546e5f13b15165e6a88b5c2723afecb3ea9576b27e3ea"
|
||||
checksum = "9adcf94f05e094fca3005698822ec791cb4433ced416afda1c5ca3b8dfc05a2f"
|
||||
|
||||
[[package]]
|
||||
name = "const_format"
|
||||
@@ -158,9 +158,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
version = "0.6.0-pre.12"
|
||||
version = "0.6.0-rc.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1943d7beadd9ce2b25f3bae73b9e9336fccc1edf38bdec1ed58d3aa183989e11"
|
||||
checksum = "e43027691f1c055da3da4f7d96af09fcec420d435d5616e51f29afd0811c56a7"
|
||||
dependencies = [
|
||||
"hybrid-array",
|
||||
"num-traits",
|
||||
@@ -171,9 +171,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.2.0-pre.5"
|
||||
version = "0.2.0-rc.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7aa2ec04f5120b830272a481e8d9d8ba4dda140d2cda59b0f1110d5eb93c38e"
|
||||
checksum = "8c070b79a496dccd931229780ad5bbedd535ceff6c3565605a8e440e18e1aa2b"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"hybrid-array",
|
||||
@@ -182,7 +182,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.115"
|
||||
version = "1.0.124"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cxxbridge-flags",
|
||||
@@ -191,7 +191,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cxx-gen"
|
||||
version = "0.7.115"
|
||||
version = "0.7.124"
|
||||
dependencies = [
|
||||
"codespan-reporting",
|
||||
"proc-macro2",
|
||||
@@ -201,11 +201,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-flags"
|
||||
version = "1.0.115"
|
||||
version = "1.0.124"
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-macro"
|
||||
version = "1.0.115"
|
||||
version = "1.0.124"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -214,9 +214,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.8.0-pre.0"
|
||||
version = "0.8.0-rc.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b489fd2221710c1dd46637d66b984161fb66134f81437a8489800306bcc2ecea"
|
||||
checksum = "05d9c07d3bd80cf0935ce478d07edf7e7a5b158446757f988f3e62082227b700"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"der_derive",
|
||||
@@ -227,9 +227,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "der_derive"
|
||||
version = "0.8.0-pre.0"
|
||||
version = "0.8.0-rc.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd1ee9778ac378876dc78f546d2821fae40a1b69ec8d82f3745392d69ff89ce6"
|
||||
checksum = "2c46c0d3c8dba679a95cc7caf42fe6220338e28c9d7c09e0a458e6f6156c06e7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -238,9 +238,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.11.0-pre.8"
|
||||
version = "0.11.0-pre.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "065d93ead7c220b85d5b4be4795d8398eac4ff68b5ee63895de0a3c1fb6edf25"
|
||||
checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"const-oid",
|
||||
@@ -250,9 +250,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ecdsa"
|
||||
version = "0.17.0-pre.5"
|
||||
version = "0.17.0-pre.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7e045ee5c360512162782f3d4cb07d2f4ce8c4ef9bf7c77ec16d1cf60b3d5ca"
|
||||
checksum = "fad051af2b2d2f356d716138c76775929be913deb5b4ea217cd2613535936bef"
|
||||
dependencies = [
|
||||
"der",
|
||||
"digest",
|
||||
@@ -264,9 +264,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "elliptic-curve"
|
||||
version = "0.14.0-pre.5"
|
||||
version = "0.14.0-pre.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a1775af172997a40c14854c3a9fde9e03e5772084b334b6a0bb18bf7f93ac16"
|
||||
checksum = "4ed8e96bb573517f42470775f8ef1b9cd7595de52ba7a8e19c48325a92c8fe4f"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"crypto-bigint",
|
||||
@@ -301,15 +301,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "flagset"
|
||||
version = "0.4.5"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdeb3aa5e95cf9aabc17f060cfa0ced7b83f042390760ca53bf09df9968acaa1"
|
||||
checksum = "b3ea1ec5f8307826a5b71094dd91fc04d4ae75d5709b20ad351c7fb4815c86ec"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.12"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
@@ -329,27 +329,27 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hkdf"
|
||||
version = "0.13.0-pre.3"
|
||||
version = "0.13.0-pre.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd5d615ab5c462f96c309b3a00b19f373025a4981312f717f9df5bbd0201530c"
|
||||
checksum = "00176ff81091018d42ff82e8324f8e5adb0b7e0468d1358f653972562dbff031"
|
||||
dependencies = [
|
||||
"hmac",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.13.0-pre.3"
|
||||
version = "0.13.0-pre.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffd790a0795ee332ed3e8959e5b177beb70d7112eb7d345428ec17427897d5ce"
|
||||
checksum = "e4b1fb14e4df79f9406b434b60acef9f45c26c50062cccf1346c6103b8c47d58"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hybrid-array"
|
||||
version = "0.2.0-rc.8"
|
||||
version = "0.2.0-rc.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53668f5da5a41d9eaf4bf7064be46d1ebe6a4e1ceed817f387587b18f2b51047"
|
||||
checksum = "4d306b679262030ad8813a82d4915fc04efff97776e4db7f8eb5137039d56400"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"zeroize",
|
||||
@@ -357,18 +357,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
dependencies = [
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
@@ -378,9 +378,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "magisk"
|
||||
@@ -443,9 +443,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.2"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
@@ -502,9 +502,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.44"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9"
|
||||
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
@@ -513,9 +513,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.18"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"libm",
|
||||
@@ -523,8 +523,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "p256"
|
||||
version = "0.14.0-pre.0"
|
||||
source = "git+https://github.com/RustCrypto/elliptic-curves.git?rev=5d1c252c2defb5808f55329f3e2955ca72d7f8b5#5d1c252c2defb5808f55329f3e2955ca72d7f8b5"
|
||||
version = "0.14.0-pre.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c32c18a74d9dda1314d2f945fb3e274848822f63f264a9e4d3f783e29b3bc1f"
|
||||
dependencies = [
|
||||
"ecdsa",
|
||||
"elliptic-curve",
|
||||
@@ -534,8 +535,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "p384"
|
||||
version = "0.14.0-pre"
|
||||
source = "git+https://github.com/RustCrypto/elliptic-curves.git?rev=5d1c252c2defb5808f55329f3e2955ca72d7f8b5#5d1c252c2defb5808f55329f3e2955ca72d7f8b5"
|
||||
version = "0.14.0-pre.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99acc40dbfad9cc3dc102828f5678c8ca14f0cbf3a1f56f74c2875b5a84427af"
|
||||
dependencies = [
|
||||
"ecdsa",
|
||||
"elliptic-curve",
|
||||
@@ -545,8 +547,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "p521"
|
||||
version = "0.14.0-pre"
|
||||
source = "git+https://github.com/RustCrypto/elliptic-curves.git?rev=5d1c252c2defb5808f55329f3e2955ca72d7f8b5#5d1c252c2defb5808f55329f3e2955ca72d7f8b5"
|
||||
version = "0.14.0-pre.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ec5d919bea930a34a522bb1c95a89f559925deab255db2c2ffa174fc48df664"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"ecdsa",
|
||||
@@ -568,18 +571,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pem-rfc7468"
|
||||
version = "1.0.0-pre.0"
|
||||
version = "1.0.0-rc.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76a65e1c27d1680f8805b3f8c9949f08d6aa5d6cbd088c9896e64a53821dc27d"
|
||||
checksum = "b6c1cde4770761bf6bd336f947b9ac1fe700b0a4ec5867cf66cf08597fe89e8c"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs1"
|
||||
version = "0.8.0-pre.0"
|
||||
version = "0.8.0-rc.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f6af6e88ac39402f67488e22faa9eb15cf065f520cf4a09419393691a6d0133"
|
||||
checksum = "0d2f4c73d459a85331915baebd5082dce5ee8ef16fd9a1ca75559ac91e66a9ee"
|
||||
dependencies = [
|
||||
"der",
|
||||
"pkcs8",
|
||||
@@ -588,9 +591,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pkcs8"
|
||||
version = "0.11.0-pre.0"
|
||||
version = "0.11.0-rc.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "935c09e0aecb0cb8f8907b57438b19a068cb74a25189b06724f061170b2465ff"
|
||||
checksum = "66180445f1dce533620a7743467ef85fe1c5e80cdaf7c7053609d7a2fbcdae20"
|
||||
dependencies = [
|
||||
"der",
|
||||
"spki",
|
||||
@@ -598,28 +601,33 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "primefield"
|
||||
version = "0.14.0-pre"
|
||||
source = "git+https://github.com/RustCrypto/elliptic-curves.git?rev=5d1c252c2defb5808f55329f3e2955ca72d7f8b5#5d1c252c2defb5808f55329f3e2955ca72d7f8b5"
|
||||
version = "0.14.0-pre.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3f2ce0fa9cccdaf216230d151ce51a15298aef50ad76081a830128ecbc6428a"
|
||||
|
||||
[[package]]
|
||||
name = "primeorder"
|
||||
version = "0.14.0-pre.0"
|
||||
source = "git+https://github.com/RustCrypto/elliptic-curves.git?rev=5d1c252c2defb5808f55329f3e2955ca72d7f8b5#5d1c252c2defb5808f55329f3e2955ca72d7f8b5"
|
||||
version = "0.14.0-pre.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9bed0c431186675ad845922b903d28c7faa2b634a6d130fb7b50bb289f5a4d52"
|
||||
dependencies = [
|
||||
"elliptic-curve",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.79"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -634,9 +642,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -672,9 +680,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rfc6979"
|
||||
version = "0.5.0-pre.3"
|
||||
version = "0.5.0-pre.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "045972f2f66b9467a2f6834b7fd0f9b23ca214b4a8700b880c36edb726e96da6"
|
||||
checksum = "871ee76a3eee98b0f805e5d1caf26929f4565073c580c053a55f886fc15dea49"
|
||||
dependencies = [
|
||||
"hmac",
|
||||
"subtle",
|
||||
@@ -682,9 +690,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rsa"
|
||||
version = "0.10.0-pre.1"
|
||||
version = "0.10.0-pre.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43e0089f12e510517c97e1adc17d0f8374efbabdd021dfb7645d6619f85633e9"
|
||||
checksum = "57e864e43f5d003321ab452feea6450f9611d7be6726489b4ec051da34774c62"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"digest",
|
||||
@@ -703,9 +711,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sec1"
|
||||
version = "0.8.0-pre.1"
|
||||
version = "0.8.0-rc.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02dc081ed777a3bab68583b52ffb8221677b6e90d483b320963a247e2c07f328"
|
||||
checksum = "32c98827dc6ed0ea1707286a3d14b4ad4e25e2643169cbf111568a46ff5b09f5"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"der",
|
||||
@@ -717,18 +725,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.197"
|
||||
version = "1.0.204"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.197"
|
||||
version = "1.0.204"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -737,9 +745,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.11.0-pre.3"
|
||||
version = "0.11.0-pre.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3885de8cb916f223718c1ccd47a840b91f806333e76002dc5cb3862154b4fed3"
|
||||
checksum = "9540978cef7a8498211c1b1c14e5ce920fe5bd524ea84f4a3d72d4602515ae93"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
@@ -748,9 +756,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.11.0-pre.3"
|
||||
version = "0.11.0-pre.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f33549bf3064b62478926aa89cbfc7c109aab66ae8f0d5d2ef839e482cc30d6"
|
||||
checksum = "540c0893cce56cdbcfebcec191ec8e0f470dd1889b6e7a0b503e310a94a168f5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
@@ -759,9 +767,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "2.3.0-pre.3"
|
||||
version = "2.3.0-pre.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1700c22ba9ce32c7b0a1495068a906c3552e7db386af7cf865162e0dea498523"
|
||||
checksum = "054d71959c7051b9042c26af337f05cc930575ed2604d7d3ced3158383e59734"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"rand_core",
|
||||
@@ -781,15 +789,15 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
|
||||
[[package]]
|
||||
name = "spki"
|
||||
version = "0.8.0-pre.0"
|
||||
version = "0.8.0-rc.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb2b56670f5ef52934c97efad30bf42585de0c33ec3e2a886e38b80d2db67243"
|
||||
checksum = "ee3fb1c675852398475928637b3ebbdd7e1d0cc24d27b3bbc81788b4eb51e310"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"der",
|
||||
@@ -797,15 +805,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.5.0"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.58"
|
||||
version = "2.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
|
||||
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -823,18 +831,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.58"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
|
||||
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.58"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -876,9 +884,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
@@ -892,41 +900,92 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.6"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "x509-cert"
|
||||
version = "0.3.0-pre"
|
||||
source = "git+https://github.com/RustCrypto/formats.git?rev=809df65b20d61e88afb7f514b5cfdd3d1958a40f#809df65b20d61e88afb7f514b5cfdd3d1958a40f"
|
||||
source = "git+https://github.com/RustCrypto/formats.git?rev=9c0e851c6db9c2c8a2601840d46375afde2663fb#9c0e851c6db9c2c8a2601840d46375afde2663fb"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"der",
|
||||
@@ -935,10 +994,31 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.7.0"
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
|
||||
dependencies = [
|
||||
"zeroize_derive",
|
||||
]
|
||||
|
@@ -13,16 +13,16 @@ num-derive = "0.4"
|
||||
thiserror = "1.0"
|
||||
byteorder = "1"
|
||||
size = "0.4"
|
||||
sha1 = "0.11.0-pre.3"
|
||||
sha2 = "=0.11.0-pre.3"
|
||||
digest = "0.11.0-pre.8"
|
||||
#p256 = "0.14"
|
||||
#p384 = "0.14"
|
||||
#p521 = "0.14"
|
||||
rsa = "0.10.0-pre.1"
|
||||
sha1 = "0.11.0-pre.4"
|
||||
sha2 = "=0.11.0-pre.4"
|
||||
digest = "0.11.0-pre.9"
|
||||
p256 = "0.14.0-pre.1"
|
||||
p384 = "0.14.0-pre.1"
|
||||
p521 = "0.14.0-pre.1"
|
||||
rsa = "0.10.0-pre.2"
|
||||
#x509-cert = "0.3"
|
||||
der = "0.8.0-pre.0"
|
||||
bytemuck = "1.14"
|
||||
der = "0.8.0-rc.0"
|
||||
bytemuck = "1.16"
|
||||
fdt = "0.1"
|
||||
const_format = "0.2"
|
||||
|
||||
@@ -40,29 +40,17 @@ default-features = false
|
||||
git = "https://github.com/tafia/quick-protobuf.git"
|
||||
rev = "2f37d5a65504de7d716b5b28fd82219501a901a9"
|
||||
|
||||
[workspace.dependencies.p256]
|
||||
git = "https://github.com/RustCrypto/elliptic-curves.git"
|
||||
rev = "5d1c252c2defb5808f55329f3e2955ca72d7f8b5"
|
||||
|
||||
[workspace.dependencies.p384]
|
||||
git = "https://github.com/RustCrypto/elliptic-curves.git"
|
||||
rev = "5d1c252c2defb5808f55329f3e2955ca72d7f8b5"
|
||||
|
||||
[workspace.dependencies.p521]
|
||||
git = "https://github.com/RustCrypto/elliptic-curves.git"
|
||||
rev = "5d1c252c2defb5808f55329f3e2955ca72d7f8b5"
|
||||
|
||||
[workspace.dependencies.x509-cert]
|
||||
git = "https://github.com/RustCrypto/formats.git"
|
||||
rev = "809df65b20d61e88afb7f514b5cfdd3d1958a40f"
|
||||
rev = "9c0e851c6db9c2c8a2601840d46375afde2663fb"
|
||||
|
||||
[profile.dev]
|
||||
opt-level = "z"
|
||||
lto = true
|
||||
lto = "thin"
|
||||
panic = "abort"
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z"
|
||||
lto = true
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
||||
panic = "abort"
|
||||
|
@@ -108,7 +108,7 @@ impl StringExt for String {
|
||||
fn nul_terminate(&mut self) -> &mut [u8] {
|
||||
self.reserve(1);
|
||||
// SAFETY: the string is reserved to have enough capacity to fit in the null byte
|
||||
// SAFETY: the null byte is explicitly added outside of the string's length
|
||||
// SAFETY: the null byte is explicitly added outside the string's length
|
||||
unsafe {
|
||||
let buf = slice::from_raw_parts_mut(self.as_mut_ptr(), self.len() + 1);
|
||||
*buf.get_unchecked_mut(self.len()) = b'\0';
|
||||
@@ -122,7 +122,7 @@ impl StringExt for PathBuf {
|
||||
fn nul_terminate(&mut self) -> &mut [u8] {
|
||||
self.reserve(1);
|
||||
// SAFETY: the PathBuf is reserved to have enough capacity to fit in the null byte
|
||||
// SAFETY: the null byte is explicitly added outside of the PathBuf's length
|
||||
// SAFETY: the null byte is explicitly added outside the PathBuf's length
|
||||
unsafe {
|
||||
let bytes: &mut [u8] = mem::transmute(self.as_mut_os_str().as_bytes());
|
||||
let buf = slice::from_raw_parts_mut(bytes.as_mut_ptr(), bytes.len() + 1);
|
||||
@@ -314,7 +314,7 @@ impl Utf8CStr {
|
||||
CStr::from_bytes_with_nul(buf)?;
|
||||
str::from_utf8(buf)?;
|
||||
// Both condition checked
|
||||
unsafe { Ok(mem::transmute(buf)) }
|
||||
unsafe { Ok(mem::transmute::<&mut [u8], &mut Utf8CStr>(buf)) }
|
||||
}
|
||||
|
||||
pub fn from_string(s: &mut String) -> &mut Utf8CStr {
|
||||
|
@@ -4,9 +4,9 @@ use std::io;
|
||||
use std::os::fd::{BorrowedFd, OwnedFd, RawFd};
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use cxx::private::c_char;
|
||||
use libc::mode_t;
|
||||
use libc::{c_char, mode_t};
|
||||
|
||||
use crate::files::map_file_at;
|
||||
pub(crate) use crate::xwrap::*;
|
||||
use crate::{
|
||||
clone_attr, cstr, fclone_attr, fd_path, map_fd, map_file, slice_from_ptr, CxxResultExt,
|
||||
@@ -61,6 +61,14 @@ pub(crate) fn map_file_for_cxx(path: &Utf8CStr, rw: bool) -> &'static mut [u8] {
|
||||
map_file(path, rw).log_cxx().unwrap_or(&mut [])
|
||||
}
|
||||
|
||||
pub(crate) fn map_file_at_for_cxx(fd: RawFd, path: &Utf8CStr, rw: bool) -> &'static mut [u8] {
|
||||
unsafe {
|
||||
map_file_at(BorrowedFd::borrow_raw(fd), path, rw)
|
||||
.log_cxx()
|
||||
.unwrap_or(&mut [])
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_fd_for_cxx(fd: RawFd, sz: usize, rw: bool) -> &'static mut [u8] {
|
||||
unsafe {
|
||||
map_fd(BorrowedFd::borrow_raw(fd), sz, rw)
|
||||
|
@@ -117,6 +117,14 @@ mmap_data::mmap_data(const char *name, bool rw) {
|
||||
}
|
||||
}
|
||||
|
||||
mmap_data::mmap_data(int dirfd, const char *name, bool rw) {
|
||||
auto slice = rust::map_file_at(dirfd, name, rw);
|
||||
if (!slice.empty()) {
|
||||
_buf = slice.data();
|
||||
_sz = slice.size();
|
||||
}
|
||||
}
|
||||
|
||||
mmap_data::mmap_data(int fd, size_t sz, bool rw) {
|
||||
auto slice = rust::map_fd(fd, sz, rw);
|
||||
if (!slice.empty()) {
|
||||
|
@@ -26,6 +26,7 @@ struct mmap_data : public byte_data {
|
||||
ALLOW_MOVE_ONLY(mmap_data)
|
||||
|
||||
explicit mmap_data(const char *name, bool rw = false);
|
||||
mmap_data(int dirfd, const char *name, bool rw = false);
|
||||
mmap_data(int fd, size_t sz, bool rw = false);
|
||||
~mmap_data();
|
||||
};
|
||||
@@ -36,11 +37,11 @@ int mkdirs(const char *path, mode_t mode);
|
||||
ssize_t canonical_path(const char * __restrict__ path, char * __restrict__ buf, size_t bufsiz);
|
||||
bool rm_rf(const char *path);
|
||||
bool frm_rf(int dirfd);
|
||||
void cp_afc(const char *src, const char *dest);
|
||||
void mv_path(const char *src, const char *dest);
|
||||
void link_path(const char *src, const char *dest);
|
||||
void clone_attr(const char *src, const char *dest);
|
||||
void fclone_attr(int src, int dest);
|
||||
bool cp_afc(const char *src, const char *dest);
|
||||
bool mv_path(const char *src, const char *dest);
|
||||
bool link_path(const char *src, const char *dest);
|
||||
bool clone_attr(const char *src, const char *dest);
|
||||
bool fclone_attr(int src, int dest);
|
||||
|
||||
} // extern "C"
|
||||
|
||||
|
@@ -856,6 +856,14 @@ impl MappedFile {
|
||||
Ok(MappedFile(map_file(path, true)?))
|
||||
}
|
||||
|
||||
pub fn openat<T: AsFd>(dir: &T, path: &Utf8CStr) -> io::Result<MappedFile> {
|
||||
Ok(MappedFile(map_file_at(dir.as_fd(), path, false)?))
|
||||
}
|
||||
|
||||
pub fn openat_rw<T: AsFd>(dir: &T, path: &Utf8CStr) -> io::Result<MappedFile> {
|
||||
Ok(MappedFile(map_file_at(dir.as_fd(), path, true)?))
|
||||
}
|
||||
|
||||
pub fn create(fd: BorrowedFd, sz: usize, rw: bool) -> io::Result<MappedFile> {
|
||||
Ok(MappedFile(map_fd(fd, sz, rw)?))
|
||||
}
|
||||
@@ -888,6 +896,14 @@ extern "C" {
|
||||
|
||||
// We mark the returned slice static because it is valid until explicitly unmapped
|
||||
pub(crate) fn map_file(path: &Utf8CStr, rw: bool) -> io::Result<&'static mut [u8]> {
|
||||
unsafe { map_file_at(BorrowedFd::borrow_raw(libc::AT_FDCWD), path, rw) }
|
||||
}
|
||||
|
||||
pub(crate) fn map_file_at(
|
||||
dirfd: BorrowedFd,
|
||||
path: &Utf8CStr,
|
||||
rw: bool,
|
||||
) -> io::Result<&'static mut [u8]> {
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const BLKGETSIZE64: u32 = 0x80081272;
|
||||
|
||||
@@ -895,18 +911,22 @@ pub(crate) fn map_file(path: &Utf8CStr, rw: bool) -> io::Result<&'static mut [u8
|
||||
const BLKGETSIZE64: u32 = 0x80041272;
|
||||
|
||||
let flag = if rw { O_RDWR } else { O_RDONLY };
|
||||
let file = FsPath::from(path).open(flag | O_CLOEXEC)?;
|
||||
let fd = unsafe {
|
||||
OwnedFd::from_raw_fd(
|
||||
libc::openat(dirfd.as_raw_fd(), path.as_ptr(), flag | O_CLOEXEC).check_os_err()?,
|
||||
)
|
||||
};
|
||||
|
||||
let attr = fd_get_attr(file.as_raw_fd())?;
|
||||
let attr = fd_get_attr(fd.as_raw_fd())?;
|
||||
let sz = if attr.is_block_device() {
|
||||
let mut sz = 0_u64;
|
||||
unsafe { ioctl(file.as_raw_fd(), BLKGETSIZE64, &mut sz) }.as_os_err()?;
|
||||
unsafe { ioctl(fd.as_raw_fd(), BLKGETSIZE64, &mut sz) }.as_os_err()?;
|
||||
sz
|
||||
} else {
|
||||
attr.st.st_size as u64
|
||||
};
|
||||
|
||||
map_fd(file.as_fd(), sz as usize, rw)
|
||||
map_fd(fd.as_fd(), sz as usize, rw)
|
||||
}
|
||||
|
||||
pub(crate) fn map_fd(fd: BorrowedFd, sz: usize, rw: bool) -> io::Result<&'static mut [u8]> {
|
||||
|
@@ -61,6 +61,8 @@ pub mod ffi {
|
||||
fn fd_path_for_cxx(fd: i32, buf: &mut [u8]) -> isize;
|
||||
#[cxx_name = "map_file"]
|
||||
fn map_file_for_cxx(path: Utf8CStrRef, rw: bool) -> &'static mut [u8];
|
||||
#[cxx_name = "map_file_at"]
|
||||
fn map_file_at_for_cxx(fd: i32, path: Utf8CStrRef, rw: bool) -> &'static mut [u8];
|
||||
#[cxx_name = "map_fd"]
|
||||
fn map_fd_for_cxx(fd: i32, sz: usize, rw: bool) -> &'static mut [u8];
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#include <bit>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
|
||||
#include <base.hpp>
|
||||
|
||||
@@ -61,6 +62,8 @@ void dyn_img_hdr::print() const {
|
||||
fprintf(stderr, "%-*s [%u]\n", PADDING, "RECOV_DTBO_SZ", recovery_dtbo_size());
|
||||
if (ver == 2 || is_vendor())
|
||||
fprintf(stderr, "%-*s [%u]\n", PADDING, "DTB_SZ", dtb_size());
|
||||
if (ver == 4 && is_vendor())
|
||||
fprintf(stderr, "%-*s [%u]\n", PADDING, "BOOTCONFIG_SZ", bootconfig_size());
|
||||
|
||||
if (uint32_t os_ver = os_version()) {
|
||||
int a,b,c,y,m = 0;
|
||||
@@ -273,8 +276,7 @@ static format_t check_fmt_lg(const uint8_t *buf, unsigned sz) {
|
||||
|
||||
#define CMD_MATCH(s) BUFFER_MATCH(h->cmdline, s)
|
||||
|
||||
const pair<const uint8_t *, dyn_img_hdr *>
|
||||
boot_img::create_hdr(const uint8_t *addr, format_t type) {
|
||||
pair<const uint8_t *, dyn_img_hdr *> boot_img::create_hdr(const uint8_t *addr, format_t type) {
|
||||
if (type == AOSP_VENDOR) {
|
||||
fprintf(stderr, "VENDOR_BOOT_HDR\n");
|
||||
auto h = reinterpret_cast<const boot_img_hdr_vnd_v3*>(addr);
|
||||
@@ -346,10 +348,23 @@ const pair<const uint8_t *, dyn_img_hdr *>
|
||||
addr += ACCLAIM_PRE_HEADER_SZ;
|
||||
}
|
||||
|
||||
// addr could be adjusted
|
||||
return make_pair(addr, make_hdr(addr));
|
||||
}
|
||||
|
||||
static const char *vendor_ramdisk_type(int type) {
|
||||
switch (type) {
|
||||
case VENDOR_RAMDISK_TYPE_PLATFORM:
|
||||
return "platform";
|
||||
case VENDOR_RAMDISK_TYPE_RECOVERY:
|
||||
return "recovery";
|
||||
case VENDOR_RAMDISK_TYPE_DLKM:
|
||||
return "dlkm";
|
||||
case VENDOR_RAMDISK_TYPE_NONE:
|
||||
default:
|
||||
return "none";
|
||||
}
|
||||
}
|
||||
|
||||
#define assert_off() \
|
||||
if ((base_addr + off) > (map.buf() + map.sz())) { \
|
||||
fprintf(stderr, "Corrupted boot image!\n"); \
|
||||
@@ -362,14 +377,6 @@ off += hdr->name##_size(); \
|
||||
off = align_to(off, hdr->page_size()); \
|
||||
assert_off();
|
||||
|
||||
#define get_ignore(name) \
|
||||
if (hdr->name##_size()) { \
|
||||
auto blk_sz = align_to(hdr->name##_size(), hdr->page_size()); \
|
||||
off += blk_sz; \
|
||||
} \
|
||||
assert_off();
|
||||
|
||||
|
||||
bool boot_img::parse_image(const uint8_t *p, format_t type) {
|
||||
auto [base_addr, hdr] = create_hdr(p, type);
|
||||
if (hdr == nullptr) {
|
||||
@@ -395,15 +402,12 @@ bool boot_img::parse_image(const uint8_t *p, format_t type) {
|
||||
get_block(extra);
|
||||
get_block(recovery_dtbo);
|
||||
get_block(dtb);
|
||||
|
||||
auto ignore_addr = base_addr + off;
|
||||
get_ignore(signature)
|
||||
get_ignore(vendor_ramdisk_table)
|
||||
get_ignore(bootconfig)
|
||||
get_block(signature);
|
||||
get_block(vendor_ramdisk_table);
|
||||
get_block(bootconfig);
|
||||
|
||||
payload = byte_view(base_addr, off);
|
||||
auto tail_addr = base_addr + off;
|
||||
ignore = byte_view(ignore_addr, tail_addr - ignore_addr);
|
||||
tail = byte_view(tail_addr, map.buf() + map.sz() - tail_addr);
|
||||
|
||||
if (auto size = hdr->kernel_size()) {
|
||||
@@ -458,24 +462,40 @@ bool boot_img::parse_image(const uint8_t *p, format_t type) {
|
||||
fprintf(stderr, "%-*s [%s]\n", PADDING, "KERNEL_FMT", fmt2name[k_fmt]);
|
||||
}
|
||||
if (auto size = hdr->ramdisk_size()) {
|
||||
if (hdr->is_vendor() && hdr->header_version() >= 4) {
|
||||
if (hdr->vendor_ramdisk_table_size()) {
|
||||
// v4 vendor boot contains multiple ramdisks
|
||||
// Do not try to mess with it for now
|
||||
r_fmt = UNKNOWN;
|
||||
using table_entry = const vendor_ramdisk_table_entry_v4;
|
||||
if (hdr->vendor_ramdisk_table_entry_size() != sizeof(table_entry)) {
|
||||
fprintf(stderr,
|
||||
"! Invalid vendor image: vendor_ramdisk_table_entry_size != %zu\n",
|
||||
sizeof(table_entry));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
span<table_entry> table(
|
||||
reinterpret_cast<table_entry *>(vendor_ramdisk_table),
|
||||
hdr->vendor_ramdisk_table_entry_num());
|
||||
for (auto &it : table) {
|
||||
format_t fmt = check_fmt_lg(ramdisk + it.ramdisk_offset, it.ramdisk_size);
|
||||
fprintf(stderr,
|
||||
"%-*s name=[%s] type=[%s] size=[%u] fmt=[%s]\n", PADDING, "VND_RAMDISK",
|
||||
it.ramdisk_name, vendor_ramdisk_type(it.ramdisk_type),
|
||||
it.ramdisk_size, fmt2name[fmt]);
|
||||
}
|
||||
} else {
|
||||
r_fmt = check_fmt_lg(ramdisk, size);
|
||||
if (r_fmt == MTK) {
|
||||
fprintf(stderr, "MTK_RAMDISK_HDR\n");
|
||||
flags[MTK_RAMDISK] = true;
|
||||
r_hdr = reinterpret_cast<const mtk_hdr *>(ramdisk);
|
||||
fprintf(stderr, "%-*s [%u]\n", PADDING, "SIZE", r_hdr->size);
|
||||
fprintf(stderr, "%-*s [%s]\n", PADDING, "NAME", r_hdr->name);
|
||||
ramdisk += sizeof(mtk_hdr);
|
||||
hdr->ramdisk_size() -= sizeof(mtk_hdr);
|
||||
r_fmt = check_fmt_lg(ramdisk, hdr->ramdisk_size());
|
||||
}
|
||||
fprintf(stderr, "%-*s [%s]\n", PADDING, "RAMDISK_FMT", fmt2name[r_fmt]);
|
||||
}
|
||||
if (r_fmt == MTK) {
|
||||
fprintf(stderr, "MTK_RAMDISK_HDR\n");
|
||||
flags[MTK_RAMDISK] = true;
|
||||
r_hdr = reinterpret_cast<const mtk_hdr *>(ramdisk);
|
||||
fprintf(stderr, "%-*s [%u]\n", PADDING, "SIZE", r_hdr->size);
|
||||
fprintf(stderr, "%-*s [%s]\n", PADDING, "NAME", r_hdr->name);
|
||||
ramdisk += sizeof(mtk_hdr);
|
||||
hdr->ramdisk_size() -= sizeof(mtk_hdr);
|
||||
r_fmt = check_fmt_lg(ramdisk, hdr->ramdisk_size());
|
||||
}
|
||||
fprintf(stderr, "%-*s [%s]\n", PADDING, "RAMDISK_FMT", fmt2name[r_fmt]);
|
||||
}
|
||||
if (auto size = hdr->extra_size()) {
|
||||
e_fmt = check_fmt_lg(extra, size);
|
||||
@@ -561,7 +581,30 @@ int unpack(const char *image, bool skip_decomp, bool hdr) {
|
||||
dump(boot.kernel_dtb.buf(), boot.kernel_dtb.sz(), KER_DTB_FILE);
|
||||
|
||||
// Dump ramdisk
|
||||
if (!skip_decomp && COMPRESSED(boot.r_fmt)) {
|
||||
if (boot.hdr->vendor_ramdisk_table_size()) {
|
||||
using table_entry = const vendor_ramdisk_table_entry_v4;
|
||||
span<table_entry> table(
|
||||
reinterpret_cast<table_entry *>(boot.vendor_ramdisk_table),
|
||||
boot.hdr->vendor_ramdisk_table_entry_num());
|
||||
|
||||
xmkdir(VND_RAMDISK_DIR, 0755);
|
||||
owned_fd dirfd = xopen(VND_RAMDISK_DIR, O_RDONLY | O_CLOEXEC);
|
||||
for (auto &it : table) {
|
||||
char file_name[40];
|
||||
if (it.ramdisk_name[0] == '\0') {
|
||||
strscpy(file_name, RAMDISK_FILE, sizeof(file_name));
|
||||
} else {
|
||||
ssprintf(file_name, sizeof(file_name), "%s.cpio", it.ramdisk_name);
|
||||
}
|
||||
owned_fd fd = xopenat(dirfd, file_name, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
|
||||
format_t fmt = check_fmt_lg(boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
|
||||
if (!skip_decomp && COMPRESSED(fmt)) {
|
||||
decompress(fmt, fd, boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
|
||||
} else {
|
||||
xwrite(fd, boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
|
||||
}
|
||||
}
|
||||
} else if (!skip_decomp && COMPRESSED(boot.r_fmt)) {
|
||||
if (boot.hdr->ramdisk_size() != 0) {
|
||||
int fd = creat(RAMDISK_FILE, 0644);
|
||||
decompress(boot.r_fmt, fd, boot.ramdisk, boot.hdr->ramdisk_size());
|
||||
@@ -591,6 +634,9 @@ int unpack(const char *image, bool skip_decomp, bool hdr) {
|
||||
// Dump dtb
|
||||
dump(boot.dtb, boot.hdr->dtb_size(), DTB_FILE);
|
||||
|
||||
// Dump bootconfig
|
||||
dump(boot.bootconfig, boot.hdr->bootconfig_size(), BOOTCONFIG_FILE);
|
||||
|
||||
return boot.flags[CHROMEOS_FLAG] ? 2 : 0;
|
||||
}
|
||||
|
||||
@@ -620,6 +666,7 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
hdr->ramdisk_size() = 0;
|
||||
hdr->second_size() = 0;
|
||||
hdr->dtb_size() = 0;
|
||||
hdr->bootconfig_size() = 0;
|
||||
|
||||
if (access(HEADER_FILE, R_OK) == 0)
|
||||
hdr->load_hdr_file();
|
||||
@@ -703,7 +750,40 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
// Copy MTK headers
|
||||
xwrite(fd, boot.r_hdr, sizeof(mtk_hdr));
|
||||
}
|
||||
if (access(RAMDISK_FILE, R_OK) == 0) {
|
||||
|
||||
using table_entry = vendor_ramdisk_table_entry_v4;
|
||||
vector<table_entry> ramdisk_table;
|
||||
|
||||
if (boot.hdr->vendor_ramdisk_table_size()) {
|
||||
// Create a copy so we can modify it
|
||||
auto entry_start = reinterpret_cast<const table_entry *>(boot.vendor_ramdisk_table);
|
||||
ramdisk_table.insert(
|
||||
ramdisk_table.begin(),
|
||||
entry_start, entry_start + boot.hdr->vendor_ramdisk_table_entry_num());
|
||||
|
||||
owned_fd dirfd = xopen(VND_RAMDISK_DIR, O_RDONLY | O_CLOEXEC);
|
||||
uint32_t ramdisk_offset = 0;
|
||||
for (auto &it : ramdisk_table) {
|
||||
char file_name[64];
|
||||
if (it.ramdisk_name[0] == '\0') {
|
||||
strscpy(file_name, RAMDISK_FILE, sizeof(file_name));
|
||||
} else {
|
||||
ssprintf(file_name, sizeof(file_name), "%s.cpio", it.ramdisk_name);
|
||||
}
|
||||
mmap_data m(dirfd, file_name);
|
||||
format_t fmt = check_fmt_lg(boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
|
||||
it.ramdisk_offset = ramdisk_offset;
|
||||
if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf(), m.sz())) && COMPRESSED(fmt)) {
|
||||
it.ramdisk_size = compress(fmt, fd, m.buf(), m.sz());
|
||||
} else {
|
||||
it.ramdisk_size = xwrite(fd, m.buf(), m.sz());
|
||||
}
|
||||
ramdisk_offset += it.ramdisk_size;
|
||||
}
|
||||
|
||||
hdr->ramdisk_size() = ramdisk_offset;
|
||||
file_align();
|
||||
} else if (access(RAMDISK_FILE, R_OK) == 0) {
|
||||
mmap_data m(RAMDISK_FILE);
|
||||
auto r_fmt = boot.r_fmt;
|
||||
if (!skip_comp && !hdr->is_vendor() && hdr->header_version() == 4 && r_fmt != LZ4_LEGACY) {
|
||||
@@ -754,10 +834,22 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
file_align();
|
||||
}
|
||||
|
||||
// Directly copy ignored blobs
|
||||
if (boot.ignore.sz()) {
|
||||
// ignore.sz() should already be aligned
|
||||
xwrite(fd, boot.ignore.buf(), boot.ignore.sz());
|
||||
// Copy boot signature
|
||||
if (boot.hdr->signature_size()) {
|
||||
xwrite(fd, boot.signature, boot.hdr->signature_size());
|
||||
file_align();
|
||||
}
|
||||
|
||||
// vendor ramdisk table
|
||||
if (!ramdisk_table.empty()) {
|
||||
xwrite(fd, ramdisk_table.data(), sizeof(table_entry) * ramdisk_table.size());
|
||||
file_align();
|
||||
}
|
||||
|
||||
// bootconfig
|
||||
if (access(BOOTCONFIG_FILE, R_OK) == 0) {
|
||||
hdr->bootconfig_size() = restore(fd, BOOTCONFIG_FILE);
|
||||
file_align();
|
||||
}
|
||||
|
||||
// Proprietary stuffs
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <bitset>
|
||||
#include <cxx.h>
|
||||
@@ -111,15 +111,21 @@ struct AvbVBMetaImageHeader {
|
||||
#define VENDOR_RAMDISK_NAME_SIZE 32
|
||||
#define VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE 16
|
||||
|
||||
/* When the boot image header has a version of 0 - 2, the structure of the boot
|
||||
#define VENDOR_RAMDISK_TYPE_NONE 0
|
||||
#define VENDOR_RAMDISK_TYPE_PLATFORM 1
|
||||
#define VENDOR_RAMDISK_TYPE_RECOVERY 2
|
||||
#define VENDOR_RAMDISK_TYPE_DLKM 3
|
||||
|
||||
/*
|
||||
* When the boot image header has a version of 0 - 2, the structure of the boot
|
||||
* image is as follows:
|
||||
*
|
||||
* +-----------------+
|
||||
* | boot header | 1 page
|
||||
* +-----------------+
|
||||
* | kernel | n pages
|
||||
* | kernel | m pages
|
||||
* +-----------------+
|
||||
* | ramdisk | m pages
|
||||
* | ramdisk | n pages
|
||||
* +-----------------+
|
||||
* | second stage | o pages
|
||||
* +-----------------+
|
||||
@@ -130,8 +136,8 @@ struct AvbVBMetaImageHeader {
|
||||
* | dtb | q pages
|
||||
* +-----------------+
|
||||
*
|
||||
* n = (kernel_size + page_size - 1) / page_size
|
||||
* m = (ramdisk_size + page_size - 1) / page_size
|
||||
* m = (kernel_size + page_size - 1) / page_size
|
||||
* n = (ramdisk_size + page_size - 1) / page_size
|
||||
* o = (second_size + page_size - 1) / page_size
|
||||
* p = (recovery_dtbo_size + page_size - 1) / page_size
|
||||
* q = (dtb_size + page_size - 1) / page_size
|
||||
@@ -211,7 +217,8 @@ struct boot_img_hdr_pxa : public boot_img_hdr_v0_common {
|
||||
char extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* When the boot image header has a version of 3 - 4, the structure of the boot
|
||||
/*
|
||||
* When the boot image header has a version of 3 - 4, the structure of the boot
|
||||
* image is as follows:
|
||||
*
|
||||
* +---------------------+
|
||||
@@ -329,7 +336,7 @@ struct vendor_ramdisk_table_entry_v4 {
|
||||
uint32_t ramdisk_size; /* size in bytes for the ramdisk image */
|
||||
uint32_t ramdisk_offset; /* offset to the ramdisk image in vendor ramdisk section */
|
||||
uint32_t ramdisk_type; /* type of the ramdisk */
|
||||
uint8_t ramdisk_name[VENDOR_RAMDISK_NAME_SIZE]; /* asciiz ramdisk name */
|
||||
char ramdisk_name[VENDOR_RAMDISK_NAME_SIZE]; /* asciiz ramdisk name */
|
||||
|
||||
// Hardware identifiers describing the board, soc or platform which this
|
||||
// ramdisk is intended to be loaded on.
|
||||
@@ -376,8 +383,12 @@ struct dyn_img_hdr {
|
||||
|
||||
// v4 specific
|
||||
decl_val(signature_size, 32)
|
||||
|
||||
// v4 vendor specific
|
||||
decl_val(vendor_ramdisk_table_size, 32)
|
||||
decl_val(bootconfig_size, 32)
|
||||
decl_val(vendor_ramdisk_table_entry_num, 32)
|
||||
decl_val(vendor_ramdisk_table_entry_size, 32)
|
||||
decl_var(bootconfig_size, 32)
|
||||
|
||||
virtual ~dyn_img_hdr() {
|
||||
free(raw);
|
||||
@@ -554,7 +565,9 @@ struct dyn_img_vnd_v4 : public dyn_img_vnd_v3 {
|
||||
impl_cls(vnd_v4)
|
||||
|
||||
impl_val(vendor_ramdisk_table_size)
|
||||
impl_val(bootconfig_size)
|
||||
impl_val(vendor_ramdisk_table_entry_num)
|
||||
impl_val(vendor_ramdisk_table_entry_size)
|
||||
impl_var(bootconfig_size)
|
||||
};
|
||||
|
||||
#undef __impl_cls
|
||||
@@ -591,7 +604,7 @@ struct boot_img {
|
||||
const mmap_data map;
|
||||
|
||||
// Android image header
|
||||
const dyn_img_hdr *hdr;
|
||||
const dyn_img_hdr *hdr = nullptr;
|
||||
|
||||
// Flags to indicate the state of current boot image
|
||||
std::bitset<BOOT_FLAGS_MAX> flags;
|
||||
@@ -607,9 +620,9 @@ struct boot_img {
|
||||
|
||||
// Layout of the memory mapped region
|
||||
// +---------+
|
||||
// | head | Vendor specific. Should be empty for standard AOSP boot images.
|
||||
// | head | Vendor specific. Should not exist for standard AOSP boot images.
|
||||
// +---------+
|
||||
// | payload | The actual boot image, including the AOSP boot image header.
|
||||
// | payload | The actual entire AOSP boot image, including the boot image header.
|
||||
// +---------+
|
||||
// | tail | Data after payload. Usually contains signature/AVB information.
|
||||
// +---------+
|
||||
@@ -618,8 +631,8 @@ struct boot_img {
|
||||
byte_view tail;
|
||||
|
||||
// MTK headers
|
||||
const mtk_hdr *k_hdr;
|
||||
const mtk_hdr *r_hdr;
|
||||
const mtk_hdr *k_hdr = nullptr;
|
||||
const mtk_hdr *r_hdr = nullptr;
|
||||
|
||||
// The pointers/values after parse_image
|
||||
// +---------------+
|
||||
@@ -629,23 +642,26 @@ struct boot_img {
|
||||
// +---------------+
|
||||
// | z_info.tail | z_info.tail.sz()
|
||||
// +---------------+
|
||||
const zimage_hdr *z_hdr;
|
||||
const zimage_hdr *z_hdr = nullptr;
|
||||
struct {
|
||||
uint32_t hdr_sz;
|
||||
byte_view tail;
|
||||
} z_info;
|
||||
|
||||
// AVB structs
|
||||
const AvbFooter *avb_footer;
|
||||
const AvbVBMetaImageHeader *vbmeta;
|
||||
const AvbFooter *avb_footer = nullptr;
|
||||
const AvbVBMetaImageHeader *vbmeta = nullptr;
|
||||
|
||||
// Pointers to blocks defined in header
|
||||
const uint8_t *kernel;
|
||||
const uint8_t *ramdisk;
|
||||
const uint8_t *second;
|
||||
const uint8_t *extra;
|
||||
const uint8_t *recovery_dtbo;
|
||||
const uint8_t *dtb;
|
||||
const uint8_t *kernel = nullptr;
|
||||
const uint8_t *ramdisk = nullptr;
|
||||
const uint8_t *second = nullptr;
|
||||
const uint8_t *extra = nullptr;
|
||||
const uint8_t *recovery_dtbo = nullptr;
|
||||
const uint8_t *dtb = nullptr;
|
||||
const uint8_t *signature = nullptr;
|
||||
const uint8_t *vendor_ramdisk_table = nullptr;
|
||||
const uint8_t *bootconfig = nullptr;
|
||||
|
||||
// dtb embedded in kernel
|
||||
byte_view kernel_dtb;
|
||||
@@ -657,7 +673,7 @@ struct boot_img {
|
||||
~boot_img();
|
||||
|
||||
bool parse_image(const uint8_t *addr, format_t type);
|
||||
const std::pair<const uint8_t *, dyn_img_hdr *> create_hdr(const uint8_t *addr, format_t type);
|
||||
std::pair<const uint8_t *, dyn_img_hdr *> create_hdr(const uint8_t *addr, format_t type);
|
||||
|
||||
// Rust FFI
|
||||
rust::Slice<const uint8_t> get_payload() const { return payload; }
|
||||
|
@@ -175,9 +175,8 @@ Supported commands:
|
||||
extract [ENTRY OUT]
|
||||
Extract ENTRY to OUT, or extract all entries to current directory
|
||||
test
|
||||
Test the cpio's status
|
||||
Return value is 0 or bitwise or-ed of following values:
|
||||
0x1:Magisk 0x2:unsupported
|
||||
Test the cpio's status. Return values:
|
||||
0:stock 1:Magisk 2:unsupported
|
||||
patch
|
||||
Apply ramdisk patches
|
||||
Configure with env variables: KEEPVERITY KEEPFORCEENCRYPT
|
||||
@@ -544,7 +543,6 @@ impl Cpio {
|
||||
}
|
||||
|
||||
fn test(&self) -> i32 {
|
||||
let mut ret = 0;
|
||||
for file in [
|
||||
"sbin/launch_daemonsu.sh",
|
||||
"sbin/su",
|
||||
@@ -561,11 +559,10 @@ impl Cpio {
|
||||
"overlay/init.magisk.rc",
|
||||
] {
|
||||
if self.exists(file) {
|
||||
ret |= MAGISK_PATCHED;
|
||||
break;
|
||||
return MAGISK_PATCHED;
|
||||
}
|
||||
}
|
||||
ret
|
||||
0
|
||||
}
|
||||
|
||||
fn restore(&mut self) -> LoggedResult<()> {
|
||||
|
@@ -7,11 +7,13 @@
|
||||
#define HEADER_FILE "header"
|
||||
#define KERNEL_FILE "kernel"
|
||||
#define RAMDISK_FILE "ramdisk.cpio"
|
||||
#define VND_RAMDISK_DIR "vendor_ramdisk"
|
||||
#define SECOND_FILE "second"
|
||||
#define EXTRA_FILE "extra"
|
||||
#define KER_DTB_FILE "kernel_dtb"
|
||||
#define RECV_DTBO_FILE "recovery_dtbo"
|
||||
#define DTB_FILE "dtb"
|
||||
#define BOOTCONFIG_FILE "bootconfig"
|
||||
#define NEW_BOOT "new-boot.img"
|
||||
|
||||
int unpack(const char *image, bool skip_decomp = false, bool hdr = false);
|
||||
|
@@ -7,8 +7,16 @@
|
||||
using namespace std;
|
||||
|
||||
#ifdef USE_CRT0
|
||||
__asm__(".global vfprintf \n vfprintf = musl_vfprintf");
|
||||
__asm__(".global vsscanf \n vsscanf = tfp_vsscanf");
|
||||
__BEGIN_DECLS
|
||||
int tfp_vsscanf(const char *s, const char *fmt, va_list args);
|
||||
int vsscanf(const char *s, const char *fmt, va_list args) {
|
||||
return tfp_vsscanf(s, fmt, args);
|
||||
}
|
||||
int musl_vfprintf(FILE *stream, const char *format, va_list arg);
|
||||
int vfprintf(FILE *stream, const char *format, va_list arg) {
|
||||
return musl_vfprintf(stream, format, arg);
|
||||
}
|
||||
__END_DECLS
|
||||
#endif
|
||||
|
||||
static void print_formats() {
|
||||
|
@@ -25,6 +25,18 @@ static bool magisk_env() {
|
||||
|
||||
LOGI("* Initializing Magisk environment\n");
|
||||
|
||||
ssprintf(buf, sizeof(buf), "%s/0/%s/install", APP_DATA_DIR, JAVA_PACKAGE_NAME);
|
||||
// Alternative binaries paths
|
||||
const char *alt_bin[] = { "/cache/data_adb/magisk", "/data/magisk", buf };
|
||||
for (auto alt : alt_bin) {
|
||||
if (access(alt, F_OK) == 0) {
|
||||
rm_rf(DATABIN);
|
||||
cp_afc(alt, DATABIN);
|
||||
rm_rf(alt);
|
||||
}
|
||||
}
|
||||
rm_rf("/cache/data_adb");
|
||||
|
||||
// Directories in /data/adb
|
||||
chmod(SECURE_DIR, 0700);
|
||||
xmkdir(DATABIN, 0755);
|
||||
|
@@ -392,21 +392,6 @@ static void daemon_entry() {
|
||||
ssprintf(path, sizeof(path), "%s/" ROOTOVL, tmp);
|
||||
rm_rf(path);
|
||||
|
||||
// Use isolated devpts if kernel support
|
||||
if (access("/dev/pts/ptmx", F_OK) == 0) {
|
||||
ssprintf(path, sizeof(path), "%s/" SHELLPTS, tmp);
|
||||
if (access(path, F_OK)) {
|
||||
xmkdirs(path, 0755);
|
||||
xmount("devpts", path, "devpts", MS_NOSUID | MS_NOEXEC, "newinstance");
|
||||
char ptmx[64];
|
||||
ssprintf(ptmx, sizeof(ptmx), "%s/ptmx", path);
|
||||
if (access(ptmx, F_OK)) {
|
||||
xumount(path);
|
||||
rmdir(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
sockaddr_un addr = {.sun_family = AF_LOCAL};
|
||||
ssprintf(addr.sun_path, sizeof(addr.sun_path), "%s/" MAIN_SOCKET, tmp);
|
||||
|
@@ -24,20 +24,12 @@ static sqlite3 *mDB = nullptr;
|
||||
#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
|
||||
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
|
||||
|
||||
static int (*sqlite3_open_v2)(
|
||||
const char *filename,
|
||||
sqlite3 **ppDb,
|
||||
int flags,
|
||||
const char *zVfs);
|
||||
using sqlite3_callback = int (*)(void*, int, char**, char**);
|
||||
static int (*sqlite3_open_v2)(const char *filename, sqlite3 **ppDb, int flags, const char *zVfs);
|
||||
static const char *(*sqlite3_errmsg)(sqlite3 *db);
|
||||
static int (*sqlite3_close)(sqlite3 *db);
|
||||
static void (*sqlite3_free)(void *v);
|
||||
static int (*sqlite3_exec)(
|
||||
sqlite3 *db,
|
||||
const char *sql,
|
||||
int (*callback)(void*, int, char**, char**),
|
||||
void *v,
|
||||
char **errmsg);
|
||||
static int (*sqlite3_exec)(sqlite3 *db, const char *sql, sqlite3_callback fn, void *v, char **errmsg);
|
||||
|
||||
// Internal Android linker APIs
|
||||
|
||||
@@ -135,51 +127,69 @@ static int ver_cb(void *ver, int, char **data, char **) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define err_ret(e) if (e) return e;
|
||||
bool db_result::check_err() {
|
||||
if (!err.empty()) {
|
||||
LOGE("sqlite3_exec: %s\n", err.data());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static char *open_and_init_db(sqlite3 *&db) {
|
||||
static db_result sql_exec(sqlite3 *db, const char *sql, sqlite3_callback fn, void *v) {
|
||||
char *err = nullptr;
|
||||
sqlite3_exec(db, sql, fn, v, &err);
|
||||
if (err) {
|
||||
db_result r = err;
|
||||
sqlite3_free(err);
|
||||
return r;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
#define sql_exe_ret(...) if (auto r = sql_exec(__VA_ARGS__); !r) return r
|
||||
#define fn_run_ret(fn) if (auto r = fn(); !r) return r
|
||||
|
||||
static db_result open_and_init_db(sqlite3 *&db) {
|
||||
if (!dload_sqlite())
|
||||
return strdup("Cannot load libsqlite.so");
|
||||
return "Cannot load libsqlite.so";
|
||||
|
||||
int ret = sqlite3_open_v2(MAGISKDB, &db,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, nullptr);
|
||||
if (ret)
|
||||
return strdup(sqlite3_errmsg(db));
|
||||
return sqlite3_errmsg(db);
|
||||
int ver = 0;
|
||||
bool upgrade = false;
|
||||
char *err = nullptr;
|
||||
sqlite3_exec(db, "PRAGMA user_version", ver_cb, &ver, &err);
|
||||
err_ret(err);
|
||||
sql_exe_ret(db, "PRAGMA user_version", ver_cb, &ver);
|
||||
if (ver > DB_VERSION) {
|
||||
// Don't support downgrading database
|
||||
sqlite3_close(db);
|
||||
return strdup("Downgrading database is not supported");
|
||||
return "Downgrading database is not supported";
|
||||
}
|
||||
|
||||
auto create_policy = [&] {
|
||||
sqlite3_exec(db,
|
||||
return sql_exec(db,
|
||||
"CREATE TABLE IF NOT EXISTS policies "
|
||||
"(uid INT, policy INT, until INT, logging INT, "
|
||||
"notification INT, PRIMARY KEY(uid))",
|
||||
nullptr, nullptr, &err);
|
||||
nullptr, nullptr);
|
||||
};
|
||||
auto create_settings = [&] {
|
||||
sqlite3_exec(db,
|
||||
return sql_exec(db,
|
||||
"CREATE TABLE IF NOT EXISTS settings "
|
||||
"(key TEXT, value INT, PRIMARY KEY(key))",
|
||||
nullptr, nullptr, &err);
|
||||
nullptr, nullptr);
|
||||
};
|
||||
auto create_strings = [&] {
|
||||
sqlite3_exec(db,
|
||||
return sql_exec(db,
|
||||
"CREATE TABLE IF NOT EXISTS strings "
|
||||
"(key TEXT, value TEXT, PRIMARY KEY(key))",
|
||||
nullptr, nullptr, &err);
|
||||
nullptr, nullptr);
|
||||
};
|
||||
auto create_denylist = [&] {
|
||||
sqlite3_exec(db,
|
||||
return sql_exec(db,
|
||||
"CREATE TABLE IF NOT EXISTS denylist "
|
||||
"(package_name TEXT, process TEXT, PRIMARY KEY(package_name, process))",
|
||||
nullptr, nullptr, &err);
|
||||
nullptr, nullptr);
|
||||
};
|
||||
|
||||
// Database changelog:
|
||||
@@ -194,21 +204,17 @@ static char *open_and_init_db(sqlite3 *&db) {
|
||||
// 12: rebuild table `policies` to drop column `package_name`
|
||||
|
||||
if (/* 0, 1, 2, 3, 4, 5, 6 */ ver <= 6) {
|
||||
create_policy();
|
||||
err_ret(err);
|
||||
create_settings();
|
||||
err_ret(err);
|
||||
create_strings();
|
||||
err_ret(err);
|
||||
create_denylist();
|
||||
err_ret(err);
|
||||
fn_run_ret(create_policy);
|
||||
fn_run_ret(create_settings);
|
||||
fn_run_ret(create_strings);
|
||||
fn_run_ret(create_denylist);
|
||||
|
||||
// Directly jump to latest
|
||||
ver = DB_VERSION;
|
||||
upgrade = true;
|
||||
}
|
||||
if (ver == 7) {
|
||||
sqlite3_exec(db,
|
||||
sql_exe_ret(db,
|
||||
"BEGIN TRANSACTION;"
|
||||
"ALTER TABLE hidelist RENAME TO hidelist_tmp;"
|
||||
"CREATE TABLE IF NOT EXISTS hidelist "
|
||||
@@ -216,14 +222,13 @@ static char *open_and_init_db(sqlite3 *&db) {
|
||||
"INSERT INTO hidelist SELECT process as package_name, process FROM hidelist_tmp;"
|
||||
"DROP TABLE hidelist_tmp;"
|
||||
"COMMIT;",
|
||||
nullptr, nullptr, &err);
|
||||
err_ret(err);
|
||||
nullptr, nullptr);
|
||||
// Directly jump to version 9
|
||||
ver = 9;
|
||||
upgrade = true;
|
||||
}
|
||||
if (ver == 8) {
|
||||
sqlite3_exec(db,
|
||||
sql_exe_ret(db,
|
||||
"BEGIN TRANSACTION;"
|
||||
"ALTER TABLE hidelist RENAME TO hidelist_tmp;"
|
||||
"CREATE TABLE IF NOT EXISTS hidelist "
|
||||
@@ -231,30 +236,26 @@ static char *open_and_init_db(sqlite3 *&db) {
|
||||
"INSERT INTO hidelist SELECT * FROM hidelist_tmp;"
|
||||
"DROP TABLE hidelist_tmp;"
|
||||
"COMMIT;",
|
||||
nullptr, nullptr, &err);
|
||||
err_ret(err);
|
||||
nullptr, nullptr);
|
||||
ver = 9;
|
||||
upgrade = true;
|
||||
}
|
||||
if (ver == 9) {
|
||||
sqlite3_exec(db, "DROP TABLE IF EXISTS logs", nullptr, nullptr, &err);
|
||||
err_ret(err);
|
||||
sql_exe_ret(db, "DROP TABLE IF EXISTS logs", nullptr, nullptr);
|
||||
ver = 10;
|
||||
upgrade = true;
|
||||
}
|
||||
if (ver == 10) {
|
||||
sqlite3_exec(db,
|
||||
sql_exe_ret(db,
|
||||
"DROP TABLE IF EXISTS hidelist;"
|
||||
"DELETE FROM settings WHERE key='magiskhide';",
|
||||
nullptr, nullptr, &err);
|
||||
err_ret(err);
|
||||
create_denylist();
|
||||
err_ret(err);
|
||||
nullptr, nullptr);
|
||||
fn_run_ret(create_denylist);
|
||||
ver = 11;
|
||||
upgrade = true;
|
||||
}
|
||||
if (ver == 11) {
|
||||
sqlite3_exec(db,
|
||||
sql_exe_ret(db,
|
||||
"BEGIN TRANSACTION;"
|
||||
"ALTER TABLE policies RENAME TO policies_tmp;"
|
||||
"CREATE TABLE IF NOT EXISTS policies "
|
||||
@@ -264,8 +265,7 @@ static char *open_and_init_db(sqlite3 *&db) {
|
||||
"SELECT uid, policy, until, logging, notification FROM policies_tmp;"
|
||||
"DROP TABLE policies_tmp;"
|
||||
"COMMIT;",
|
||||
nullptr, nullptr, &err);
|
||||
err_ret(err);
|
||||
nullptr, nullptr);
|
||||
ver = 12;
|
||||
upgrade = true;
|
||||
}
|
||||
@@ -274,28 +274,25 @@ static char *open_and_init_db(sqlite3 *&db) {
|
||||
// Set version
|
||||
char query[32];
|
||||
sprintf(query, "PRAGMA user_version=%d", ver);
|
||||
sqlite3_exec(db, query, nullptr, nullptr, &err);
|
||||
err_ret(err);
|
||||
sql_exe_ret(db, query, nullptr, nullptr);
|
||||
}
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
char *db_exec(const char *sql) {
|
||||
char *err = nullptr;
|
||||
db_result db_exec(const char *sql) {
|
||||
if (mDB == nullptr) {
|
||||
err = open_and_init_db(mDB);
|
||||
db_err_cmd(err,
|
||||
auto res = open_and_init_db(mDB);
|
||||
if (res.check_err()) {
|
||||
// Open fails, remove and reconstruct
|
||||
unlink(MAGISKDB);
|
||||
err = open_and_init_db(mDB);
|
||||
err_ret(err);
|
||||
);
|
||||
res = open_and_init_db(mDB);
|
||||
if (!res) return res;
|
||||
}
|
||||
}
|
||||
if (mDB) {
|
||||
sqlite3_exec(mDB, sql, nullptr, nullptr, &err);
|
||||
return err;
|
||||
sql_exe_ret(mDB, sql, nullptr, nullptr);
|
||||
}
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
static int sqlite_db_row_callback(void *cb, int col_num, char **data, char **col_name) {
|
||||
@@ -306,26 +303,24 @@ static int sqlite_db_row_callback(void *cb, int col_num, char **data, char **col
|
||||
return func(row) ? 0 : 1;
|
||||
}
|
||||
|
||||
char *db_exec(const char *sql, const db_row_cb &fn) {
|
||||
char *err = nullptr;
|
||||
db_result db_exec(const char *sql, const db_row_cb &fn) {
|
||||
if (mDB == nullptr) {
|
||||
err = open_and_init_db(mDB);
|
||||
db_err_cmd(err,
|
||||
auto res = open_and_init_db(mDB);
|
||||
if (res.check_err()) {
|
||||
// Open fails, remove and reconstruct
|
||||
unlink(MAGISKDB);
|
||||
err = open_and_init_db(mDB);
|
||||
err_ret(err);
|
||||
);
|
||||
res = open_and_init_db(mDB);
|
||||
if (!res) return res;
|
||||
}
|
||||
}
|
||||
if (mDB) {
|
||||
sqlite3_exec(mDB, sql, sqlite_db_row_callback, (void *) &fn, &err);
|
||||
return err;
|
||||
sql_exe_ret(mDB, sql, sqlite_db_row_callback, (void *) &fn);
|
||||
}
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
int get_db_settings(db_settings &cfg, int key) {
|
||||
char *err = nullptr;
|
||||
db_result res;
|
||||
auto settings_cb = [&](db_row &row) -> bool {
|
||||
cfg[row["key"]] = parse_int(row["value"]);
|
||||
DBLOGV("query %s=[%s]\n", row["key"].data(), row["value"].data());
|
||||
@@ -334,26 +329,22 @@ int get_db_settings(db_settings &cfg, int key) {
|
||||
if (key >= 0) {
|
||||
char query[128];
|
||||
ssprintf(query, sizeof(query), "SELECT * FROM settings WHERE key='%s'", DB_SETTING_KEYS[key]);
|
||||
err = db_exec(query, settings_cb);
|
||||
res = db_exec(query, settings_cb);
|
||||
} else {
|
||||
err = db_exec("SELECT * FROM settings", settings_cb);
|
||||
res = db_exec("SELECT * FROM settings", settings_cb);
|
||||
}
|
||||
db_err_cmd(err, return 1);
|
||||
return 0;
|
||||
return res.check_err() ? 1 : 0;
|
||||
}
|
||||
|
||||
int set_db_settings(int key, int value) {
|
||||
char *err;
|
||||
char sql[128];
|
||||
ssprintf(sql, sizeof(sql), "INSERT OR REPLACE INTO settings VALUES ('%s', %d)",
|
||||
DB_SETTING_KEYS[key], value);
|
||||
err = db_exec(sql);
|
||||
db_err_cmd(err, return 1)
|
||||
return 0;
|
||||
return db_exec(sql).check_err() ? 1 : 0;
|
||||
}
|
||||
|
||||
int get_db_strings(db_strings &str, int key) {
|
||||
char *err = nullptr;
|
||||
db_result res;
|
||||
auto string_cb = [&](db_row &row) -> bool {
|
||||
str[row["key"]] = row["value"];
|
||||
DBLOGV("query %s=[%s]\n", row["key"].data(), row["value"].data());
|
||||
@@ -362,26 +353,22 @@ int get_db_strings(db_strings &str, int key) {
|
||||
if (key >= 0) {
|
||||
char query[128];
|
||||
ssprintf(query, sizeof(query), "SELECT * FROM strings WHERE key='%s'", DB_STRING_KEYS[key]);
|
||||
err = db_exec(query, string_cb);
|
||||
res = db_exec(query, string_cb);
|
||||
} else {
|
||||
err = db_exec("SELECT * FROM strings", string_cb);
|
||||
res = db_exec("SELECT * FROM strings", string_cb);
|
||||
}
|
||||
db_err_cmd(err, return 1);
|
||||
return 0;
|
||||
return res.check_err() ? 1 : 0;
|
||||
}
|
||||
|
||||
void rm_db_strings(int key) {
|
||||
char *err;
|
||||
char query[128];
|
||||
ssprintf(query, sizeof(query), "DELETE FROM strings WHERE key == '%s'", DB_STRING_KEYS[key]);
|
||||
err = db_exec(query);
|
||||
db_err_cmd(err, return);
|
||||
db_exec(query).check_err();
|
||||
}
|
||||
|
||||
void exec_sql(int client) {
|
||||
run_finally f([=]{ close(client); });
|
||||
void exec_sql(owned_fd client) {
|
||||
string sql = read_string(client);
|
||||
char *err = db_exec(sql.data(), [client](db_row &row) -> bool {
|
||||
auto res = db_exec(sql.data(), [fd = (int) client](db_row &row) -> bool {
|
||||
string out;
|
||||
bool first = true;
|
||||
for (auto it : row) {
|
||||
@@ -391,18 +378,9 @@ void exec_sql(int client) {
|
||||
out += '=';
|
||||
out += it.second;
|
||||
}
|
||||
write_string(client, out);
|
||||
write_string(fd, out);
|
||||
return true;
|
||||
});
|
||||
write_int(client, 0);
|
||||
db_err_cmd(err, return; );
|
||||
}
|
||||
|
||||
bool db_err(char *e) {
|
||||
if (e) {
|
||||
LOGE("sqlite3_exec: %s\n", e);
|
||||
sqlite3_free(e);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
res.check_err();
|
||||
}
|
||||
|
@@ -201,7 +201,7 @@ void scan_deny_apps() {
|
||||
LOGI("denylist rm: [%s]\n", it->first.data());
|
||||
ssprintf(sql, sizeof(sql), "DELETE FROM denylist WHERE package_name='%s'",
|
||||
it->first.data());
|
||||
db_err(db_exec(sql));
|
||||
db_exec(sql).check_err();
|
||||
it = pkg_to_procs.erase(it);
|
||||
} else {
|
||||
update_app_id(app_id, it->first, false);
|
||||
@@ -222,11 +222,12 @@ static bool ensure_data() {
|
||||
LOGI("denylist: initializing internal data structures\n");
|
||||
|
||||
default_new(pkg_to_procs_);
|
||||
char *err = db_exec("SELECT * FROM denylist", [](db_row &row) -> bool {
|
||||
auto res = db_exec("SELECT * FROM denylist", [](db_row &row) -> bool {
|
||||
add_hide_set(row["package_name"].data(), row["process"].data());
|
||||
return true;
|
||||
});
|
||||
db_err_cmd(err, goto error)
|
||||
if (res.check_err())
|
||||
goto error;
|
||||
|
||||
default_new(app_id_to_pkgs_);
|
||||
scan_deny_apps();
|
||||
@@ -262,9 +263,7 @@ static int add_list(const char *pkg, const char *proc) {
|
||||
char sql[4096];
|
||||
ssprintf(sql, sizeof(sql),
|
||||
"INSERT INTO denylist (package_name, process) VALUES('%s', '%s')", pkg, proc);
|
||||
char *err = db_exec(sql);
|
||||
db_err_cmd(err, return DenyResponse::ERROR)
|
||||
return DenyResponse::OK;
|
||||
return db_exec(sql).check_err() ? DenyResponse::ERROR : DenyResponse::OK;
|
||||
}
|
||||
|
||||
int add_list(int client) {
|
||||
@@ -308,9 +307,7 @@ static int rm_list(const char *pkg, const char *proc) {
|
||||
else
|
||||
ssprintf(sql, sizeof(sql),
|
||||
"DELETE FROM denylist WHERE package_name='%s' AND process='%s'", pkg, proc);
|
||||
char *err = db_exec(sql);
|
||||
db_err_cmd(err, return DenyResponse::ERROR)
|
||||
return DenyResponse::OK;
|
||||
return db_exec(sql).check_err() ? DenyResponse::ERROR : DenyResponse::OK;
|
||||
}
|
||||
|
||||
int rm_list(int client) {
|
||||
|
@@ -124,14 +124,21 @@ struct su_access {
|
||||
|
||||
using db_row = std::map<std::string_view, std::string_view>;
|
||||
using db_row_cb = std::function<bool(db_row&)>;
|
||||
struct owned_fd;
|
||||
|
||||
struct db_result {
|
||||
db_result() = default;
|
||||
db_result(const char *s) : err(s) {}
|
||||
bool check_err();
|
||||
operator bool() { return err.empty(); }
|
||||
private:
|
||||
std::string err;
|
||||
};
|
||||
|
||||
int get_db_settings(db_settings &cfg, int key = -1);
|
||||
int set_db_settings(int key, int value);
|
||||
int get_db_strings(db_strings &str, int key = -1);
|
||||
void rm_db_strings(int key);
|
||||
void exec_sql(int client);
|
||||
char *db_exec(const char *sql);
|
||||
char *db_exec(const char *sql, const db_row_cb &fn);
|
||||
bool db_err(char *e);
|
||||
|
||||
#define db_err_cmd(e, cmd) if (db_err(e)) { cmd; }
|
||||
void exec_sql(owned_fd client);
|
||||
db_result db_exec(const char *sql);
|
||||
db_result db_exec(const char *sql, const db_row_cb &fn);
|
||||
|
@@ -1,7 +1,6 @@
|
||||
#![feature(format_args_nl)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(option_take_if)]
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
|
||||
use base::Utf8CStr;
|
||||
@@ -10,7 +9,7 @@ use daemon::{daemon_entry, find_apk_path, get_magiskd, MagiskD};
|
||||
use logging::{
|
||||
android_logging, magisk_logging, zygisk_close_logd, zygisk_get_logd, zygisk_logging,
|
||||
};
|
||||
use mount::{find_preinit_device, revert_unmount, setup_mounts};
|
||||
use mount::{find_preinit_device, revert_unmount, setup_mounts, clean_mounts};
|
||||
use resetprop::{persist_delete_prop, persist_get_prop, persist_get_props, persist_set_prop};
|
||||
|
||||
mod cert;
|
||||
@@ -93,6 +92,7 @@ pub mod ffi {
|
||||
fn find_apk_path(pkg: Utf8CStrRef, data: &mut [u8]) -> usize;
|
||||
fn read_certificate(fd: i32, version: i32) -> Vec<u8>;
|
||||
fn setup_mounts();
|
||||
fn clean_mounts();
|
||||
fn find_preinit_device() -> String;
|
||||
fn revert_unmount(pid: i32);
|
||||
unsafe fn persist_get_prop(name: Utf8CStrRef, prop_cb: Pin<&mut PropCb>);
|
||||
|
@@ -157,11 +157,9 @@ void tmpfs_node::mount() {
|
||||
if (!isa<tmpfs_node>(parent())) {
|
||||
auto worker_dir = worker_path();
|
||||
mkdirs(worker_dir.data(), 0);
|
||||
bind_mount("tmpfs", worker_dir.data(), worker_dir.data());
|
||||
clone_attr(exist() ? node_path().data() : parent()->node_path().data(), worker_dir.data());
|
||||
dir_node::mount();
|
||||
VLOGD(replace() ? "replace" : "move", worker_dir.data(), node_path().data());
|
||||
xmount(worker_dir.data(), node_path().data(), nullptr, MS_MOVE, nullptr);
|
||||
bind_mount(replace() ? "replace" : "move", worker_dir.data(), node_path().data());
|
||||
xmount(nullptr, node_path().data(), nullptr, MS_REMOUNT | MS_BIND | MS_RDONLY, nullptr);
|
||||
} else {
|
||||
const string dest = worker_path();
|
||||
@@ -213,6 +211,8 @@ public:
|
||||
const string src = get_magisk_tmp() + "/magisk"s;
|
||||
(void) is64bit;
|
||||
#endif
|
||||
if (access(src.data(), F_OK))
|
||||
return;
|
||||
create_and_mount("zygisk", src, true);
|
||||
}
|
||||
|
||||
@@ -333,10 +333,7 @@ void load_modules() {
|
||||
}
|
||||
|
||||
// cleanup mounts
|
||||
ssprintf(buf, sizeof(buf), "%s/" WORKERDIR, get_magisk_tmp());
|
||||
xumount2(buf, MNT_DETACH);
|
||||
ssprintf(buf, sizeof(buf), "%s/" MODULEMNT, get_magisk_tmp());
|
||||
xumount2(buf, MNT_DETACH);
|
||||
clean_mounts();
|
||||
}
|
||||
|
||||
/************************
|
||||
|
@@ -94,36 +94,40 @@ pub fn setup_mounts() {
|
||||
ptr::null(),
|
||||
)
|
||||
.as_os_err()?;
|
||||
libc::mount(
|
||||
ptr::null(),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn clean_mounts() {
|
||||
let magisk_tmp = get_magisk_tmp();
|
||||
|
||||
let mut buf = Utf8CStrBufArr::default();
|
||||
|
||||
let module_mnt = FsPathBuf::new(&mut buf).join(magisk_tmp).join(MODULEMNT);
|
||||
let _: LoggedResult<()> = try {
|
||||
unsafe {
|
||||
libc::umount2(
|
||||
module_mnt.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_PRIVATE,
|
||||
ptr::null(),
|
||||
libc::MNT_DETACH,
|
||||
)
|
||||
.as_os_err()?;
|
||||
}
|
||||
};
|
||||
|
||||
// Prepare worker
|
||||
let worker_dir = FsPathBuf::new(&mut buf).join(magisk_tmp).join(WORKERDIR);
|
||||
let _: LoggedResult<()> = try {
|
||||
worker_dir.mkdir(0)?;
|
||||
unsafe {
|
||||
libc::mount(
|
||||
worker_dir.as_ptr(),
|
||||
ptr::null(),
|
||||
worker_dir.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_BIND,
|
||||
libc::MS_PRIVATE | libc::MS_REC,
|
||||
ptr::null(),
|
||||
)
|
||||
.as_os_err()?;
|
||||
libc::mount(
|
||||
ptr::null(),
|
||||
libc::umount2(
|
||||
worker_dir.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_PRIVATE,
|
||||
ptr::null(),
|
||||
libc::MNT_DETACH,
|
||||
)
|
||||
.as_os_err()?;
|
||||
}
|
||||
|
@@ -222,6 +222,7 @@ void install_module(const char *file) {
|
||||
setenv("OUTFD", "1", 1);
|
||||
setenv("ZIPFILE", zip, 1);
|
||||
setenv("ASH_STANDALONE", "1", 1);
|
||||
setenv("MAGISKTMP", get_magisk_tmp(), 0);
|
||||
free(zip);
|
||||
|
||||
int fd = xopen("/dev/null", O_RDONLY);
|
||||
|
@@ -63,11 +63,11 @@ void su_info::check_db() {
|
||||
}
|
||||
|
||||
if (eval_uid > 0) {
|
||||
char query[256], *err;
|
||||
char query[256];
|
||||
ssprintf(query, sizeof(query),
|
||||
"SELECT policy, logging, notification FROM policies "
|
||||
"WHERE uid=%d AND (until=0 OR until>%li)", eval_uid, time(nullptr));
|
||||
err = db_exec(query, [&](db_row &row) -> bool {
|
||||
auto res = db_exec(query, [&](db_row &row) -> bool {
|
||||
access.policy = (policy_t) parse_int(row["policy"]);
|
||||
access.log = parse_int(row["logging"]);
|
||||
access.notify = parse_int(row["notification"]);
|
||||
@@ -75,7 +75,8 @@ void su_info::check_db() {
|
||||
access.policy, access.log, access.notify);
|
||||
return true;
|
||||
});
|
||||
db_err_cmd(err, return);
|
||||
if (res.check_err())
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to check our manager
|
||||
@@ -123,15 +124,16 @@ bool uid_granted_root(int uid) {
|
||||
|
||||
bool granted = false;
|
||||
|
||||
char query[256], *err;
|
||||
char query[256];
|
||||
ssprintf(query, sizeof(query),
|
||||
"SELECT policy FROM policies WHERE uid=%d AND (until=0 OR until>%li)",
|
||||
uid, time(nullptr));
|
||||
err = db_exec(query, [&](db_row &row) -> bool {
|
||||
auto res = db_exec(query, [&](db_row &row) -> bool {
|
||||
granted = parse_int(row["policy"]) == ALLOW;
|
||||
return true;
|
||||
});
|
||||
db_err_cmd(err, return false);
|
||||
if (res.check_err())
|
||||
return false;
|
||||
|
||||
return granted;
|
||||
}
|
||||
@@ -140,9 +142,7 @@ void prune_su_access() {
|
||||
cached.reset();
|
||||
vector<bool> app_no_list = get_app_no_list();
|
||||
vector<int> rm_uids;
|
||||
char query[256], *err;
|
||||
strscpy(query, "SELECT uid FROM policies", sizeof(query));
|
||||
err = db_exec(query, [&](db_row &row) -> bool {
|
||||
auto res = db_exec("SELECT uid FROM policies", [&](db_row &row) -> bool {
|
||||
int uid = parse_int(row["uid"]);
|
||||
int app_id = to_app_id(uid);
|
||||
if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
|
||||
@@ -154,11 +154,13 @@ void prune_su_access() {
|
||||
}
|
||||
return true;
|
||||
});
|
||||
db_err_cmd(err, return);
|
||||
if (res.check_err())
|
||||
return;
|
||||
|
||||
for (int uid : rm_uids) {
|
||||
char query[256];
|
||||
ssprintf(query, sizeof(query), "DELETE FROM policies WHERE uid == %d", uid);
|
||||
db_err(db_exec(query));
|
||||
db_exec(query).check_err();
|
||||
}
|
||||
}
|
||||
|
||||
|
2
native/src/external/crt0
vendored
2
native/src/external/crt0
vendored
Submodule native/src/external/crt0 updated: 17233ab90e...1602918648
2
native/src/external/cxx-rs
vendored
2
native/src/external/cxx-rs
vendored
Submodule native/src/external/cxx-rs updated: 16abd4d2b4...7535230afb
@@ -41,16 +41,16 @@ static string extract_quoted_str_until(chars<escapes...>, chars<breaks...>,
|
||||
}
|
||||
|
||||
// Parse string into key value pairs.
|
||||
// The string format: [delim][key][padding]=[padding][value][delim]
|
||||
template<char delim, char... padding>
|
||||
// The string format: [delim][key][padding][eq][padding][value][delim]
|
||||
template<char delim, char eq, char... padding>
|
||||
static kv_pairs parse_impl(chars<padding...>, string_view str) {
|
||||
kv_pairs kv;
|
||||
char skip_array[] = {'=', padding...};
|
||||
char skip_array[] = {eq, padding...};
|
||||
string_view skip(skip_array, std::size(skip_array));
|
||||
bool quoted = false;
|
||||
for (size_t pos = 0u; pos < str.size(); pos = str.find_first_not_of(delim, pos)) {
|
||||
auto key = extract_quoted_str_until(
|
||||
chars<padding..., delim>{}, chars<'='>{}, str, pos, quoted);
|
||||
chars<padding..., delim>{}, chars<eq>{}, str, pos, quoted);
|
||||
pos = str.find_first_not_of(skip, pos);
|
||||
if (pos == string_view::npos || str[pos] == delim) {
|
||||
kv.emplace_back(key, "");
|
||||
@@ -63,10 +63,13 @@ static kv_pairs parse_impl(chars<padding...>, string_view str) {
|
||||
}
|
||||
|
||||
static kv_pairs parse_cmdline(string_view str) {
|
||||
return parse_impl<' '>(chars<>{}, str);
|
||||
return parse_impl<' ', '='>(chars<>{}, str);
|
||||
}
|
||||
static kv_pairs parse_bootconfig(string_view str) {
|
||||
return parse_impl<'\n'>(chars<' '>{}, str);
|
||||
return parse_impl<'\n', '='>(chars<' '>{}, str);
|
||||
}
|
||||
static kv_pairs parse_partition_map(std::string_view str) {
|
||||
return parse_impl<';', ','>(chars<>{}, str);
|
||||
}
|
||||
|
||||
#define test_bit(bit, array) (array[bit / 8] & (1 << (bit % 8)))
|
||||
@@ -207,6 +210,25 @@ void load_kernel_info(BootConfig *config) {
|
||||
config->print();
|
||||
}
|
||||
|
||||
// `androidboot.partition_map` allows associating a partition name for a raw block device
|
||||
// through a comma separated and semicolon deliminated list. For example,
|
||||
// `androidboot.partition_map=vdb,metadata;vdc,userdata` maps `vdb` to `metadata` and `vdc` to
|
||||
// `userdata`.
|
||||
// https://android.googlesource.com/platform/system/core/+/refs/heads/android13-release/init/devices.cpp#191
|
||||
|
||||
kv_pairs load_partition_map() {
|
||||
const string_view kPartitionMapKey = "androidboot.partition_map";
|
||||
for (const auto &[key, value] : parse_cmdline(full_read("/proc/cmdline"))) {
|
||||
if (key == kPartitionMapKey)
|
||||
return parse_partition_map(value);
|
||||
}
|
||||
for (const auto &[key, value] : parse_bootconfig(full_read("/proc/bootconfig"))) {
|
||||
if (key == kPartitionMapKey)
|
||||
return parse_partition_map(value);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool check_two_stage() {
|
||||
if (access("/apex", F_OK) == 0)
|
||||
return true;
|
||||
|
@@ -12,7 +12,12 @@
|
||||
using namespace std;
|
||||
|
||||
#ifdef USE_CRT0
|
||||
__asm__(".global vfprintf \n vfprintf = tfp_vfprintf");
|
||||
__BEGIN_DECLS
|
||||
int tfp_vfprintf(FILE *stream, const char *format, va_list arg);
|
||||
int vfprintf(FILE *stream, const char *format, va_list arg) {
|
||||
return tfp_vfprintf(stream, format, arg);
|
||||
}
|
||||
__END_DECLS
|
||||
#endif
|
||||
|
||||
bool unxz(out_stream &strm, rust::Slice<const uint8_t> bytes) {
|
||||
|
@@ -29,6 +29,7 @@ extern std::vector<std::string> mount_list;
|
||||
int magisk_proxy_main(int argc, char *argv[]);
|
||||
bool unxz(out_stream &strm, rust::Slice<const uint8_t> bytes);
|
||||
void load_kernel_info(BootConfig *config);
|
||||
kv_pairs load_partition_map();
|
||||
bool check_two_stage();
|
||||
const char *backup_init();
|
||||
void restore_ramdisk_init();
|
||||
|
@@ -29,21 +29,23 @@ bool avd_hack = false;
|
||||
static void parse_device(devinfo *dev, const char *uevent) {
|
||||
dev->partname[0] = '\0';
|
||||
dev->devpath[0] = '\0';
|
||||
dev->dmname[0] = '\0';
|
||||
dev->devname[0] = '\0';
|
||||
parse_prop_file(uevent, [=](string_view key, string_view value) -> bool {
|
||||
if (key == "MAJOR")
|
||||
dev->major = parse_int(value.data());
|
||||
else if (key == "MINOR")
|
||||
dev->minor = parse_int(value.data());
|
||||
else if (key == "DEVNAME")
|
||||
strcpy(dev->devname, value.data());
|
||||
strscpy(dev->devname, value.data(), sizeof(dev->devname));
|
||||
else if (key == "PARTNAME")
|
||||
strcpy(dev->partname, value.data());
|
||||
strscpy(dev->partname, value.data(), sizeof(dev->devname));
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
static void collect_devices() {
|
||||
static void collect_devices(const auto &partition_map) {
|
||||
char path[PATH_MAX];
|
||||
devinfo dev{};
|
||||
if (auto dir = xopen_dir("/sys/dev/block"); dir) {
|
||||
@@ -55,7 +57,13 @@ static void collect_devices() {
|
||||
sprintf(path, "/sys/dev/block/%s/dm/name", entry->d_name);
|
||||
if (access(path, F_OK) == 0) {
|
||||
auto name = rtrim(full_read(path));
|
||||
strcpy(dev.dmname, name.data());
|
||||
strscpy(dev.dmname, name.data(), sizeof(dev.dmname));
|
||||
}
|
||||
if (auto it = std::ranges::find_if(partition_map, [&](const auto &i) {
|
||||
return i.first == dev.devname;
|
||||
}); dev.partname[0] == '\0' && it != partition_map.end()) {
|
||||
// use androidboot.partition_map as partname fallback.
|
||||
strscpy(dev.partname, it->second.data(), sizeof(dev.partname));
|
||||
}
|
||||
sprintf(path, "/sys/dev/block/%s", entry->d_name);
|
||||
xrealpath(path, dev.devpath, sizeof(dev.devpath));
|
||||
@@ -70,8 +78,9 @@ static struct {
|
||||
} blk_info;
|
||||
|
||||
static dev_t setup_block() {
|
||||
static const auto partition_map = load_partition_map();
|
||||
if (dev_list.empty())
|
||||
collect_devices();
|
||||
collect_devices(partition_map);
|
||||
|
||||
for (int tries = 0; tries < 3; ++tries) {
|
||||
for (auto &dev : dev_list) {
|
||||
@@ -93,7 +102,7 @@ static dev_t setup_block() {
|
||||
// Wait 10ms and try again
|
||||
usleep(10000);
|
||||
dev_list.clear();
|
||||
collect_devices();
|
||||
collect_devices(partition_map);
|
||||
}
|
||||
|
||||
// The requested partname does not exist
|
||||
@@ -236,6 +245,7 @@ void MagiskInit::setup_tmp(const char *path) {
|
||||
|
||||
xmkdir(INTLROOT, 0711);
|
||||
xmkdir(DEVICEDIR, 0711);
|
||||
xmkdir(WORKERDIR, 0);
|
||||
|
||||
mount_preinit_dir(preinit_dev);
|
||||
|
||||
@@ -249,5 +259,21 @@ void MagiskInit::setup_tmp(const char *path) {
|
||||
|
||||
xmount(".", path, nullptr, MS_BIND, nullptr);
|
||||
|
||||
chdir(path);
|
||||
|
||||
// Prepare worker
|
||||
xmount(WORKERDIR, WORKERDIR, nullptr, MS_BIND, nullptr);
|
||||
|
||||
// Use isolated devpts if kernel support
|
||||
if (access("/dev/pts/ptmx", F_OK) == 0) {
|
||||
xmkdirs(SHELLPTS, 0755);
|
||||
xmount("devpts", SHELLPTS, "devpts", MS_NOSUID | MS_NOEXEC, "newinstance");
|
||||
xmount(nullptr, SHELLPTS, nullptr, MS_PRIVATE, nullptr);
|
||||
if (access(SHELLPTS "/ptmx", F_OK)) {
|
||||
umount2(SHELLPTS, MNT_DETACH);
|
||||
rmdir(SHELLPTS);
|
||||
}
|
||||
}
|
||||
|
||||
chdir("/");
|
||||
}
|
||||
|
@@ -12,10 +12,31 @@
|
||||
using namespace std;
|
||||
|
||||
static vector<string> rc_list;
|
||||
static string magic_mount_list;
|
||||
|
||||
#define NEW_INITRC_DIR "/system/etc/init/hw"
|
||||
#define INIT_RC "init.rc"
|
||||
|
||||
static void magic_mount(const string &sdir, const string &ddir = "") {
|
||||
auto dir = xopen_dir(sdir.data());
|
||||
if (!dir) return;
|
||||
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
||||
string src = sdir + "/" + entry->d_name;
|
||||
string dest = ddir + "/" + entry->d_name;
|
||||
if (access(dest.data(), F_OK) == 0) {
|
||||
if (entry->d_type == DT_DIR) {
|
||||
// Recursive
|
||||
magic_mount(src, dest);
|
||||
} else {
|
||||
LOGD("Mount [%s] -> [%s]\n", src.data(), dest.data());
|
||||
xmount(src.data(), dest.data(), nullptr, MS_BIND, nullptr);
|
||||
magic_mount_list += dest;
|
||||
magic_mount_list += '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void patch_rc_scripts(const char *src_path, const char *tmp_path, bool writable) {
|
||||
auto src_dir = xopen_dir(src_path);
|
||||
if (!src_dir) return;
|
||||
@@ -105,6 +126,43 @@ static void patch_rc_scripts(const char *src_path, const char *tmp_path, bool wr
|
||||
});
|
||||
fclone_attr(fileno(src.get()), fileno(dest.get()));
|
||||
}
|
||||
|
||||
if (faccessat(src_fd, "init.fission_host.rc", F_OK, 0) == 0) {
|
||||
{
|
||||
LOGD("Patching fissiond\n");
|
||||
mmap_data fissiond("/system/bin/fissiond", false);
|
||||
for (size_t off : fissiond.patch("ro.build.system.fission_single_os", "ro.build.system.xxxxxxxxxxxxxxxxx")) {
|
||||
LOGD("Patch @ %08zX [ro.build.system.fission_single_os] -> [ro.build.system.xxxxxxxxxxxxxxxxx]\n", off);
|
||||
}
|
||||
mkdirs(ROOTOVL "/system/bin", 0755);
|
||||
if (auto target_fissiond = xopen_file(ROOTOVL "/system/bin/fissiond", "we")) {
|
||||
fwrite(fissiond.buf(), 1, fissiond.sz(), target_fissiond.get());
|
||||
clone_attr("/system/bin/fissiond", ROOTOVL "/system/bin/fissiond");
|
||||
}
|
||||
}
|
||||
LOGD("hijack isolated\n");
|
||||
auto hijack = xopen_file("/sys/devices/system/cpu/isolated", "re");
|
||||
mkfifo(INTLROOT "/isolated", 0777);
|
||||
xmount(INTLROOT "/isolated", "/sys/devices/system/cpu/isolated", nullptr, MS_BIND, nullptr);
|
||||
if (!xfork()) {
|
||||
auto dest = xopen_file(INTLROOT "/isolated", "we");
|
||||
LOGD("hijacked isolated\n");
|
||||
xumount2("/sys/devices/system/cpu/isolated", MNT_DETACH);
|
||||
unlink(INTLROOT "/isolated");
|
||||
string content;
|
||||
full_read(fileno(hijack.get()), content);
|
||||
{
|
||||
string target = "/dev/cells/cell2"s + tmp_path;
|
||||
xmkdirs(target.data(), 0);
|
||||
xmount(tmp_path, target.data(), nullptr, MS_BIND | MS_REC,nullptr);
|
||||
magic_mount(ROOTOVL, "/dev/cells/cell2");
|
||||
auto mount = xopen_file(ROOTMNT, "w");
|
||||
fwrite(magic_mount_list.data(), 1, magic_mount_list.length(), mount.get());
|
||||
}
|
||||
fprintf(dest.get(), "%s", content.data());
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void load_overlay_rc(const char *overlay) {
|
||||
@@ -164,28 +222,6 @@ static void recreate_sbin(const char *mirror, bool use_bind_mount) {
|
||||
}
|
||||
}
|
||||
|
||||
static string magic_mount_list;
|
||||
|
||||
static void magic_mount(const string &sdir, const string &ddir = "") {
|
||||
auto dir = xopen_dir(sdir.data());
|
||||
if (!dir) return;
|
||||
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
||||
string src = sdir + "/" + entry->d_name;
|
||||
string dest = ddir + "/" + entry->d_name;
|
||||
if (access(dest.data(), F_OK) == 0) {
|
||||
if (entry->d_type == DT_DIR) {
|
||||
// Recursive
|
||||
magic_mount(src, dest);
|
||||
} else {
|
||||
LOGD("Mount [%s] -> [%s]\n", src.data(), dest.data());
|
||||
xmount(src.data(), dest.data(), nullptr, MS_BIND, nullptr);
|
||||
magic_mount_list += dest;
|
||||
magic_mount_list += '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_files(bool sbin) {
|
||||
const char *magisk_xz = sbin ? "/sbin/magisk.xz" : "magisk.xz";
|
||||
const char *stub_xz = sbin ? "/sbin/stub.xz" : "stub.xz";
|
||||
|
@@ -78,7 +78,7 @@ run_uninstaller() {
|
||||
}
|
||||
|
||||
restore_imgs() {
|
||||
[ -z $SHA1 ] && return 1
|
||||
local SHA1=$(grep_prop SHA1 $MAGISKTMP/.magisk/config)
|
||||
local BACKUPDIR=/data/magisk_backup_$SHA1
|
||||
[ -d $BACKUPDIR ] || return 1
|
||||
|
||||
@@ -232,7 +232,6 @@ app_init() {
|
||||
check_boot_ramdisk && RAMDISKEXIST=true
|
||||
get_flags >/dev/null
|
||||
run_migrations >/dev/null
|
||||
SHA1=$(grep_prop SHA1 $MAGISKTMP/.magisk/config)
|
||||
check_encryption
|
||||
|
||||
# Dump variables
|
||||
|
@@ -10,6 +10,7 @@ emu_pid=
|
||||
atd_min_api=30
|
||||
atd_max_api=34
|
||||
lsposed_min_api=27
|
||||
lsposed_max_api=34
|
||||
huge_ram_min_api=26
|
||||
|
||||
cleanup() {
|
||||
@@ -67,29 +68,24 @@ test_emu() {
|
||||
|
||||
print_title "* Testing $pkg ($variant)"
|
||||
|
||||
if [ -n "$AVD_TEST_VERBOSE" ]; then
|
||||
"$emu" @test $emu_args &
|
||||
emu_pid=$!
|
||||
adb logcat &
|
||||
if [ -n "$AVD_TEST_LOG" ]; then
|
||||
"$emu" @test $emu_args > kernel.log 2>&1 &
|
||||
else
|
||||
"$emu" @test $emu_args 2>/dev/null &
|
||||
emu_pid=$!
|
||||
"$emu" @test $emu_args > /dev/null 2>&1 &
|
||||
fi
|
||||
|
||||
emu_pid=$!
|
||||
wait_emu wait_for_boot
|
||||
|
||||
test_setup $variant
|
||||
|
||||
# Install LSPosed
|
||||
if [ $api -ge $lsposed_min_api -a $api -le $atd_max_api ]; then
|
||||
if [ $api -ge $lsposed_min_api -a $api -le $lsposed_max_api ]; then
|
||||
adb push out/lsposed.zip /data/local/tmp/lsposed.zip
|
||||
echo 'PATH=$PATH:/debug_ramdisk magisk --install-module /data/local/tmp/lsposed.zip' | adb shell /system/xbin/su
|
||||
fi
|
||||
|
||||
adb reboot
|
||||
if [ -n "$AVD_TEST_VERBOSE" ]; then
|
||||
adb logcat &
|
||||
fi
|
||||
wait_emu wait_for_boot
|
||||
|
||||
test_app
|
||||
@@ -147,9 +143,6 @@ run_test() {
|
||||
fi
|
||||
|
||||
emu_args="$emu_args_base -memory $memory"
|
||||
if [ -n "$AVD_TEST_VERBOSE" ]; then
|
||||
emu_args="$emu_args -show-kernel"
|
||||
fi
|
||||
|
||||
# Setup emulator
|
||||
"$sdk" --channel=3 $pkg
|
||||
@@ -157,12 +150,15 @@ run_test() {
|
||||
|
||||
# Launch stock emulator
|
||||
print_title "* Launching $pkg"
|
||||
"$emu" @test $emu_args 2>/dev/null &
|
||||
"$emu" @test $emu_args >/dev/null 2>&1 &
|
||||
emu_pid=$!
|
||||
wait_emu wait_for_bootanim
|
||||
|
||||
# Update arguments for Magisk runs
|
||||
emu_args="$emu_args -ramdisk magisk_patched.img -feature -SystemAsRoot"
|
||||
if [ -n "$AVD_TEST_LOG" ]; then
|
||||
emu_args="$emu_args -show-kernel -logcat '' -logcat-output logcat.log"
|
||||
fi
|
||||
|
||||
# Patch and test debug build
|
||||
./build.py avd_patch -s "$ramdisk" magisk_patched.img
|
||||
|
@@ -119,14 +119,16 @@ else
|
||||
STATUS=0
|
||||
SKIP_BACKUP="#"
|
||||
fi
|
||||
case $((STATUS & 3)) in
|
||||
0 ) # Stock boot
|
||||
case $STATUS in
|
||||
0 )
|
||||
# Stock boot
|
||||
ui_print "- Stock boot image detected"
|
||||
SHA1=$(./magiskboot sha1 "$BOOTIMAGE" 2>/dev/null)
|
||||
cat $BOOTIMAGE > stock_boot.img
|
||||
cp -af ramdisk.cpio ramdisk.cpio.orig 2>/dev/null
|
||||
;;
|
||||
1 ) # Magisk patched
|
||||
1 )
|
||||
# Magisk patched
|
||||
ui_print "- Magisk patched boot image detected"
|
||||
./magiskboot cpio ramdisk.cpio \
|
||||
"extract .backup/.magisk config.orig" \
|
||||
@@ -134,7 +136,8 @@ case $((STATUS & 3)) in
|
||||
cp -af ramdisk.cpio ramdisk.cpio.orig
|
||||
rm -f stock_boot.img
|
||||
;;
|
||||
2 ) # Unsupported
|
||||
2 )
|
||||
# Unsupported
|
||||
ui_print "! Boot image patched by unsupported programs"
|
||||
abort "! Please restore back to stock boot image"
|
||||
;;
|
||||
|
@@ -19,7 +19,7 @@ run_cvd_bin() {
|
||||
}
|
||||
|
||||
setup_env() {
|
||||
curl -LO https://github.com/topjohnwu/magisk-files/releases/download/files/cuttlefish-base_0.9.29_amd64.deb
|
||||
curl -LO https://github.com/topjohnwu/magisk-files/releases/download/files/cuttlefish-base_0.9.30_amd64.deb
|
||||
sudo dpkg -i ./cuttlefish-base_*_*64.deb || sudo apt-get install -f
|
||||
rm cuttlefish-base_*_*64.deb
|
||||
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||
@@ -32,22 +32,22 @@ setup_env() {
|
||||
|
||||
download_cf() {
|
||||
local branch=$1
|
||||
local target=$2
|
||||
local device=$2
|
||||
|
||||
if [ -z $branch ]; then
|
||||
branch='aosp-main'
|
||||
fi
|
||||
if [ -z $target ]; then
|
||||
target='aosp_cf_x86_64_phone-trunk_staging-userdebug'
|
||||
if [ -z $device ]; then
|
||||
device='aosp_cf_x86_64_phone'
|
||||
fi
|
||||
local device=$(echo $target | cut -d '-' -f 1)
|
||||
local target="${device}-trunk_staging-userdebug"
|
||||
|
||||
local build_id=$(curl -sL https://ci.android.com/builds/branches/${branch}/status.json | \
|
||||
jq -r ".targets[] | select(.name == \"$target\") | .last_known_good_build")
|
||||
local sys_img_url="https://ci.android.com/builds/submitted/${build_id}/${target}/latest/raw/${device}-img-${build_id}.zip"
|
||||
local host_pkg_url="https://ci.android.com/builds/submitted/${build_id}/${target}/latest/raw/cvd-host_package.tar.gz"
|
||||
|
||||
print_title "* Download $branch ($build_id) $target images"
|
||||
print_title "* Download $target ($build_id) images"
|
||||
curl -L $sys_img_url -o aosp_cf_phone-img.zip
|
||||
curl -LO $host_pkg_url
|
||||
rm -rf $CF_HOME
|
||||
|
@@ -29,6 +29,8 @@ enable_version_config() {
|
||||
if ! grep -qE '^version=' $CONFIG; then
|
||||
echo 'version=' >> $CONFIG
|
||||
fi
|
||||
# Make sure abiList is not set when building for release
|
||||
sed -i "s:^abiList=:# abiList=:g" $CONFIG
|
||||
}
|
||||
|
||||
disable_version_config() {
|
||||
@@ -87,8 +89,6 @@ update_release_json() {
|
||||
}
|
||||
|
||||
build_canary() {
|
||||
enable_version_config
|
||||
|
||||
# Update version code
|
||||
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||
code=$((code + 1))
|
||||
@@ -119,14 +119,10 @@ build_canary() {
|
||||
$BUILDCMD clean
|
||||
$BUILDCMD all
|
||||
$BUILDCMD -r all
|
||||
|
||||
disable_version_config
|
||||
}
|
||||
|
||||
# $1 = ver, $2 = stable?
|
||||
build_release() {
|
||||
enable_version_config
|
||||
|
||||
# Update version configs
|
||||
local ver=$1
|
||||
local stable=$2
|
||||
@@ -160,8 +156,6 @@ build_release() {
|
||||
# Build
|
||||
$BUILDCMD clean
|
||||
$BUILDCMD -r all
|
||||
|
||||
disable_version_config
|
||||
}
|
||||
|
||||
stable() {
|
||||
@@ -238,6 +232,8 @@ fi
|
||||
|
||||
git pull
|
||||
|
||||
trap disable_version_config EXIT
|
||||
enable_version_config
|
||||
case $1 in
|
||||
"canary" ) build_canary ;;
|
||||
"stable" ) stable $2 ;;
|
||||
|
@@ -207,7 +207,7 @@ find_block() {
|
||||
for BLOCK in "$@"; do
|
||||
DEVICE=$(find /dev/block \( -type b -o -type c -o -type l \) -iname $BLOCK | head -n 1) 2>/dev/null
|
||||
if [ ! -z $DEVICE ]; then
|
||||
readlink -f $DEVICE
|
||||
echo $DEVICE
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
@@ -226,7 +226,7 @@ find_block() {
|
||||
for DEV in "$@"; do
|
||||
DEVICE=$(find /dev \( -type b -o -type c -o -type l \) -maxdepth 1 -iname $DEV | head -n 1) 2>/dev/null
|
||||
if [ ! -z $DEVICE ]; then
|
||||
readlink -f $DEVICE
|
||||
echo $DEVICE
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
@@ -370,14 +370,20 @@ get_flags() {
|
||||
find_boot_image() {
|
||||
BOOTIMAGE=
|
||||
if $RECOVERYMODE; then
|
||||
BOOTIMAGE=$(find_block "recovery_ramdisk$SLOT" "recovery$SLOT" "sos")
|
||||
elif [ ! -z $SLOT ]; then
|
||||
BOOTIMAGE=$(find_block "ramdisk$SLOT" "recovery_ramdisk$SLOT" "init_boot$SLOT" "boot$SLOT")
|
||||
BOOTIMAGE=$(find_block "recovery$SLOT" "sos")
|
||||
elif [ -e "/dev/block/by-name/init_boot$SLOT" ] && [ "$(uname -r | cut -d. -f1)" -ge 5 ] && uname -r | grep -Evq "android12-|^5\.4"; then
|
||||
# init_boot is only used with GKI 13+. It is possible that some devices with init_boot
|
||||
# partition still uses Android 12 GKI or previous kernels, so we need to explicitly detect that scenario.
|
||||
BOOTIMAGE="/dev/block/by-name/init_boot$SLOT"
|
||||
elif [ -e "/dev/block/by-name/boot$SLOT" ]; then
|
||||
# Standard location since AOSP Android 10+
|
||||
BOOTIMAGE="/dev/block/by-name/boot$SLOT"
|
||||
elif [ -n "$SLOT" ]; then
|
||||
# Fallback for A/B devices running < Android 10
|
||||
BOOTIMAGE=$(find_block "ramdisk$SLOT" "boot$SLOT")
|
||||
else
|
||||
BOOTIMAGE=$(find_block ramdisk recovery_ramdisk kern-a android_boot kernel bootimg init_boot boot lnx boot_a)
|
||||
fi
|
||||
if [ "$BOOTIMAGE" = "init_boot$SLOT" ]; then
|
||||
uname -r | grep -q "android12-" && BOOTIMAGE="boot$SLOT"
|
||||
# Fallback for all legacy and non-standard devices
|
||||
BOOTIMAGE=$(find_block ramdisk kern-a android_boot kernel bootimg boot lnx boot_a)
|
||||
fi
|
||||
if [ -z $BOOTIMAGE ]; then
|
||||
# Lets see what fstabs tells me
|
||||
@@ -524,7 +530,7 @@ check_data() {
|
||||
}
|
||||
|
||||
run_migrations() {
|
||||
local LOCSHA1
|
||||
local SHA1
|
||||
local TARGET
|
||||
# Legacy app installation
|
||||
local BACKUP=$MAGISKBIN/stock_boot*.gz
|
||||
@@ -536,22 +542,23 @@ run_migrations() {
|
||||
# Legacy backup
|
||||
for gz in /data/stock_boot*.gz; do
|
||||
[ -f $gz ] || break
|
||||
LOCSHA1=$(basename $gz | sed -e 's/stock_boot_//' -e 's/.img.gz//')
|
||||
[ -z $LOCSHA1 ] && break
|
||||
mkdir /data/magisk_backup_${LOCSHA1} 2>/dev/null
|
||||
mv $gz /data/magisk_backup_${LOCSHA1}/boot.img.gz
|
||||
SHA1=$(basename $gz | sed -e 's/stock_boot_//' -e 's/.img.gz//')
|
||||
[ -z $SHA1 ] && break
|
||||
mkdir /data/magisk_backup_${SHA1} 2>/dev/null
|
||||
mv $gz /data/magisk_backup_${SHA1}/boot.img.gz
|
||||
done
|
||||
|
||||
# Stock backups
|
||||
LOCSHA1=$SHA1
|
||||
SHA1=
|
||||
for name in boot dtb dtbo dtbs; do
|
||||
BACKUP=$MAGISKBIN/stock_${name}.img
|
||||
[ -f $BACKUP ] || continue
|
||||
if [ $name = 'boot' ]; then
|
||||
LOCSHA1=$($MAGISKBIN/magiskboot sha1 $BACKUP)
|
||||
mkdir /data/magisk_backup_${LOCSHA1} 2>/dev/null
|
||||
SHA1=$($MAGISKBIN/magiskboot sha1 $BACKUP)
|
||||
mkdir /data/magisk_backup_${SHA1} 2>/dev/null
|
||||
fi
|
||||
TARGET=/data/magisk_backup_${LOCSHA1}/${name}.img
|
||||
[ -z $SHA1 ] && break
|
||||
TARGET=/data/magisk_backup_${SHA1}/${name}.img
|
||||
cp $BACKUP $TARGET
|
||||
rm -f $BACKUP
|
||||
gzip -9f $TARGET
|
||||
|
Reference in New Issue
Block a user