Compare commits

...

51 Commits

Author SHA1 Message Date
topjohnwu
8e82113bce Release new canary build 2024-08-23 01:07:45 -07:00
vvb2060
f723ef153b zygisk_node: skip magisk32 if 64bit zygote only 2024-08-22 11:58:29 -07:00
topjohnwu
1dc723fb6d Attempt to reuse cache on Windows 2024-08-21 22:06:12 -07:00
topjohnwu
8f271c2575 Custom sccache support in CI 2024-08-21 16:51:30 -07:00
topjohnwu
7cf56b4406 Simplify ramdisk test 2024-08-21 16:46:37 -07:00
Wang Han
c2eb603957 Require GMS to be system app
Fixes https://github.com/topjohnwu/Magisk/issues/8279.
2024-08-20 10:36:14 -07:00
topjohnwu
e6bd2ff60f Fix stock image restore
Fix #8211
2024-08-20 02:23:20 -07:00
topjohnwu
5604074eba Fix module auto install
Fix #8208
2024-08-20 01:09:25 -07:00
topjohnwu
3f061c1a1e Update dependencies 2024-08-19 17:54:02 -07:00
LoveSy
55e78a7b1a BYD XDJA container support 2024-08-19 17:50:16 -07:00
vvb2060
000f1d6041 Revert "Don't support alternative binary paths"
This reverts commit 1eeb2a34a1.
2024-08-19 11:52:55 -07:00
vvb2060
2cbec20238 find_boot_image: test GKI 1.0 2024-08-19 03:05:24 -07:00
vvb2060
4b724c7257 find_boot_image: test previous kernels (<=4.19) 2024-08-19 03:05:24 -07:00
vvb2060
ab04c6ab39 find_boot_image: keep symlink 2024-08-19 03:05:24 -07:00
topjohnwu
821a6c6954 Only save gradle cache on asset build job 2024-08-18 21:42:28 -07:00
topjohnwu
5f27a62221 Use gradle version catalog 2024-08-18 13:12:23 -07:00
topjohnwu
c76cc4c6bd Update cuttlefish hostside tools 2024-08-16 15:58:29 -07:00
𝗦𝗵𝗟𝗲𝗿𝗣
52b75c53b6 Update TR Locales 2024-08-16 11:38:36 -07:00
topjohnwu
9db2e99086 Test 16k on Cuttlefish 2024-08-15 22:51:40 -07:00
LoveSy
e9e2ecf2dd load partition_map only once 2024-08-15 10:10:18 -07:00
LoveSy
9a9e617c35 Use find_if 2024-08-15 10:10:18 -07:00
LoveSy
3a0becc783 Use parse_impl for partition_map 2024-08-15 10:10:18 -07:00
ChsBuffer
1f974cb220 Use androidboot.partition_map as a fallback for matching partition names in the preinit finding. 2024-08-15 10:10:18 -07:00
LoveSy
1db80228e8 Move worker mount to magiskinit 2024-08-15 02:39:51 -07:00
LoveSy
838e1e254d Move devpts mount to magiskinit 2024-08-15 02:39:51 -07:00
topjohnwu
554eda8fe1 Switch to gmake on macOS 2024-08-15 02:37:59 -07:00
topjohnwu
2bdc047c4d Call sqlite3_free only on sqlite3 malloc-ed objects 2024-08-14 13:23:59 -07:00
topjohnwu
e64f59ce5b Make CI faster 2024-08-14 00:21:45 -07:00
topjohnwu
b8140ad4e6 Re-enable Windows CI 2024-08-13 21:12:06 -07:00
LoveSy
5a55483698 Set -fno-threadsafe-statics for crt0
Since crt0 has no pthread support, we don't need lock for statics.
2024-08-12 10:57:45 -07:00
vvb2060
2d341863f5 set MAGISKTMP 2024-08-12 02:05:58 -07:00
LoveSy
278046becb Fix wrong cxx_extern return value
This fix UB
2024-08-12 02:05:26 -07:00
topjohnwu
5c0497354f Temporarily disable Windows CI 2024-08-12 02:04:13 -07:00
topjohnwu
98c258df93 Update AGP 2024-08-11 04:30:01 -07:00
topjohnwu
c578cccfd5 Update to ONDK r27.4 2024-08-11 04:16:19 -07:00
Andrew Gunnerson
07835a3e0e util_functions.sh: Fix syntax error due to missing then
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-08-06 01:16:19 -07:00
topjohnwu
09131aca89 Fix find_boot_image
Close #8255
2024-08-05 11:24:30 -07:00
topjohnwu
9ce998a6df Fix arab strings 2024-08-04 01:54:28 -07:00
topjohnwu
ca36b42d79 Update release.sh 2024-08-03 01:55:03 -07:00
topjohnwu
37df39ec37 Address clippy warnings 2024-08-03 01:52:16 -07:00
topjohnwu
1701361a73 Update cargo dependencies 2024-08-03 01:49:14 -07:00
topjohnwu
4c14ae33f5 Properly configure Rust builds 2024-08-03 01:28:53 -07:00
topjohnwu
d4a9ef7b7f Cleanup build.py 2024-08-03 00:05:49 -07:00
topjohnwu
1539cfe888 Support setting custom ABI list
Also stop building riscv64 by default
2024-08-01 14:33:08 -07:00
topjohnwu
9093be1329 Run commands through shell on Windows 2024-07-31 17:21:18 -07:00
topjohnwu
606d076251 Build debug with thin lto 2024-07-31 17:00:01 -07:00
残页
46a34e19bc Check vendor boot ramdisk table size 2024-07-31 16:59:51 -07:00
topjohnwu
5ac7dc0b37 Support vendor boot unpack/repack
Fix #6460, close #6620
2024-07-30 04:00:12 -07:00
topjohnwu
3b27de3715 Output logs to files 2024-07-25 03:48:13 -07:00
topjohnwu
939bfac920 Make sure version is fetched correctly 2024-07-25 03:04:27 -07:00
muhammadbahaa2001
f601bf12d5 Updated Arabic 2024-07-25 03:03:49 -07:00
62 changed files with 1666 additions and 1061 deletions

View File

@@ -1,4 +1,8 @@
name: Magisk Setup
inputs:
is-asset-build:
required: false
default: false
runs:
using: "composite"
steps:
@@ -13,32 +17,84 @@ runs:
with:
python-version: "3.x"
- name: Set up sccache
uses: hendrikmuhs/ccache-action@v1.2
- name: Install GNU make
if: runner.os == 'macOS'
shell: bash
run: |
brew install make
echo 'GNUMAKE=gmake' >> "$GITHUB_ENV"
- name: Cache sccache
uses: actions/cache@v4
with:
variant: sccache
key: ${{ runner.os }}-${{ github.sha }}
restore-keys: ${{ runner.os }}
max-size: 10000M
path: .sccache
key: sccache-${{ runner.os }}-${{ github.sha }}
restore-keys: sccache-${{ runner.os }}-
- name: Set up sccache
shell: bash
env:
SCCACHE_DIRECT: false
SCCACHE_DIR: ${{ github.workspace }}/.sccache
SCCACHE_CACHE_SIZE: 2G
SCCACHE_IDLE_TIMEOUT: 0
run: |
bash $GITHUB_ACTION_PATH/sccache.sh
sccache --start-server
sccache -z
- name: Show sccache stats
uses: gacts/run-and-post-run@v1
with:
run: sccache -s
post: sccache -s
- name: Set GRADLE_USER_HOME
shell: bash
run: echo "GRADLE_USER_HOME=$GITHUB_WORKSPACE/.gradle" >> "$GITHUB_ENV"
- name: Cache Gradle dependencies
uses: actions/cache@v4
if: inputs.is-asset-build == 'true'
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
!~/.gradle/caches/build-cache-*
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
restore-keys: ${{ runner.os }}-gradle-
.gradle/caches
.gradle/wrapper
!.gradle/caches/build-cache-*
key: gradle-cache-${{ hashFiles('gradle/**') }}
restore-keys: gradle-cache-
- name: Cache build cache
uses: actions/cache@v4
- name: Restore Gradle dependencies
uses: actions/cache/restore@v4
if: inputs.is-asset-build == 'false'
with:
path: |
~/.gradle/caches/build-cache-*
key: ${{ runner.os }}-build-cache-${{ github.sha }}
restore-keys: ${{ runner.os }}-build-cache-
.gradle/caches
.gradle/wrapper
!.gradle/caches/build-cache-*
key: gradle-cache-${{ hashFiles('gradle/**') }}
restore-keys: gradle-cache-
enableCrossOsArchive: true
- name: Cache Gradle build cache
uses: actions/cache@v4
if: inputs.is-asset-build == 'true'
with:
path: |
.gradle/caches/build-cache-*
key: gradle-build-cache-${{ github.sha }}
restore-keys: gradle-build-cache-
- name: Restore Gradle build cache
uses: actions/cache/restore@v4
if: inputs.is-asset-build == 'false'
with:
path: |
.gradle/caches/build-cache-*
key: gradle-build-cache-${{ github.sha }}
restore-keys: gradle-build-cache-
enableCrossOsArchive: true
- name: Set up NDK
run: python build.py -v ndk
shell: bash
run: python build.py -v ndk

25
.github/actions/setup/sccache.sh vendored Executable file
View 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
View File

@@ -0,0 +1 @@
abiList=arm64-v8a

View File

@@ -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
View File

@@ -13,7 +13,7 @@ native/out
# Android Studio / Gradle
*.iml
.gradle
.idea
/local.properties
/.idea
/build
/captures

View File

@@ -22,7 +22,7 @@ Click the icon below to download Magisk apk.
[![](https://img.shields.io/badge/Magisk-v27.0-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v27.0)
[![](https://img.shields.io/badge/Magisk%20Beta-v27.0-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v27.0)
[![](https://img.shields.io/badge/Magisk-Canary-red)](https://github.com/topjohnwu/Magisk/releases/tag/canary-27006)
[![](https://img.shields.io/badge/Magisk-Canary-red)](https://github.com/topjohnwu/Magisk/releases/tag/canary-27007)
## Useful Links

View File

@@ -47,22 +47,21 @@ android {
dependencies {
implementation(project(":app:core"))
implementation("com.github.topjohnwu:indeterminate-checkbox:1.0.7")
implementation("dev.rikka.rikkax.layoutinflater:layoutinflater:1.3.0")
implementation("dev.rikka.rikkax.insets:insets:1.3.0")
implementation("dev.rikka.rikkax.recyclerview:recyclerview-ktx:1.3.2")
implementation(libs.indeterminate.checkbox)
implementation(libs.rikka.layoutinflater)
implementation(libs.rikka.insets)
implementation(libs.rikka.recyclerview)
val vNav = "2.7.7"
implementation("androidx.navigation:navigation-fragment-ktx:${vNav}")
implementation("androidx.navigation:navigation-ui-ktx:${vNav}")
implementation(libs.navigation.fragment.ktx)
implementation(libs.navigation.ui.ktx)
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("androidx.recyclerview:recyclerview:1.3.2")
implementation("androidx.transition:transition:1.5.1")
implementation("androidx.fragment:fragment-ktx:1.8.2")
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("com.google.android.material:material:1.12.0")
implementation(libs.constraintlayout)
implementation(libs.swiperefreshlayout)
implementation(libs.recyclerview)
implementation(libs.transition)
implementation(libs.fragment.ktx)
implementation(libs.appcompat)
implementation(libs.material)
// Make sure kapt runs with a proper kotlin-stdlib
kapt(kotlin("stdlib"))

View File

@@ -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,

View File

@@ -30,39 +30,34 @@ android {
dependencies {
api(project(":app:shared"))
api("com.jakewharton.timber:timber:5.0.1")
api("io.noties.markwon:core:4.6.2")
implementation("org.bouncycastle:bcpkix-jdk18on:1.78.1")
implementation("org.apache.commons:commons-compress:1.26.2")
api(libs.timber)
api(libs.markwon.core)
implementation(libs.bcpkix)
implementation(libs.commons.compress)
val vLibsu = "6.0.0"
api("com.github.topjohnwu.libsu:core:${vLibsu}")
api("com.github.topjohnwu.libsu:service:${vLibsu}")
api("com.github.topjohnwu.libsu:nio:${vLibsu}")
api(libs.libsu.core)
api(libs.libsu.service)
api(libs.libsu.nio)
val vRetrofit = "2.11.0"
implementation("com.squareup.retrofit2:retrofit:${vRetrofit}")
implementation("com.squareup.retrofit2:converter-moshi:${vRetrofit}")
implementation("com.squareup.retrofit2:converter-scalars:${vRetrofit}")
implementation(libs.retrofit)
implementation(libs.retrofit.moshi)
implementation(libs.retrofit.scalars)
val vOkHttp = "4.12.0"
implementation("com.squareup.okhttp3:okhttp:${vOkHttp}")
implementation("com.squareup.okhttp3:logging-interceptor:${vOkHttp}")
implementation("com.squareup.okhttp3:okhttp-dnsoverhttps:${vOkHttp}")
implementation(libs.okhttp)
implementation(libs.okhttp.logging)
implementation(libs.okhttp.dnsoverhttps)
val vMoshi = "1.15.1"
implementation("com.squareup.moshi:moshi:${vMoshi}")
ksp("com.squareup.moshi:moshi-kotlin-codegen:${vMoshi}")
implementation(libs.moshi)
ksp(libs.moshi.codegen)
val vRoom = "2.6.1"
implementation("androidx.room:room-runtime:${vRoom}")
implementation("androidx.room:room-ktx:${vRoom}")
ksp("androidx.room:room-compiler:${vRoom}")
implementation(libs.room.runtime)
implementation(libs.room.ktx)
ksp(libs.room.compiler)
implementation("androidx.core:core-splashscreen:1.0.1")
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.activity:activity:1.9.1")
implementation("androidx.collection:collection-ktx:1.4.2")
implementation("androidx.profileinstaller:profileinstaller:1.3.1")
implementation("androidx.lifecycle:lifecycle-process:2.8.4")
implementation(libs.core.splashscreen)
implementation(libs.core.ktx)
implementation(libs.activity)
implementation(libs.collection.ktx)
implementation(libs.profileinstaller)
implementation(libs.lifecycle.process)
}

View File

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

View File

@@ -134,10 +134,12 @@ abstract class MagiskInstallImpl protected constructor(
val abi32 = Const.CPU_ABI_32
if (Process.is64Bit() && abi32 != null) {
val magisk32 = File(installDir, "magisk32")
val entry = zf.getEntry("lib/$abi32/libmagisk.so")
zf.getInputStream(entry).writeTo(magisk32)
magisk32.setExecutable(true)
if (entry != null) {
val magisk32 = File(installDir, "magisk32")
zf.getInputStream(entry).writeTo(magisk32)
magisk32.setExecutable(true)
}
}
}
} else {

View File

@@ -2,130 +2,154 @@
<!--Sections-->
<string name="modules">الإضافات</string>
<string name="superuser">صلاحية الروت</string>
<string name="superuser">المستخدم الخارق</string>
<string name="logs">السجلات</string>
<string name="settings">الإعدادات</string>
<string name="install">تثبيت</string>
<string name="section_home">الأساسي</string>
<string name="section_theme">السِمات</string>
<string name="install">التثبيت</string>
<string name="section_home">الرئيسية</string>
<string name="section_theme">المظهر</string>
<string name="denylist">القائمة السوداء</string>
<!--Home-->
<string name="no_connection">لا يوجد إتصال</string>
<string name="app_changelog">تفاصيل التحديث</string>
<string name="no_connection">لا يوجد اتصال متاح</string>
<string name="app_changelog">سجل التغييرات</string>
<string name="loading">جارٍ التحميل...</string>
<string name="update">تحديث</string>
<string name="not_available">غير/متوفر</string>
<string name="not_available">غير متاح</string>
<string name="hide">إخفاء</string>
<string name="home_package">الحزمة</string>
<string name="home_app_title">التطبيق</string>
<string name="home_support_title">تبرع لنا</string>
<string name="home_item_source">الكود المصدري للتطبيق</string>
<string name="home_support_content">مـاجـيسك هي، وستظل دوماً، مجانيةً و مفتوحة المصدر، اظهر اهتمامك لنا لكي نبقيها هكذا بدعم مالي صغير</string>
<string name="home_installed_version">تم التثبيت</string>
<string name="home_latest_version">آخر إصدار</string>
<string name="invalid_update_channel">مصدر التحديث غير صالح</string>
<string name="home_notice_content">قم بتحميل Magisk فقط من صفحة GitHub الرسمية. الملفات من مصادر غير معروفة قد تكون ضارة!</string>
<string name="home_support_title">ادعمنا</string>
<string name="home_follow_title">تابعنا</string>
<string name="home_item_source">المصدر</string>
<string name="home_support_content">Magisk مجاني ومفتوح المصدر وسيظل كذلك دائمًا. يمكنك إظهار دعمك لنا من خلال التبرع.</string>
<string name="home_installed_version">المثبتة</string>
<string name="home_latest_version">الأحدث</string>
<string name="invalid_update_channel">قناة التحديث غير صالحة</string>
<string name="uninstall_magisk_title">إلغاء تثبيت Magisk</string>
<string name="uninstall_magisk_msg">ستُعطل/ستُحذف جميع الإضافات. سيُحذف الروت، وربما ستشفر بياناتك إذا لم تكن غير مشفرة حالياً.</string>
<string name="uninstall_magisk_msg">ستتم إزالة جميع الوحدات / تعطيلها!\nسيتم إزالة الروت!\nأي تخزين داخلي تم فك تشفيره باستخدام Magisk سيتم إعادة تشفيره!</string>
<!--Install-->
<string name="keep_force_encryption">فرض التشفير الإجباري</string>
<string name="keep_dm_verity">فرض تشفيرات AVB2.0/dm-verity</string>
<string name="recovery_mode">وضـع الريكفري</string>
<string name="keep_force_encryption">الحفاظ على التشفير الإجباري</string>
<string name="keep_dm_verity">الحفاظ على AVB 2.0/dm-verity</string>
<string name="recovery_mode">وضع الاسترداد</string>
<string name="install_options_title">الخيارات</string>
<string name="install_method_title">الطريقة</string>
<string name="install_next">التالي</string>
<string name="install_start">هيا، بنا</string>
<string name="manager_download_install">اضغط للتنزيل و التثبيت</string>
<string name="direct_install">تثبيت مباشر (موصى بها)</string>
<string name="install_inactive_slot">التثبيت على المنطقة الغير نشطة (بعد OTA)</string>
<string name="install_inactive_slot_msg">سيُجبر جهازك للاقلاع على المنطقة الغير النشطة بعد إعادة التشغيل!\n استخدم هذا الخيار فقط بعد الانتهاء من OTA. استمرار؟</string>
<string name="setup_title">إعدادات إضافية</string>
<string name="select_patch_file">حدد و عدل ملفاً</string>
<string name="patch_file_msg">اختر ملف (*.img) أو ملف odin (*.tar)</string>
<string name="reboot_delay_toast">إعادة التشغيل بعد ٥ ثواني…</string>
<string name="install_start">هيا بنا</string>
<string name="manager_download_install">اضغط للتنزيل والتثبيت</string>
<string name="direct_install">التثبيت المباشر (موصى به)</string>
<string name="install_inactive_slot">التثبيت على الشريحة غير النشطة (بعد OTA)</string>
<string name="install_inactive_slot_msg">سيتم إجبار جهازك على التمهيد إلى الشريحة غير النشطة الحالية بعد إعادة التشغيل!\nاستخدم هذا الخيار فقط بعد الانتهاء من OTA.\nهل تود المتابعة؟</string>
<string name="setup_title">إعداد إضافي</string>
<string name="select_patch_file">اختر وقم بعمل باتش ملف</string>
<string name="patch_file_msg">اختر صورة خام (*.img) أو ملف ODIN tarfile (*.tar) أو payload.bin (*.bin)</string>
<string name="reboot_delay_toast">سيتم إعادة التشغيل في 5 ثوانٍ...</string>
<string name="flash_screen_title">التثبيت</string>
<!--Superuser-->
<string name="su_request_title">طلبات صلاحية الروت</string>
<string name="su_request_title">طلب المستخدم الخارق</string>
<string name="touch_filtered_warning">نظرًا لأن تطبيقًا ما يحجب طلب المستخدم الخارق، لا يمكن لـ Magisk التحقق من استجابتك</string>
<string name="deny">رفض</string>
<string name="prompt">طلب</string>
<string name="grant">سماح</string>
<string name="su_warning">يمنح حق الوصول الكامل إلى جهازك. ارفض إذا كنت غير متأكد!</string>
<string name="forever">للأبد</string>
<string name="prompt">إشعار</string>
<string name="grant">منح</string>
<string name="su_warning">يمنح حق الوصول الكامل لجهازك.\nارفض إذا لم تكن متأكدًا!</string>
<string name="forever">دائمًا</string>
<string name="once">مرة واحدة</string>
<string name="tenmin">10 دقائق</string>
<string name="tenmin">جار0 دقائق</string>
<string name="twentymin">20 دقيقة</string>
<string name="thirtymin">30 دقيقة</string>
<string name="sixtymin">60 دقيقة</string>
<string name="su_allow_toast">تم منح صلاحيات الروت لـ%1$s</string>
<string name="su_deny_toast">تم رفض صلاحيات الروت لـ%1$s </string>
<string name="su_snack_grant">تم منح صلاحيات الروت لـ%1$s</string>
<string name="su_snack_deny">تم رفض صلاحيات الروت لـ%1$s</string>
<string name="su_snack_notif_on">تم تفعيل الإشعارات لـ%1$s</string>
<string name="su_snack_notif_off">تم تعطيل الإشعارات لـ%1$s</string>
<string name="su_snack_log_on">تم تفعيل السجلات لـ%1$s</string>
<string name="su_snack_log_off">تم تعطيل السجلات لـ%1$s</string>
<string name="su_revoke_title">منع؟</string>
<string name="su_revoke_msg">هل تريد منع صلاحية %1$s?</string>
<string name="toast">اشعار</string>
<string name="none">بدون</string>
<string name="su_allow_toast">%جار$s تم منحه حقوق المستخدم الخارق</string>
<string name="su_deny_toast">%جار$s تم رفض حقوق المستخدم الخارق</string>
<string name="su_snack_grant">تم منح حقوق المستخدم الخارق لـ %جار$s</string>
<string name="su_snack_deny">تم رفض حقوق المستخدم الخارق لـ %جار$s</string>
<string name="su_snack_notif_on">تم تفعيل الإشعارات لـ %جار$s</string>
<string name="su_snack_notif_off">تم تعطيل الإشعارات لـ %جار$s</string>
<string name="su_snack_log_on">تم تفعيل السجلات لـ %جار$s</string>
<string name="su_snack_log_off">تم تعطيل السجلات لـ %جار$s</string>
<string name="su_revoke_title">إلغاء؟</string>
<string name="su_revoke_msg">تأكيد لإلغاء حقوق المستخدم الخارق لـ %جار$s</string>
<string name="toast">إشعار</string>
<string name="none">لا شيء</string>
<string name="superuser_toggle_notification">الإشعارات</string>
<string name="superuser_toggle_revoke">منع</string>
<string name="superuser_policy_none">لم يسأل آية تطبيق لصلاحيات الروت</string>
<string name="superuser_toggle_revoke">إلغاء</string>
<string name="superuser_policy_none">لم يطلب أي تطبيق بعد إذن المستخدم الخارق.</string>
<!--Logs-->
<string name="log_data_none">لا يوجد أية سجلات هنا :-:، حاول استعمال تطبيقات روت اكثر</string>
<string name="log_data_magisk_none">لا توجد أيةَ سجلات ⊙_⊙</string>
<string name="menuSaveLog">حفظ السجلات</string>
<string name="menuClearLog">حذف السجلات</string>
<string name="logs_cleared">تم الحذف بنجاح</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">UID: %1$d</string>
<string name="log_data_none">أنت خالٍ من السجلات، جرب استخدام تطبيقات الروت الخاصة بك أكثر</string>
<string name="log_data_magisk_none">سجلات Magisk فارغة، هذا غريب</string>
<string name="menuSaveLog">حفظ السجل</string>
<string name="menuClearLog">مسح السجل الآن</string>
<string name="logs_cleared">تم مسح السجل بنجاح</string>
<string name="pid">PID: %جار$d</string>
<string name="target_uid">UID الهدف: %جار$d</string>
<string name="target_pid">PID هدف النطاق المركب: %s</string>
<string name="selinux_context">سياق SELinux: %s</string>
<string name="supp_group">المجموعة التكميلية: %s</string>
<!--SafetyNet-->
<!-- MagiskHide -->
<string name="show_system_app">إظهار برامج النظام</string>
<string name="hide_filter_hint">البحث بالإسم</string>
<string name="hide_search">ابحث</string>
<!--MagiskHide-->
<string name="show_system_app">عرض تطبيقات النظام</string>
<string name="show_os_app">عرض تطبيقات نظام التشغيل</string>
<string name="hide_filter_hint">التصفية بالاسم</string>
<string name="hide_search">بحث</string>
<!--Module Fragment-->
<string name="no_info_provided">(لم توفر معلومات)</string>
<string name="reboot_recovery">إعادة التشغيل إلى Recovery</string>
<string name="reboot_bootloader">إعادة التشغيل إلى Bootloader</string>
<string name="reboot_download">إعادة التشغيل إلى وضـع Odin</string>
<string name="reboot_edl">إعادة التشغيل إلى وضـعية EDL</string>
<string name="module_version_author">%1$sبواسطة%2$s</string>
<string name="module_state_remove">إزالة </string>
<string name="module_state_restore">إسترجاع</string>
<string name="module_action_install_external">اختر من الذاكرة الداخلية</string>
<string name="update_available">التحديث متوفر</string>
<string name="external_rw_permission_denied">امنحني إذن الولوج للذاكرة الداخلية</string>
<!--Module-->
<string name="no_info_provided">(لم يتم تقديم معلومات)</string>
<string name="reboot_userspace">إعادة تشغيل ناعمة</string>
<string name="reboot_recovery">إعادة التشغيل إلى وضع الاسترداد</string>
<string name="reboot_bootloader">إعادة التشغيل إلى محمل الإقلاع</string>
<string name="reboot_download">إعادة التشغيل إلى وضع التنزيل</string>
<string name="reboot_edl">إعادة التشغيل إلى وضع EDL</string>
<string name="reboot_safe_mode">وضع الآمن</string>
<string name="module_state_remove">إزالة</string>
<string name="module_state_restore">استعادة</string>
<string name="module_action_install_external">التثبيت من التخزين</string>
<string name="update_available">تحديث متاح</string>
<string name="suspend_text_riru">تم تعليق الإضافةة لأن %جار$s مفعّل</string>
<string name="suspend_text_zygisk">تم تعليق الإضافةة لأن %جار$s غير مفعّل</string>
<string name="zygisk_module_unloaded">لم يتم تحميل إضافة Zygisk بسبب عدم التوافق</string>
<string name="module_empty">لم يتم تثبيت أي إضافة</string>
<string name="confirm_install">هل تريد تثبيت الإضافة %جار$s؟</string>
<string name="confirm_install_title">تأكيد التثبيت</string>
<!--Settings -->
<string name="settings_dark_mode_title">وضـعية الِسمات</string>
<string name="settings_dark_mode_message">حدد الوضـع الذي يناسب ذوقك</string>
<string name="settings_dark_mode_light">الوضـع المضيء</string>
<string name="settings_dark_mode_system">اتبّع النظام</string>
<string name="settings_dark_mode_dark">وضـع الظلام</string>
<string name="settings_download_path_title">مسار التحميل</string>
<string name="settings_download_path_message">ستحمل الملفات إلى %1$s</string>
<!--Settings-->
<string name="settings_dark_mode_title">وضع الثيم</string>
<string name="settings_dark_mode_message">اختر الوضع الذي يناسب نمطك!</string>
<string name="settings_dark_mode_light">دائمًا فاتح</string>
<string name="settings_dark_mode_system">تابع النظام</string>
<string name="settings_dark_mode_dark">دائمًا داكن</string>
<string name="settings_download_path_title">مسار التنزيل</string>
<string name="settings_download_path_message">سيتم حفظ الملفات في %جار$s</string>
<string name="settings_hide_app_title">إخفاء تطبيق Magisk</string>
<string name="settings_hide_app_summary">تثبيت تطبيق وكيل بمعرف حزمة عشوائي واسم تطبيق مخصص</string>
<string name="settings_restore_app_title">استعادة تطبيق Magisk</string>
<string name="settings_restore_app_summary">إظهار التطبيق واستعادة APK الأصلي</string>
<string name="language">اللغة</string>
<string name="system_default">(الأفتراضي)</string>
<string name="system_default">(افتراضي النظام)</string>
<string name="settings_check_update_title">تحقق من التحديثات</string>
<string name="settings_check_update_summary">التحقق من التحديثات في الخلفية بشكل دوري</string>
<string name="settings_update_channel_title">مصدر التحديثات</string>
<string name="settings_check_update_summary">التحقق دوريًا من التحديثات في الخلفية</string>
<string name="settings_update_channel_title">قناة التحديث</string>
<string name="settings_update_stable">مستقر</string>
<string name="settings_update_beta">تجريبي</string>
<string name="settings_update_beta">بيتا</string>
<string name="settings_update_custom">مخصص</string>
<string name="settings_update_custom_msg">أدخل الرابط لمصدرك المخصص</string>
<string name="settings_hosts_title">موانع الاعلانات</string>
<string name="settings_hosts_summary">حجب الاعلانات دون تعديل النظام</string>
<string name="settings_hosts_toast">تم تمكين خاصية حجب الاعلانات</string>
<string name="settings_app_name_hint">الإسم الجديد</string>
<string name="settings_app_name_helper">التطبيق الجديد سوف يملك هذا الإسم</string>
<string name="settings_app_name_error">الصيغة غير مقبولة</string>
<string name="settings_update_custom_msg">أدخل عنوان URL لقناة مخصصة</string>
<string name="settings_zygisk_summary">تشغيل أجزاء من Magisk في خدمة zygote</string>
<string name="settings_denylist_title">تفعيل القائمة السوداء</string>
<string name="settings_denylist_summary">سيتم إرجاع جميع تعديلات Magisk للعمليات الموجودة في القائمة السوداء</string>
<string name="settings_denylist_config_title">تكوين القائمة السوداء</string>
<string name="settings_denylist_config_summary">اختر العمليات التي سيتم تضمينها في القائمة السوداء</string>
<string name="settings_hosts_title">مضيفين بدون نظام</string>
<string name="settings_hosts_summary">دعم المضيفين بدون نظام لتطبيقات حظر الإعلانات</string>
<string name="settings_hosts_toast">تم إضافة إضافة المضيفين بدون نظام</string>
<string name="settings_app_name_hint">اسم جديد</string>
<string name="settings_app_name_helper">سيتم إعادة تغليف التطبيق بهذا الاسم</string>
<string name="settings_app_name_error">تنسيق غير صالح</string>
<string name="settings_su_app_adb">التطبيقات و ADB</string>
<string name="settings_su_app">التطبيقات فقط</string>
<string name="settings_su_adb">ADB فقط</string>
@@ -136,55 +160,86 @@
<string name="settings_su_request_30">30 ثانية</string>
<string name="settings_su_request_45">45 ثانية</string>
<string name="settings_su_request_60">60 ثانية</string>
<string name="superuser_access">صلاحيات الروت</string>
<string name="auto_response">الفعل التلقائي</string>
<string name="request_timeout">المهلة قبل الفعل التلقائي</string>
<string name="superuser_notification">إشعارات طلبات الروت</string>
<string name="settings_su_reauth_title">إعادة المصادقة بعد الترقية</string>
<string name="settings_su_reauth_summary">أعد مصادقة صلاحيات الروت بعد إجراء ترقيات للتطبيق</string>
<string name="settings_customization">تخصيص</string>
<string name="superuser_access">وصول المستخدم الخارق</string>
<string name="auto_response">استجابة تلقائية</string>
<string name="request_timeout">انتهاء مهلة الطلب</string>
<string name="superuser_notification">إشعار المستخدم الخارق</string>
<string name="settings_su_reauth_title">إعادة التوثيق بعد الترقية</string>
<string name="settings_su_reauth_summary">طلب أذونات المستخدم الخارق مرة أخرى بعد ترقية التطبيقات</string>
<string name="settings_su_tapjack_title">حماية من اختراق النقرات</string>
<string name="settings_su_tapjack_summary">لن يستجيب مربع حوار طلب المستخدم الخارق لأي إدخال أثناء تغطيته بواسطة أي نافذة أو تراكب آخر</string>
<string name="settings_su_auth_title">توثيق المستخدم</string>
<string name="settings_su_auth_summary">طلب توثيق المستخدم أثناء طلبات المستخدم الخارق</string>
<string name="settings_su_auth_insecure">لا توجد طريقة توثيق مهيأة على الجهاز</string>
<string name="settings_customization">التخصيص</string>
<string name="setting_add_shortcut_summary">إضافة اختصار جميل إلى الشاشة الرئيسية في حالة كان الاسم والأيقونة صعب التعرف عليهما بعد إخفاء التطبيق</string>
<string name="settings_doh_title">DNS عبر HTTPS</string>
<string name="settings_doh_description">الحل لمشكلة تسميم DNS في بعض الدول</string>
<string name="settings_random_name_title">تغيير الاسم عشوائيًا</string>
<string name="settings_random_name_description">تغيير اسم ملف الخرج عشوائيًا لصور وملفات tar المصححة لمنع الاكتشاف</string>
<string name="multiuser_mode">نمط مستخدمين متعددين</string>
<string name="multiuser_mode">وضع المستخدمين المتعددين</string>
<string name="settings_owner_only">مالك الجهاز فقط</string>
<string name="settings_owner_manage">المالك هو من يحدد</string>
<string name="settings_user_independent">مستقل </string>
<string name="owner_only_summary">للمالك فقط له صلاحيات الروت</string>
<string name="owner_manage_summary">فقط المالك من يرفض و يمنح صلاحيات الروت</string>
<string name="user_independent_summary">كل مستخدم له قواعد روت خاصة به</string>
<string name="settings_owner_manage">يديرها مالك الجهاز</string>
<string name="settings_user_independent">مستقل عن المستخدم</string>
<string name="owner_only_summary">فقط المالك له وصول روت</string>
<string name="owner_manage_summary">فقط المالك يمكنه إدارة وصول الروت وتلقي طلبات الإذن</string>
<string name="user_independent_summary">كل مستخدم لديه قواعد الروت الخاصة به</string>
<string name="mount_namespace_mode">نمط Mount Namespace</string>
<string name="settings_ns_global">نمط Namespace العام</string>
<string name="settings_ns_requester">نمط NameSpace المتوارث</string>
<string name="settings_ns_isolate">نمط NameSpace المعزول</string>
<string name="global_summary">جميع الجلسات الروت تستخدم NameSpace العام</string>
<string name="requester_summary">جميع الجلسات الروت تستخدم NameSpace المتوارث</string>
<string name="isolate_summary">جميع الجلسات الروت تستخدم NameSpace المعزول</string>
<string name="mount_namespace_mode">وضع مساحة التثبيت</string>
<string name="settings_ns_global">مساحة أسماء عامة</string>
<string name="settings_ns_requester">وراثة مساحة الأسماء</string>
<string name="settings_ns_isolate">مساحة أسماء معزولة</string>
<string name="global_summary">جميع جلسات الروت تستخدم مساحة التثبيت العامة</string>
<string name="requester_summary">جلسات الروت سترث مساحة الأسماء من طالب الروت</string>
<string name="isolate_summary">كل جلسة روت سيكون لها مساحة أسماء معزولة خاصة بها</string>
<!--Notifications-->
<string name="update_channel">تحديثات Magisk</string>
<string name="progress_channel">إشعارات التقدم</string>
<string name="updated_channel">اكتمل التحديث</string>
<string name="download_complete">اكتمل التنزيل</string>
<string name="download_file_error">فشل تنزيل الملف</string>
<string name="magisk_update_title">تحديث مـاجـيسك متوفر!</string>
<string name="download_file_error">خطأ في تنزيل الملف</string>
<string name="magisk_update_title">تحديث Magisk متاح!</string>
<string name="updated_title">تم تحديث Magisk</string>
<string name="updated_text">اضغط لفتح التطبيق</string>
<!--Toasts, Dialogs-->
<string name="yes">نعم</string>
<string name="no">لا</string>
<string name="download">تنزيل</string>
<string name="reboot">إعادة التشغيل</string>
<string name="release_notes">معلومات الأصدار الجديد</string>
<string name="flashing">يتم الحرق...</string>
<string name="release_notes">ملاحظات الإصدار</string>
<string name="flashing">جارٍ التثبيت...</string>
<string name="done">تم!</string>
<string name="failure">فشل!</string>
<string name="open_link_failed_toast">لم يُعثر على تطبيق لفتح الرابط …</string>
<string name="complete_uninstall">إلغاء التثبيت بالكامل</string>
<string name="hide_app_title">جارٍ إخفاء تطبيق Magisk...</string>
<string name="open_link_failed_toast">لم يتم العثور على تطبيق لفتح الرابط</string>
<string name="complete_uninstall">إلغاء التثبيت الكامل</string>
<string name="restore_img">استعادة الصور</string>
<string name="restore_img_msg">جار الأستعادة</string>
<string name="restore_done">تم الأستعادة</string>
<string name="restore_fail">النسخة الاحتياطية الأصلية غير موجودة!</string>
<string name="setup_fail">فشل التضبيط</string>
<string name="env_fix_title"> الإعداد الأضافي مطلوب</string>
<string name="setup_msg">جار تضبيت البيئة</string>
<string name="unsupport_magisk_title">إصدار مـاجـيسك غير مدعوم</string>
<string name="restore_img_msg">جارٍ الاستعادة...</string>
<string name="restore_done">اكتملت الاستعادة!</string>
<string name="restore_fail">لا يوجد نسخة احتياطية أصلية!</string>
<string name="setup_fail">فشل الإعداد</string>
<string name="env_fix_title">يتطلب إعداد إضافي</string>
<string name="env_fix_msg">يحتاج جهازك إلى إعداد إضافي ليعمل Magisk بشكل صحيح. هل تريد المتابعة وإعادة التشغيل؟</string>
<string name="env_full_fix_msg">يحتاج جهازك إلى إعادة تثبيت Magisk ليعمل بشكل صحيح. يرجى إعادة تثبيت Magisk من داخل التطبيق، لا يمكن لوضع الاسترداد الحصول على معلومات الجهاز الصحيحة.</string>
<string name="setup_msg">جارٍ تشغيل إعداد البيئة...</string>
<string name="unsupport_magisk_title">إصدار Magisk غير مدعوم</string>
<string name="unsupport_magisk_msg">هذا الإصدار من التطبيق لا يدعم إصدارات Magisk الأقل من %جار$s.\n\nسيعمل التطبيق كما لو أن Magisk غير مثبت، يرجى ترقية Magisk في أقرب وقت ممكن.</string>
<string name="unsupport_general_title">حالة غير طبيعية</string>
<string name="unsupport_system_app_msg">تشغيل هذا التطبيق كتطبيق نظام غير مدعوم. يرجى إعادة التطبيق إلى تطبيق مستخدم.</string>
<string name="unsupport_other_su_msg">تم اكتشاف "su" ثنائي ليس من Magisk. يرجى إزالة أي حل روت منافس و/أو إعادة تثبيت Magisk.</string>
<string name="unsupport_external_storage_msg">تم تثبيت Magisk في التخزين الخارجي. يرجى نقل التطبيق إلى التخزين الداخلي.</string>
<string name="unsupport_nonroot_stub_msg">لا يمكن للتطبيق المخفي Magisk الاستمرار في العمل لأن الروت قد فقد. يرجى استعادة APK الأصلي.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">امنح إذن التخزين لتمكين هذه الوظيفة</string>
<string name="post_notifications_denied">امنح إذن الإشعارات لتمكين هذه الوظيفة</string>
<string name="install_unknown_denied">اسمح بتثبيت "التطبيقات غير المعروفة" لتمكين هذه الوظيفة</string>
<string name="add_shortcut_title">إضافة اختصار إلى الشاشة الرئيسية</string>
<string name="add_shortcut_msg">بعد إخفاء هذا التطبيق، قد يصبح من الصعب التعرف على اسمه ورمزه. هل تريد إضافة اختصار جميل إلى الشاشة الرئيسية؟</string>
<string name="app_not_found">لم يتم العثور على تطبيق لمعالجة هذا الإجراء</string>
<string name="reboot_apply_change">إعادة التشغيل لتطبيق التغييرات</string>
<string name="restore_app_confirmation">سيؤدي هذا إلى استعادة التطبيق المخفي إلى التطبيق الأصلي. هل تريد حقًا القيام بذلك؟</string>
</resources>

View File

@@ -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 gire 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ıacak uygulama bulunamadı</string>
<string name="complete_uninstall">Kaldırmayı Tamamla</string>
<string name="open_link_failed_toast">Bağlantıyı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 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>

View File

@@ -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")

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">عليك الترقية ماجـيسك Manager لإكمال تهيئة التطبيق.هل اكمل؟</string>
<string name="no_internet_msg">يرجى الاتصال بالانترنيت! ترقية ماجـيسك مطلوب...</string>
<string name="upgrade_msg">عليك الترقية Magisk لإكمال تهيئة التطبيق. هل تريد التنزيل والتثبيت؟</string>
<string name="no_internet_msg">يرجى اللإتصال بالإنترنت! ترقية Magisk مطلوبة.</string>
<string name="dling">جارٍ التنزيل</string>
<string name="relaunch_app">يرجى إعادة تشغيل التطبيق يدوياً</string>
</resources>

510
build.py
View File

@@ -5,6 +5,7 @@ import lzma
import multiprocessing
import os
import platform
import re
import shutil
import stat
import subprocess
@@ -38,6 +39,7 @@ def vprint(str):
print(str)
# Environment checks and detection
is_windows = os.name == "nt"
EXE_EXT = ".exe" if is_windows else ""
@@ -51,7 +53,6 @@ if is_windows:
# We can't do ANSI color codes in terminal on Windows without colorama
no_color = True
# Environment checks
if not sys.version_info >= (3, 8):
error("Requires Python 3.8+")
@@ -63,42 +64,40 @@ except KeyError:
except KeyError:
error("Please set Android SDK path to environment variable ANDROID_HOME")
if shutil.which("sccache") is not None:
os.environ["RUSTC_WRAPPER"] = "sccache"
os.environ["NDK_CCACHE"] = "sccache"
os.environ["CARGO_INCREMENTAL"] = "0"
if shutil.which("ccache") is not None:
os.environ["NDK_CCACHE"] = "ccache"
cpu_count = multiprocessing.cpu_count()
os_name = platform.system().lower()
archs = ["armeabi-v7a", "x86", "arm64-v8a", "x86_64", "riscv64"]
triples = [
"armv7a-linux-androideabi",
"i686-linux-android",
"aarch64-linux-android",
"x86_64-linux-android",
"riscv64-linux-android",
]
# Common constants
support_abis = {
"armeabi-v7a": "thumbv7neon-linux-androideabi",
"x86": "i686-linux-android",
"arm64-v8a": "aarch64-linux-android",
"x86_64": "x86_64-linux-android",
"riscv64": "riscv64-linux-android",
}
default_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"}
support_targets = default_targets | {"resetprop"}
rust_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"}
# Common paths
ndk_root = sdk_path / "ndk"
ndk_path = ndk_root / "magisk"
ndk_build = ndk_path / "ndk-build"
rust_bin = ndk_path / "toolchains" / "rust" / "bin"
llvm_bin = ndk_path / "toolchains" / "llvm" / "prebuilt" / f"{os_name}-x86_64" / "bin"
cargo = rust_bin / f"cargo{EXE_EXT}"
gradlew = Path("gradlew" + (".bat" if is_windows else "")).resolve()
adb_path = sdk_path / "platform-tools" / f"adb{EXE_EXT}"
cargo = rust_bin / "cargo"
gradlew = Path.cwd() / "gradlew"
adb_path = sdk_path / "platform-tools" / "adb"
native_gen_path = Path("native", "out", "generated").resolve()
# Global vars
config = {}
STDOUT = None
build_tools = None
args = {}
build_abis = {}
###################
# Helper functions
###################
def mv(source: Path, target: Path):
@@ -137,20 +136,26 @@ def rm_on_error(func, path, _):
def rm_rf(path: Path):
vprint(f"rm -rf {path}")
shutil.rmtree(path, ignore_errors=False, onerror=rm_on_error)
if sys.version_info >= (3, 12):
shutil.rmtree(path, ignore_errors=False, onexc=rm_on_error)
else:
shutil.rmtree(path, ignore_errors=False, onerror=rm_on_error)
def execv(cmd, env=None):
return subprocess.run(cmd, stdout=STDOUT, env=env)
def execv(cmds: list, env=None):
out = None if args.force_out or args.verbose > 0 else subprocess.DEVNULL
# Use shell on Windows to support PATHEXT
return subprocess.run(cmds, stdout=out, env=env, shell=is_windows)
def system(cmd):
return subprocess.run(cmd, shell=True, stdout=STDOUT)
def cmd_out(cmd, env=None):
def cmd_out(cmds: list):
return (
subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, env=env)
subprocess.run(
cmds,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
shell=is_windows,
)
.stdout.strip()
.decode("utf-8")
)
@@ -160,51 +165,9 @@ def xz(data):
return lzma.compress(data, preset=9, check=lzma.CHECK_NONE)
def parse_props(file):
props = {}
with open(file, "r") as f:
for line in [l.strip(" \t\r\n") for l in f]:
if line.startswith("#") or len(line) == 0:
continue
prop = line.split("=")
if len(prop) != 2:
continue
value = prop[1].strip(" \t\r\n")
if len(value) == 0:
continue
props[prop[0].strip(" \t\r\n")] = value
return props
def load_config(args):
commit_hash = cmd_out(["git", "rev-parse", "--short=8", "HEAD"])
# Default values
config["version"] = commit_hash
config["versionCode"] = 1000000
config["outdir"] = "out"
args.config = Path(args.config)
# Load prop files
if args.config.exists():
config.update(parse_props(args.config))
if Path("gradle.properties").exists():
for key, value in parse_props("gradle.properties").items():
if key.startswith("magisk."):
config[key[7:]] = value
try:
config["versionCode"] = int(config["versionCode"])
except ValueError:
error('Config error: "versionCode" is required to be an integer')
config["outdir"] = Path(config["outdir"])
config["outdir"].mkdir(mode=0o755, parents=True, exist_ok=True)
global STDOUT
STDOUT = None if args.verbose > 0 else subprocess.DEVNULL
###############
# Build Native
###############
def clean_elf():
@@ -225,26 +188,28 @@ def clean_elf():
elf_cleaner,
]
)
args = [elf_cleaner, "--api-level", "23"]
args.extend(
Path("native", "out", arch, bin)
for arch in archs
for bin in ["magisk", "magiskpolicy"]
)
execv(args)
cmds = [elf_cleaner, "--api-level", "23"]
cmds.extend(glob.glob("native/out/*/magisk"))
cmds.extend(glob.glob("native/out/*/magiskpolicy"))
execv(cmds)
def run_ndk_build(args, flags):
def run_ndk_build(cmds: list):
os.chdir("native")
flags = "NDK_PROJECT_PATH=. NDK_APPLICATION_MK=src/Application.mk " + flags
cmds.append("NDK_PROJECT_PATH=.")
cmds.append("NDK_APPLICATION_MK=src/Application.mk")
cmds.append(f"APP_ABI={' '.join(build_abis.keys())}")
cmds.append(f"-j{cpu_count}")
if args.verbose > 1:
flags = "V=1 " + flags
proc = system(f"{ndk_build} {flags} -j{cpu_count}")
cmds.append("V=1")
if not args.release:
cmds.append("MAGISK_DEBUG=1")
proc = execv([ndk_build, *cmds])
if proc.returncode != 0:
error("Build binary failed!")
os.chdir("..")
for arch in archs:
for arch in build_abis.keys():
arch_dir = Path("native", "libs", arch)
out_dir = Path("native", "out", arch)
for source in arch_dir.iterdir():
@@ -252,40 +217,40 @@ def run_ndk_build(args, flags):
mv(source, target)
def build_cpp_src(args, targets: set):
def build_cpp_src(targets: set):
dump_flag_header()
flags = ""
cmds = []
clean = False
if "magisk" in targets:
flags += " B_MAGISK=1"
cmds.append("B_MAGISK=1")
clean = True
if "magiskpolicy" in targets:
flags += " B_POLICY=1"
cmds.append("B_POLICY=1")
clean = True
if "magiskinit" in targets:
flags += " B_PRELOAD=1"
cmds.append("B_PRELOAD=1")
if "resetprop" in targets:
flags += " B_PROP=1"
cmds.append("B_PROP=1")
if flags:
run_ndk_build(args, flags)
if cmds:
run_ndk_build(cmds)
flags = ""
cmds.clear()
if "magiskinit" in targets:
flags += " B_INIT=1"
cmds.append("B_INIT=1")
if "magiskboot" in targets:
flags += " B_BOOT=1"
cmds.append("B_BOOT=1")
if flags:
flags += " B_CRT0=1"
run_ndk_build(args, flags)
if cmds:
cmds.append("B_CRT0=1")
run_ndk_build(cmds)
if clean:
clean_elf()
@@ -295,11 +260,11 @@ def run_cargo(cmds):
env = os.environ.copy()
env["PATH"] = f'{rust_bin}{os.pathsep}{env["PATH"]}'
env["CARGO_BUILD_RUSTC"] = str(rust_bin / f"rustc{EXE_EXT}")
env["RUSTFLAGS"] = f"-Clinker-plugin-lto -Zthreads={min(8, cpu_count)}"
env["CARGO_BUILD_RUSTFLAGS"] = f"-Z threads={min(8, cpu_count)}"
return execv([cargo, *cmds], env)
def build_rust_src(args, targets: set):
def build_rust_src(targets: set):
targets = targets.copy()
if "resetprop" in targets:
targets.add("magisk")
@@ -309,54 +274,40 @@ def build_rust_src(args, targets: set):
os.chdir(Path("native", "src"))
native_out = Path("..", "out")
native_out.mkdir(mode=0o755, exist_ok=True)
# Start building the actual build commands
# Start building the build commands
cmds = ["build", "-p", ""]
rust_out = "debug"
if args.release:
cmds.append("-r")
rust_out = "release"
profile = "release"
else:
profile = "debug"
if args.verbose == 0:
cmds.append("-q")
elif args.verbose > 1:
cmds.append("--verbose")
cmds.append("--target")
cmds.append("")
for triple in build_abis.values():
cmds.append("--target")
cmds.append(triple)
for arch, triple in zip(archs, triples):
rust_triple = (
"thumbv7neon-linux-androideabi" if triple.startswith("armv7") else triple
)
cmds[-1] = rust_triple
for tgt in targets:
cmds[2] = tgt
proc = run_cargo(cmds)
if proc.returncode != 0:
error("Build binary failed!")
for tgt in targets:
cmds[2] = tgt
proc = run_cargo(cmds)
if proc.returncode != 0:
error("Build binary failed!")
os.chdir(Path("..", ".."))
native_out = Path("native", "out")
rust_out = native_out / "rust"
for arch, triple in build_abis.items():
arch_out = native_out / arch
arch_out.mkdir(mode=0o755, exist_ok=True)
for tgt in targets:
source = Path("target", rust_triple, rust_out, f"lib{tgt}.a")
source = rust_out / triple / profile / f"lib{tgt}.a"
target = arch_out / f"lib{tgt}-rs.a"
mv(source, target)
os.chdir(Path("..", ".."))
def run_cargo_cmd(args):
global STDOUT
STDOUT = None
if len(args.commands) >= 1 and args.commands[0] == "--":
args.commands = args.commands[1:]
os.chdir(Path("native", "src"))
run_cargo(args.commands)
os.chdir(Path("..", ".."))
def write_if_diff(file_name: Path, text: str):
do_write = True
@@ -387,7 +338,7 @@ def dump_flag_header():
write_if_diff(Path(native_gen_path, "flags.h"), flag_txt)
def build_binary(args):
def build_native():
# Verify NDK install
try:
with open(Path(ndk_path, "ONDK_VERSION"), "r") as ondk_ver:
@@ -402,10 +353,22 @@ def build_binary(args):
if not targets:
return
header("* Building binaries: " + " ".join(targets))
header("* Building: " + " ".join(targets))
build_rust_src(args, targets)
build_cpp_src(args, targets)
if sccache := shutil.which("sccache"):
os.environ["RUSTC_WRAPPER"] = sccache
os.environ["NDK_CCACHE"] = sccache
os.environ["CARGO_INCREMENTAL"] = "0"
if ccache := shutil.which("ccache"):
os.environ["NDK_CCACHE"] = ccache
build_rust_src(targets)
build_cpp_src(targets)
############
# Build App
############
def find_jdk():
@@ -440,7 +403,7 @@ def find_jdk():
return env
def build_apk(args, module):
def build_apk(module: str):
env = find_jdk()
build_type = "Release" if args.release else "Debug"
@@ -466,9 +429,9 @@ def build_apk(args, module):
header(f"Output: {target}")
def build_app(args):
def build_app():
header("* Building the Magisk app")
build_apk(args, ":app:apk")
build_apk(":app:apk")
build_type = "release" if args.release else "debug"
@@ -484,13 +447,18 @@ def build_app(args):
cp(source, target)
def build_stub(args):
def build_stub():
header("* Building the stub app")
build_apk(args, ":app:stub")
build_apk(":app:stub")
def cleanup(args):
support_targets = {"native", "cpp", "rust", "java"}
################
# Build General
################
def cleanup():
support_targets = {"native", "cpp", "rust", "app"}
if args.targets:
targets = set(args.targets) & support_targets
if "native" in targets:
@@ -503,7 +471,6 @@ def cleanup(args):
header("* Cleaning C++")
rm_rf(Path("native", "libs"))
rm_rf(Path("native", "obj"))
rm_rf(Path("native", "out"))
if "rust" in targets:
header("* Cleaning Rust")
@@ -513,12 +480,34 @@ def cleanup(args):
for rs_gen in glob.glob("native/**/*-rs.*pp", recursive=True):
rm(rs_gen)
if "java" in targets:
header("* Cleaning java")
if "native" in targets:
rm_rf(Path("native", "out"))
if "app" in targets:
header("* Cleaning app")
execv([gradlew, ":app:clean"], env=find_jdk())
def setup_ndk(args):
def build_all():
build_native()
build_app()
############
# Utilities
############
def cargo_cli():
args.force_out = True
if len(args.commands) >= 1 and args.commands[0] == "--":
args.commands = args.commands[1:]
os.chdir(Path("native", "src"))
run_cargo(args.commands)
os.chdir(Path("..", ".."))
def setup_ndk():
ndk_ver = config["ondkVersion"]
url = f"https://github.com/topjohnwu/ondk/releases/download/{ndk_ver}/ondk-{ndk_ver}-{os_name}.tar.xz"
ndk_archive = url.split("/")[-1]
@@ -537,7 +526,7 @@ def setup_ndk(args):
mv(ondk_path, ndk_path)
def push_files(args, script):
def push_files(script):
abi = cmd_out([adb_path, "shell", "getprop", "ro.product.cpu.abi"])
if not abi:
error("Cannot detect emulator ABI")
@@ -565,22 +554,22 @@ def push_files(args, script):
error("adb push failed!")
def setup_avd(args):
def setup_avd():
if not args.skip:
build_all(args)
build_all()
header("* Setting up emulator")
push_files(args, Path("scripts", "avd_magisk.sh"))
push_files(Path("scripts", "avd_magisk.sh"))
proc = execv([adb_path, "shell", "sh", "/data/local/tmp/avd_magisk.sh"])
if proc.returncode != 0:
error("avd_magisk.sh failed!")
def patch_avd_file(args):
def patch_avd_file():
if not args.skip:
build_all(args)
build_all()
input = Path(args.image)
if args.output:
@@ -593,7 +582,7 @@ def patch_avd_file(args):
header(f"* Patching {input.name}")
push_files(args, Path("scripts", "avd_patch.sh"))
push_files(Path("scripts", "avd_patch.sh"))
proc = execv([adb_path, "push", input, "/data/local/tmp"])
if proc.returncode != 0:
@@ -610,12 +599,7 @@ def patch_avd_file(args):
header(f"Output: {output}")
def build_all(args):
build_binary(args)
build_app(args)
def setup_rustup(args):
def setup_rustup():
wrapper_dir = Path(args.wrapper_dir)
rm_rf(wrapper_dir)
wrapper_dir.mkdir(mode=0o755, parents=True, exist_ok=True)
@@ -631,10 +615,10 @@ def setup_rustup(args):
# Build rustup_wrapper
wrapper_src = Path("tools", "rustup_wrapper")
cargo_toml = wrapper_src / "Cargo.toml"
execv(
[cargo, "build", "--release", f"--manifest-path={cargo_toml}"]
+ (["--verbose"] if args.verbose > 1 else [])
)
cmds = ["build", "--release", f"--manifest-path={cargo_toml}"]
if args.verbose > 1:
cmds.append("--verbose")
run_cargo(cmds)
# Replace rustup with wrapper
wrapper = wrapper_dir / (f"rustup{EXE_EXT}")
@@ -643,77 +627,149 @@ def setup_rustup(args):
wrapper.chmod(0o755)
parser = argparse.ArgumentParser(description="Magisk build script")
parser.set_defaults(func=lambda x: None)
parser.add_argument(
"-r", "--release", action="store_true", help="compile in release mode"
)
parser.add_argument("-v", "--verbose", action="count", default=0, help="verbose output")
parser.add_argument(
"-c",
"--config",
default="config.prop",
help="custom config file (default: config.prop)",
)
subparsers = parser.add_subparsers(title="actions")
##################
# Config and args
##################
all_parser = subparsers.add_parser("all", help="build everything")
all_parser.set_defaults(func=build_all)
binary_parser = subparsers.add_parser("binary", help="build binaries")
binary_parser.add_argument(
"targets",
nargs="*",
help=f"{', '.join(support_targets)}, \
or empty for defaults ({', '.join(default_targets)})",
)
binary_parser.set_defaults(func=build_binary)
def parse_props(file):
props = {}
with open(file, "r") as f:
for line in [l.strip(" \t\r\n") for l in f]:
if line.startswith("#") or len(line) == 0:
continue
prop = line.split("=")
if len(prop) != 2:
continue
key = prop[0].strip(" \t\r\n")
value = prop[1].strip(" \t\r\n")
if not key or not value:
continue
props[key] = value
return props
cargo_parser = subparsers.add_parser("cargo", help="run cargo with proper environment")
cargo_parser.add_argument("commands", nargs=argparse.REMAINDER)
cargo_parser.set_defaults(func=run_cargo_cmd)
rustup_parser = subparsers.add_parser("rustup", help="setup rustup wrapper")
rustup_parser.add_argument("wrapper_dir", help="path to setup rustup wrapper binaries")
rustup_parser.set_defaults(func=setup_rustup)
def load_config():
commit_hash = cmd_out(["git", "rev-parse", "--short=8", "HEAD"])
app_parser = subparsers.add_parser("app", help="build the Magisk app")
app_parser.set_defaults(func=build_app)
# Default values
config["version"] = commit_hash
config["versionCode"] = 1000000
config["outdir"] = "out"
stub_parser = subparsers.add_parser("stub", help="build the stub app")
stub_parser.set_defaults(func=build_stub)
args.config = Path(args.config)
avd_parser = subparsers.add_parser("emulator", help="setup AVD for development")
avd_parser.add_argument(
"-s", "--skip", action="store_true", help="skip building binaries and the app"
)
avd_parser.set_defaults(func=setup_avd)
# Load prop files
if args.config.exists():
config.update(parse_props(args.config))
avd_patch_parser = subparsers.add_parser(
"avd_patch", help="patch AVD ramdisk.img or init_boot.img"
)
avd_patch_parser.add_argument("image", help="path to ramdisk.img or init_boot.img")
avd_patch_parser.add_argument("output", help="optional output file name", nargs="?")
avd_patch_parser.add_argument(
"-s", "--skip", action="store_true", help="skip building binaries and the app"
)
avd_patch_parser.set_defaults(func=patch_avd_file)
if Path("gradle.properties").exists():
for key, value in parse_props("gradle.properties").items():
if key.startswith("magisk."):
config[key[7:]] = value
clean_parser = subparsers.add_parser("clean", help="cleanup")
clean_parser.add_argument(
"targets", nargs="*", help="native, cpp, rust, java, or empty to clean all"
)
clean_parser.set_defaults(func=cleanup)
try:
config["versionCode"] = int(config["versionCode"])
except ValueError:
error('Config error: "versionCode" is required to be an integer')
ndk_parser = subparsers.add_parser("ndk", help="setup Magisk NDK")
ndk_parser.set_defaults(func=setup_ndk)
config["outdir"] = Path(config["outdir"])
config["outdir"].mkdir(mode=0o755, parents=True, exist_ok=True)
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
if "abiList" in config:
abiList = re.split("\\s*,\\s*", config["abiList"])
archs = set(abiList) & support_abis.keys()
else:
archs = {"armeabi-v7a", "x86", "arm64-v8a", "x86_64"}
args = parser.parse_args()
load_config(args)
triples = map(support_abis.get, archs)
# Call corresponding functions
args.func(args)
global build_abis
build_abis = dict(zip(archs, triples))
def parse_args():
parser = argparse.ArgumentParser(description="Magisk build script")
parser.set_defaults(func=lambda x: None)
parser.add_argument(
"-r", "--release", action="store_true", help="compile in release mode"
)
parser.add_argument(
"-v", "--verbose", action="count", default=0, help="verbose output"
)
parser.add_argument(
"-c",
"--config",
default="config.prop",
help="custom config file (default: config.prop)",
)
subparsers = parser.add_subparsers(title="actions")
all_parser = subparsers.add_parser("all", help="build everything")
native_parser = subparsers.add_parser("native", help="build native binaries")
native_parser.add_argument(
"targets",
nargs="*",
help=f"{', '.join(support_targets)}, \
or empty for defaults ({', '.join(default_targets)})",
)
app_parser = subparsers.add_parser("app", help="build the Magisk app")
stub_parser = subparsers.add_parser("stub", help="build the stub app")
clean_parser = subparsers.add_parser("clean", help="cleanup")
clean_parser.add_argument(
"targets", nargs="*", help="native, cpp, rust, java, or empty to clean all"
)
ndk_parser = subparsers.add_parser("ndk", help="setup Magisk NDK")
emu_parser = subparsers.add_parser("emulator", help="setup AVD for development")
emu_parser.add_argument(
"-s", "--skip", action="store_true", help="skip building binaries and the app"
)
avd_patch_parser = subparsers.add_parser(
"avd_patch", help="patch AVD ramdisk.img or init_boot.img"
)
avd_patch_parser.add_argument("image", help="path to ramdisk.img or init_boot.img")
avd_patch_parser.add_argument("output", help="optional output file name", nargs="?")
avd_patch_parser.add_argument(
"-s", "--skip", action="store_true", help="skip building binaries and the app"
)
cargo_parser = subparsers.add_parser(
"cargo", help="call 'cargo' commands against the project"
)
cargo_parser.add_argument("commands", nargs=argparse.REMAINDER)
rustup_parser = subparsers.add_parser("rustup", help="setup rustup wrapper")
rustup_parser.add_argument(
"wrapper_dir", help="path to setup rustup wrapper binaries"
)
# Set callbacks
all_parser.set_defaults(func=build_all)
native_parser.set_defaults(func=build_native)
cargo_parser.set_defaults(func=cargo_cli)
rustup_parser.set_defaults(func=setup_rustup)
app_parser.set_defaults(func=build_app)
stub_parser.set_defaults(func=build_stub)
emu_parser.set_defaults(func=setup_avd)
avd_patch_parser.set_defaults(func=patch_avd_file)
clean_parser.set_defaults(func=cleanup)
ndk_parser.set_defaults(func=setup_ndk)
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
return parser.parse_args()
args = parse_args()
load_config()
vars(args)["force_out"] = False
args.func()

View File

@@ -25,10 +25,10 @@ tasks.withType<KotlinCompile>().configureEach {
}
dependencies {
implementation(kotlin("gradle-plugin", "2.0.0"))
implementation("com.android.tools.build:gradle:8.5.1")
implementation("com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:2.0.0-1.0.23")
implementation("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.7")
implementation("org.lsposed.lsparanoid:gradle-plugin:0.6.0")
implementation("org.eclipse.jgit:org.eclipse.jgit:6.10.0.202406032230-r")
implementation(kotlin("gradle-plugin", libs.versions.kotlin.get()))
implementation(libs.android.gradle.plugin)
implementation(libs.ksp.plugin)
implementation(libs.navigation.safe.args.plugin)
implementation(libs.lsparanoid.plugin)
implementation(libs.jgit)
}

View File

@@ -0,0 +1,7 @@
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}

View File

@@ -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> {

View File

@@ -72,7 +72,7 @@ fun Project.setupCommon() {
compileSdkVersion(34)
buildToolsVersion = "34.0.0"
ndkPath = "$sdkDirectory/ndk/magisk"
ndkVersion = "27.0.11902837"
ndkVersion = "27.0.12077973"
defaultConfig {
minSdk = 23
@@ -121,9 +121,11 @@ const val BUSYBOX_ZIP_CHECKSUM =
fun Project.setupCoreLib() {
setupCommon()
val abiList = Config.abiList
val syncLibs by tasks.registering(Sync::class) {
into("src/main/jniLibs")
for (abi in arrayOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64", "riscv64")) {
for (abi in abiList) {
into(abi) {
from(rootProject.file("native/out/$abi")) {
include("magiskboot", "magiskinit", "magiskpolicy", "magisk", "libinit-ld.so")
@@ -132,7 +134,7 @@ fun Project.setupCoreLib() {
}
}
onlyIf {
if (inputs.sourceFiles.files.size != 25)
if (inputs.sourceFiles.files.size != abiList.size * 5)
throw StopExecutionException("Please build binaries first! (./build.py binary)")
true
}
@@ -158,6 +160,7 @@ fun Project.setupCoreLib() {
}
}
from(zipTree(bb))
include(abiList.map { "$it/libbusybox.so" })
into("src/main/jniLibs")
}

View File

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

View File

@@ -30,5 +30,5 @@ android.nonFinalResIds=false
# Magisk
magisk.stubVersion=40
magisk.versionCode=27006
magisk.ondkVersion=r27.2
magisk.versionCode=27007
magisk.ondkVersion=r27.4

65
gradle/libs.versions.toml Normal file
View File

@@ -0,0 +1,65 @@
[versions]
kotlin = "2.0.10"
android = "8.5.2"
ksp = "2.0.10-1.0.24"
rikka = "1.3.0"
navigation = "2.7.7"
libsu = "6.0.0"
moshi = "1.15.1"
okhttp = "4.12.0"
retrofit = "2.11.0"
room = "2.6.1"
[libraries]
bcpkix = { module = "org.bouncycastle:bcpkix-jdk18on", version = "1.78.1" }
commons-compress = { module = "org.apache.commons:commons-compress", version = "1.27.0" }
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
retrofit-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" }
retrofit-scalars = { module = "com.squareup.retrofit2:converter-scalars", version.ref = "retrofit" }
markwon-core = { module = "io.noties.markwon:core", version = "4.6.2" }
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
okhttp-dnsoverhttps = { module = "com.squareup.okhttp3:okhttp-dnsoverhttps", version.ref = "okhttp" }
okhttp-logging = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" }
moshi = { module = "com.squareup.moshi:moshi", version.ref = "moshi" }
moshi-codegen = { module = "com.squareup.moshi:moshi-kotlin-codegen", version.ref = "moshi" }
timber = { module = "com.jakewharton.timber:timber", version = "5.0.1" }
jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version = "6.10.0.202406032230-r" }
# AndroidX
activity = { module = "androidx.activity:activity", version = "1.9.1" }
appcompat = { module = "androidx.appcompat:appcompat", version = "1.7.0" }
core-ktx = { module = "androidx.core:core-ktx", version = "1.13.1" }
core-splashscreen = { module = "androidx.core:core-splashscreen", version = "1.0.1" }
constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.1.4" }
fragment-ktx = { module = "androidx.fragment:fragment-ktx", version = "1.8.2" }
navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "navigation" }
navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version.ref = "navigation" }
profileinstaller = { module = "androidx.profileinstaller:profileinstaller", version = "1.3.1" }
recyclerview = { module = "androidx.recyclerview:recyclerview", version = "1.3.2" }
room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version = "1.1.0" }
transition = { module = "androidx.transition:transition", version = "1.5.1" }
collection-ktx = { module = "androidx.collection:collection-ktx", version = "1.4.3" }
lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version = "2.8.4" }
material = { module = "com.google.android.material:material", version = "1.12.0" }
# topjohnwu
indeterminate-checkbox = { module = "com.github.topjohnwu:indeterminate-checkbox", version = "1.0.7" }
libsu-core = { module = "com.github.topjohnwu.libsu:core", version.ref = "libsu" }
libsu-service = { module = "com.github.topjohnwu.libsu:service", version.ref = "libsu" }
libsu-nio = { module = "com.github.topjohnwu.libsu:nio", version.ref = "libsu" }
# Rikka
rikka-recyclerview = { module = "dev.rikka.rikkax.recyclerview:recyclerview-ktx", version = "1.3.2" }
rikka-layoutinflater = { module = "dev.rikka.rikkax.layoutinflater:layoutinflater", version.ref = "rikka" }
rikka-insets = { module = "dev.rikka.rikkax.insets:insets", version.ref = "rikka" }
# Build plugins
android-gradle-plugin = { module = "com.android.tools.build:gradle", version.ref = "android" }
ksp-plugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
navigation-safe-args-plugin = { module = "androidx.navigation:navigation-safe-args-gradle-plugin", version.ref = "navigation" }
lsparanoid-plugin = { module = "org.lsposed.lsparanoid:gradle-plugin", version = "0.6.0" }
[plugins]

View File

@@ -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"]

View File

@@ -1,2 +0,0 @@
test.cpp
target/

View File

@@ -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
View File

@@ -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",
]

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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()) {

View File

@@ -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"

View File

@@ -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]> {

View File

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

View File

@@ -1,6 +1,7 @@
#include <bit>
#include <functional>
#include <memory>
#include <span>
#include <base.hpp>
@@ -61,6 +62,8 @@ void dyn_img_hdr::print() const {
fprintf(stderr, "%-*s [%u]\n", PADDING, "RECOV_DTBO_SZ", recovery_dtbo_size());
if (ver == 2 || is_vendor())
fprintf(stderr, "%-*s [%u]\n", PADDING, "DTB_SZ", dtb_size());
if (ver == 4 && is_vendor())
fprintf(stderr, "%-*s [%u]\n", PADDING, "BOOTCONFIG_SZ", bootconfig_size());
if (uint32_t os_ver = os_version()) {
int a,b,c,y,m = 0;
@@ -273,8 +276,7 @@ static format_t check_fmt_lg(const uint8_t *buf, unsigned sz) {
#define CMD_MATCH(s) BUFFER_MATCH(h->cmdline, s)
const pair<const uint8_t *, dyn_img_hdr *>
boot_img::create_hdr(const uint8_t *addr, format_t type) {
pair<const uint8_t *, dyn_img_hdr *> boot_img::create_hdr(const uint8_t *addr, format_t type) {
if (type == AOSP_VENDOR) {
fprintf(stderr, "VENDOR_BOOT_HDR\n");
auto h = reinterpret_cast<const boot_img_hdr_vnd_v3*>(addr);
@@ -346,10 +348,23 @@ const pair<const uint8_t *, dyn_img_hdr *>
addr += ACCLAIM_PRE_HEADER_SZ;
}
// addr could be adjusted
return make_pair(addr, make_hdr(addr));
}
static const char *vendor_ramdisk_type(int type) {
switch (type) {
case VENDOR_RAMDISK_TYPE_PLATFORM:
return "platform";
case VENDOR_RAMDISK_TYPE_RECOVERY:
return "recovery";
case VENDOR_RAMDISK_TYPE_DLKM:
return "dlkm";
case VENDOR_RAMDISK_TYPE_NONE:
default:
return "none";
}
}
#define assert_off() \
if ((base_addr + off) > (map.buf() + map.sz())) { \
fprintf(stderr, "Corrupted boot image!\n"); \
@@ -362,14 +377,6 @@ off += hdr->name##_size(); \
off = align_to(off, hdr->page_size()); \
assert_off();
#define get_ignore(name) \
if (hdr->name##_size()) { \
auto blk_sz = align_to(hdr->name##_size(), hdr->page_size()); \
off += blk_sz; \
} \
assert_off();
bool boot_img::parse_image(const uint8_t *p, format_t type) {
auto [base_addr, hdr] = create_hdr(p, type);
if (hdr == nullptr) {
@@ -395,15 +402,12 @@ bool boot_img::parse_image(const uint8_t *p, format_t type) {
get_block(extra);
get_block(recovery_dtbo);
get_block(dtb);
auto ignore_addr = base_addr + off;
get_ignore(signature)
get_ignore(vendor_ramdisk_table)
get_ignore(bootconfig)
get_block(signature);
get_block(vendor_ramdisk_table);
get_block(bootconfig);
payload = byte_view(base_addr, off);
auto tail_addr = base_addr + off;
ignore = byte_view(ignore_addr, tail_addr - ignore_addr);
tail = byte_view(tail_addr, map.buf() + map.sz() - tail_addr);
if (auto size = hdr->kernel_size()) {
@@ -458,24 +462,40 @@ bool boot_img::parse_image(const uint8_t *p, format_t type) {
fprintf(stderr, "%-*s [%s]\n", PADDING, "KERNEL_FMT", fmt2name[k_fmt]);
}
if (auto size = hdr->ramdisk_size()) {
if (hdr->is_vendor() && hdr->header_version() >= 4) {
if (hdr->vendor_ramdisk_table_size()) {
// v4 vendor boot contains multiple ramdisks
// Do not try to mess with it for now
r_fmt = UNKNOWN;
using table_entry = const vendor_ramdisk_table_entry_v4;
if (hdr->vendor_ramdisk_table_entry_size() != sizeof(table_entry)) {
fprintf(stderr,
"! Invalid vendor image: vendor_ramdisk_table_entry_size != %zu\n",
sizeof(table_entry));
exit(1);
}
span<table_entry> table(
reinterpret_cast<table_entry *>(vendor_ramdisk_table),
hdr->vendor_ramdisk_table_entry_num());
for (auto &it : table) {
format_t fmt = check_fmt_lg(ramdisk + it.ramdisk_offset, it.ramdisk_size);
fprintf(stderr,
"%-*s name=[%s] type=[%s] size=[%u] fmt=[%s]\n", PADDING, "VND_RAMDISK",
it.ramdisk_name, vendor_ramdisk_type(it.ramdisk_type),
it.ramdisk_size, fmt2name[fmt]);
}
} else {
r_fmt = check_fmt_lg(ramdisk, size);
if (r_fmt == MTK) {
fprintf(stderr, "MTK_RAMDISK_HDR\n");
flags[MTK_RAMDISK] = true;
r_hdr = reinterpret_cast<const mtk_hdr *>(ramdisk);
fprintf(stderr, "%-*s [%u]\n", PADDING, "SIZE", r_hdr->size);
fprintf(stderr, "%-*s [%s]\n", PADDING, "NAME", r_hdr->name);
ramdisk += sizeof(mtk_hdr);
hdr->ramdisk_size() -= sizeof(mtk_hdr);
r_fmt = check_fmt_lg(ramdisk, hdr->ramdisk_size());
}
fprintf(stderr, "%-*s [%s]\n", PADDING, "RAMDISK_FMT", fmt2name[r_fmt]);
}
if (r_fmt == MTK) {
fprintf(stderr, "MTK_RAMDISK_HDR\n");
flags[MTK_RAMDISK] = true;
r_hdr = reinterpret_cast<const mtk_hdr *>(ramdisk);
fprintf(stderr, "%-*s [%u]\n", PADDING, "SIZE", r_hdr->size);
fprintf(stderr, "%-*s [%s]\n", PADDING, "NAME", r_hdr->name);
ramdisk += sizeof(mtk_hdr);
hdr->ramdisk_size() -= sizeof(mtk_hdr);
r_fmt = check_fmt_lg(ramdisk, hdr->ramdisk_size());
}
fprintf(stderr, "%-*s [%s]\n", PADDING, "RAMDISK_FMT", fmt2name[r_fmt]);
}
if (auto size = hdr->extra_size()) {
e_fmt = check_fmt_lg(extra, size);
@@ -561,7 +581,30 @@ int unpack(const char *image, bool skip_decomp, bool hdr) {
dump(boot.kernel_dtb.buf(), boot.kernel_dtb.sz(), KER_DTB_FILE);
// Dump ramdisk
if (!skip_decomp && COMPRESSED(boot.r_fmt)) {
if (boot.hdr->vendor_ramdisk_table_size()) {
using table_entry = const vendor_ramdisk_table_entry_v4;
span<table_entry> table(
reinterpret_cast<table_entry *>(boot.vendor_ramdisk_table),
boot.hdr->vendor_ramdisk_table_entry_num());
xmkdir(VND_RAMDISK_DIR, 0755);
owned_fd dirfd = xopen(VND_RAMDISK_DIR, O_RDONLY | O_CLOEXEC);
for (auto &it : table) {
char file_name[40];
if (it.ramdisk_name[0] == '\0') {
strscpy(file_name, RAMDISK_FILE, sizeof(file_name));
} else {
ssprintf(file_name, sizeof(file_name), "%s.cpio", it.ramdisk_name);
}
owned_fd fd = xopenat(dirfd, file_name, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
format_t fmt = check_fmt_lg(boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
if (!skip_decomp && COMPRESSED(fmt)) {
decompress(fmt, fd, boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
} else {
xwrite(fd, boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
}
}
} else if (!skip_decomp && COMPRESSED(boot.r_fmt)) {
if (boot.hdr->ramdisk_size() != 0) {
int fd = creat(RAMDISK_FILE, 0644);
decompress(boot.r_fmt, fd, boot.ramdisk, boot.hdr->ramdisk_size());
@@ -591,6 +634,9 @@ int unpack(const char *image, bool skip_decomp, bool hdr) {
// Dump dtb
dump(boot.dtb, boot.hdr->dtb_size(), DTB_FILE);
// Dump bootconfig
dump(boot.bootconfig, boot.hdr->bootconfig_size(), BOOTCONFIG_FILE);
return boot.flags[CHROMEOS_FLAG] ? 2 : 0;
}
@@ -620,6 +666,7 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
hdr->ramdisk_size() = 0;
hdr->second_size() = 0;
hdr->dtb_size() = 0;
hdr->bootconfig_size() = 0;
if (access(HEADER_FILE, R_OK) == 0)
hdr->load_hdr_file();
@@ -703,7 +750,40 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
// Copy MTK headers
xwrite(fd, boot.r_hdr, sizeof(mtk_hdr));
}
if (access(RAMDISK_FILE, R_OK) == 0) {
using table_entry = vendor_ramdisk_table_entry_v4;
vector<table_entry> ramdisk_table;
if (boot.hdr->vendor_ramdisk_table_size()) {
// Create a copy so we can modify it
auto entry_start = reinterpret_cast<const table_entry *>(boot.vendor_ramdisk_table);
ramdisk_table.insert(
ramdisk_table.begin(),
entry_start, entry_start + boot.hdr->vendor_ramdisk_table_entry_num());
owned_fd dirfd = xopen(VND_RAMDISK_DIR, O_RDONLY | O_CLOEXEC);
uint32_t ramdisk_offset = 0;
for (auto &it : ramdisk_table) {
char file_name[64];
if (it.ramdisk_name[0] == '\0') {
strscpy(file_name, RAMDISK_FILE, sizeof(file_name));
} else {
ssprintf(file_name, sizeof(file_name), "%s.cpio", it.ramdisk_name);
}
mmap_data m(dirfd, file_name);
format_t fmt = check_fmt_lg(boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
it.ramdisk_offset = ramdisk_offset;
if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf(), m.sz())) && COMPRESSED(fmt)) {
it.ramdisk_size = compress(fmt, fd, m.buf(), m.sz());
} else {
it.ramdisk_size = xwrite(fd, m.buf(), m.sz());
}
ramdisk_offset += it.ramdisk_size;
}
hdr->ramdisk_size() = ramdisk_offset;
file_align();
} else if (access(RAMDISK_FILE, R_OK) == 0) {
mmap_data m(RAMDISK_FILE);
auto r_fmt = boot.r_fmt;
if (!skip_comp && !hdr->is_vendor() && hdr->header_version() == 4 && r_fmt != LZ4_LEGACY) {
@@ -754,10 +834,22 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
file_align();
}
// Directly copy ignored blobs
if (boot.ignore.sz()) {
// ignore.sz() should already be aligned
xwrite(fd, boot.ignore.buf(), boot.ignore.sz());
// Copy boot signature
if (boot.hdr->signature_size()) {
xwrite(fd, boot.signature, boot.hdr->signature_size());
file_align();
}
// vendor ramdisk table
if (!ramdisk_table.empty()) {
xwrite(fd, ramdisk_table.data(), sizeof(table_entry) * ramdisk_table.size());
file_align();
}
// bootconfig
if (access(BOOTCONFIG_FILE, R_OK) == 0) {
hdr->bootconfig_size() = restore(fd, BOOTCONFIG_FILE);
file_align();
}
// Proprietary stuffs

View File

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

View File

@@ -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<()> {

View File

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

View File

@@ -7,8 +7,16 @@
using namespace std;
#ifdef USE_CRT0
__asm__(".global vfprintf \n vfprintf = musl_vfprintf");
__asm__(".global vsscanf \n vsscanf = tfp_vsscanf");
__BEGIN_DECLS
int tfp_vsscanf(const char *s, const char *fmt, va_list args);
int vsscanf(const char *s, const char *fmt, va_list args) {
return tfp_vsscanf(s, fmt, args);
}
int musl_vfprintf(FILE *stream, const char *format, va_list arg);
int vfprintf(FILE *stream, const char *format, va_list arg) {
return musl_vfprintf(stream, format, arg);
}
__END_DECLS
#endif
static void print_formats() {

View File

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

View File

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

View File

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

View File

@@ -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) {

View File

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

View File

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

View File

@@ -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();
}
/************************

View File

@@ -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()?;
}

View File

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

View File

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

View File

@@ -41,16 +41,16 @@ static string extract_quoted_str_until(chars<escapes...>, chars<breaks...>,
}
// Parse string into key value pairs.
// The string format: [delim][key][padding]=[padding][value][delim]
template<char delim, char... padding>
// The string format: [delim][key][padding][eq][padding][value][delim]
template<char delim, char eq, char... padding>
static kv_pairs parse_impl(chars<padding...>, string_view str) {
kv_pairs kv;
char skip_array[] = {'=', padding...};
char skip_array[] = {eq, padding...};
string_view skip(skip_array, std::size(skip_array));
bool quoted = false;
for (size_t pos = 0u; pos < str.size(); pos = str.find_first_not_of(delim, pos)) {
auto key = extract_quoted_str_until(
chars<padding..., delim>{}, chars<'='>{}, str, pos, quoted);
chars<padding..., delim>{}, chars<eq>{}, str, pos, quoted);
pos = str.find_first_not_of(skip, pos);
if (pos == string_view::npos || str[pos] == delim) {
kv.emplace_back(key, "");
@@ -63,10 +63,13 @@ static kv_pairs parse_impl(chars<padding...>, string_view str) {
}
static kv_pairs parse_cmdline(string_view str) {
return parse_impl<' '>(chars<>{}, str);
return parse_impl<' ', '='>(chars<>{}, str);
}
static kv_pairs parse_bootconfig(string_view str) {
return parse_impl<'\n'>(chars<' '>{}, str);
return parse_impl<'\n', '='>(chars<' '>{}, str);
}
static kv_pairs parse_partition_map(std::string_view str) {
return parse_impl<';', ','>(chars<>{}, str);
}
#define test_bit(bit, array) (array[bit / 8] & (1 << (bit % 8)))
@@ -207,6 +210,25 @@ void load_kernel_info(BootConfig *config) {
config->print();
}
// `androidboot.partition_map` allows associating a partition name for a raw block device
// through a comma separated and semicolon deliminated list. For example,
// `androidboot.partition_map=vdb,metadata;vdc,userdata` maps `vdb` to `metadata` and `vdc` to
// `userdata`.
// https://android.googlesource.com/platform/system/core/+/refs/heads/android13-release/init/devices.cpp#191
kv_pairs load_partition_map() {
const string_view kPartitionMapKey = "androidboot.partition_map";
for (const auto &[key, value] : parse_cmdline(full_read("/proc/cmdline"))) {
if (key == kPartitionMapKey)
return parse_partition_map(value);
}
for (const auto &[key, value] : parse_bootconfig(full_read("/proc/bootconfig"))) {
if (key == kPartitionMapKey)
return parse_partition_map(value);
}
return {};
}
bool check_two_stage() {
if (access("/apex", F_OK) == 0)
return true;

View File

@@ -12,7 +12,12 @@
using namespace std;
#ifdef USE_CRT0
__asm__(".global vfprintf \n vfprintf = tfp_vfprintf");
__BEGIN_DECLS
int tfp_vfprintf(FILE *stream, const char *format, va_list arg);
int vfprintf(FILE *stream, const char *format, va_list arg) {
return tfp_vfprintf(stream, format, arg);
}
__END_DECLS
#endif
bool unxz(out_stream &strm, rust::Slice<const uint8_t> bytes) {

View File

@@ -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();

View File

@@ -29,21 +29,23 @@ bool avd_hack = false;
static void parse_device(devinfo *dev, const char *uevent) {
dev->partname[0] = '\0';
dev->devpath[0] = '\0';
dev->dmname[0] = '\0';
dev->devname[0] = '\0';
parse_prop_file(uevent, [=](string_view key, string_view value) -> bool {
if (key == "MAJOR")
dev->major = parse_int(value.data());
else if (key == "MINOR")
dev->minor = parse_int(value.data());
else if (key == "DEVNAME")
strcpy(dev->devname, value.data());
strscpy(dev->devname, value.data(), sizeof(dev->devname));
else if (key == "PARTNAME")
strcpy(dev->partname, value.data());
strscpy(dev->partname, value.data(), sizeof(dev->devname));
return true;
});
}
static void collect_devices() {
static void collect_devices(const auto &partition_map) {
char path[PATH_MAX];
devinfo dev{};
if (auto dir = xopen_dir("/sys/dev/block"); dir) {
@@ -55,7 +57,13 @@ static void collect_devices() {
sprintf(path, "/sys/dev/block/%s/dm/name", entry->d_name);
if (access(path, F_OK) == 0) {
auto name = rtrim(full_read(path));
strcpy(dev.dmname, name.data());
strscpy(dev.dmname, name.data(), sizeof(dev.dmname));
}
if (auto it = std::ranges::find_if(partition_map, [&](const auto &i) {
return i.first == dev.devname;
}); dev.partname[0] == '\0' && it != partition_map.end()) {
// use androidboot.partition_map as partname fallback.
strscpy(dev.partname, it->second.data(), sizeof(dev.partname));
}
sprintf(path, "/sys/dev/block/%s", entry->d_name);
xrealpath(path, dev.devpath, sizeof(dev.devpath));
@@ -70,8 +78,9 @@ static struct {
} blk_info;
static dev_t setup_block() {
static const auto partition_map = load_partition_map();
if (dev_list.empty())
collect_devices();
collect_devices(partition_map);
for (int tries = 0; tries < 3; ++tries) {
for (auto &dev : dev_list) {
@@ -93,7 +102,7 @@ static dev_t setup_block() {
// Wait 10ms and try again
usleep(10000);
dev_list.clear();
collect_devices();
collect_devices(partition_map);
}
// The requested partname does not exist
@@ -236,6 +245,7 @@ void MagiskInit::setup_tmp(const char *path) {
xmkdir(INTLROOT, 0711);
xmkdir(DEVICEDIR, 0711);
xmkdir(WORKERDIR, 0);
mount_preinit_dir(preinit_dev);
@@ -249,5 +259,21 @@ void MagiskInit::setup_tmp(const char *path) {
xmount(".", path, nullptr, MS_BIND, nullptr);
chdir(path);
// Prepare worker
xmount(WORKERDIR, WORKERDIR, nullptr, MS_BIND, nullptr);
// Use isolated devpts if kernel support
if (access("/dev/pts/ptmx", F_OK) == 0) {
xmkdirs(SHELLPTS, 0755);
xmount("devpts", SHELLPTS, "devpts", MS_NOSUID | MS_NOEXEC, "newinstance");
xmount(nullptr, SHELLPTS, nullptr, MS_PRIVATE, nullptr);
if (access(SHELLPTS "/ptmx", F_OK)) {
umount2(SHELLPTS, MNT_DETACH);
rmdir(SHELLPTS);
}
}
chdir("/");
}

View File

@@ -12,10 +12,31 @@
using namespace std;
static vector<string> rc_list;
static string magic_mount_list;
#define NEW_INITRC_DIR "/system/etc/init/hw"
#define INIT_RC "init.rc"
static void magic_mount(const string &sdir, const string &ddir = "") {
auto dir = xopen_dir(sdir.data());
if (!dir) return;
for (dirent *entry; (entry = xreaddir(dir.get()));) {
string src = sdir + "/" + entry->d_name;
string dest = ddir + "/" + entry->d_name;
if (access(dest.data(), F_OK) == 0) {
if (entry->d_type == DT_DIR) {
// Recursive
magic_mount(src, dest);
} else {
LOGD("Mount [%s] -> [%s]\n", src.data(), dest.data());
xmount(src.data(), dest.data(), nullptr, MS_BIND, nullptr);
magic_mount_list += dest;
magic_mount_list += '\n';
}
}
}
}
static void patch_rc_scripts(const char *src_path, const char *tmp_path, bool writable) {
auto src_dir = xopen_dir(src_path);
if (!src_dir) return;
@@ -105,6 +126,43 @@ static void patch_rc_scripts(const char *src_path, const char *tmp_path, bool wr
});
fclone_attr(fileno(src.get()), fileno(dest.get()));
}
if (faccessat(src_fd, "init.fission_host.rc", F_OK, 0) == 0) {
{
LOGD("Patching fissiond\n");
mmap_data fissiond("/system/bin/fissiond", false);
for (size_t off : fissiond.patch("ro.build.system.fission_single_os", "ro.build.system.xxxxxxxxxxxxxxxxx")) {
LOGD("Patch @ %08zX [ro.build.system.fission_single_os] -> [ro.build.system.xxxxxxxxxxxxxxxxx]\n", off);
}
mkdirs(ROOTOVL "/system/bin", 0755);
if (auto target_fissiond = xopen_file(ROOTOVL "/system/bin/fissiond", "we")) {
fwrite(fissiond.buf(), 1, fissiond.sz(), target_fissiond.get());
clone_attr("/system/bin/fissiond", ROOTOVL "/system/bin/fissiond");
}
}
LOGD("hijack isolated\n");
auto hijack = xopen_file("/sys/devices/system/cpu/isolated", "re");
mkfifo(INTLROOT "/isolated", 0777);
xmount(INTLROOT "/isolated", "/sys/devices/system/cpu/isolated", nullptr, MS_BIND, nullptr);
if (!xfork()) {
auto dest = xopen_file(INTLROOT "/isolated", "we");
LOGD("hijacked isolated\n");
xumount2("/sys/devices/system/cpu/isolated", MNT_DETACH);
unlink(INTLROOT "/isolated");
string content;
full_read(fileno(hijack.get()), content);
{
string target = "/dev/cells/cell2"s + tmp_path;
xmkdirs(target.data(), 0);
xmount(tmp_path, target.data(), nullptr, MS_BIND | MS_REC,nullptr);
magic_mount(ROOTOVL, "/dev/cells/cell2");
auto mount = xopen_file(ROOTMNT, "w");
fwrite(magic_mount_list.data(), 1, magic_mount_list.length(), mount.get());
}
fprintf(dest.get(), "%s", content.data());
exit(0);
}
}
}
static void load_overlay_rc(const char *overlay) {
@@ -164,28 +222,6 @@ static void recreate_sbin(const char *mirror, bool use_bind_mount) {
}
}
static string magic_mount_list;
static void magic_mount(const string &sdir, const string &ddir = "") {
auto dir = xopen_dir(sdir.data());
if (!dir) return;
for (dirent *entry; (entry = xreaddir(dir.get()));) {
string src = sdir + "/" + entry->d_name;
string dest = ddir + "/" + entry->d_name;
if (access(dest.data(), F_OK) == 0) {
if (entry->d_type == DT_DIR) {
// Recursive
magic_mount(src, dest);
} else {
LOGD("Mount [%s] -> [%s]\n", src.data(), dest.data());
xmount(src.data(), dest.data(), nullptr, MS_BIND, nullptr);
magic_mount_list += dest;
magic_mount_list += '\n';
}
}
}
}
static void extract_files(bool sbin) {
const char *magisk_xz = sbin ? "/sbin/magisk.xz" : "magisk.xz";
const char *stub_xz = sbin ? "/sbin/stub.xz" : "stub.xz";

View File

@@ -78,7 +78,7 @@ run_uninstaller() {
}
restore_imgs() {
[ -z $SHA1 ] && return 1
local SHA1=$(grep_prop SHA1 $MAGISKTMP/.magisk/config)
local BACKUPDIR=/data/magisk_backup_$SHA1
[ -d $BACKUPDIR ] || return 1
@@ -232,7 +232,6 @@ app_init() {
check_boot_ramdisk && RAMDISKEXIST=true
get_flags >/dev/null
run_migrations >/dev/null
SHA1=$(grep_prop SHA1 $MAGISKTMP/.magisk/config)
check_encryption
# Dump variables

View File

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

View File

@@ -119,14 +119,16 @@ else
STATUS=0
SKIP_BACKUP="#"
fi
case $((STATUS & 3)) in
0 ) # Stock boot
case $STATUS in
0 )
# Stock boot
ui_print "- Stock boot image detected"
SHA1=$(./magiskboot sha1 "$BOOTIMAGE" 2>/dev/null)
cat $BOOTIMAGE > stock_boot.img
cp -af ramdisk.cpio ramdisk.cpio.orig 2>/dev/null
;;
1 ) # Magisk patched
1 )
# Magisk patched
ui_print "- Magisk patched boot image detected"
./magiskboot cpio ramdisk.cpio \
"extract .backup/.magisk config.orig" \
@@ -134,7 +136,8 @@ case $((STATUS & 3)) in
cp -af ramdisk.cpio ramdisk.cpio.orig
rm -f stock_boot.img
;;
2 ) # Unsupported
2 )
# Unsupported
ui_print "! Boot image patched by unsupported programs"
abort "! Please restore back to stock boot image"
;;

View File

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

View File

@@ -29,6 +29,8 @@ enable_version_config() {
if ! grep -qE '^version=' $CONFIG; then
echo 'version=' >> $CONFIG
fi
# Make sure abiList is not set when building for release
sed -i "s:^abiList=:# abiList=:g" $CONFIG
}
disable_version_config() {
@@ -87,8 +89,6 @@ update_release_json() {
}
build_canary() {
enable_version_config
# Update version code
local code=$(grep_prop magisk.versionCode $GCONFIG)
code=$((code + 1))
@@ -119,14 +119,10 @@ build_canary() {
$BUILDCMD clean
$BUILDCMD all
$BUILDCMD -r all
disable_version_config
}
# $1 = ver, $2 = stable?
build_release() {
enable_version_config
# Update version configs
local ver=$1
local stable=$2
@@ -160,8 +156,6 @@ build_release() {
# Build
$BUILDCMD clean
$BUILDCMD -r all
disable_version_config
}
stable() {
@@ -238,6 +232,8 @@ fi
git pull
trap disable_version_config EXIT
enable_version_config
case $1 in
"canary" ) build_canary ;;
"stable" ) stable $2 ;;

View File

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