mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-08-14 16:07:26 +00:00
Compare commits
97 Commits
canary-270
...
canary-280
Author | SHA1 | Date | |
---|---|---|---|
![]() |
070719db50 | ||
![]() |
28cccdf7aa | ||
![]() |
b7e0986a5c | ||
![]() |
da709745dd | ||
![]() |
8b6771d487 | ||
![]() |
e1b847fbc5 | ||
![]() |
7188de1205 | ||
![]() |
44fb7dbcbe | ||
![]() |
8086b5933c | ||
![]() |
7f675f4bf7 | ||
![]() |
5e6b53e0da | ||
![]() |
5b29fefc65 | ||
![]() |
16a168535d | ||
![]() |
33f70f8f6d | ||
![]() |
4f18a66d73 | ||
![]() |
250dc16007 | ||
![]() |
7af273e047 | ||
![]() |
e381aebaa0 | ||
![]() |
45d91c9658 | ||
![]() |
4a9158f667 | ||
![]() |
0d9ee89e7f | ||
![]() |
abaff72304 | ||
![]() |
b828e2d0b2 | ||
![]() |
53d7cbc11b | ||
![]() |
310be7ab47 | ||
![]() |
60894e458f | ||
![]() |
fbebb6ac10 | ||
![]() |
a9f8c20703 | ||
![]() |
ae0b15d197 | ||
![]() |
869aa62328 | ||
![]() |
dcd3bc58a3 | ||
![]() |
a82f17c594 | ||
![]() |
b38fd1ca5f | ||
![]() |
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 | ||
![]() |
0495468d02 | ||
![]() |
300a2a242c | ||
![]() |
33aebb5976 | ||
![]() |
b3d6809c0b | ||
![]() |
461f7e9f89 | ||
![]() |
9cc50b20d8 | ||
![]() |
f488e9df8f | ||
![]() |
0dc596e206 | ||
![]() |
c3bf03190b | ||
![]() |
021ae891a9 | ||
![]() |
9c03514eb1 | ||
![]() |
eb74b266e1 | ||
![]() |
80eb6ff25a |
92
.github/actions/setup/action.yml
vendored
92
.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:
|
||||
@@ -6,39 +10,91 @@ runs:
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: "17"
|
||||
java-version: "21"
|
||||
|
||||
- name: Set up Python 3
|
||||
uses: actions/setup-python@v5
|
||||
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
|
||||
|
@@ -21,9 +21,8 @@ Some highlight features:
|
||||
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://raw.githubusercontent.com/topjohnwu/magisk-files/canary/app-release.apk)
|
||||
[](https://raw.githubusercontent.com/topjohnwu/magisk-files/canary/app-debug.apk)
|
||||
[](https://github.com/topjohnwu/Magisk/releases/tag/v28.0)
|
||||
[](https://github.com/topjohnwu/Magisk/releases/tag/canary-28001)
|
||||
|
||||
## Useful Links
|
||||
|
||||
@@ -31,8 +30,6 @@ Click the icon below to download Magisk apk.
|
||||
- [Building and Development](https://topjohnwu.github.io/Magisk/build.html)
|
||||
- [Magisk Documentation](https://topjohnwu.github.io/Magisk/)
|
||||
- [Zygisk module sample](https://github.com/topjohnwu/zygisk-module-sample)
|
||||
- [Canary channel changelog](https://github.com/topjohnwu/magisk-files/blob/canary/notes.md)
|
||||
|
||||
|
||||
## Bug Reports
|
||||
|
||||
|
@@ -13,7 +13,7 @@ kapt {
|
||||
useBuildCache = true
|
||||
mapDiagnosticLocations = true
|
||||
javacOptions {
|
||||
option("-Xmaxerrs", 1000)
|
||||
option("-Xmaxerrs", "1000")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,27 +42,31 @@ android {
|
||||
buildFeatures {
|
||||
dataBinding = true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":app:core"))
|
||||
coreLibraryDesugaring(libs.jdk.libs)
|
||||
|
||||
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.0")
|
||||
implementation("androidx.fragment:fragment-ktx:1.8.1")
|
||||
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,13 +1,18 @@
|
||||
package com.topjohnwu.magisk.dialog
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.core.os.postDelayed
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.topjohnwu.magisk.core.BuildConfig
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
import com.topjohnwu.magisk.core.R
|
||||
import com.topjohnwu.magisk.core.ktx.reboot
|
||||
import com.topjohnwu.magisk.core.ktx.toast
|
||||
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
|
||||
import com.topjohnwu.magisk.events.DialogBuilder
|
||||
import com.topjohnwu.magisk.ui.home.HomeViewModel
|
||||
import com.topjohnwu.magisk.view.MagiskDialog
|
||||
import com.topjohnwu.superuser.internal.UiThreadHandler
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class EnvFixDialog(private val vm: HomeViewModel, private val code: Int) : DialogBuilder {
|
||||
@@ -27,9 +32,15 @@ class EnvFixDialog(private val vm: HomeViewModel, private val code: Int) : Dialo
|
||||
setCancelable(false)
|
||||
}
|
||||
dialog.activity.lifecycleScope.launch {
|
||||
MagiskInstaller.FixEnv {
|
||||
MagiskInstaller.FixEnv().exec { success ->
|
||||
dialog.dismiss()
|
||||
}.exec()
|
||||
context.toast(
|
||||
if (success) R.string.reboot_delay_toast else R.string.setup_fail,
|
||||
Toast.LENGTH_LONG
|
||||
)
|
||||
if (success)
|
||||
UiThreadHandler.handler.postDelayed(5000) { reboot() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -1,15 +1,17 @@
|
||||
package com.topjohnwu.magisk.dialog
|
||||
|
||||
import android.app.ProgressDialog
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.topjohnwu.magisk.arch.NavigationActivity
|
||||
import com.topjohnwu.magisk.arch.UIActivity
|
||||
import com.topjohnwu.magisk.core.R
|
||||
import com.topjohnwu.magisk.core.ktx.toast
|
||||
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
|
||||
import com.topjohnwu.magisk.events.DialogBuilder
|
||||
import com.topjohnwu.magisk.ui.flash.FlashFragment
|
||||
import com.topjohnwu.magisk.view.MagiskDialog
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class UninstallDialog : DialogBuilder {
|
||||
|
||||
@@ -19,7 +21,7 @@ class UninstallDialog : DialogBuilder {
|
||||
setMessage(R.string.uninstall_magisk_msg)
|
||||
setButton(MagiskDialog.ButtonType.POSITIVE) {
|
||||
text = R.string.restore_img
|
||||
onClick { restore(dialog.context) }
|
||||
onClick { restore(dialog.activity) }
|
||||
}
|
||||
setButton(MagiskDialog.ButtonType.NEGATIVE) {
|
||||
text = R.string.complete_uninstall
|
||||
@@ -29,18 +31,20 @@ class UninstallDialog : DialogBuilder {
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
private fun restore(context: Context) {
|
||||
val dialog = ProgressDialog(context).apply {
|
||||
setMessage(context.getString(R.string.restore_img_msg))
|
||||
private fun restore(activity: UIActivity<*>) {
|
||||
val dialog = ProgressDialog(activity).apply {
|
||||
setMessage(activity.getString(R.string.restore_img_msg))
|
||||
show()
|
||||
}
|
||||
|
||||
Shell.cmd("restore_imgs").submit { result ->
|
||||
dialog.dismiss()
|
||||
if (result.isSuccess) {
|
||||
context.toast(R.string.restore_done, Toast.LENGTH_SHORT)
|
||||
} else {
|
||||
context.toast(R.string.restore_fail, Toast.LENGTH_LONG)
|
||||
activity.lifecycleScope.launch {
|
||||
MagiskInstaller.Restore().exec { success ->
|
||||
dialog.dismiss()
|
||||
if (success) {
|
||||
activity.toast(R.string.restore_done, Toast.LENGTH_SHORT)
|
||||
} else {
|
||||
activity.toast(R.string.restore_fail, Toast.LENGTH_LONG)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,116 @@
|
||||
package com.topjohnwu.magisk.ui.module
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.core.view.isVisible
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.BaseFragment
|
||||
import com.topjohnwu.magisk.arch.viewModel
|
||||
import com.topjohnwu.magisk.core.ktx.toast
|
||||
import com.topjohnwu.magisk.databinding.FragmentActionMd2Binding
|
||||
import com.topjohnwu.magisk.ui.flash.FlashViewModel
|
||||
import timber.log.Timber
|
||||
import com.topjohnwu.magisk.core.R as CoreR
|
||||
|
||||
class ActionFragment : BaseFragment<FragmentActionMd2Binding>(), MenuProvider {
|
||||
|
||||
override val layoutRes = R.layout.fragment_action_md2
|
||||
override val viewModel by viewModel<ActionViewModel>()
|
||||
override val snackbarView: View get() = binding.snackbarContainer
|
||||
|
||||
private var defaultOrientation = -1
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
viewModel.args = ActionFragmentArgs.fromBundle(requireArguments())
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
activity?.setTitle(viewModel.args.name)
|
||||
binding.closeBtn.setOnClickListener {
|
||||
activity?.onBackPressed();
|
||||
}
|
||||
|
||||
viewModel.state.observe(this) {
|
||||
activity?.supportActionBar?.setSubtitle(
|
||||
when (it) {
|
||||
ActionViewModel.State.RUNNING -> CoreR.string.running
|
||||
ActionViewModel.State.SUCCESS -> CoreR.string.done
|
||||
ActionViewModel.State.FAILED -> CoreR.string.failure
|
||||
}
|
||||
)
|
||||
when (it) {
|
||||
ActionViewModel.State.SUCCESS -> {
|
||||
activity?.apply {
|
||||
toast(
|
||||
getString(
|
||||
com.topjohnwu.magisk.core.R.string.done_action,
|
||||
this@ActionFragment.viewModel.args.name
|
||||
), Toast.LENGTH_LONG
|
||||
)
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
ActionViewModel.State.FAILED -> {
|
||||
binding.closeBtn.apply {
|
||||
if (!this.isVisible) this.show()
|
||||
if (!this.isFocused) this.requestFocus()
|
||||
}
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_flash, menu)
|
||||
}
|
||||
|
||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||
return viewModel.onMenuItemClicked(item)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
defaultOrientation = activity?.requestedOrientation ?: -1
|
||||
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
|
||||
if (savedInstanceState == null) {
|
||||
viewModel.startRunAction()
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("WrongConstant")
|
||||
override fun onDestroyView() {
|
||||
if (defaultOrientation != -1) {
|
||||
activity?.requestedOrientation = defaultOrientation
|
||||
}
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onKeyEvent(event: KeyEvent): Boolean {
|
||||
return when (event.keyCode) {
|
||||
KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN -> true
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed(): Boolean {
|
||||
if (viewModel.state.value == ActionViewModel.State.RUNNING) return true
|
||||
return super.onBackPressed()
|
||||
}
|
||||
|
||||
override fun onPreBind(binding: FragmentActionMd2Binding) = Unit
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
package com.topjohnwu.magisk.ui.module
|
||||
|
||||
import android.view.MenuItem
|
||||
import androidx.databinding.Bindable
|
||||
import androidx.databinding.ObservableArrayList
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.map
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.BaseViewModel
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
import com.topjohnwu.magisk.core.ktx.synchronized
|
||||
import com.topjohnwu.magisk.core.ktx.timeFormatStandard
|
||||
import com.topjohnwu.magisk.core.ktx.toTime
|
||||
import com.topjohnwu.magisk.core.tasks.RunAction
|
||||
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
|
||||
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
|
||||
import com.topjohnwu.magisk.databinding.set
|
||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.ui.flash.ConsoleItem
|
||||
import com.topjohnwu.superuser.CallbackList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class ActionViewModel : BaseViewModel() {
|
||||
|
||||
enum class State {
|
||||
RUNNING, SUCCESS, FAILED
|
||||
}
|
||||
|
||||
private val _state = MutableLiveData(State.RUNNING)
|
||||
val state: LiveData<State> get() = _state
|
||||
val running = state.map { it == State.RUNNING }
|
||||
|
||||
val items = ObservableArrayList<ConsoleItem>()
|
||||
lateinit var args: ActionFragmentArgs
|
||||
|
||||
private val logItems = mutableListOf<String>().synchronized()
|
||||
private val outItems = object : CallbackList<String>() {
|
||||
override fun onAddElement(e: String?) {
|
||||
e ?: return
|
||||
items.add(ConsoleItem(e))
|
||||
logItems.add(e)
|
||||
}
|
||||
}
|
||||
|
||||
fun startRunAction() {
|
||||
viewModelScope.launch {
|
||||
onResult(RunAction(args.id, outItems, logItems).exec())
|
||||
}
|
||||
}
|
||||
|
||||
private fun onResult(success: Boolean) {
|
||||
_state.value = if (success) State.SUCCESS else State.FAILED
|
||||
}
|
||||
|
||||
fun onMenuItemClicked(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.action_save -> savePressed()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun savePressed() = withExternalRW {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val name = "%s_action_log_%s.log".format(
|
||||
args.name,
|
||||
System.currentTimeMillis().toTime(timeFormatStandard)
|
||||
)
|
||||
val file = MediaStoreUtils.getFile(name)
|
||||
file.uri.outputStream().bufferedWriter().use { writer ->
|
||||
synchronized(logItems) {
|
||||
logItems.forEach {
|
||||
writer.write(it)
|
||||
writer.newLine()
|
||||
}
|
||||
}
|
||||
}
|
||||
SnackbarEvent(file.toString()).publish()
|
||||
}
|
||||
}
|
||||
}
|
@@ -25,6 +25,7 @@ class LocalModuleRvItem(
|
||||
override val layoutRes = R.layout.item_module_md2
|
||||
|
||||
val showNotice: Boolean
|
||||
val showAction: Boolean
|
||||
val noticeText: TextHolder
|
||||
|
||||
init {
|
||||
@@ -35,6 +36,7 @@ class LocalModuleRvItem(
|
||||
showNotice = zygiskUnloaded ||
|
||||
(Info.isZygiskEnabled && isRiru) ||
|
||||
(!Info.isZygiskEnabled && isZygisk)
|
||||
showAction = item.hasAction && !showNotice
|
||||
noticeText =
|
||||
when {
|
||||
zygiskUnloaded -> CoreR.string.zygisk_module_unloaded.asText()
|
||||
|
@@ -4,8 +4,10 @@ import android.net.Uri
|
||||
import androidx.databinding.Bindable
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.MainDirections
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.AsyncLoadViewModel
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
import com.topjohnwu.magisk.core.base.ContentResultCallback
|
||||
import com.topjohnwu.magisk.core.model.module.LocalModule
|
||||
@@ -96,6 +98,10 @@ class ModuleViewModel : AsyncLoadViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
fun runAction(id: String, name: String) {
|
||||
MainDirections.actionActionFragment(id, name).navigate()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val uri = MutableLiveData<Uri?>()
|
||||
}
|
||||
|
@@ -78,8 +78,8 @@ class SuperuserViewModel(
|
||||
this@SuperuserViewModel, policy,
|
||||
info.packageName,
|
||||
info.sharedUserId != null,
|
||||
info.applicationInfo.loadIcon(pm),
|
||||
info.applicationInfo.getLabel(pm)
|
||||
info.applicationInfo?.loadIcon(pm) ?: pm.defaultActivityIcon,
|
||||
info.applicationInfo?.getLabel(pm) ?: info.packageName
|
||||
)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
null
|
||||
|
@@ -111,7 +111,7 @@ class SuRequestViewModel(
|
||||
// shared UID. We have no way to know where this request comes from.
|
||||
icon = pm.defaultActivityIcon
|
||||
title = "[SharedUID] ${info.sharedUserId}"
|
||||
packageName = info.sharedUserId
|
||||
packageName = info.sharedUserId.toString()
|
||||
} else {
|
||||
val prefix = if (info.sharedUserId == null) "" else "[SharedUID] "
|
||||
icon = app.loadIcon(pm)
|
||||
|
5
app/apk/src/main/res/drawable/ic_action_md2.xml
Normal file
5
app/apk/src/main/res/drawable/ic_action_md2.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||
|
||||
<path android:fillColor="@android:color/white" android:pathData="M8,5v14l11,-7z"/>
|
||||
|
||||
</vector>
|
68
app/apk/src/main/res/layout/fragment_action_md2.xml
Normal file
68
app/apk/src/main/res/layout/fragment_action_md2.xml
Normal file
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<data>
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="com.topjohnwu.magisk.ui.module.ActionViewModel" />
|
||||
|
||||
</data>
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<HorizontalScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/internal_action_bar_size"
|
||||
app:layout_fitsSystemWindowsInsets="top"
|
||||
tools:layout_marginTop="@dimen/internal_action_bar_size">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/flash_content"
|
||||
scrollToLast="@{true}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
app:fitsSystemWindowsInsets="start|end|bottom"
|
||||
app:items="@{viewModel.items}"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:listitem="@layout/item_console_md2" />
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/close_btn"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="@dimen/l1"
|
||||
android:layout_marginBottom="@dimen/l1"
|
||||
android:clickable="true"
|
||||
android:enabled="true"
|
||||
android:focusable="true"
|
||||
android:text="@string/close"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="?colorOnPrimary"
|
||||
android:textStyle="bold"
|
||||
app:backgroundTint="?colorPrimary"
|
||||
app:icon="@drawable/ic_close_md2"
|
||||
app:iconTint="?colorOnPrimary"
|
||||
app:layout_fitsSystemWindowsInsets="bottom" />
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/snackbar_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:fitsSystemWindowsInsets="top|bottom" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
</layout>
|
@@ -189,12 +189,32 @@
|
||||
android:textColor="?colorError"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/module_remove"
|
||||
app:layout_constraintEnd_toStartOf="@+id/bottom_bar_barrier"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/module_config"
|
||||
app:layout_constraintTop_toTopOf="@+id/module_remove"
|
||||
tools:lines="2"
|
||||
tools:text="@tools:sample/lorem/random"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/module_config"
|
||||
style="@style/WidgetFoundation.Button.Text"
|
||||
goneUnless="@{item.showAction}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:enabled="@{item.enabled}"
|
||||
android:focusable="true"
|
||||
android:onClick="@{() -> viewModel.runAction(item.item.id, item.item.name)}"
|
||||
android:text="@string/module_action"
|
||||
android:textAllCaps="false"
|
||||
android:visibility="gone"
|
||||
app:icon="@drawable/ic_action_md2"
|
||||
app:iconGravity="textStart"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/module_remove"
|
||||
app:layout_constraintTop_toTopOf="@+id/module_remove"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:srcCompat="@drawable/ic_download_md2" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
@@ -53,6 +53,21 @@
|
||||
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/actionFragment"
|
||||
android:name="com.topjohnwu.magisk.ui.module.ActionFragment"
|
||||
android:label="ActionFragment"
|
||||
tools:layout="@layout/fragment_action_md2" >
|
||||
|
||||
<argument
|
||||
android:name="id"
|
||||
app:argType="string" />
|
||||
|
||||
<argument
|
||||
android:name="name"
|
||||
app:argType="string" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/installFragment"
|
||||
android:name="com.topjohnwu.magisk.ui.install.InstallFragment"
|
||||
@@ -152,4 +167,12 @@
|
||||
app:popEnterAnim="@anim/fragment_enter_pop"
|
||||
app:popExitAnim="@anim/fragment_exit_pop" />
|
||||
|
||||
<action
|
||||
android:id="@+id/action_actionFragment"
|
||||
app:destination="@id/actionFragment"
|
||||
app:enterAnim="@anim/fragment_enter"
|
||||
app:exitAnim="@anim/fragment_exit"
|
||||
app:popEnterAnim="@anim/fragment_enter_pop"
|
||||
app:popExitAnim="@anim/fragment_exit_pop" />
|
||||
|
||||
</navigation>
|
||||
|
5
app/build.gradle.kts
Normal file
5
app/build.gradle.kts
Normal file
@@ -0,0 +1,5 @@
|
||||
tasks.register("clean") {
|
||||
subprojects.forEach {
|
||||
dependsOn(":app:${it.name}:clean")
|
||||
}
|
||||
}
|
@@ -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.0")
|
||||
implementation("androidx.collection:collection-ktx:1.4.1")
|
||||
implementation("androidx.profileinstaller:profileinstaller:1.3.1")
|
||||
implementation("androidx.lifecycle:lifecycle-process:2.8.3")
|
||||
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
|
||||
|
@@ -37,6 +37,7 @@ data class LocalModule(
|
||||
val isRiru: Boolean get() = (id == "riru-core") || riruFolder.exists()
|
||||
val isZygisk: Boolean get() = zygiskFolder.exists()
|
||||
val zygiskUnloaded: Boolean get() = unloaded.exists()
|
||||
val hasAction: Boolean;
|
||||
|
||||
var enable: Boolean
|
||||
get() = !disableFile.exists()
|
||||
@@ -100,6 +101,8 @@ data class LocalModule(
|
||||
if (name.isEmpty()) {
|
||||
name = id
|
||||
}
|
||||
|
||||
hasAction = RootUtils.fs.getFile(path, "action.sh").exists()
|
||||
}
|
||||
|
||||
suspend fun fetch(): Boolean {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package com.topjohnwu.magisk.core.model.su
|
||||
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.PackageManager
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
@@ -24,7 +24,7 @@ class SuLog(
|
||||
}
|
||||
|
||||
fun PackageManager.createSuLog(
|
||||
info: PackageInfo,
|
||||
info: ApplicationInfo,
|
||||
toUid: Int,
|
||||
fromPid: Int,
|
||||
command: String,
|
||||
@@ -33,13 +33,12 @@ fun PackageManager.createSuLog(
|
||||
context: String,
|
||||
gids: String,
|
||||
): SuLog {
|
||||
val appInfo = info.applicationInfo
|
||||
return SuLog(
|
||||
fromUid = appInfo.uid,
|
||||
fromUid = info.uid,
|
||||
toUid = toUid,
|
||||
fromPid = fromPid,
|
||||
packageName = getNameForUid(appInfo.uid)!!,
|
||||
appName = appInfo.getLabel(this),
|
||||
packageName = getNameForUid(info.uid)!!,
|
||||
appName = info.getLabel(this),
|
||||
command = command,
|
||||
action = policy,
|
||||
target = target,
|
||||
|
@@ -64,7 +64,7 @@ object SuCallbackHandler {
|
||||
val pm = context.packageManager
|
||||
|
||||
val log = runCatching {
|
||||
pm.getPackageInfo(fromUid, pid)?.let {
|
||||
pm.getPackageInfo(fromUid, pid)?.applicationInfo?.let {
|
||||
pm.createSuLog(it, toUid, pid, command, policy, target, seContext, gids)
|
||||
}
|
||||
}.getOrNull() ?: createSuLog(fromUid, toUid, pid, command, policy, target, seContext, gids)
|
||||
|
@@ -125,8 +125,9 @@ object AppMigration {
|
||||
apk: File, out: OutputStream,
|
||||
pkg: String, label: CharSequence
|
||||
): Boolean {
|
||||
val info = context.packageManager.getPackageArchiveInfo(apk.path, 0) ?: return false
|
||||
val origLabel = info.applicationInfo.nonLocalizedLabel.toString()
|
||||
val pm = context.packageManager
|
||||
val info = pm.getPackageArchiveInfo(apk.path, 0)?.applicationInfo ?: return false
|
||||
val origLabel = info.nonLocalizedLabel.toString()
|
||||
try {
|
||||
JarMap.open(apk, true).use { jar ->
|
||||
val je = jar.getJarEntry(ANDROID_MANIFEST)
|
||||
@@ -190,11 +191,12 @@ object AppMigration {
|
||||
|
||||
// Install and auto launch app
|
||||
val session = APKInstall.startSession(activity, pkg, onFailure) {
|
||||
Config.suManager = pkg
|
||||
Shell.cmd("touch $AppApkPath").exec()
|
||||
launchApp(activity, pkg)
|
||||
}
|
||||
|
||||
Config.suManager = pkg
|
||||
val cmd = "touch $AppApkPath; adb_pm_install $repack $pkg"
|
||||
val cmd = "adb_pm_install $repack $pkg"
|
||||
if (Shell.cmd(cmd).exec().isSuccess) return true
|
||||
|
||||
try {
|
||||
@@ -239,11 +241,12 @@ object AppMigration {
|
||||
}
|
||||
val apk = StubApk.current(activity)
|
||||
val session = APKInstall.startSession(activity, APP_PACKAGE_NAME, onFailure) {
|
||||
Config.suManager = ""
|
||||
Shell.cmd("touch $AppApkPath").exec()
|
||||
launchApp(activity, APP_PACKAGE_NAME)
|
||||
dialog.dismiss()
|
||||
}
|
||||
Config.suManager = ""
|
||||
val cmd = "touch $AppApkPath; adb_pm_install $apk $APP_PACKAGE_NAME"
|
||||
val cmd = "adb_pm_install $apk $APP_PACKAGE_NAME"
|
||||
if (Shell.cmd(cmd).await().isSuccess) return
|
||||
val success = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
|
@@ -6,7 +6,6 @@ import android.system.ErrnoException
|
||||
import android.system.Os
|
||||
import android.system.OsConstants
|
||||
import android.system.OsConstants.O_WRONLY
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.WorkerThread
|
||||
import androidx.core.os.postDelayed
|
||||
import com.topjohnwu.magisk.StubApk
|
||||
@@ -15,13 +14,10 @@ import com.topjohnwu.magisk.core.BuildConfig
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
import com.topjohnwu.magisk.core.R
|
||||
import com.topjohnwu.magisk.core.di.ServiceLocator
|
||||
import com.topjohnwu.magisk.core.isRunningAsStub
|
||||
import com.topjohnwu.magisk.core.ktx.copyAll
|
||||
import com.topjohnwu.magisk.core.ktx.copyAndClose
|
||||
import com.topjohnwu.magisk.core.ktx.reboot
|
||||
import com.topjohnwu.magisk.core.ktx.toast
|
||||
import com.topjohnwu.magisk.core.ktx.writeTo
|
||||
import com.topjohnwu.magisk.core.utils.DummyList
|
||||
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
|
||||
@@ -134,10 +130,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 {
|
||||
@@ -583,6 +581,8 @@ abstract class MagiskInstallImpl protected constructor(
|
||||
|
||||
protected suspend fun fixEnv() = extractFiles() && "fix_env $installDir".sh().isSuccess
|
||||
|
||||
protected fun restore() = findImage() && "restore_imgs $srcBoot".sh().isSuccess
|
||||
|
||||
protected fun uninstall() = "run_uninstaller $AppApkPath".sh().isSuccess
|
||||
|
||||
@WorkerThread
|
||||
@@ -606,11 +606,10 @@ abstract class MagiskInstallImpl protected constructor(
|
||||
}
|
||||
}
|
||||
|
||||
abstract class MagiskInstaller(
|
||||
abstract class ConsoleInstaller(
|
||||
console: MutableList<String>,
|
||||
logs: MutableList<String>
|
||||
) : MagiskInstallImpl(console, logs) {
|
||||
|
||||
override suspend fun exec(): Boolean {
|
||||
val success = super.exec()
|
||||
if (success) {
|
||||
@@ -620,40 +619,51 @@ abstract class MagiskInstaller(
|
||||
}
|
||||
return success
|
||||
}
|
||||
}
|
||||
|
||||
abstract class CallBackInstaller : MagiskInstallImpl(DummyList, DummyList) {
|
||||
suspend fun exec(callback: (Boolean) -> Unit): Boolean {
|
||||
val success = exec()
|
||||
callback(success)
|
||||
return success
|
||||
}
|
||||
}
|
||||
|
||||
class MagiskInstaller {
|
||||
|
||||
class Patch(
|
||||
private val uri: Uri,
|
||||
console: MutableList<String>,
|
||||
logs: MutableList<String>
|
||||
) : MagiskInstaller(console, logs) {
|
||||
) : ConsoleInstaller(console, logs) {
|
||||
override suspend fun operations() = patchFile(uri)
|
||||
}
|
||||
|
||||
class SecondSlot(
|
||||
console: MutableList<String>,
|
||||
logs: MutableList<String>
|
||||
) : MagiskInstaller(console, logs) {
|
||||
) : ConsoleInstaller(console, logs) {
|
||||
override suspend fun operations() = secondSlot()
|
||||
}
|
||||
|
||||
class Direct(
|
||||
console: MutableList<String>,
|
||||
logs: MutableList<String>
|
||||
) : MagiskInstaller(console, logs) {
|
||||
) : ConsoleInstaller(console, logs) {
|
||||
override suspend fun operations() = direct()
|
||||
}
|
||||
|
||||
class Emulator(
|
||||
console: MutableList<String>,
|
||||
logs: MutableList<String>
|
||||
) : MagiskInstaller(console, logs) {
|
||||
) : ConsoleInstaller(console, logs) {
|
||||
override suspend fun operations() = fixEnv()
|
||||
}
|
||||
|
||||
class Uninstall(
|
||||
console: MutableList<String>,
|
||||
logs: MutableList<String>
|
||||
) : MagiskInstallImpl(console, logs) {
|
||||
) : ConsoleInstaller(console, logs) {
|
||||
override suspend fun operations() = uninstall()
|
||||
|
||||
override suspend fun exec(): Boolean {
|
||||
@@ -667,19 +677,11 @@ abstract class MagiskInstaller(
|
||||
}
|
||||
}
|
||||
|
||||
class FixEnv(private val callback: () -> Unit) : MagiskInstallImpl(DummyList, DummyList) {
|
||||
override suspend fun operations() = fixEnv()
|
||||
class Restore : CallBackInstaller() {
|
||||
override suspend fun operations() = restore()
|
||||
}
|
||||
|
||||
override suspend fun exec(): Boolean {
|
||||
val success = super.exec()
|
||||
callback()
|
||||
context.toast(
|
||||
if (success) R.string.reboot_delay_toast else R.string.setup_fail,
|
||||
Toast.LENGTH_LONG
|
||||
)
|
||||
if (success)
|
||||
UiThreadHandler.handler.postDelayed(5000) { reboot() }
|
||||
return success
|
||||
}
|
||||
class FixEnv : CallBackInstaller() {
|
||||
override suspend fun operations() = fixEnv()
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,42 @@
|
||||
package com.topjohnwu.magisk.core.tasks
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.core.net.toFile
|
||||
import com.topjohnwu.magisk.core.AppContext
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
import com.topjohnwu.magisk.core.ktx.writeTo
|
||||
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.displayName
|
||||
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream
|
||||
import com.topjohnwu.magisk.core.utils.unzip
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
|
||||
open class RunAction(
|
||||
private val module: String,
|
||||
private val console: MutableList<String>,
|
||||
private val logs: MutableList<String>
|
||||
) {
|
||||
@Throws(IOException::class)
|
||||
private suspend fun run(): Boolean {
|
||||
return Shell.cmd("run_action \'$module\'").to(console, logs).exec().isSuccess
|
||||
}
|
||||
|
||||
open suspend fun exec() = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
if (!run()) {
|
||||
console.add("! Run action failed")
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
Timber.e(e)
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
@@ -105,6 +105,7 @@
|
||||
<string name="reboot_safe_mode">Modo de segurança</string>
|
||||
<string name="module_version_author">%1$s por %2$s</string>
|
||||
<string name="module_state_remove">Remover</string>
|
||||
<string name="module_action">Ação</string>
|
||||
<string name="module_state_restore">Restaurar</string>
|
||||
<string name="module_action_install_external">Instalar a partir do armazenamento</string>
|
||||
<string name="update_available">Atualização disponível</string>
|
||||
@@ -173,7 +174,7 @@
|
||||
<string name="settings_doh_title">DNS sobre HTTPS</string>
|
||||
<string name="settings_doh_description">Solução alternativa para envenenamento de DNS em alguns países</string>
|
||||
<string name="settings_random_name_title">Randomizar nome de saída</string>
|
||||
<string name="settings_random_name_description">Randomize o nome do arquivo de saída de imagens corrigidas e arquivos tar para evitar a detecção</string>
|
||||
<string name="settings_random_name_description">Randomize o nome do arquivo de saída de imagens corrigidas e arquivos tar (*.tar) para evitar a detecção</string>
|
||||
<string name="multiuser_mode">Modo multiusuário</string>
|
||||
<string name="settings_owner_only">Somente proprietário do dispositivo</string>
|
||||
<string name="settings_owner_manage">Gerenciado pelo proprietário do dispositivo</string>
|
||||
@@ -205,9 +206,12 @@
|
||||
<string name="repo_install_title">Instalar %1$s %2$s(%3$d)</string>
|
||||
<string name="download">Baixar</string>
|
||||
<string name="reboot">Reiniciar</string>
|
||||
<string name="close">Fechar</string>
|
||||
<string name="release_notes">Notas da atualização</string>
|
||||
<string name="flashing">Flashando…</string>
|
||||
<string name="running">Executando…</string>
|
||||
<string name="done">Concluído!</string>
|
||||
<string name="done_action">Ação de execução de %1$s concluída</string>
|
||||
<string name="failure">Falhou!</string>
|
||||
<string name="hide_app_title">Ocultando o app do Magisk…</string>
|
||||
<string name="open_link_failed_toast">Nenhum app encontrado para abrir o link</string>
|
||||
|
@@ -105,6 +105,7 @@
|
||||
<string name="reboot_safe_mode">Modo de segurança</string>
|
||||
<string name="module_version_author">%1$s por %2$s</string>
|
||||
<string name="module_state_remove">Remover</string>
|
||||
<string name="module_action">Ação</string>
|
||||
<string name="module_state_restore">Restaurar</string>
|
||||
<string name="module_action_install_external">Instalar a partir do armazenamento</string>
|
||||
<string name="update_available">Atualização disponível</string>
|
||||
@@ -173,7 +174,7 @@
|
||||
<string name="settings_doh_title">DNS sobre HTTPS</string>
|
||||
<string name="settings_doh_description">Solução alternativa para envenenamento de DNS em alguns países</string>
|
||||
<string name="settings_random_name_title">Randomizar nome de saída</string>
|
||||
<string name="settings_random_name_description">Randomize o nome do arquivo de saída de imagens corrigidas e arquivos tar para evitar a detecção</string>
|
||||
<string name="settings_random_name_description">Randomize o nome do arquivo de saída de imagens corrigidas e arquivos tar (*.tar) para evitar a detecção</string>
|
||||
<string name="multiuser_mode">Modo multiusuário</string>
|
||||
<string name="settings_owner_only">Somente proprietário do dispositivo</string>
|
||||
<string name="settings_owner_manage">Gerenciado pelo proprietário do dispositivo</string>
|
||||
@@ -205,9 +206,12 @@
|
||||
<string name="repo_install_title">Instalar %1$s %2$s(%3$d)</string>
|
||||
<string name="download">Baixar</string>
|
||||
<string name="reboot">Reiniciar</string>
|
||||
<string name="close">Fechar</string>
|
||||
<string name="release_notes">Notas da atualização</string>
|
||||
<string name="flashing">Flashando…</string>
|
||||
<string name="running">Executando…</string>
|
||||
<string name="done">Concluído!</string>
|
||||
<string name="done_action">Ação de execução de %1$s concluída</string>
|
||||
<string name="failure">Falhou!</string>
|
||||
<string name="hide_app_title">Ocultando o app do Magisk…</string>
|
||||
<string name="open_link_failed_toast">Nenhum app encontrado para abrir o link</string>
|
||||
|
@@ -74,7 +74,6 @@
|
||||
<string name="su_revoke_msg">Konfirmo për të hequr të drejtat e %1$s?</string>
|
||||
<string name="toast">Dolli</string>
|
||||
<string name="none">Asnjë</string>
|
||||
|
||||
<string name="superuser_toggle_notification">Njoftimet</string>
|
||||
<string name="superuser_toggle_revoke">Të drejtat</string>
|
||||
<string name="superuser_policy_none">Asnjë aplikacion nuk ka kërkuar akoma akses për super-përdoruesin.</string>
|
||||
@@ -91,8 +90,6 @@
|
||||
<string name="selinux_context">Konteksti SELinux: %s</string>
|
||||
<string name="supp_group">Grupi suplementar: %s</string>
|
||||
|
||||
<!--SafetyNet-->
|
||||
|
||||
<!--MagiskHide-->
|
||||
<string name="show_system_app">Shfaq aplikacionet e sistemit</string>
|
||||
<string name="show_os_app">Shfaq aplikacionet e sistemit operativ</string>
|
||||
@@ -109,6 +106,7 @@
|
||||
<string name="reboot_safe_mode">Rinis në safe mode</string>
|
||||
<string name="module_version_author">%1$s nga %2$s</string>
|
||||
<string name="module_state_remove">Hiqe</string>
|
||||
<string name="module_action">Veprim</string>
|
||||
<string name="module_state_restore">Rikëthe</string>
|
||||
<string name="module_action_install_external">Instaloni nga sdcard</string>
|
||||
<string name="update_available">Përditësimi në dispozicion</string>
|
||||
@@ -207,9 +205,12 @@
|
||||
<string name="repo_install_title">Instalo %1$s %2$s(%3$d)</string>
|
||||
<string name="download">Shkarko</string>
|
||||
<string name="reboot">Rinis</string>
|
||||
<string name="close">Mbylle</string>
|
||||
<string name="release_notes">Shënimet e lëshimit</string>
|
||||
<string name="flashing">Duke flashuar…</string>
|
||||
<string name="running">Duke vepruar...</string>
|
||||
<string name="done">U krye!</string>
|
||||
<string name="done_action">Veprimi i ekzekutimit të %1$s u krye</string>
|
||||
<string name="failure">Dështoi!</string>
|
||||
<string name="hide_app_title">Fshehja e aplikacionit Magisk…</string>
|
||||
<string name="open_link_failed_toast">Nuk u gjet asnjë aplikacion për të hapur lidhjen</string>
|
||||
|
@@ -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>
|
||||
|
@@ -109,6 +109,7 @@
|
||||
<string name="reboot_safe_mode">安全模式</string>
|
||||
<string name="module_version_author">%1$s,作者 %2$s</string>
|
||||
<string name="module_state_remove">移除</string>
|
||||
<string name="module_action">操作</string>
|
||||
<string name="module_state_restore">还原</string>
|
||||
<string name="module_action_install_external">从本地安装</string>
|
||||
<string name="update_available">可更新</string>
|
||||
@@ -176,6 +177,8 @@
|
||||
<string name="setting_add_shortcut_summary">在隐藏后难以识别名称和图标的情况下,添加快捷方式到桌面</string>
|
||||
<string name="settings_doh_title">安全 DNS(DoH)</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="settings_owner_only">仅设备所有者</string>
|
||||
@@ -209,9 +212,12 @@
|
||||
<string name="repo_install_title">安装 %1$s %2$s(%3$d)</string>
|
||||
<string name="download">下载</string>
|
||||
<string name="reboot">重启</string>
|
||||
<string name="close">关闭</string>
|
||||
<string name="release_notes">发布说明</string>
|
||||
<string name="flashing">正在刷入</string>
|
||||
<string name="running">运行中……</string>
|
||||
<string name="done">完成!</string>
|
||||
<string name="done_action">%1$s 操作运行完成</string>
|
||||
<string name="failure">失败</string>
|
||||
<string name="hide_app_title">正在隐藏 Magisk 应用</string>
|
||||
<string name="open_link_failed_toast">找不到能打开此链接的应用</string>
|
||||
|
@@ -109,6 +109,7 @@
|
||||
<string name="reboot_safe_mode">Safe mode</string>
|
||||
<string name="module_version_author">%1$s by %2$s</string>
|
||||
<string name="module_state_remove">Remove</string>
|
||||
<string name="module_action">Action</string>
|
||||
<string name="module_state_restore">Restore</string>
|
||||
<string name="module_action_install_external">Install from storage</string>
|
||||
<string name="update_available">Update Available</string>
|
||||
@@ -211,9 +212,12 @@
|
||||
<string name="repo_install_title">Install %1$s %2$s(%3$d)</string>
|
||||
<string name="download">Download</string>
|
||||
<string name="reboot">Reboot</string>
|
||||
<string name="close">Close</string>
|
||||
<string name="release_notes">Release notes</string>
|
||||
<string name="flashing">Flashing…</string>
|
||||
<string name="running">Running…</string>
|
||||
<string name="done">Done!</string>
|
||||
<string name="done_action">Done running action of %1$s</string>
|
||||
<string name="failure">Failed!</string>
|
||||
<string name="hide_app_title">Hiding the Magisk app…</string>
|
||||
<string name="open_link_failed_toast">No app found to open the link</string>
|
||||
|
@@ -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")
|
||||
|
@@ -6,7 +6,7 @@ plugins {
|
||||
lsparanoid {
|
||||
seed = if (RAND_SEED != 0) RAND_SEED else null
|
||||
includeDependencies = true
|
||||
global = true
|
||||
classFilter = { true }
|
||||
}
|
||||
|
||||
android {
|
||||
|
@@ -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>
|
||||
|
661
build.py
661
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",
|
||||
]
|
||||
default_targets = ["magisk", "magiskinit", "magiskboot", "magiskpolicy"]
|
||||
support_targets = default_targets + ["resetprop"]
|
||||
rust_targets = ["magisk", "magiskinit", "magiskboot", "magiskpolicy"]
|
||||
# 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,94 +188,127 @@ 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 tgt in support_targets + ["libinit-ld.so"]:
|
||||
source = Path("native", "libs", arch, tgt)
|
||||
target = Path("native", "out", arch, tgt)
|
||||
|
||||
for arch in build_abis.keys():
|
||||
arch_dir = Path("native", "libs", arch)
|
||||
out_dir = Path("native", "out", arch)
|
||||
for source in arch_dir.iterdir():
|
||||
target = out_dir / source.name
|
||||
mv(source, target)
|
||||
|
||||
|
||||
def build_cpp_src(targets: set):
|
||||
dump_flag_header()
|
||||
|
||||
cmds = []
|
||||
clean = False
|
||||
|
||||
if "magisk" in targets:
|
||||
cmds.append("B_MAGISK=1")
|
||||
clean = True
|
||||
|
||||
if "magiskpolicy" in targets:
|
||||
cmds.append("B_POLICY=1")
|
||||
clean = True
|
||||
|
||||
if "magiskinit" in targets:
|
||||
cmds.append("B_PRELOAD=1")
|
||||
|
||||
if "resetprop" in targets:
|
||||
cmds.append("B_PROP=1")
|
||||
|
||||
if cmds:
|
||||
run_ndk_build(cmds)
|
||||
|
||||
cmds.clear()
|
||||
|
||||
if "magiskinit" in targets:
|
||||
cmds.append("B_INIT=1")
|
||||
|
||||
if "magiskboot" in targets:
|
||||
cmds.append("B_BOOT=1")
|
||||
|
||||
if cmds:
|
||||
cmds.append("B_CRT0=1")
|
||||
run_ndk_build(cmds)
|
||||
|
||||
if clean:
|
||||
clean_elf()
|
||||
|
||||
|
||||
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 run_cargo_build(args):
|
||||
native_out = Path("..", "out")
|
||||
native_out.mkdir(mode=0o755, exist_ok=True)
|
||||
|
||||
targets = set(args.target) & set(rust_targets)
|
||||
if "resetprop" in args.target:
|
||||
def build_rust_src(targets: set):
|
||||
targets = targets.copy()
|
||||
if "resetprop" in targets:
|
||||
targets.add("magisk")
|
||||
|
||||
if len(targets) == 0:
|
||||
targets = targets & rust_targets
|
||||
if not targets:
|
||||
return
|
||||
|
||||
# Start building the actual build commands
|
||||
os.chdir(Path("native", "src"))
|
||||
|
||||
# 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 target in targets:
|
||||
cmds[2] = target
|
||||
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)
|
||||
|
||||
|
||||
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
|
||||
if file_name.exists():
|
||||
@@ -324,25 +320,6 @@ def write_if_diff(file_name: Path, text: str):
|
||||
f.write(text)
|
||||
|
||||
|
||||
def binary_dump(src, var_name, compressor=xz):
|
||||
out_str = f"constexpr unsigned char {var_name}[] = {{"
|
||||
for i, c in enumerate(compressor(src.read())):
|
||||
if i % 16 == 0:
|
||||
out_str += "\n"
|
||||
out_str += f"0x{c:02X},"
|
||||
out_str += "\n};\n"
|
||||
return out_str
|
||||
|
||||
|
||||
def dump_bin_header(args):
|
||||
native_gen_path.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
for arch in archs:
|
||||
preload = Path("native", "out", arch, "libinit-ld.so")
|
||||
with open(preload, "rb") as src:
|
||||
text = binary_dump(src, "init_ld_xz")
|
||||
write_if_diff(Path(native_gen_path, f"{arch}_binaries.h"), text)
|
||||
|
||||
|
||||
def dump_flag_header():
|
||||
flag_txt = textwrap.dedent(
|
||||
"""\
|
||||
@@ -361,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:
|
||||
@@ -369,65 +346,29 @@ def build_binary(args):
|
||||
except:
|
||||
error('Unmatched NDK. Please install/upgrade NDK with "build.py ndk"')
|
||||
|
||||
if "target" not in vars(args):
|
||||
vars(args)["target"] = []
|
||||
|
||||
if args.target:
|
||||
args.target = set(args.target) & set(support_targets)
|
||||
if not args.target:
|
||||
return
|
||||
if "targets" not in vars(args) or not args.targets:
|
||||
targets = default_targets
|
||||
else:
|
||||
args.target = default_targets
|
||||
targets = set(args.targets) & support_targets
|
||||
if not targets:
|
||||
return
|
||||
|
||||
header("* Building binaries: " + " ".join(args.target))
|
||||
header("* Building: " + " ".join(targets))
|
||||
|
||||
os.chdir(Path("native", "src"))
|
||||
run_cargo_build(args)
|
||||
os.chdir(Path("..", ".."))
|
||||
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
|
||||
|
||||
dump_flag_header()
|
||||
build_rust_src(targets)
|
||||
build_cpp_src(targets)
|
||||
|
||||
flag = ""
|
||||
clean = False
|
||||
|
||||
if "magisk" in args.target:
|
||||
flag += " B_MAGISK=1"
|
||||
clean = True
|
||||
|
||||
if "magiskpolicy" in args.target:
|
||||
flag += " B_POLICY=1"
|
||||
clean = True
|
||||
|
||||
if "magiskinit" in args.target:
|
||||
flag += " B_PRELOAD=1"
|
||||
|
||||
if "resetprop" in args.target:
|
||||
flag += " B_PROP=1"
|
||||
|
||||
if flag:
|
||||
run_ndk_build(args, flag)
|
||||
|
||||
flag = ""
|
||||
|
||||
if "magiskinit" in args.target:
|
||||
# magiskinit embeds preload.so
|
||||
dump_bin_header(args)
|
||||
flag += " B_INIT=1"
|
||||
|
||||
if "magiskboot" in args.target:
|
||||
flag += " B_BOOT=1"
|
||||
|
||||
if flag:
|
||||
flag += " B_CRT0=1"
|
||||
run_ndk_build(args, flag)
|
||||
|
||||
if clean:
|
||||
clean_elf()
|
||||
|
||||
# BusyBox is built with different API level
|
||||
|
||||
if "busybox" in args.target:
|
||||
run_ndk_build(args, "B_BB=1")
|
||||
############
|
||||
# Build App
|
||||
############
|
||||
|
||||
|
||||
def find_jdk():
|
||||
@@ -462,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"
|
||||
@@ -488,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"
|
||||
|
||||
@@ -506,28 +447,32 @@ 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"}
|
||||
if args.target:
|
||||
args.target = set(args.target) & support_targets
|
||||
if "native" in args.target:
|
||||
args.target.add("cpp")
|
||||
args.target.add("rust")
|
||||
################
|
||||
# Build General
|
||||
################
|
||||
|
||||
|
||||
def cleanup():
|
||||
support_targets = {"native", "cpp", "rust", "app"}
|
||||
if args.targets:
|
||||
targets = set(args.targets) & support_targets
|
||||
if "native" in targets:
|
||||
targets.add("cpp")
|
||||
targets.add("rust")
|
||||
else:
|
||||
args.target = support_targets
|
||||
targets = support_targets
|
||||
|
||||
if "cpp" in args.target:
|
||||
if "cpp" in targets:
|
||||
header("* Cleaning C++")
|
||||
rm_rf(Path("native", "libs"))
|
||||
rm_rf(Path("native", "obj"))
|
||||
rm_rf(Path("native", "out"))
|
||||
|
||||
if "rust" in args.target:
|
||||
if "rust" in targets:
|
||||
header("* Cleaning Rust")
|
||||
rm_rf(Path("native", "src", "target"))
|
||||
rm(Path("native", "src", "boot", "proto", "mod.rs"))
|
||||
@@ -535,21 +480,34 @@ def cleanup(args):
|
||||
for rs_gen in glob.glob("native/**/*-rs.*pp", recursive=True):
|
||||
rm(rs_gen)
|
||||
|
||||
if "java" in args.target:
|
||||
header("* Cleaning java")
|
||||
execv(
|
||||
[
|
||||
gradlew,
|
||||
":app:apk:clean",
|
||||
":app:core:clean",
|
||||
":app:shared:clean",
|
||||
":app:stub:clean",
|
||||
],
|
||||
env=find_jdk(),
|
||||
)
|
||||
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]
|
||||
@@ -568,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")
|
||||
@@ -596,37 +554,37 @@ 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:
|
||||
args.release = False
|
||||
build_all(args)
|
||||
build_all()
|
||||
|
||||
args.target = Path(args.target)
|
||||
src_file = f"/data/local/tmp/{args.target.name}"
|
||||
out_file = f"{src_file}.magisk"
|
||||
input = Path(args.image)
|
||||
if args.output:
|
||||
args.output = Path(args.output)
|
||||
output = Path(args.output)
|
||||
else:
|
||||
args.output = args.target.parent / f"{args.target.name}.magisk"
|
||||
output = input.parent / f"{input.name}.magisk"
|
||||
|
||||
header(f"* Patching {args.target.name}")
|
||||
src_file = f"/data/local/tmp/{input.name}"
|
||||
out_file = f"{src_file}.magisk"
|
||||
|
||||
push_files(args, Path("scripts", "avd_patch.sh"))
|
||||
header(f"* Patching {input.name}")
|
||||
|
||||
proc = execv([adb_path, "push", args.target, "/data/local/tmp"])
|
||||
push_files(Path("scripts", "avd_patch.sh"))
|
||||
|
||||
proc = execv([adb_path, "push", input, "/data/local/tmp"])
|
||||
if proc.returncode != 0:
|
||||
error("adb push failed!")
|
||||
|
||||
@@ -634,19 +592,14 @@ def patch_avd_file(args):
|
||||
if proc.returncode != 0:
|
||||
error("avd_patch.sh failed!")
|
||||
|
||||
proc = execv([adb_path, "pull", out_file, args.output])
|
||||
proc = execv([adb_path, "pull", out_file, output])
|
||||
if proc.returncode != 0:
|
||||
error("adb pull failed!")
|
||||
|
||||
header(f"Output: {args.output}")
|
||||
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)
|
||||
@@ -662,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}")
|
||||
@@ -674,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(
|
||||
"target",
|
||||
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("target", 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(
|
||||
"target", 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.5.2")
|
||||
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> {
|
||||
|
@@ -69,18 +69,18 @@ private val Project.androidComponents
|
||||
|
||||
fun Project.setupCommon() {
|
||||
androidBase {
|
||||
compileSdkVersion(34)
|
||||
compileSdkVersion(35)
|
||||
buildToolsVersion = "34.0.0"
|
||||
ndkPath = "$sdkDirectory/ndk/magisk"
|
||||
ndkVersion = "27.0.11902837"
|
||||
ndkVersion = "27.0.12077973"
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 23
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
@@ -108,31 +108,33 @@ fun Project.setupCommon() {
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
compilerOptions {
|
||||
jvmTarget = JvmTarget.JVM_17
|
||||
jvmTarget = JvmTarget.JVM_21
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const val BUSYBOX_DOWNLOAD_URL =
|
||||
"https://github.com/topjohnwu/magisk-files/releases/download/files/busybox-1.36.1.0.zip"
|
||||
"https://github.com/topjohnwu/magisk-files/releases/download/files/busybox-1.36.1.1.zip"
|
||||
const val BUSYBOX_ZIP_CHECKSUM =
|
||||
"ea4f3019b0087dcb68130b32ab59dc2db0ee0af11d8396124a94c4231c5ea441"
|
||||
"b4d0551feabaf314e53c79316c980e8f66432e9fb91a69dbbf10a93564b40951"
|
||||
|
||||
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")
|
||||
rename { "lib$it.so" }
|
||||
include("magiskboot", "magiskinit", "magiskpolicy", "magisk", "libinit-ld.so")
|
||||
rename { if (it.endsWith(".so")) it else "lib$it.so" }
|
||||
}
|
||||
}
|
||||
}
|
||||
onlyIf {
|
||||
if (inputs.sourceFiles.files.size != 20)
|
||||
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")
|
||||
}
|
||||
|
||||
@@ -293,7 +296,7 @@ fun Project.setupAppCommon() {
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
targetSdk = 34
|
||||
targetSdk = 35
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@@ -372,8 +375,8 @@ fun Project.setupStub() {
|
||||
val outAppClassDir = layout.buildDirectory.file("generated/source/app/${variantLowered}").get().asFile
|
||||
val outResDir = layout.buildDirectory.dir("generated/source/res/${variantLowered}").get().asFile
|
||||
val aapt = File(androidApp.sdkDirectory, "build-tools/${androidApp.buildToolsVersion}/aapt2")
|
||||
val apk = layout.buildDirectory.file("intermediates/processed_res/" +
|
||||
"${variantLowered}/process${variantCapped}Resources/out/resources-${variantLowered}.ap_").get().asFile
|
||||
val apk = layout.buildDirectory.file("intermediates/linked_resources_binary_format/" +
|
||||
"${variantLowered}/process${variantCapped}Resources/linked-resources-binary-format-${variantLowered}.ap_").get().asFile
|
||||
|
||||
val genManifestTask = tasks.register("generate${variantCapped}ObfuscatedClass") {
|
||||
inputs.property("seed", RAND_SEED)
|
||||
@@ -414,8 +417,8 @@ fun Project.setupStub() {
|
||||
registerJavaGeneratingTask(processResourcesTask, outResDir)
|
||||
}
|
||||
// Override optimizeReleaseResources task
|
||||
val apk = layout.buildDirectory.file("intermediates/processed_res/" +
|
||||
"release/processReleaseResources/out/resources-release.ap_").get().asFile
|
||||
val apk = layout.buildDirectory.file("intermediates/linked_resources_binary_format/" +
|
||||
"release/processReleaseResources/linked-resources-binary-format-release.ap_").get().asFile
|
||||
val optRes = layout.buildDirectory.file("intermediates/optimized_processed_res/" +
|
||||
"release/optimizeReleaseResources/resources-release-optimize.ap_").get().asFile
|
||||
afterEvaluate {
|
||||
|
@@ -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
|
||||
|
@@ -1,5 +1,29 @@
|
||||
# Magisk Changelog
|
||||
|
||||
### v28.0
|
||||
|
||||
- [General] Support 16k page size
|
||||
- [General] Add basic support for RISC-V (not built in releases)
|
||||
- [General] Use a minimal libc to build static executables (`magiskinit` and `magiskboot`) for smaller sizes
|
||||
- [Core] Remove unnecessary mirror for magic mount
|
||||
- [Core] Update boot image detection logic to support more devices
|
||||
- [MagiskInit] Rewrite 2SI logic for injecting `magiskinit` as `init`
|
||||
- [MagiskInit] Update preinit partition detection
|
||||
- [Zygisk] Update internal JNI hooking implementation
|
||||
- [MagiskPolicy] Preserve sepolicy config flag after patching
|
||||
- [MagiskPolicy] Optimize patching rules to reduce the amount of new rules being injected
|
||||
- [DenyList] Support enforcing denylist when Zygisk is disabled
|
||||
- [Resetprop] Improve implementation to workaround several property modification detections
|
||||
- [Resetprop] Update to properly work with property overlays
|
||||
- [App] Major internal code refactoring
|
||||
- [App] Support patching Samsung firmware with images larger than 8GiB
|
||||
- [App] Use user-initiated job instead of foreground services on Android 14
|
||||
- [App] Support Android 13+ built-in per-app language preferences
|
||||
- [App] Add `action.sh` support to allow modules to define an action triggered from UI
|
||||
- [MagiskBoot] Support spliting kernel images without decompression
|
||||
- [MagiskBoot] Properly support vendor boot images
|
||||
- [MagiskBoot] Disable Samsung PROCA from kernel image
|
||||
|
||||
### v27.0
|
||||
|
||||
- [Zygisk] Introduce new code injection mechanism
|
||||
|
@@ -54,6 +54,7 @@ A Magisk module is a folder placed in `/data/adb/modules` with the structure bel
|
||||
│ ├── post-fs-data.sh <--- This script will be executed in post-fs-data
|
||||
│ ├── service.sh <--- This script will be executed in late_start service
|
||||
| ├── uninstall.sh <--- This script will be executed when Magisk removes your module
|
||||
| ├── action.sh <--- This script will be executed when user click the action button in Magisk app
|
||||
│ ├── system.prop <--- Properties in this file will be loaded as system properties by resetprop
|
||||
│ ├── sepolicy.rule <--- Additional custom sepolicy rules
|
||||
│ │
|
||||
@@ -231,7 +232,7 @@ The list above will result in the following files being created: `$MODPATH/syste
|
||||
In Magisk, you can run boot scripts in 2 different modes: **post-fs-data** and **late_start service** mode.
|
||||
|
||||
- post-fs-data mode
|
||||
- This stage is BLOCKING. The boot process is paused before execution is done, or 10 seconds have passed.
|
||||
- This stage is BLOCKING. The boot process is paused before execution is done, or 40 seconds have passed.
|
||||
- Scripts run before any modules are mounted. This allows a module developer to dynamically adjust their modules before it gets mounted.
|
||||
- This stage happens before Zygote is started, which pretty much means everything in Android
|
||||
- **WARNING:** using `setprop` will deadlock the boot process! Please use `resetprop -n <prop_name> <prop_value>` instead.
|
||||
|
25
docs/releases/28000.md
Normal file
25
docs/releases/28000.md
Normal file
@@ -0,0 +1,25 @@
|
||||
## 2024.10.10 Magisk v28.0
|
||||
|
||||
- [General] Support 16k page size
|
||||
- [General] Add basic support for RISC-V (not built in releases)
|
||||
- [General] Use a minimal libc to build static executables (`magiskinit` and `magiskboot`) for smaller sizes
|
||||
- [Core] Remove unnecessary mirror for magic mount
|
||||
- [Core] Update boot image detection logic to support more devices
|
||||
- [MagiskInit] Rewrite 2SI logic for injecting `magiskinit` as `init`
|
||||
- [MagiskInit] Update preinit partition detection
|
||||
- [Zygisk] Update internal JNI hooking implementation
|
||||
- [MagiskPolicy] Preserve sepolicy config flag after patching
|
||||
- [MagiskPolicy] Optimize patching rules to reduce the amount of new rules being injected
|
||||
- [DenyList] Support enforcing denylist when Zygisk is disabled
|
||||
- [Resetprop] Improve implementation to workaround several property modification detections
|
||||
- [Resetprop] Update to properly work with property overlays
|
||||
- [App] Major internal code refactoring
|
||||
- [App] Support patching Samsung firmware with images larger than 8GiB
|
||||
- [App] Use user-initiated job instead of foreground services on Android 14
|
||||
- [App] Support Android 13+ built-in per-app language preferences
|
||||
- [App] Add `action.sh` support to allow modules to define an action triggered from UI
|
||||
- [MagiskBoot] Support spliting kernel images without decompression
|
||||
- [MagiskBoot] Properly support vendor boot images
|
||||
- [MagiskBoot] Disable Samsung PROCA from kernel image
|
||||
|
||||
### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
|
@@ -1,5 +1,6 @@
|
||||
# Release Notes
|
||||
|
||||
- [v28.0](28000.md)
|
||||
- [v27.0](27000.md)
|
||||
- [v26.4](26400.md)
|
||||
- [v26.3](26300.md)
|
||||
|
@@ -41,7 +41,9 @@ Supported actions:
|
||||
|
||||
repack [-n] <origbootimg> [outbootimg]
|
||||
Repack boot image components using files from the current directory
|
||||
to [outbootimg], or 'new-boot.img' if not specified.
|
||||
to [outbootimg], or 'new-boot.img' if not specified. Current directory
|
||||
should only contain required files for [outbootimg], or incorrect
|
||||
[outbootimg] may be produced.
|
||||
<origbootimg> is the original boot image used to unpack the components.
|
||||
By default, each component will be automatically compressed using its
|
||||
corresponding format detected in <origbootimg>. If a component file
|
||||
|
@@ -20,6 +20,9 @@ org.gradle.parallel=true
|
||||
# Enable build cache
|
||||
org.gradle.caching=true
|
||||
|
||||
# Use K2 in kapt
|
||||
kapt.use.k2=true
|
||||
|
||||
# Android
|
||||
android.useAndroidX=true
|
||||
android.injected.testOnly=false
|
||||
@@ -27,5 +30,5 @@ android.nonFinalResIds=false
|
||||
|
||||
# Magisk
|
||||
magisk.stubVersion=40
|
||||
magisk.versionCode=27005
|
||||
magisk.ondkVersion=r27.2
|
||||
magisk.versionCode=28001
|
||||
magisk.ondkVersion=r27.4
|
||||
|
66
gradle/libs.versions.toml
Normal file
66
gradle/libs.versions.toml
Normal file
@@ -0,0 +1,66 @@
|
||||
[versions]
|
||||
kotlin = "2.0.20"
|
||||
android = "8.7.0"
|
||||
ksp = "2.0.20-1.0.25"
|
||||
rikka = "1.3.0"
|
||||
navigation = "2.8.2"
|
||||
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.1" }
|
||||
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.2" }
|
||||
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.4" }
|
||||
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.4.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.4" }
|
||||
lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version = "2.8.6" }
|
||||
material = { module = "com.google.android.material:material", version = "1.12.0" }
|
||||
jdk-libs = { module = "com.android.tools:desugar_jdk_libs_nio", version = "2.1.2" }
|
||||
|
||||
# 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]
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
@@ -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"
|
||||
|
@@ -7,7 +7,7 @@ LOCAL_MODULE := libbase
|
||||
LOCAL_C_INCLUDES := \
|
||||
src/include \
|
||||
$(LOCAL_PATH)/include \
|
||||
$(LOCAL_PATH)/../external/cxx-rs/include \
|
||||
src/external/cxx-rs/include \
|
||||
out/generated
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
|
||||
LOCAL_EXPORT_STATIC_LIBRARIES := libcxx
|
||||
|
@@ -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]> {
|
||||
|
@@ -1,13 +0,0 @@
|
||||
#if defined(__arm__)
|
||||
#include <armeabi-v7a_binaries.h>
|
||||
#elif defined(__aarch64__)
|
||||
#include <arm64-v8a_binaries.h>
|
||||
#elif defined(__i386__)
|
||||
#include <x86_binaries.h>
|
||||
#elif defined(__x86_64__)
|
||||
#include <x86_64_binaries.h>
|
||||
#elif defined(__riscv)
|
||||
#include <riscv64_binaries.h>
|
||||
#else
|
||||
#error Unsupported ABI
|
||||
#endif
|
@@ -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,12 +348,25 @@ 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())) { \
|
||||
if ((base_addr + off) > (map.buf() + map_end)) { \
|
||||
fprintf(stderr, "Corrupted boot image!\n"); \
|
||||
return false; \
|
||||
}
|
||||
@@ -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) {
|
||||
@@ -388,6 +395,7 @@ bool boot_img::parse_image(const uint8_t *p, format_t type) {
|
||||
|
||||
hdr->print();
|
||||
|
||||
size_t map_end = align_to(map.sz(), getpagesize());
|
||||
size_t off = hdr->hdr_space();
|
||||
get_block(kernel);
|
||||
get_block(ramdisk);
|
||||
@@ -395,16 +403,13 @@ 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);
|
||||
tail = byte_view(tail_addr, map.buf() + map_end - tail_addr);
|
||||
|
||||
if (auto size = hdr->kernel_size()) {
|
||||
if (int dtb_off = find_dtb_offset(kernel, size); dtb_off > 0) {
|
||||
@@ -458,24 +463,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 +582,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 +635,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 +667,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 +751,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 +835,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,12 @@
|
||||
using namespace std;
|
||||
|
||||
#ifdef USE_CRT0
|
||||
__asm__(".global vfprintf \n vfprintf = musl_vfprintf");
|
||||
__asm__(".global vsscanf \n vsscanf = tfp_vsscanf");
|
||||
__BEGIN_DECLS
|
||||
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() {
|
||||
@@ -40,7 +44,9 @@ Supported actions:
|
||||
|
||||
repack [-n] <origbootimg> [outbootimg]
|
||||
Repack boot image components using files from the current directory
|
||||
to [outbootimg], or 'new-boot.img' if not specified.
|
||||
to [outbootimg], or 'new-boot.img' if not specified. Current directory
|
||||
should only contain required files for [outbootimg], or incorrect
|
||||
[outbootimg] may be produced.
|
||||
<origbootimg> is the original boot image used to unpack the components.
|
||||
By default, each component will be automatically compressed using its
|
||||
corresponding format detected in <origbootimg>. If a component file
|
||||
@@ -142,6 +148,8 @@ int main(int argc, char *argv[]) {
|
||||
unlink(EXTRA_FILE);
|
||||
unlink(RECV_DTBO_FILE);
|
||||
unlink(DTB_FILE);
|
||||
unlink(BOOTCONFIG_FILE);
|
||||
rm_rf(VND_RAMDISK_DIR);
|
||||
} else if (argc > 2 && action == "sha1") {
|
||||
uint8_t sha1[20];
|
||||
{
|
||||
|
@@ -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()?;
|
||||
}
|
||||
@@ -201,12 +205,16 @@ pub fn find_preinit_device() -> String {
|
||||
let (_, preinit_info, _) = matched_info.select_nth_unstable_by(
|
||||
0,
|
||||
|(ap, MountInfo { fs_type: at, .. }), (bp, MountInfo { fs_type: bt, .. })| match (
|
||||
ap,
|
||||
bp,
|
||||
at.as_str() == "ext4",
|
||||
bt.as_str() == "ext4",
|
||||
) {
|
||||
// take ext4 over others (f2fs) because f2fs has a kernel bug that causes kernel panic
|
||||
(true, false) => Less,
|
||||
(false, true) => Greater,
|
||||
// metadata is not affected by f2fs kernel bug
|
||||
(PartId::Metadata, _, _, true) | (_, PartId::Metadata, true, _) => ap.cmp(bp),
|
||||
// otherwise, take ext4 f2fs because f2fs has a kernel bug that causes kernel panic
|
||||
(_, _, true, false) => Less,
|
||||
(_, _, false, true) => Greater,
|
||||
// if both has the same fs type, compare the mount point
|
||||
_ => ap.cmp(bp),
|
||||
},
|
||||
|
@@ -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...795cab5ab6
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,8 +210,29 @@ 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)
|
||||
if (access("/first_stage_ramdisk", F_OK) == 0)
|
||||
return true;
|
||||
if (access("/second_stage_resources", F_OK) == 0)
|
||||
return true;
|
||||
if (access("/system/bin/init", F_OK) == 0)
|
||||
return true;
|
||||
|
@@ -6,14 +6,18 @@
|
||||
#include <xz.h>
|
||||
|
||||
#include <base.hpp>
|
||||
#include <embed.hpp>
|
||||
|
||||
#include "init.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef USE_CRT0
|
||||
__asm__(".global vfprintf \n vfprintf = tfp_vfprintf");
|
||||
__BEGIN_DECLS
|
||||
int tiny_vfprintf(FILE *stream, const char *format, va_list arg);
|
||||
int vfprintf(FILE *stream, const char *format, va_list arg) {
|
||||
return tiny_vfprintf(stream, format, arg);
|
||||
}
|
||||
__END_DECLS
|
||||
#endif
|
||||
|
||||
bool unxz(out_stream &strm, rust::Slice<const uint8_t> bytes) {
|
||||
@@ -86,15 +90,17 @@ int main(int argc, char *argv[]) {
|
||||
} else {
|
||||
// This will also mount /sys and /proc
|
||||
load_kernel_info(&config);
|
||||
bool recovery = access("/sbin/recovery", F_OK) == 0 ||
|
||||
access("/system/bin/recovery", F_OK) == 0;
|
||||
|
||||
if (config.skip_initramfs)
|
||||
if (config.force_normal_boot)
|
||||
init = new FirstStageInit(argv, &config);
|
||||
else if (!recovery && check_two_stage())
|
||||
init = new FirstStageInit(argv, &config);
|
||||
else if (config.skip_initramfs)
|
||||
init = new LegacySARInit(argv, &config);
|
||||
else if (config.force_normal_boot)
|
||||
init = new FirstStageInit(argv, &config);
|
||||
else if (access("/sbin/recovery", F_OK) == 0 || access("/system/bin/recovery", F_OK) == 0)
|
||||
else if (recovery)
|
||||
init = new RecoveryInit(argv, &config);
|
||||
else if (check_two_stage())
|
||||
init = new FirstStageInit(argv, &config);
|
||||
else
|
||||
init = new RootFSInit(argv, &config);
|
||||
}
|
||||
|
@@ -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
|
||||
@@ -191,8 +200,7 @@ mount_root:
|
||||
xmount("tmpfs", "/dev", "tmpfs", 0, "mode=755");
|
||||
mount_list.emplace_back("/dev");
|
||||
|
||||
// Use the apex folder to determine whether 2SI (Android 10+)
|
||||
bool is_two_stage = access("/apex", F_OK) == 0;
|
||||
bool is_two_stage = access("/system/bin/init", F_OK) == 0;
|
||||
LOGD("is_two_stage: [%d]\n", is_two_stage);
|
||||
|
||||
// For API 28 AVD, it uses legacy SAR setup that requires
|
||||
@@ -236,6 +244,7 @@ void MagiskInit::setup_tmp(const char *path) {
|
||||
|
||||
xmkdir(INTLROOT, 0711);
|
||||
xmkdir(DEVICEDIR, 0711);
|
||||
xmkdir(WORKERDIR, 0);
|
||||
|
||||
mount_preinit_dir(preinit_dev);
|
||||
|
||||
@@ -249,5 +258,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,31 +222,10 @@ 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";
|
||||
const char *init_ld_xz = sbin ? "/sbin/init-ld.xz" : "init-ld.xz";
|
||||
|
||||
if (access(magisk_xz, F_OK) == 0) {
|
||||
mmap_data magisk(magisk_xz);
|
||||
@@ -206,6 +243,14 @@ static void extract_files(bool sbin) {
|
||||
unxz(ch, stub);
|
||||
close(fd);
|
||||
}
|
||||
if (access(init_ld_xz, F_OK) == 0) {
|
||||
mmap_data init_ld(init_ld_xz);
|
||||
unlink(init_ld_xz);
|
||||
int fd = xopen("init-ld", O_WRONLY | O_CREAT, 0);
|
||||
fd_stream ch(fd);
|
||||
unxz(ch, init_ld);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
void MagiskInit::parse_config_file() {
|
||||
@@ -279,16 +324,19 @@ void MagiskInit::patch_ro_root() {
|
||||
patch_rc_scripts("/", tmp_dir.data(), false);
|
||||
}
|
||||
|
||||
// Extract magisk
|
||||
// Extract overlay archives
|
||||
extract_files(false);
|
||||
|
||||
// Oculus Go will use a special sepolicy if unlocked
|
||||
if (access("/sepolicy.unlocked", F_OK) == 0) {
|
||||
patch_sepolicy("/sepolicy.unlocked", ROOTOVL "/sepolicy.unlocked");
|
||||
} else if ((access(SPLIT_PLAT_CIL, F_OK) != 0 && access("/sepolicy", F_OK) == 0) ||
|
||||
!hijack_sepolicy()) {
|
||||
patch_sepolicy("/sepolicy", ROOTOVL "/sepolicy");
|
||||
} else {
|
||||
bool patch = access(SPLIT_PLAT_CIL, F_OK) != 0 && access("/sepolicy", F_OK) == 0;
|
||||
if (patch || !hijack_sepolicy()) {
|
||||
patch_sepolicy("/sepolicy", ROOTOVL "/sepolicy");
|
||||
}
|
||||
}
|
||||
unlink("init-ld");
|
||||
|
||||
// Mount rootdir
|
||||
magic_mount(ROOTOVL);
|
||||
@@ -338,12 +386,14 @@ void MagiskInit::patch_rw_root() {
|
||||
setup_tmp(PRE_TMPDIR);
|
||||
chdir(PRE_TMPDIR);
|
||||
|
||||
// Extract magisk
|
||||
// Extract overlay archives
|
||||
extract_files(true);
|
||||
|
||||
if ((!treble && access("/sepolicy", F_OK) == 0) || !hijack_sepolicy()) {
|
||||
bool patch = !treble && access("/sepolicy", F_OK) == 0;
|
||||
if (patch || !hijack_sepolicy()) {
|
||||
patch_sepolicy("/sepolicy", "/sepolicy");
|
||||
}
|
||||
unlink("init-ld");
|
||||
|
||||
chdir("/");
|
||||
|
||||
|
@@ -14,7 +14,6 @@ pub fn inject_magisk_rc(fd: RawFd, tmp_dir: &Utf8CStr) {
|
||||
file,
|
||||
r#"
|
||||
on post-fs-data
|
||||
start logd
|
||||
exec {0} 0 0 -- {1}/magisk --post-fs-data
|
||||
|
||||
on property:vold.decrypt=trigger_restart_framework
|
||||
|
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <consts.hpp>
|
||||
#include <sepolicy.hpp>
|
||||
#include <embed.hpp>
|
||||
|
||||
#include "init.hpp"
|
||||
|
||||
@@ -31,16 +30,6 @@ void MagiskInit::patch_sepolicy(const char *in, const char *out) {
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_preload() {
|
||||
int fd = xopen("/dev/preload.so", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
|
||||
if (fd < 0)
|
||||
return;
|
||||
fd_stream ch(fd);
|
||||
if (!unxz(ch, byte_view(init_ld_xz, sizeof(init_ld_xz))))
|
||||
return;
|
||||
close(fd);
|
||||
}
|
||||
|
||||
#define MOCK_COMPAT SELINUXMOCK "/compatible"
|
||||
#define MOCK_LOAD SELINUXMOCK "/load"
|
||||
#define MOCK_ENFORCE SELINUXMOCK "/enforce"
|
||||
@@ -53,7 +42,7 @@ bool MagiskInit::hijack_sepolicy() {
|
||||
// This meant that instead of going through convoluted methods trying to alter
|
||||
// and block init's control flow, we can just LD_PRELOAD and replace the
|
||||
// security_load_policy function with our own implementation.
|
||||
dump_preload();
|
||||
cp_afc("init-ld", "/dev/preload.so");
|
||||
setenv("LD_PRELOAD", "/dev/preload.so", 1);
|
||||
}
|
||||
|
||||
@@ -100,18 +89,10 @@ bool MagiskInit::hijack_sepolicy() {
|
||||
|
||||
// Read all custom rules into memory
|
||||
string rules;
|
||||
if (auto dir = xopen_dir("/data/" PREINITMIRR)) {
|
||||
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
||||
auto name = "/data/" PREINITMIRR "/"s + entry->d_name;
|
||||
auto rule_file = name + "/sepolicy.rule";
|
||||
if (xaccess(rule_file.data(), R_OK) == 0 &&
|
||||
access((name + "/disable").data(), F_OK) != 0 &&
|
||||
access((name + "/remove").data(), F_OK) != 0) {
|
||||
LOGD("Load custom sepolicy patch: [%s]\n", rule_file.data());
|
||||
full_read(rule_file.data(), rules);
|
||||
rules += '\n';
|
||||
}
|
||||
}
|
||||
auto rule = "/data/" PREINITMIRR "/sepolicy.rule";
|
||||
if (xaccess(rule, R_OK) == 0) {
|
||||
LOGD("Loading custom sepolicy patch: [%s]\n", rule);
|
||||
rules = full_read(rule);
|
||||
}
|
||||
// Create a new process waiting for init operations
|
||||
if (xfork()) {
|
||||
|
@@ -118,10 +118,6 @@ impl SepolicyExt for sepolicy {
|
||||
|
||||
fn load_rules_from_reader<T: BufRead>(mut self: Pin<&mut sepolicy>, reader: &mut T) {
|
||||
reader.foreach_lines(|line| {
|
||||
let line = line.trim();
|
||||
if line.is_empty() {
|
||||
return true;
|
||||
}
|
||||
parse_statement(self.as_mut(), line);
|
||||
true
|
||||
});
|
||||
|
@@ -271,6 +271,10 @@ bool sepol_impl::add_rule(const char *s, const char *t, const char *c, const cha
|
||||
#define ioctl_func(x) (x & 0xFF)
|
||||
|
||||
void sepol_impl::add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls, const Xperm &p, int effect) {
|
||||
if (db->policyvers < POLICYDB_VERSION_XPERMS_IOCTL) {
|
||||
LOGW("policy version %u does not support ioctl extended permissions rules\n", db->policyvers);
|
||||
return;
|
||||
}
|
||||
if (src == nullptr) {
|
||||
for_each_attr(db->p_types.table, [&](type_datum_t *type) {
|
||||
add_xperm_rule(type, tgt, cls, p, effect);
|
||||
|
@@ -3,7 +3,6 @@ use std::io::stderr;
|
||||
use std::{iter::Peekable, pin::Pin, vec::IntoIter};
|
||||
|
||||
use base::{error, warn, FmtAdaptor};
|
||||
|
||||
use crate::ffi::Xperm;
|
||||
use crate::sepolicy;
|
||||
|
||||
@@ -436,15 +435,16 @@ fn extract_token<'a>(s: &'a str, tokens: &mut Vec<Token<'a>>) {
|
||||
fn tokenize_statement(statement: &str) -> Vec<Token> {
|
||||
let mut tokens = Vec::new();
|
||||
for s in statement.split_whitespace() {
|
||||
if s.starts_with('#') {
|
||||
break;
|
||||
}
|
||||
extract_token(s, &mut tokens);
|
||||
}
|
||||
tokens
|
||||
}
|
||||
|
||||
pub fn parse_statement(sepolicy: Pin<&mut sepolicy>, statement: &str) {
|
||||
let statement = statement.trim();
|
||||
if statement.is_empty() || statement.starts_with('#') {
|
||||
return;
|
||||
}
|
||||
let mut tokens = tokenize_statement(statement).into_iter().peekable();
|
||||
let result = exec_statement(sepolicy, &mut tokens);
|
||||
if let Err(e) = result {
|
||||
|
@@ -2,10 +2,14 @@
|
||||
# Magisk app internal scripts
|
||||
##################################
|
||||
|
||||
# $1 = delay
|
||||
# $2 = command
|
||||
run_delay() {
|
||||
(sleep $1; $2)&
|
||||
}
|
||||
|
||||
# $1 = version string
|
||||
# $2 = version code
|
||||
env_check() {
|
||||
for file in busybox magiskboot magiskinit util_functions.sh boot_patch.sh; do
|
||||
[ -f "$MAGISKBIN/$file" ] || return 1
|
||||
@@ -21,6 +25,8 @@ env_check() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# $1 = dir to copy
|
||||
# $2 = destination (optional)
|
||||
cp_readlink() {
|
||||
if [ -z $2 ]; then
|
||||
cd $1
|
||||
@@ -39,6 +45,7 @@ cp_readlink() {
|
||||
cd /
|
||||
}
|
||||
|
||||
# $1 = install dir
|
||||
fix_env() {
|
||||
# Cleanup and make dirs
|
||||
rm -rf $MAGISKBIN/*
|
||||
@@ -49,6 +56,8 @@ fix_env() {
|
||||
chown -R 0:0 $MAGISKBIN
|
||||
}
|
||||
|
||||
# $1 = install dir
|
||||
# $2 = boot partition
|
||||
direct_install() {
|
||||
echo "- Flashing new boot image"
|
||||
flash_image $1/new-boot.img $2
|
||||
@@ -70,6 +79,7 @@ direct_install() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# $1 = uninstaller zip
|
||||
run_uninstaller() {
|
||||
rm -rf /dev/tmp
|
||||
mkdir -p /dev/tmp/install
|
||||
@@ -77,24 +87,16 @@ run_uninstaller() {
|
||||
INSTALLER=/dev/tmp/install sh /dev/tmp/install/assets/uninstaller.sh dummy 1 "$1"
|
||||
}
|
||||
|
||||
# $1 = boot partition
|
||||
restore_imgs() {
|
||||
[ -z $SHA1 ] && return 1
|
||||
local SHA1=$(grep_prop SHA1 $MAGISKTMP/.magisk/config)
|
||||
local BACKUPDIR=/data/magisk_backup_$SHA1
|
||||
[ -d $BACKUPDIR ] || return 1
|
||||
|
||||
get_flags
|
||||
find_boot_image
|
||||
|
||||
for name in dtb dtbo; do
|
||||
[ -f $BACKUPDIR/${name}.img.gz ] || continue
|
||||
local IMAGE=$(find_block $name$SLOT)
|
||||
[ -z $IMAGE ] && continue
|
||||
flash_image $BACKUPDIR/${name}.img.gz $IMAGE
|
||||
done
|
||||
[ -f $BACKUPDIR/boot.img.gz ] || return 1
|
||||
flash_image $BACKUPDIR/boot.img.gz $BOOTIMAGE
|
||||
flash_image $BACKUPDIR/boot.img.gz $1
|
||||
}
|
||||
|
||||
# $1 = path to bootctl executable
|
||||
post_ota() {
|
||||
cd /data/adb
|
||||
cp -f $1 bootctl
|
||||
@@ -131,6 +133,8 @@ EOF
|
||||
cd /
|
||||
}
|
||||
|
||||
# $1 = APK
|
||||
# $2 = package name
|
||||
adb_pm_install() {
|
||||
local tmp=/data/local/tmp/temp.apk
|
||||
cp -f "$1" $tmp
|
||||
@@ -189,6 +193,15 @@ printvar() {
|
||||
eval echo $1=\$$1
|
||||
}
|
||||
|
||||
run_action() {
|
||||
local MODID="$1"
|
||||
cd "/data/adb/modules/$MODID"
|
||||
sh ./action.sh
|
||||
local RES=$?
|
||||
cd /
|
||||
return $RES
|
||||
}
|
||||
|
||||
##########################
|
||||
# Non-root util_functions
|
||||
##########################
|
||||
@@ -232,7 +245,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
|
||||
|
@@ -71,13 +71,14 @@ export KEEPFORCEENCRYPT=true
|
||||
echo "KEEPVERITY=$KEEPVERITY" > config
|
||||
echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
|
||||
echo "PREINITDEVICE=$(./magisk --preinit-device)" >> config
|
||||
# For API 28, we also patch advancedFeatures.ini to disable SAR
|
||||
# Manually override skip_initramfs by setting RECOVERYMODE=true
|
||||
# For API 28, we also manually disable SystemAsRoot
|
||||
# Explicitly override skip_initramfs by setting RECOVERYMODE=true
|
||||
[ $API = "28" ] && echo 'RECOVERYMODE=true' >> config
|
||||
cat config
|
||||
|
||||
./magiskboot compress=xz magisk magisk.xz
|
||||
./magiskboot compress=xz stub.apk stub.xz
|
||||
./magiskboot compress=xz init-ld init-ld.xz
|
||||
|
||||
./magiskboot cpio ramdisk.cpio \
|
||||
"add 0750 init magiskinit" \
|
||||
@@ -85,12 +86,13 @@ cat config
|
||||
"mkdir 0750 overlay.d/sbin" \
|
||||
"add 0644 overlay.d/sbin/magisk.xz magisk.xz" \
|
||||
"add 0644 overlay.d/sbin/stub.xz stub.xz" \
|
||||
"add 0644 overlay.d/sbin/init-ld.xz init-ld.xz" \
|
||||
"patch" \
|
||||
"backup ramdisk.cpio.orig" \
|
||||
"mkdir 000 .backup" \
|
||||
"add 000 .backup/.magisk config"
|
||||
|
||||
rm -f ramdisk.cpio.orig config magisk*.xz stub.xz
|
||||
rm -f ramdisk.cpio.orig config *.xz
|
||||
if $IS_RAMDISK; then
|
||||
./magiskboot compress=gzip ramdisk.cpio "$OUTPUT_FILE"
|
||||
else
|
||||
|
@@ -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
|
||||
@@ -210,7 +206,7 @@ fi
|
||||
|
||||
yes | "$sdk" --licenses > /dev/null
|
||||
curl -L $lsposed_url -o out/lsposed.zip
|
||||
"$sdk" --channel=3 tools platform-tools emulator
|
||||
"$sdk" --channel=3 platform-tools emulator
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
run_test $1 $2
|
||||
@@ -221,7 +217,7 @@ else
|
||||
# Android 15 Beta
|
||||
run_test 35 google_apis
|
||||
# Run 16k page tests
|
||||
run_test VanillaIceCream google_apis_ps16k
|
||||
run_test 35 google_apis_ps16k
|
||||
fi
|
||||
|
||||
"$avd" delete avd -n test
|
||||
|
@@ -20,6 +20,7 @@
|
||||
# magiskinit binary The binary to replace /init.
|
||||
# magisk binary The magisk binary.
|
||||
# magiskboot binary A tool to manipulate boot images.
|
||||
# init-ld binary The library that will be LD_PRELOAD of /init
|
||||
# stub.apk binary The stub Magisk app to embed into ramdisk.
|
||||
# chromeos folder This folder includes the utility and keys to sign
|
||||
# (optional) chromeos boot images. Only used for Pixel C.
|
||||
@@ -118,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" \
|
||||
@@ -133,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"
|
||||
;;
|
||||
@@ -161,6 +165,7 @@ $BOOTMODE && [ -z "$PREINITDEVICE" ] && PREINITDEVICE=$(./magisk --preinit-devic
|
||||
# Compress to save precious ramdisk space
|
||||
./magiskboot compress=xz magisk magisk.xz
|
||||
./magiskboot compress=xz stub.apk stub.xz
|
||||
./magiskboot compress=xz init-ld init-ld.xz
|
||||
|
||||
echo "KEEPVERITY=$KEEPVERITY" > config
|
||||
echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
|
||||
@@ -177,13 +182,14 @@ fi
|
||||
"mkdir 0750 overlay.d/sbin" \
|
||||
"add 0644 overlay.d/sbin/magisk.xz magisk.xz" \
|
||||
"add 0644 overlay.d/sbin/stub.xz stub.xz" \
|
||||
"add 0644 overlay.d/sbin/init-ld.xz init-ld.xz" \
|
||||
"patch" \
|
||||
"$SKIP_BACKUP backup ramdisk.cpio.orig" \
|
||||
"mkdir 000 .backup" \
|
||||
"add 000 .backup/.magisk config" \
|
||||
|| abort "! Unable to patch ramdisk"
|
||||
|
||||
rm -f ramdisk.cpio.orig config magisk*.xz stub.xz
|
||||
rm -f ramdisk.cpio.orig config *.xz
|
||||
|
||||
#################
|
||||
# Binary Patches
|
||||
@@ -214,6 +220,13 @@ if [ -f kernel ]; then
|
||||
# After: [mov w2, #-32768]
|
||||
./magiskboot hexpatch kernel 821B8012 E2FF8F12 && PATCHEDKERNEL=true
|
||||
|
||||
# Disable Samsung PROCA
|
||||
# proca_config -> proca_magisk
|
||||
./magiskboot hexpatch kernel \
|
||||
70726F63615F636F6E66696700 \
|
||||
70726F63615F6D616769736B00 \
|
||||
&& PATCHEDKERNEL=true
|
||||
|
||||
# Force kernel to load rootfs for legacy SAR devices
|
||||
# skip_initramfs -> want_initramfs
|
||||
$LEGACYSAR && ./magiskboot hexpatch kernel \
|
||||
|
@@ -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
|
||||
|
244
scripts/release.sh
Executable file
244
scripts/release.sh
Executable file
@@ -0,0 +1,244 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# On macOS, gsed is required (brew install gnu-sed)
|
||||
# Required tools: jq, gh
|
||||
# The GitHub cli (gh) has to be properly authenticated
|
||||
|
||||
# These variables can be modified as needed
|
||||
MAGISK_FILES=../magisk-files
|
||||
CONFIG=config.prop
|
||||
NOTES=notes.md
|
||||
|
||||
# These are constants, do not modify
|
||||
GCONFIG=gradle.properties
|
||||
README=README.MD
|
||||
BUILDCMD="./build.py -c $CONFIG"
|
||||
CWD=$(pwd)
|
||||
|
||||
grep_prop() {
|
||||
local REGEX="s/^$1=//p"
|
||||
shift
|
||||
local FILES=$@
|
||||
sed -n "$REGEX" $FILES | head -n 1
|
||||
}
|
||||
|
||||
enable_version_config() {
|
||||
# Make sure version is not commented out and exists
|
||||
sed -i "s:^# version=:version=:g" $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() {
|
||||
# Comment out version config
|
||||
sed -i "s:^version=:# version=:g" $CONFIG
|
||||
}
|
||||
|
||||
# $1 = tag
|
||||
update_readme_stable() {
|
||||
sed -i "s:badge/Magisk-v.*:badge/Magisk-${1}-blue)](https\://github.com/topjohnwu/Magisk/releases/tag/$1):g" $README
|
||||
}
|
||||
|
||||
# $1 = tag
|
||||
update_readme_beta() {
|
||||
sed -i "s:badge/Magisk%20Beta.*:badge/Magisk%20Beta-${1}-blue)](https\://github.com/topjohnwu/Magisk/releases/tag/$1):g" $README
|
||||
}
|
||||
|
||||
# $1 = tag
|
||||
update_readme_canary() {
|
||||
sed -i "s:badge/Magisk-Canary.*:badge/Magisk-Canary-red)](https\://github.com/topjohnwu/Magisk/releases/tag/$1):g" $README
|
||||
}
|
||||
|
||||
gen_link() {
|
||||
echo "https://github.com/topjohnwu/Magisk/releases/download/$1/$2"
|
||||
}
|
||||
|
||||
update_canary_json() {
|
||||
local ver=$(grep_prop version $CONFIG)
|
||||
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||
local tag="canary-$code"
|
||||
local json
|
||||
|
||||
json=$MAGISK_FILES/canary.json
|
||||
jq ".magisk.version=\"$ver\"|.magisk.versionCode=\"$code\"|
|
||||
.magisk.link=\"$(gen_link $tag app-release.apk)\"|
|
||||
.magisk.note=\"$(gen_link $tag notes.md)\"" $json > ${json}.tmp
|
||||
mv ${json}.tmp $json
|
||||
|
||||
json=$MAGISK_FILES/debug.json
|
||||
jq ".magisk.version=\"$ver\"|.magisk.versionCode=\"$code\"|
|
||||
.magisk.link=\"$(gen_link $tag app-debug.apk)\"|
|
||||
.magisk.note=\"$(gen_link $tag notes.md)\"" $json > ${json}.tmp
|
||||
mv ${json}.tmp $json
|
||||
}
|
||||
|
||||
# $1 = json path
|
||||
update_release_json() {
|
||||
local json=$1
|
||||
local ver=$(grep_prop version $CONFIG)
|
||||
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||
|
||||
jq ".magisk.version=\"$ver\"|.magisk.versionCode=\"$code\"|
|
||||
.magisk.link=\"$(gen_link v${ver} Magisk-v${ver}.apk)\"|
|
||||
.magisk.note=\"https://topjohnwu.github.io/Magisk/releases/${code}.md\"" $json > ${json}.tmp
|
||||
mv ${json}.tmp $json
|
||||
}
|
||||
|
||||
build_canary() {
|
||||
# Update version code
|
||||
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||
code=$((code + 1))
|
||||
local tag="canary-$code"
|
||||
sed -i "s:versionCode=.*:versionCode=${code}:g" $GCONFIG
|
||||
update_readme_canary $tag
|
||||
|
||||
# Commit version code changes
|
||||
git add -u .
|
||||
git status
|
||||
git commit -m "Release new canary build"
|
||||
git tag $tag
|
||||
|
||||
# Update version name
|
||||
local ver=$(git rev-parse --short=8 HEAD)
|
||||
sed -i "s:version=.*:version=${ver}:g" $CONFIG
|
||||
sed -i "s:## Magisk (.*:## Magisk (${ver}) (${code}):g" $NOTES
|
||||
|
||||
# Update and commit JSON
|
||||
update_canary_json
|
||||
cd $MAGISK_FILES
|
||||
git add -u .
|
||||
git status
|
||||
git commit -m "Update Canary Channel: Upstream to $ver"
|
||||
cd $CWD
|
||||
|
||||
# Build
|
||||
$BUILDCMD clean
|
||||
$BUILDCMD all
|
||||
$BUILDCMD -r all
|
||||
}
|
||||
|
||||
# $1 = ver, $2 = stable?
|
||||
build_release() {
|
||||
# Update version configs
|
||||
local ver=$1
|
||||
local stable=$2
|
||||
local code=$(echo - | awk "{ print $ver * 1000 }")
|
||||
local tag="v$ver"
|
||||
sed -i "s:versionCode=.*:versionCode=${code}:g" $GCONFIG
|
||||
sed -i "s:version=.*:version=${ver}:g" $CONFIG
|
||||
|
||||
# Update and commit JSON
|
||||
if $stable; then
|
||||
update_readme_stable $tag
|
||||
update_readme_beta $tag
|
||||
update_release_json $MAGISK_FILES/stable.json
|
||||
cp -vf $MAGISK_FILES/stable.json $MAGISK_FILES/beta.json
|
||||
else
|
||||
update_readme_beta $tag
|
||||
update_release_json $MAGISK_FILES/beta.json
|
||||
fi
|
||||
cd $MAGISK_FILES
|
||||
git add -u .
|
||||
git status
|
||||
git commit -m "Release Magisk v$ver"
|
||||
cd $CWD
|
||||
|
||||
# Commit version code changes
|
||||
git add -u .
|
||||
git status
|
||||
git commit -m "Release Magisk v$ver"
|
||||
git tag $tag
|
||||
|
||||
# Build
|
||||
$BUILDCMD clean
|
||||
$BUILDCMD -r all
|
||||
}
|
||||
|
||||
stable() {
|
||||
[ -z $1 ] && exit 1
|
||||
local ver=$1
|
||||
build_release $ver true
|
||||
}
|
||||
|
||||
beta() {
|
||||
[ -z $1 ] && exit 1
|
||||
local ver=$1
|
||||
build_release $ver false
|
||||
}
|
||||
|
||||
pub() {
|
||||
gh auth status
|
||||
|
||||
local latest_tag=$(git describe --abbrev=0 --tags)
|
||||
local ver=$(grep_prop version $CONFIG)
|
||||
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||
local out=$(grep_prop outdir $CONFIG)
|
||||
local tag title
|
||||
|
||||
if [ -z $out ]; then
|
||||
out=out
|
||||
fi
|
||||
|
||||
git push origin master
|
||||
git push --tags
|
||||
|
||||
if [ $(($code % 100)) -ne 0 ]; then
|
||||
tag="canary-$code"
|
||||
title="Magisk ($ver) ($code)"
|
||||
|
||||
# Assert tag format
|
||||
[ $latest_tag = $tag ]
|
||||
|
||||
# Publish release
|
||||
tail -n +3 $NOTES > release.md
|
||||
gh release create --verify-tag $tag -p -t "$title" -F release.md $out/app-release.apk $out/app-debug.apk $NOTES
|
||||
else
|
||||
tag="v$ver"
|
||||
title="Magisk v$ver"
|
||||
|
||||
# Assert tag format
|
||||
[ $latest_tag = $tag ]
|
||||
|
||||
# Publish release
|
||||
tail -n +3 docs/releases/$code.md > release.md
|
||||
gh release create --verify-tag $tag -t "$title" -F release.md "$out/app-release.apk#Magisk-v${ver}.apk"
|
||||
fi
|
||||
|
||||
rm -f release.md
|
||||
cd $MAGISK_FILES
|
||||
git push origin master
|
||||
cd $CWD
|
||||
}
|
||||
|
||||
revert() {
|
||||
local latest_tag=$(git describe --abbrev=0 --tags)
|
||||
|
||||
git tag -d $latest_tag
|
||||
git reset --hard HEAD~
|
||||
cd $MAGISK_FILES
|
||||
git reset --hard HEAD~
|
||||
cd $CWD
|
||||
}
|
||||
|
||||
# Use GNU sed on macOS
|
||||
if command -v gsed >/dev/null; then
|
||||
function sed() { gsed "$@"; }
|
||||
export -f sed
|
||||
fi
|
||||
|
||||
git pull
|
||||
|
||||
trap disable_version_config EXIT
|
||||
enable_version_config
|
||||
case $1 in
|
||||
"canary" ) build_canary ;;
|
||||
"stable" ) stable $2 ;;
|
||||
"beta" ) beta $2 ;;
|
||||
"pub" ) pub ;;
|
||||
"revert" ) revert ;;
|
||||
* ) exit 1 ;;
|
||||
esac
|
@@ -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