mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-08-15 01:57:26 +00:00
Compare commits
97 Commits
canary-270
...
canary-280
Author | SHA1 | Date | |
---|---|---|---|
![]() |
070719db50 | ||
![]() |
28cccdf7aa | ||
![]() |
b7e0986a5c | ||
![]() |
da709745dd | ||
![]() |
8b6771d487 | ||
![]() |
e1b847fbc5 | ||
![]() |
7188de1205 | ||
![]() |
44fb7dbcbe | ||
![]() |
8086b5933c | ||
![]() |
7f675f4bf7 | ||
![]() |
5e6b53e0da | ||
![]() |
5b29fefc65 | ||
![]() |
16a168535d | ||
![]() |
33f70f8f6d | ||
![]() |
4f18a66d73 | ||
![]() |
250dc16007 | ||
![]() |
7af273e047 | ||
![]() |
e381aebaa0 | ||
![]() |
45d91c9658 | ||
![]() |
4a9158f667 | ||
![]() |
0d9ee89e7f | ||
![]() |
abaff72304 | ||
![]() |
b828e2d0b2 | ||
![]() |
53d7cbc11b | ||
![]() |
310be7ab47 | ||
![]() |
60894e458f | ||
![]() |
fbebb6ac10 | ||
![]() |
a9f8c20703 | ||
![]() |
ae0b15d197 | ||
![]() |
869aa62328 | ||
![]() |
dcd3bc58a3 | ||
![]() |
a82f17c594 | ||
![]() |
b38fd1ca5f | ||
![]() |
8e82113bce | ||
![]() |
f723ef153b | ||
![]() |
1dc723fb6d | ||
![]() |
8f271c2575 | ||
![]() |
7cf56b4406 | ||
![]() |
c2eb603957 | ||
![]() |
e6bd2ff60f | ||
![]() |
5604074eba | ||
![]() |
3f061c1a1e | ||
![]() |
55e78a7b1a | ||
![]() |
000f1d6041 | ||
![]() |
2cbec20238 | ||
![]() |
4b724c7257 | ||
![]() |
ab04c6ab39 | ||
![]() |
821a6c6954 | ||
![]() |
5f27a62221 | ||
![]() |
c76cc4c6bd | ||
![]() |
52b75c53b6 | ||
![]() |
9db2e99086 | ||
![]() |
e9e2ecf2dd | ||
![]() |
9a9e617c35 | ||
![]() |
3a0becc783 | ||
![]() |
1f974cb220 | ||
![]() |
1db80228e8 | ||
![]() |
838e1e254d | ||
![]() |
554eda8fe1 | ||
![]() |
2bdc047c4d | ||
![]() |
e64f59ce5b | ||
![]() |
b8140ad4e6 | ||
![]() |
5a55483698 | ||
![]() |
2d341863f5 | ||
![]() |
278046becb | ||
![]() |
5c0497354f | ||
![]() |
98c258df93 | ||
![]() |
c578cccfd5 | ||
![]() |
07835a3e0e | ||
![]() |
09131aca89 | ||
![]() |
9ce998a6df | ||
![]() |
ca36b42d79 | ||
![]() |
37df39ec37 | ||
![]() |
1701361a73 | ||
![]() |
4c14ae33f5 | ||
![]() |
d4a9ef7b7f | ||
![]() |
1539cfe888 | ||
![]() |
9093be1329 | ||
![]() |
606d076251 | ||
![]() |
46a34e19bc | ||
![]() |
5ac7dc0b37 | ||
![]() |
3b27de3715 | ||
![]() |
939bfac920 | ||
![]() |
f601bf12d5 | ||
![]() |
0495468d02 | ||
![]() |
300a2a242c | ||
![]() |
33aebb5976 | ||
![]() |
b3d6809c0b | ||
![]() |
461f7e9f89 | ||
![]() |
9cc50b20d8 | ||
![]() |
f488e9df8f | ||
![]() |
0dc596e206 | ||
![]() |
c3bf03190b | ||
![]() |
021ae891a9 | ||
![]() |
9c03514eb1 | ||
![]() |
eb74b266e1 | ||
![]() |
80eb6ff25a |
92
.github/actions/setup/action.yml
vendored
92
.github/actions/setup/action.yml
vendored
@@ -1,4 +1,8 @@
|
|||||||
name: Magisk Setup
|
name: Magisk Setup
|
||||||
|
inputs:
|
||||||
|
is-asset-build:
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
@@ -6,39 +10,91 @@ runs:
|
|||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
java-version: "17"
|
java-version: "21"
|
||||||
|
|
||||||
- name: Set up Python 3
|
- name: Set up Python 3
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
|
|
||||||
- name: Set up sccache
|
- name: Install GNU make
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
if: runner.os == 'macOS'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
brew install make
|
||||||
|
echo 'GNUMAKE=gmake' >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
- name: Cache sccache
|
||||||
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
variant: sccache
|
path: .sccache
|
||||||
key: ${{ runner.os }}-${{ github.sha }}
|
key: sccache-${{ runner.os }}-${{ github.sha }}
|
||||||
restore-keys: ${{ runner.os }}
|
restore-keys: sccache-${{ runner.os }}-
|
||||||
max-size: 10000M
|
|
||||||
|
- 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
|
- name: Cache Gradle dependencies
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
|
if: inputs.is-asset-build == 'true'
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.gradle/caches
|
.gradle/caches
|
||||||
~/.gradle/wrapper
|
.gradle/wrapper
|
||||||
!~/.gradle/caches/build-cache-*
|
!.gradle/caches/build-cache-*
|
||||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
key: gradle-cache-${{ hashFiles('gradle/**') }}
|
||||||
restore-keys: ${{ runner.os }}-gradle-
|
restore-keys: gradle-cache-
|
||||||
|
|
||||||
- name: Cache build cache
|
- name: Restore Gradle dependencies
|
||||||
uses: actions/cache@v4
|
uses: actions/cache/restore@v4
|
||||||
|
if: inputs.is-asset-build == 'false'
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.gradle/caches/build-cache-*
|
.gradle/caches
|
||||||
key: ${{ runner.os }}-build-cache-${{ github.sha }}
|
.gradle/wrapper
|
||||||
restore-keys: ${{ runner.os }}-build-cache-
|
!.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
|
- name: Set up NDK
|
||||||
run: python build.py -v ndk
|
|
||||||
shell: bash
|
shell: bash
|
||||||
|
run: python build.py -v ndk
|
||||||
|
25
.github/actions/setup/sccache.sh
vendored
Executable file
25
.github/actions/setup/sccache.sh
vendored
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Get latest sccache version
|
||||||
|
get_sccache_ver() {
|
||||||
|
curl -sL 'https://api.github.com/repos/mozilla/sccache/releases/latest' | jq -r .name
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1=variant
|
||||||
|
# $2=install_dir
|
||||||
|
# $3=exe
|
||||||
|
install_from_gh() {
|
||||||
|
local ver=$(curl -sL 'https://api.github.com/repos/mozilla/sccache/releases/latest' | jq -r .name)
|
||||||
|
local url="https://github.com/mozilla/sccache/releases/download/${ver}/sccache-${ver}-$1.tar.gz"
|
||||||
|
local dest="$2/$3"
|
||||||
|
curl -L "$url" | tar xz -O --wildcards "*/$3" > $dest
|
||||||
|
chmod +x $dest
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $RUNNER_OS = "macOS" ]; then
|
||||||
|
brew install sccache
|
||||||
|
elif [ $RUNNER_OS = "Linux" ]; then
|
||||||
|
install_from_gh x86_64-unknown-linux-musl /usr/local/bin sccache
|
||||||
|
elif [ $RUNNER_OS = "Windows" ]; then
|
||||||
|
install_from_gh x86_64-pc-windows-msvc $USERPROFILE/.cargo/bin sccache.exe
|
||||||
|
fi
|
1
.github/ci.prop
vendored
Normal file
1
.github/ci.prop
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
abiList=arm64-v8a
|
54
.github/workflows/build.yml
vendored
54
.github/workflows/build.yml
vendored
@@ -17,9 +17,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build Magisk artifacts
|
name: Build Magisk artifacts
|
||||||
runs-on: ubuntu-latest
|
runs-on: macos-14
|
||||||
env:
|
|
||||||
SCCACHE_DIRECT: false
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
steps:
|
steps:
|
||||||
@@ -27,10 +25,11 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: "recursive"
|
submodules: "recursive"
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Setup environment
|
- name: Setup environment
|
||||||
uses: ./.github/actions/setup
|
uses: ./.github/actions/setup
|
||||||
|
with:
|
||||||
|
is-asset-build: true
|
||||||
|
|
||||||
- name: Build release
|
- name: Build release
|
||||||
run: ./build.py -vr all
|
run: ./build.py -vr all
|
||||||
@@ -58,24 +57,21 @@ jobs:
|
|||||||
test-build:
|
test-build:
|
||||||
name: Test building on ${{ matrix.os }}
|
name: Test building on ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
|
||||||
SCCACHE_DIRECT: false
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [windows-latest, macos-14]
|
os: [windows-latest, ubuntu-latest]
|
||||||
steps:
|
steps:
|
||||||
- name: Check out
|
- name: Check out
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: "recursive"
|
submodules: "recursive"
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Setup environment
|
- name: Setup environment
|
||||||
uses: ./.github/actions/setup
|
uses: ./.github/actions/setup
|
||||||
|
|
||||||
- name: Build debug
|
- name: Test build
|
||||||
run: python build.py -v all
|
run: python build.py -v -c .github/ci.prop all
|
||||||
|
|
||||||
- name: Stop gradle daemon
|
- name: Stop gradle daemon
|
||||||
run: ./gradlew --stop
|
run: ./gradlew --stop
|
||||||
@@ -96,8 +92,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Check out
|
- name: Check out
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Download build artifacts
|
- name: Download build artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
@@ -114,9 +108,18 @@ jobs:
|
|||||||
- name: Run AVD test
|
- name: Run AVD test
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
env:
|
env:
|
||||||
AVD_TEST_VERBOSE: 1
|
AVD_TEST_LOG: 1
|
||||||
run: scripts/avd_test.sh ${{ matrix.version }} ${{ matrix.type }}
|
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:
|
avd-test-32:
|
||||||
name: Test API ${{ matrix.version }} (x86)
|
name: Test API ${{ matrix.version }} (x86)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -129,8 +132,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Check out
|
- name: Check out
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Download build artifacts
|
- name: Download build artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
@@ -148,11 +149,20 @@ jobs:
|
|||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
env:
|
env:
|
||||||
FORCE_32_BIT: 1
|
FORCE_32_BIT: 1
|
||||||
AVD_TEST_VERBOSE: 1
|
AVD_TEST_LOG: 1
|
||||||
run: scripts/avd_test.sh ${{ matrix.version }}
|
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:
|
cf_test:
|
||||||
name: Test ${{ matrix.branch }} (${{ matrix.target }})
|
name: Test ${{ matrix.device }}
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
needs: build
|
needs: build
|
||||||
env:
|
env:
|
||||||
@@ -162,13 +172,13 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- branch: "aosp-main"
|
- 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:
|
steps:
|
||||||
- name: Check out
|
- name: Check out
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Download build artifacts
|
- name: Download build artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
@@ -179,7 +189,7 @@ jobs:
|
|||||||
- name: Setup Cuttlefish environment
|
- name: Setup Cuttlefish environment
|
||||||
run: |
|
run: |
|
||||||
scripts/cuttlefish.sh setup
|
scripts/cuttlefish.sh setup
|
||||||
scripts/cuttlefish.sh download ${{ matrix.branch }} ${{ matrix.target }}
|
scripts/cuttlefish.sh download ${{ matrix.branch }} ${{ matrix.device }}
|
||||||
|
|
||||||
- name: Run Cuttlefish test
|
- name: Run Cuttlefish test
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
@@ -189,7 +199,7 @@ jobs:
|
|||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: "cvd-logs"
|
name: "cvd-logs-${{ matrix.device }}"
|
||||||
path: |
|
path: |
|
||||||
/home/runner/aosp_cf_phone/cuttlefish/instances/cvd-1/logs
|
/home/runner/aosp_cf_phone/cuttlefish/instances/cvd-1/logs
|
||||||
/home/runner/aosp_cf_phone/cuttlefish/instances/cvd-1/cuttlefish_config.json
|
/home/runner/aosp_cf_phone/cuttlefish/instances/cvd-1/cuttlefish_config.json
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -13,7 +13,7 @@ native/out
|
|||||||
# Android Studio / Gradle
|
# Android Studio / Gradle
|
||||||
*.iml
|
*.iml
|
||||||
.gradle
|
.gradle
|
||||||
|
.idea
|
||||||
/local.properties
|
/local.properties
|
||||||
/.idea
|
|
||||||
/build
|
/build
|
||||||
/captures
|
/captures
|
||||||
|
@@ -21,9 +21,8 @@ Some highlight features:
|
|||||||
Click the icon below to download Magisk apk.
|
Click the icon below to download Magisk apk.
|
||||||
|
|
||||||
[](https://github.com/topjohnwu/Magisk/releases/tag/v27.0)
|
[](https://github.com/topjohnwu/Magisk/releases/tag/v27.0)
|
||||||
[](https://github.com/topjohnwu/Magisk/releases/tag/v27.0)
|
[](https://github.com/topjohnwu/Magisk/releases/tag/v28.0)
|
||||||
[](https://raw.githubusercontent.com/topjohnwu/magisk-files/canary/app-release.apk)
|
[](https://github.com/topjohnwu/Magisk/releases/tag/canary-28001)
|
||||||
[](https://raw.githubusercontent.com/topjohnwu/magisk-files/canary/app-debug.apk)
|
|
||||||
|
|
||||||
## Useful Links
|
## Useful Links
|
||||||
|
|
||||||
@@ -31,8 +30,6 @@ Click the icon below to download Magisk apk.
|
|||||||
- [Building and Development](https://topjohnwu.github.io/Magisk/build.html)
|
- [Building and Development](https://topjohnwu.github.io/Magisk/build.html)
|
||||||
- [Magisk Documentation](https://topjohnwu.github.io/Magisk/)
|
- [Magisk Documentation](https://topjohnwu.github.io/Magisk/)
|
||||||
- [Zygisk module sample](https://github.com/topjohnwu/zygisk-module-sample)
|
- [Zygisk module sample](https://github.com/topjohnwu/zygisk-module-sample)
|
||||||
- [Canary channel changelog](https://github.com/topjohnwu/magisk-files/blob/canary/notes.md)
|
|
||||||
|
|
||||||
|
|
||||||
## Bug Reports
|
## Bug Reports
|
||||||
|
|
||||||
|
@@ -13,7 +13,7 @@ kapt {
|
|||||||
useBuildCache = true
|
useBuildCache = true
|
||||||
mapDiagnosticLocations = true
|
mapDiagnosticLocations = true
|
||||||
javacOptions {
|
javacOptions {
|
||||||
option("-Xmaxerrs", 1000)
|
option("-Xmaxerrs", "1000")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,27 +42,31 @@ android {
|
|||||||
buildFeatures {
|
buildFeatures {
|
||||||
dataBinding = true
|
dataBinding = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
isCoreLibraryDesugaringEnabled = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":app:core"))
|
implementation(project(":app:core"))
|
||||||
|
coreLibraryDesugaring(libs.jdk.libs)
|
||||||
|
|
||||||
implementation("com.github.topjohnwu:indeterminate-checkbox:1.0.7")
|
implementation(libs.indeterminate.checkbox)
|
||||||
implementation("dev.rikka.rikkax.layoutinflater:layoutinflater:1.3.0")
|
implementation(libs.rikka.layoutinflater)
|
||||||
implementation("dev.rikka.rikkax.insets:insets:1.3.0")
|
implementation(libs.rikka.insets)
|
||||||
implementation("dev.rikka.rikkax.recyclerview:recyclerview-ktx:1.3.2")
|
implementation(libs.rikka.recyclerview)
|
||||||
|
|
||||||
val vNav = "2.7.7"
|
implementation(libs.navigation.fragment.ktx)
|
||||||
implementation("androidx.navigation:navigation-fragment-ktx:${vNav}")
|
implementation(libs.navigation.ui.ktx)
|
||||||
implementation("androidx.navigation:navigation-ui-ktx:${vNav}")
|
|
||||||
|
|
||||||
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
|
implementation(libs.constraintlayout)
|
||||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
implementation(libs.swiperefreshlayout)
|
||||||
implementation("androidx.recyclerview:recyclerview:1.3.2")
|
implementation(libs.recyclerview)
|
||||||
implementation("androidx.transition:transition:1.5.0")
|
implementation(libs.transition)
|
||||||
implementation("androidx.fragment:fragment-ktx:1.8.1")
|
implementation(libs.fragment.ktx)
|
||||||
implementation("androidx.appcompat:appcompat:1.7.0")
|
implementation(libs.appcompat)
|
||||||
implementation("com.google.android.material:material:1.12.0")
|
implementation(libs.material)
|
||||||
|
|
||||||
// Make sure kapt runs with a proper kotlin-stdlib
|
// Make sure kapt runs with a proper kotlin-stdlib
|
||||||
kapt(kotlin("stdlib"))
|
kapt(kotlin("stdlib"))
|
||||||
|
@@ -1,13 +1,18 @@
|
|||||||
package com.topjohnwu.magisk.dialog
|
package com.topjohnwu.magisk.dialog
|
||||||
|
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.core.os.postDelayed
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.topjohnwu.magisk.core.BuildConfig
|
import com.topjohnwu.magisk.core.BuildConfig
|
||||||
import com.topjohnwu.magisk.core.Info
|
import com.topjohnwu.magisk.core.Info
|
||||||
import com.topjohnwu.magisk.core.R
|
import com.topjohnwu.magisk.core.R
|
||||||
|
import com.topjohnwu.magisk.core.ktx.reboot
|
||||||
|
import com.topjohnwu.magisk.core.ktx.toast
|
||||||
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
|
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
|
||||||
import com.topjohnwu.magisk.events.DialogBuilder
|
import com.topjohnwu.magisk.events.DialogBuilder
|
||||||
import com.topjohnwu.magisk.ui.home.HomeViewModel
|
import com.topjohnwu.magisk.ui.home.HomeViewModel
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
||||||
|
import com.topjohnwu.superuser.internal.UiThreadHandler
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class EnvFixDialog(private val vm: HomeViewModel, private val code: Int) : DialogBuilder {
|
class EnvFixDialog(private val vm: HomeViewModel, private val code: Int) : DialogBuilder {
|
||||||
@@ -27,9 +32,15 @@ class EnvFixDialog(private val vm: HomeViewModel, private val code: Int) : Dialo
|
|||||||
setCancelable(false)
|
setCancelable(false)
|
||||||
}
|
}
|
||||||
dialog.activity.lifecycleScope.launch {
|
dialog.activity.lifecycleScope.launch {
|
||||||
MagiskInstaller.FixEnv {
|
MagiskInstaller.FixEnv().exec { success ->
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}.exec()
|
context.toast(
|
||||||
|
if (success) R.string.reboot_delay_toast else R.string.setup_fail,
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
)
|
||||||
|
if (success)
|
||||||
|
UiThreadHandler.handler.postDelayed(5000) { reboot() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
package com.topjohnwu.magisk.dialog
|
package com.topjohnwu.magisk.dialog
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import com.topjohnwu.magisk.core.R
|
import com.topjohnwu.magisk.core.R
|
||||||
import com.topjohnwu.magisk.core.di.ServiceLocator
|
import com.topjohnwu.magisk.core.di.ServiceLocator
|
||||||
import com.topjohnwu.magisk.core.download.DownloadEngine
|
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.core.model.module.OnlineModule
|
||||||
import com.topjohnwu.magisk.ui.flash.FlashFragment
|
import com.topjohnwu.magisk.ui.flash.FlashFragment
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
||||||
|
import com.topjohnwu.magisk.view.Notifications
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
class OnlineModuleInstallDialog(private val item: OnlineModule) : MarkDownDialog() {
|
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
|
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) {
|
override fun build(dialog: MagiskDialog) {
|
||||||
super.build(dialog)
|
super.build(dialog)
|
||||||
dialog.apply {
|
dialog.apply {
|
||||||
|
|
||||||
fun download(install: Boolean) {
|
fun download(install: Boolean) {
|
||||||
val module = Subject.Module(item, install)
|
DownloadEngine.startWithActivity(activity, Module(item, install))
|
||||||
module.piCreator = FlashFragment::installIntent
|
|
||||||
DownloadEngine.startWithActivity(activity, module)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val title = context.getString(R.string.repo_install_title,
|
val title = context.getString(R.string.repo_install_title,
|
||||||
|
@@ -1,15 +1,17 @@
|
|||||||
package com.topjohnwu.magisk.dialog
|
package com.topjohnwu.magisk.dialog
|
||||||
|
|
||||||
import android.app.ProgressDialog
|
import android.app.ProgressDialog
|
||||||
import android.content.Context
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.topjohnwu.magisk.arch.NavigationActivity
|
import com.topjohnwu.magisk.arch.NavigationActivity
|
||||||
|
import com.topjohnwu.magisk.arch.UIActivity
|
||||||
import com.topjohnwu.magisk.core.R
|
import com.topjohnwu.magisk.core.R
|
||||||
import com.topjohnwu.magisk.core.ktx.toast
|
import com.topjohnwu.magisk.core.ktx.toast
|
||||||
|
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
|
||||||
import com.topjohnwu.magisk.events.DialogBuilder
|
import com.topjohnwu.magisk.events.DialogBuilder
|
||||||
import com.topjohnwu.magisk.ui.flash.FlashFragment
|
import com.topjohnwu.magisk.ui.flash.FlashFragment
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
||||||
import com.topjohnwu.superuser.Shell
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class UninstallDialog : DialogBuilder {
|
class UninstallDialog : DialogBuilder {
|
||||||
|
|
||||||
@@ -19,7 +21,7 @@ class UninstallDialog : DialogBuilder {
|
|||||||
setMessage(R.string.uninstall_magisk_msg)
|
setMessage(R.string.uninstall_magisk_msg)
|
||||||
setButton(MagiskDialog.ButtonType.POSITIVE) {
|
setButton(MagiskDialog.ButtonType.POSITIVE) {
|
||||||
text = R.string.restore_img
|
text = R.string.restore_img
|
||||||
onClick { restore(dialog.context) }
|
onClick { restore(dialog.activity) }
|
||||||
}
|
}
|
||||||
setButton(MagiskDialog.ButtonType.NEGATIVE) {
|
setButton(MagiskDialog.ButtonType.NEGATIVE) {
|
||||||
text = R.string.complete_uninstall
|
text = R.string.complete_uninstall
|
||||||
@@ -29,18 +31,20 @@ class UninstallDialog : DialogBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
private fun restore(context: Context) {
|
private fun restore(activity: UIActivity<*>) {
|
||||||
val dialog = ProgressDialog(context).apply {
|
val dialog = ProgressDialog(activity).apply {
|
||||||
setMessage(context.getString(R.string.restore_img_msg))
|
setMessage(activity.getString(R.string.restore_img_msg))
|
||||||
show()
|
show()
|
||||||
}
|
}
|
||||||
|
|
||||||
Shell.cmd("restore_imgs").submit { result ->
|
activity.lifecycleScope.launch {
|
||||||
|
MagiskInstaller.Restore().exec { success ->
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
if (result.isSuccess) {
|
if (success) {
|
||||||
context.toast(R.string.restore_done, Toast.LENGTH_SHORT)
|
activity.toast(R.string.restore_done, Toast.LENGTH_SHORT)
|
||||||
} else {
|
} else {
|
||||||
context.toast(R.string.restore_fail, Toast.LENGTH_LONG)
|
activity.toast(R.string.restore_fail, Toast.LENGTH_LONG)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,116 @@
|
|||||||
|
package com.topjohnwu.magisk.ui.module
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.pm.ActivityInfo
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.KeyEvent
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuInflater
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.core.view.MenuProvider
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.arch.BaseFragment
|
||||||
|
import com.topjohnwu.magisk.arch.viewModel
|
||||||
|
import com.topjohnwu.magisk.core.ktx.toast
|
||||||
|
import com.topjohnwu.magisk.databinding.FragmentActionMd2Binding
|
||||||
|
import com.topjohnwu.magisk.ui.flash.FlashViewModel
|
||||||
|
import timber.log.Timber
|
||||||
|
import com.topjohnwu.magisk.core.R as CoreR
|
||||||
|
|
||||||
|
class ActionFragment : BaseFragment<FragmentActionMd2Binding>(), MenuProvider {
|
||||||
|
|
||||||
|
override val layoutRes = R.layout.fragment_action_md2
|
||||||
|
override val viewModel by viewModel<ActionViewModel>()
|
||||||
|
override val snackbarView: View get() = binding.snackbarContainer
|
||||||
|
|
||||||
|
private var defaultOrientation = -1
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
viewModel.args = ActionFragmentArgs.fromBundle(requireArguments())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
activity?.setTitle(viewModel.args.name)
|
||||||
|
binding.closeBtn.setOnClickListener {
|
||||||
|
activity?.onBackPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.state.observe(this) {
|
||||||
|
activity?.supportActionBar?.setSubtitle(
|
||||||
|
when (it) {
|
||||||
|
ActionViewModel.State.RUNNING -> CoreR.string.running
|
||||||
|
ActionViewModel.State.SUCCESS -> CoreR.string.done
|
||||||
|
ActionViewModel.State.FAILED -> CoreR.string.failure
|
||||||
|
}
|
||||||
|
)
|
||||||
|
when (it) {
|
||||||
|
ActionViewModel.State.SUCCESS -> {
|
||||||
|
activity?.apply {
|
||||||
|
toast(
|
||||||
|
getString(
|
||||||
|
com.topjohnwu.magisk.core.R.string.done_action,
|
||||||
|
this@ActionFragment.viewModel.args.name
|
||||||
|
), Toast.LENGTH_LONG
|
||||||
|
)
|
||||||
|
onBackPressed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionViewModel.State.FAILED -> {
|
||||||
|
binding.closeBtn.apply {
|
||||||
|
if (!this.isVisible) this.show()
|
||||||
|
if (!this.isFocused) this.requestFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
|
inflater.inflate(R.menu.menu_flash, menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||||
|
return viewModel.onMenuItemClicked(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
defaultOrientation = activity?.requestedOrientation ?: -1
|
||||||
|
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
|
||||||
|
if (savedInstanceState == null) {
|
||||||
|
viewModel.startRunAction()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("WrongConstant")
|
||||||
|
override fun onDestroyView() {
|
||||||
|
if (defaultOrientation != -1) {
|
||||||
|
activity?.requestedOrientation = defaultOrientation
|
||||||
|
}
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onKeyEvent(event: KeyEvent): Boolean {
|
||||||
|
return when (event.keyCode) {
|
||||||
|
KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN -> true
|
||||||
|
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBackPressed(): Boolean {
|
||||||
|
if (viewModel.state.value == ActionViewModel.State.RUNNING) return true
|
||||||
|
return super.onBackPressed()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPreBind(binding: FragmentActionMd2Binding) = Unit
|
||||||
|
}
|
@@ -0,0 +1,84 @@
|
|||||||
|
package com.topjohnwu.magisk.ui.module
|
||||||
|
|
||||||
|
import android.view.MenuItem
|
||||||
|
import androidx.databinding.Bindable
|
||||||
|
import androidx.databinding.ObservableArrayList
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.map
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.topjohnwu.magisk.BR
|
||||||
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.arch.BaseViewModel
|
||||||
|
import com.topjohnwu.magisk.core.Info
|
||||||
|
import com.topjohnwu.magisk.core.ktx.synchronized
|
||||||
|
import com.topjohnwu.magisk.core.ktx.timeFormatStandard
|
||||||
|
import com.topjohnwu.magisk.core.ktx.toTime
|
||||||
|
import com.topjohnwu.magisk.core.tasks.RunAction
|
||||||
|
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
|
||||||
|
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
|
||||||
|
import com.topjohnwu.magisk.databinding.set
|
||||||
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
|
import com.topjohnwu.magisk.ui.flash.ConsoleItem
|
||||||
|
import com.topjohnwu.superuser.CallbackList
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class ActionViewModel : BaseViewModel() {
|
||||||
|
|
||||||
|
enum class State {
|
||||||
|
RUNNING, SUCCESS, FAILED
|
||||||
|
}
|
||||||
|
|
||||||
|
private val _state = MutableLiveData(State.RUNNING)
|
||||||
|
val state: LiveData<State> get() = _state
|
||||||
|
val running = state.map { it == State.RUNNING }
|
||||||
|
|
||||||
|
val items = ObservableArrayList<ConsoleItem>()
|
||||||
|
lateinit var args: ActionFragmentArgs
|
||||||
|
|
||||||
|
private val logItems = mutableListOf<String>().synchronized()
|
||||||
|
private val outItems = object : CallbackList<String>() {
|
||||||
|
override fun onAddElement(e: String?) {
|
||||||
|
e ?: return
|
||||||
|
items.add(ConsoleItem(e))
|
||||||
|
logItems.add(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun startRunAction() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
onResult(RunAction(args.id, outItems, logItems).exec())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onResult(success: Boolean) {
|
||||||
|
_state.value = if (success) State.SUCCESS else State.FAILED
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onMenuItemClicked(item: MenuItem): Boolean {
|
||||||
|
when (item.itemId) {
|
||||||
|
R.id.action_save -> savePressed()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun savePressed() = withExternalRW {
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
val name = "%s_action_log_%s.log".format(
|
||||||
|
args.name,
|
||||||
|
System.currentTimeMillis().toTime(timeFormatStandard)
|
||||||
|
)
|
||||||
|
val file = MediaStoreUtils.getFile(name)
|
||||||
|
file.uri.outputStream().bufferedWriter().use { writer ->
|
||||||
|
synchronized(logItems) {
|
||||||
|
logItems.forEach {
|
||||||
|
writer.write(it)
|
||||||
|
writer.newLine()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SnackbarEvent(file.toString()).publish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -25,6 +25,7 @@ class LocalModuleRvItem(
|
|||||||
override val layoutRes = R.layout.item_module_md2
|
override val layoutRes = R.layout.item_module_md2
|
||||||
|
|
||||||
val showNotice: Boolean
|
val showNotice: Boolean
|
||||||
|
val showAction: Boolean
|
||||||
val noticeText: TextHolder
|
val noticeText: TextHolder
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -35,6 +36,7 @@ class LocalModuleRvItem(
|
|||||||
showNotice = zygiskUnloaded ||
|
showNotice = zygiskUnloaded ||
|
||||||
(Info.isZygiskEnabled && isRiru) ||
|
(Info.isZygiskEnabled && isRiru) ||
|
||||||
(!Info.isZygiskEnabled && isZygisk)
|
(!Info.isZygiskEnabled && isZygisk)
|
||||||
|
showAction = item.hasAction && !showNotice
|
||||||
noticeText =
|
noticeText =
|
||||||
when {
|
when {
|
||||||
zygiskUnloaded -> CoreR.string.zygisk_module_unloaded.asText()
|
zygiskUnloaded -> CoreR.string.zygisk_module_unloaded.asText()
|
||||||
|
@@ -4,8 +4,10 @@ import android.net.Uri
|
|||||||
import androidx.databinding.Bindable
|
import androidx.databinding.Bindable
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
|
import com.topjohnwu.magisk.MainDirections
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.AsyncLoadViewModel
|
import com.topjohnwu.magisk.arch.AsyncLoadViewModel
|
||||||
|
import com.topjohnwu.magisk.core.Const
|
||||||
import com.topjohnwu.magisk.core.Info
|
import com.topjohnwu.magisk.core.Info
|
||||||
import com.topjohnwu.magisk.core.base.ContentResultCallback
|
import com.topjohnwu.magisk.core.base.ContentResultCallback
|
||||||
import com.topjohnwu.magisk.core.model.module.LocalModule
|
import com.topjohnwu.magisk.core.model.module.LocalModule
|
||||||
@@ -96,6 +98,10 @@ class ModuleViewModel : AsyncLoadViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun runAction(id: String, name: String) {
|
||||||
|
MainDirections.actionActionFragment(id, name).navigate()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val uri = MutableLiveData<Uri?>()
|
private val uri = MutableLiveData<Uri?>()
|
||||||
}
|
}
|
||||||
|
@@ -78,8 +78,8 @@ class SuperuserViewModel(
|
|||||||
this@SuperuserViewModel, policy,
|
this@SuperuserViewModel, policy,
|
||||||
info.packageName,
|
info.packageName,
|
||||||
info.sharedUserId != null,
|
info.sharedUserId != null,
|
||||||
info.applicationInfo.loadIcon(pm),
|
info.applicationInfo?.loadIcon(pm) ?: pm.defaultActivityIcon,
|
||||||
info.applicationInfo.getLabel(pm)
|
info.applicationInfo?.getLabel(pm) ?: info.packageName
|
||||||
)
|
)
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
null
|
null
|
||||||
|
@@ -111,7 +111,7 @@ class SuRequestViewModel(
|
|||||||
// shared UID. We have no way to know where this request comes from.
|
// shared UID. We have no way to know where this request comes from.
|
||||||
icon = pm.defaultActivityIcon
|
icon = pm.defaultActivityIcon
|
||||||
title = "[SharedUID] ${info.sharedUserId}"
|
title = "[SharedUID] ${info.sharedUserId}"
|
||||||
packageName = info.sharedUserId
|
packageName = info.sharedUserId.toString()
|
||||||
} else {
|
} else {
|
||||||
val prefix = if (info.sharedUserId == null) "" else "[SharedUID] "
|
val prefix = if (info.sharedUserId == null) "" else "[SharedUID] "
|
||||||
icon = app.loadIcon(pm)
|
icon = app.loadIcon(pm)
|
||||||
|
5
app/apk/src/main/res/drawable/ic_action_md2.xml
Normal file
5
app/apk/src/main/res/drawable/ic_action_md2.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M8,5v14l11,-7z"/>
|
||||||
|
|
||||||
|
</vector>
|
68
app/apk/src/main/res/layout/fragment_action_md2.xml
Normal file
68
app/apk/src/main/res/layout/fragment_action_md2.xml
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="viewModel"
|
||||||
|
type="com.topjohnwu.magisk.ui.module.ActionViewModel" />
|
||||||
|
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<HorizontalScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="@dimen/internal_action_bar_size"
|
||||||
|
app:layout_fitsSystemWindowsInsets="top"
|
||||||
|
tools:layout_marginTop="@dimen/internal_action_bar_size">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/flash_content"
|
||||||
|
scrollToLast="@{true}"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:fitsSystemWindowsInsets="start|end|bottom"
|
||||||
|
app:items="@{viewModel.items}"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
|
tools:listitem="@layout/item_console_md2" />
|
||||||
|
|
||||||
|
</HorizontalScrollView>
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||||
|
android:id="@+id/close_btn"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|end"
|
||||||
|
android:layout_margin="@dimen/l1"
|
||||||
|
android:layout_marginBottom="@dimen/l1"
|
||||||
|
android:clickable="true"
|
||||||
|
android:enabled="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:text="@string/close"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="?colorOnPrimary"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:backgroundTint="?colorPrimary"
|
||||||
|
app:icon="@drawable/ic_close_md2"
|
||||||
|
app:iconTint="?colorOnPrimary"
|
||||||
|
app:layout_fitsSystemWindowsInsets="bottom" />
|
||||||
|
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
android:id="@+id/snackbar_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:fitsSystemWindowsInsets="top|bottom" />
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
|
</layout>
|
@@ -189,12 +189,32 @@
|
|||||||
android:textColor="?colorError"
|
android:textColor="?colorError"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/module_remove"
|
app:layout_constraintBottom_toBottomOf="@+id/module_remove"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/bottom_bar_barrier"
|
app:layout_constraintEnd_toStartOf="@+id/bottom_bar_barrier"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toEndOf="@id/module_config"
|
||||||
app:layout_constraintTop_toTopOf="@+id/module_remove"
|
app:layout_constraintTop_toTopOf="@+id/module_remove"
|
||||||
tools:lines="2"
|
tools:lines="2"
|
||||||
tools:text="@tools:sample/lorem/random"
|
tools:text="@tools:sample/lorem/random"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/module_config"
|
||||||
|
style="@style/WidgetFoundation.Button.Text"
|
||||||
|
goneUnless="@{item.showAction}"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clickable="true"
|
||||||
|
android:enabled="@{item.enabled}"
|
||||||
|
android:focusable="true"
|
||||||
|
android:onClick="@{() -> viewModel.runAction(item.item.id, item.item.name)}"
|
||||||
|
android:text="@string/module_action"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:icon="@drawable/ic_action_md2"
|
||||||
|
app:iconGravity="textStart"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/module_remove"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/module_remove"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:srcCompat="@drawable/ic_download_md2" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
@@ -53,6 +53,21 @@
|
|||||||
|
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/actionFragment"
|
||||||
|
android:name="com.topjohnwu.magisk.ui.module.ActionFragment"
|
||||||
|
android:label="ActionFragment"
|
||||||
|
tools:layout="@layout/fragment_action_md2" >
|
||||||
|
|
||||||
|
<argument
|
||||||
|
android:name="id"
|
||||||
|
app:argType="string" />
|
||||||
|
|
||||||
|
<argument
|
||||||
|
android:name="name"
|
||||||
|
app:argType="string" />
|
||||||
|
</fragment>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/installFragment"
|
android:id="@+id/installFragment"
|
||||||
android:name="com.topjohnwu.magisk.ui.install.InstallFragment"
|
android:name="com.topjohnwu.magisk.ui.install.InstallFragment"
|
||||||
@@ -152,4 +167,12 @@
|
|||||||
app:popEnterAnim="@anim/fragment_enter_pop"
|
app:popEnterAnim="@anim/fragment_enter_pop"
|
||||||
app:popExitAnim="@anim/fragment_exit_pop" />
|
app:popExitAnim="@anim/fragment_exit_pop" />
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_actionFragment"
|
||||||
|
app:destination="@id/actionFragment"
|
||||||
|
app:enterAnim="@anim/fragment_enter"
|
||||||
|
app:exitAnim="@anim/fragment_exit"
|
||||||
|
app:popEnterAnim="@anim/fragment_enter_pop"
|
||||||
|
app:popExitAnim="@anim/fragment_exit_pop" />
|
||||||
|
|
||||||
</navigation>
|
</navigation>
|
||||||
|
5
app/build.gradle.kts
Normal file
5
app/build.gradle.kts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
tasks.register("clean") {
|
||||||
|
subprojects.forEach {
|
||||||
|
dependsOn(":app:${it.name}:clean")
|
||||||
|
}
|
||||||
|
}
|
@@ -30,39 +30,34 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
api(project(":app:shared"))
|
api(project(":app:shared"))
|
||||||
|
|
||||||
api("com.jakewharton.timber:timber:5.0.1")
|
api(libs.timber)
|
||||||
api("io.noties.markwon:core:4.6.2")
|
api(libs.markwon.core)
|
||||||
implementation("org.bouncycastle:bcpkix-jdk18on:1.78.1")
|
implementation(libs.bcpkix)
|
||||||
implementation("org.apache.commons:commons-compress:1.26.2")
|
implementation(libs.commons.compress)
|
||||||
|
|
||||||
val vLibsu = "6.0.0"
|
api(libs.libsu.core)
|
||||||
api("com.github.topjohnwu.libsu:core:${vLibsu}")
|
api(libs.libsu.service)
|
||||||
api("com.github.topjohnwu.libsu:service:${vLibsu}")
|
api(libs.libsu.nio)
|
||||||
api("com.github.topjohnwu.libsu:nio:${vLibsu}")
|
|
||||||
|
|
||||||
val vRetrofit = "2.11.0"
|
implementation(libs.retrofit)
|
||||||
implementation("com.squareup.retrofit2:retrofit:${vRetrofit}")
|
implementation(libs.retrofit.moshi)
|
||||||
implementation("com.squareup.retrofit2:converter-moshi:${vRetrofit}")
|
implementation(libs.retrofit.scalars)
|
||||||
implementation("com.squareup.retrofit2:converter-scalars:${vRetrofit}")
|
|
||||||
|
|
||||||
val vOkHttp = "4.12.0"
|
implementation(libs.okhttp)
|
||||||
implementation("com.squareup.okhttp3:okhttp:${vOkHttp}")
|
implementation(libs.okhttp.logging)
|
||||||
implementation("com.squareup.okhttp3:logging-interceptor:${vOkHttp}")
|
implementation(libs.okhttp.dnsoverhttps)
|
||||||
implementation("com.squareup.okhttp3:okhttp-dnsoverhttps:${vOkHttp}")
|
|
||||||
|
|
||||||
val vMoshi = "1.15.1"
|
implementation(libs.moshi)
|
||||||
implementation("com.squareup.moshi:moshi:${vMoshi}")
|
ksp(libs.moshi.codegen)
|
||||||
ksp("com.squareup.moshi:moshi-kotlin-codegen:${vMoshi}")
|
|
||||||
|
|
||||||
val vRoom = "2.6.1"
|
implementation(libs.room.runtime)
|
||||||
implementation("androidx.room:room-runtime:${vRoom}")
|
implementation(libs.room.ktx)
|
||||||
implementation("androidx.room:room-ktx:${vRoom}")
|
ksp(libs.room.compiler)
|
||||||
ksp("androidx.room:room-compiler:${vRoom}")
|
|
||||||
|
|
||||||
implementation("androidx.core:core-splashscreen:1.0.1")
|
implementation(libs.core.splashscreen)
|
||||||
implementation("androidx.core:core-ktx:1.13.1")
|
implementation(libs.core.ktx)
|
||||||
implementation("androidx.activity:activity:1.9.0")
|
implementation(libs.activity)
|
||||||
implementation("androidx.collection:collection-ktx:1.4.1")
|
implementation(libs.collection.ktx)
|
||||||
implementation("androidx.profileinstaller:profileinstaller:1.3.1")
|
implementation(libs.profileinstaller)
|
||||||
implementation("androidx.lifecycle:lifecycle-process:2.8.3")
|
implementation(libs.lifecycle.process)
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,7 @@ import kotlinx.parcelize.Parcelize
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
sealed class Subject : Parcelable {
|
abstract class Subject : Parcelable {
|
||||||
|
|
||||||
abstract val url: String
|
abstract val url: String
|
||||||
abstract val file: Uri
|
abstract val file: Uri
|
||||||
@@ -27,24 +27,13 @@ sealed class Subject : Parcelable {
|
|||||||
|
|
||||||
open fun pendingIntent(context: Context): PendingIntent? = null
|
open fun pendingIntent(context: Context): PendingIntent? = null
|
||||||
|
|
||||||
@Parcelize
|
abstract class Module : Subject() {
|
||||||
class Module(
|
abstract val module: OnlineModule
|
||||||
private val module: OnlineModule,
|
final override val url: String get() = module.zipUrl
|
||||||
override val autoLaunch: Boolean,
|
final override val title: String get() = module.downloadFilename
|
||||||
override val notifyId: Int = Notifications.nextId()
|
final override val file by lazy {
|
||||||
) : Subject() {
|
|
||||||
override val url: String get() = module.zipUrl
|
|
||||||
override val title: String get() = module.downloadFilename
|
|
||||||
|
|
||||||
@IgnoredOnParcel
|
|
||||||
override val file by lazy {
|
|
||||||
MediaStoreUtils.getFile(title).uri
|
MediaStoreUtils.getFile(title).uri
|
||||||
}
|
}
|
||||||
|
|
||||||
@IgnoredOnParcel
|
|
||||||
var piCreator: ((Context, Uri) -> PendingIntent)? = null
|
|
||||||
|
|
||||||
override fun pendingIntent(context: Context) = piCreator?.invoke(context, file)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
|
@@ -37,6 +37,7 @@ data class LocalModule(
|
|||||||
val isRiru: Boolean get() = (id == "riru-core") || riruFolder.exists()
|
val isRiru: Boolean get() = (id == "riru-core") || riruFolder.exists()
|
||||||
val isZygisk: Boolean get() = zygiskFolder.exists()
|
val isZygisk: Boolean get() = zygiskFolder.exists()
|
||||||
val zygiskUnloaded: Boolean get() = unloaded.exists()
|
val zygiskUnloaded: Boolean get() = unloaded.exists()
|
||||||
|
val hasAction: Boolean;
|
||||||
|
|
||||||
var enable: Boolean
|
var enable: Boolean
|
||||||
get() = !disableFile.exists()
|
get() = !disableFile.exists()
|
||||||
@@ -100,6 +101,8 @@ data class LocalModule(
|
|||||||
if (name.isEmpty()) {
|
if (name.isEmpty()) {
|
||||||
name = id
|
name = id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasAction = RootUtils.fs.getFile(path, "action.sh").exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun fetch(): Boolean {
|
suspend fun fetch(): Boolean {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
package com.topjohnwu.magisk.core.model.su
|
package com.topjohnwu.magisk.core.model.su
|
||||||
|
|
||||||
import android.content.pm.PackageInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
@@ -24,7 +24,7 @@ class SuLog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun PackageManager.createSuLog(
|
fun PackageManager.createSuLog(
|
||||||
info: PackageInfo,
|
info: ApplicationInfo,
|
||||||
toUid: Int,
|
toUid: Int,
|
||||||
fromPid: Int,
|
fromPid: Int,
|
||||||
command: String,
|
command: String,
|
||||||
@@ -33,13 +33,12 @@ fun PackageManager.createSuLog(
|
|||||||
context: String,
|
context: String,
|
||||||
gids: String,
|
gids: String,
|
||||||
): SuLog {
|
): SuLog {
|
||||||
val appInfo = info.applicationInfo
|
|
||||||
return SuLog(
|
return SuLog(
|
||||||
fromUid = appInfo.uid,
|
fromUid = info.uid,
|
||||||
toUid = toUid,
|
toUid = toUid,
|
||||||
fromPid = fromPid,
|
fromPid = fromPid,
|
||||||
packageName = getNameForUid(appInfo.uid)!!,
|
packageName = getNameForUid(info.uid)!!,
|
||||||
appName = appInfo.getLabel(this),
|
appName = info.getLabel(this),
|
||||||
command = command,
|
command = command,
|
||||||
action = policy,
|
action = policy,
|
||||||
target = target,
|
target = target,
|
||||||
|
@@ -64,7 +64,7 @@ object SuCallbackHandler {
|
|||||||
val pm = context.packageManager
|
val pm = context.packageManager
|
||||||
|
|
||||||
val log = runCatching {
|
val log = runCatching {
|
||||||
pm.getPackageInfo(fromUid, pid)?.let {
|
pm.getPackageInfo(fromUid, pid)?.applicationInfo?.let {
|
||||||
pm.createSuLog(it, toUid, pid, command, policy, target, seContext, gids)
|
pm.createSuLog(it, toUid, pid, command, policy, target, seContext, gids)
|
||||||
}
|
}
|
||||||
}.getOrNull() ?: createSuLog(fromUid, toUid, pid, command, policy, target, seContext, gids)
|
}.getOrNull() ?: createSuLog(fromUid, toUid, pid, command, policy, target, seContext, gids)
|
||||||
|
@@ -125,8 +125,9 @@ object AppMigration {
|
|||||||
apk: File, out: OutputStream,
|
apk: File, out: OutputStream,
|
||||||
pkg: String, label: CharSequence
|
pkg: String, label: CharSequence
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val info = context.packageManager.getPackageArchiveInfo(apk.path, 0) ?: return false
|
val pm = context.packageManager
|
||||||
val origLabel = info.applicationInfo.nonLocalizedLabel.toString()
|
val info = pm.getPackageArchiveInfo(apk.path, 0)?.applicationInfo ?: return false
|
||||||
|
val origLabel = info.nonLocalizedLabel.toString()
|
||||||
try {
|
try {
|
||||||
JarMap.open(apk, true).use { jar ->
|
JarMap.open(apk, true).use { jar ->
|
||||||
val je = jar.getJarEntry(ANDROID_MANIFEST)
|
val je = jar.getJarEntry(ANDROID_MANIFEST)
|
||||||
@@ -190,11 +191,12 @@ object AppMigration {
|
|||||||
|
|
||||||
// Install and auto launch app
|
// Install and auto launch app
|
||||||
val session = APKInstall.startSession(activity, pkg, onFailure) {
|
val session = APKInstall.startSession(activity, pkg, onFailure) {
|
||||||
|
Config.suManager = pkg
|
||||||
|
Shell.cmd("touch $AppApkPath").exec()
|
||||||
launchApp(activity, pkg)
|
launchApp(activity, pkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
Config.suManager = pkg
|
val cmd = "adb_pm_install $repack $pkg"
|
||||||
val cmd = "touch $AppApkPath; adb_pm_install $repack $pkg"
|
|
||||||
if (Shell.cmd(cmd).exec().isSuccess) return true
|
if (Shell.cmd(cmd).exec().isSuccess) return true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -239,11 +241,12 @@ object AppMigration {
|
|||||||
}
|
}
|
||||||
val apk = StubApk.current(activity)
|
val apk = StubApk.current(activity)
|
||||||
val session = APKInstall.startSession(activity, APP_PACKAGE_NAME, onFailure) {
|
val session = APKInstall.startSession(activity, APP_PACKAGE_NAME, onFailure) {
|
||||||
|
Config.suManager = ""
|
||||||
|
Shell.cmd("touch $AppApkPath").exec()
|
||||||
launchApp(activity, APP_PACKAGE_NAME)
|
launchApp(activity, APP_PACKAGE_NAME)
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
Config.suManager = ""
|
val cmd = "adb_pm_install $apk $APP_PACKAGE_NAME"
|
||||||
val cmd = "touch $AppApkPath; adb_pm_install $apk $APP_PACKAGE_NAME"
|
|
||||||
if (Shell.cmd(cmd).await().isSuccess) return
|
if (Shell.cmd(cmd).await().isSuccess) return
|
||||||
val success = withContext(Dispatchers.IO) {
|
val success = withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
@@ -6,7 +6,6 @@ import android.system.ErrnoException
|
|||||||
import android.system.Os
|
import android.system.Os
|
||||||
import android.system.OsConstants
|
import android.system.OsConstants
|
||||||
import android.system.OsConstants.O_WRONLY
|
import android.system.OsConstants.O_WRONLY
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
import androidx.core.os.postDelayed
|
import androidx.core.os.postDelayed
|
||||||
import com.topjohnwu.magisk.StubApk
|
import com.topjohnwu.magisk.StubApk
|
||||||
@@ -15,13 +14,10 @@ import com.topjohnwu.magisk.core.BuildConfig
|
|||||||
import com.topjohnwu.magisk.core.Config
|
import com.topjohnwu.magisk.core.Config
|
||||||
import com.topjohnwu.magisk.core.Const
|
import com.topjohnwu.magisk.core.Const
|
||||||
import com.topjohnwu.magisk.core.Info
|
import com.topjohnwu.magisk.core.Info
|
||||||
import com.topjohnwu.magisk.core.R
|
|
||||||
import com.topjohnwu.magisk.core.di.ServiceLocator
|
import com.topjohnwu.magisk.core.di.ServiceLocator
|
||||||
import com.topjohnwu.magisk.core.isRunningAsStub
|
import com.topjohnwu.magisk.core.isRunningAsStub
|
||||||
import com.topjohnwu.magisk.core.ktx.copyAll
|
import com.topjohnwu.magisk.core.ktx.copyAll
|
||||||
import com.topjohnwu.magisk.core.ktx.copyAndClose
|
import com.topjohnwu.magisk.core.ktx.copyAndClose
|
||||||
import com.topjohnwu.magisk.core.ktx.reboot
|
|
||||||
import com.topjohnwu.magisk.core.ktx.toast
|
|
||||||
import com.topjohnwu.magisk.core.ktx.writeTo
|
import com.topjohnwu.magisk.core.ktx.writeTo
|
||||||
import com.topjohnwu.magisk.core.utils.DummyList
|
import com.topjohnwu.magisk.core.utils.DummyList
|
||||||
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
|
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
|
||||||
@@ -134,12 +130,14 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
|
|
||||||
val abi32 = Const.CPU_ABI_32
|
val abi32 = Const.CPU_ABI_32
|
||||||
if (Process.is64Bit() && abi32 != null) {
|
if (Process.is64Bit() && abi32 != null) {
|
||||||
val magisk32 = File(installDir, "magisk32")
|
|
||||||
val entry = zf.getEntry("lib/$abi32/libmagisk.so")
|
val entry = zf.getEntry("lib/$abi32/libmagisk.so")
|
||||||
|
if (entry != null) {
|
||||||
|
val magisk32 = File(installDir, "magisk32")
|
||||||
zf.getInputStream(entry).writeTo(magisk32)
|
zf.getInputStream(entry).writeTo(magisk32)
|
||||||
magisk32.setExecutable(true)
|
magisk32.setExecutable(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
val info = context.applicationInfo
|
val info = context.applicationInfo
|
||||||
val libs = File(info.nativeLibraryDir).listFiles { _, name ->
|
val libs = File(info.nativeLibraryDir).listFiles { _, name ->
|
||||||
@@ -583,6 +581,8 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
|
|
||||||
protected suspend fun fixEnv() = extractFiles() && "fix_env $installDir".sh().isSuccess
|
protected suspend fun fixEnv() = extractFiles() && "fix_env $installDir".sh().isSuccess
|
||||||
|
|
||||||
|
protected fun restore() = findImage() && "restore_imgs $srcBoot".sh().isSuccess
|
||||||
|
|
||||||
protected fun uninstall() = "run_uninstaller $AppApkPath".sh().isSuccess
|
protected fun uninstall() = "run_uninstaller $AppApkPath".sh().isSuccess
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
@@ -606,11 +606,10 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class MagiskInstaller(
|
abstract class ConsoleInstaller(
|
||||||
console: MutableList<String>,
|
console: MutableList<String>,
|
||||||
logs: MutableList<String>
|
logs: MutableList<String>
|
||||||
) : MagiskInstallImpl(console, logs) {
|
) : MagiskInstallImpl(console, logs) {
|
||||||
|
|
||||||
override suspend fun exec(): Boolean {
|
override suspend fun exec(): Boolean {
|
||||||
val success = super.exec()
|
val success = super.exec()
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -620,40 +619,51 @@ abstract class MagiskInstaller(
|
|||||||
}
|
}
|
||||||
return success
|
return success
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CallBackInstaller : MagiskInstallImpl(DummyList, DummyList) {
|
||||||
|
suspend fun exec(callback: (Boolean) -> Unit): Boolean {
|
||||||
|
val success = exec()
|
||||||
|
callback(success)
|
||||||
|
return success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MagiskInstaller {
|
||||||
|
|
||||||
class Patch(
|
class Patch(
|
||||||
private val uri: Uri,
|
private val uri: Uri,
|
||||||
console: MutableList<String>,
|
console: MutableList<String>,
|
||||||
logs: MutableList<String>
|
logs: MutableList<String>
|
||||||
) : MagiskInstaller(console, logs) {
|
) : ConsoleInstaller(console, logs) {
|
||||||
override suspend fun operations() = patchFile(uri)
|
override suspend fun operations() = patchFile(uri)
|
||||||
}
|
}
|
||||||
|
|
||||||
class SecondSlot(
|
class SecondSlot(
|
||||||
console: MutableList<String>,
|
console: MutableList<String>,
|
||||||
logs: MutableList<String>
|
logs: MutableList<String>
|
||||||
) : MagiskInstaller(console, logs) {
|
) : ConsoleInstaller(console, logs) {
|
||||||
override suspend fun operations() = secondSlot()
|
override suspend fun operations() = secondSlot()
|
||||||
}
|
}
|
||||||
|
|
||||||
class Direct(
|
class Direct(
|
||||||
console: MutableList<String>,
|
console: MutableList<String>,
|
||||||
logs: MutableList<String>
|
logs: MutableList<String>
|
||||||
) : MagiskInstaller(console, logs) {
|
) : ConsoleInstaller(console, logs) {
|
||||||
override suspend fun operations() = direct()
|
override suspend fun operations() = direct()
|
||||||
}
|
}
|
||||||
|
|
||||||
class Emulator(
|
class Emulator(
|
||||||
console: MutableList<String>,
|
console: MutableList<String>,
|
||||||
logs: MutableList<String>
|
logs: MutableList<String>
|
||||||
) : MagiskInstaller(console, logs) {
|
) : ConsoleInstaller(console, logs) {
|
||||||
override suspend fun operations() = fixEnv()
|
override suspend fun operations() = fixEnv()
|
||||||
}
|
}
|
||||||
|
|
||||||
class Uninstall(
|
class Uninstall(
|
||||||
console: MutableList<String>,
|
console: MutableList<String>,
|
||||||
logs: MutableList<String>
|
logs: MutableList<String>
|
||||||
) : MagiskInstallImpl(console, logs) {
|
) : ConsoleInstaller(console, logs) {
|
||||||
override suspend fun operations() = uninstall()
|
override suspend fun operations() = uninstall()
|
||||||
|
|
||||||
override suspend fun exec(): Boolean {
|
override suspend fun exec(): Boolean {
|
||||||
@@ -667,19 +677,11 @@ abstract class MagiskInstaller(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FixEnv(private val callback: () -> Unit) : MagiskInstallImpl(DummyList, DummyList) {
|
class Restore : CallBackInstaller() {
|
||||||
override suspend fun operations() = fixEnv()
|
override suspend fun operations() = restore()
|
||||||
|
|
||||||
override suspend fun exec(): Boolean {
|
|
||||||
val success = super.exec()
|
|
||||||
callback()
|
|
||||||
context.toast(
|
|
||||||
if (success) R.string.reboot_delay_toast else R.string.setup_fail,
|
|
||||||
Toast.LENGTH_LONG
|
|
||||||
)
|
|
||||||
if (success)
|
|
||||||
UiThreadHandler.handler.postDelayed(5000) { reboot() }
|
|
||||||
return success
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FixEnv : CallBackInstaller() {
|
||||||
|
override suspend fun operations() = fixEnv()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,42 @@
|
|||||||
|
package com.topjohnwu.magisk.core.tasks
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import androidx.core.net.toFile
|
||||||
|
import com.topjohnwu.magisk.core.AppContext
|
||||||
|
import com.topjohnwu.magisk.core.Const
|
||||||
|
import com.topjohnwu.magisk.core.ktx.writeTo
|
||||||
|
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.displayName
|
||||||
|
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream
|
||||||
|
import com.topjohnwu.magisk.core.utils.unzip
|
||||||
|
import com.topjohnwu.superuser.Shell
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileNotFoundException
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
open class RunAction(
|
||||||
|
private val module: String,
|
||||||
|
private val console: MutableList<String>,
|
||||||
|
private val logs: MutableList<String>
|
||||||
|
) {
|
||||||
|
@Throws(IOException::class)
|
||||||
|
private suspend fun run(): Boolean {
|
||||||
|
return Shell.cmd("run_action \'$module\'").to(console, logs).exec().isSuccess
|
||||||
|
}
|
||||||
|
|
||||||
|
open suspend fun exec() = withContext(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
if (!run()) {
|
||||||
|
console.add("! Run action failed")
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
Timber.e(e)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -105,6 +105,7 @@
|
|||||||
<string name="reboot_safe_mode">Modo de segurança</string>
|
<string name="reboot_safe_mode">Modo de segurança</string>
|
||||||
<string name="module_version_author">%1$s por %2$s</string>
|
<string name="module_version_author">%1$s por %2$s</string>
|
||||||
<string name="module_state_remove">Remover</string>
|
<string name="module_state_remove">Remover</string>
|
||||||
|
<string name="module_action">Ação</string>
|
||||||
<string name="module_state_restore">Restaurar</string>
|
<string name="module_state_restore">Restaurar</string>
|
||||||
<string name="module_action_install_external">Instalar a partir do armazenamento</string>
|
<string name="module_action_install_external">Instalar a partir do armazenamento</string>
|
||||||
<string name="update_available">Atualização disponível</string>
|
<string name="update_available">Atualização disponível</string>
|
||||||
@@ -173,7 +174,7 @@
|
|||||||
<string name="settings_doh_title">DNS sobre HTTPS</string>
|
<string name="settings_doh_title">DNS sobre HTTPS</string>
|
||||||
<string name="settings_doh_description">Solução alternativa para envenenamento de DNS em alguns países</string>
|
<string name="settings_doh_description">Solução alternativa para envenenamento de DNS em alguns países</string>
|
||||||
<string name="settings_random_name_title">Randomizar nome de saída</string>
|
<string name="settings_random_name_title">Randomizar nome de saída</string>
|
||||||
<string name="settings_random_name_description">Randomize o nome do arquivo de saída de imagens corrigidas e arquivos tar para evitar a detecção</string>
|
<string name="settings_random_name_description">Randomize o nome do arquivo de saída de imagens corrigidas e arquivos tar (*.tar) para evitar a detecção</string>
|
||||||
<string name="multiuser_mode">Modo multiusuário</string>
|
<string name="multiuser_mode">Modo multiusuário</string>
|
||||||
<string name="settings_owner_only">Somente proprietário do dispositivo</string>
|
<string name="settings_owner_only">Somente proprietário do dispositivo</string>
|
||||||
<string name="settings_owner_manage">Gerenciado pelo proprietário do dispositivo</string>
|
<string name="settings_owner_manage">Gerenciado pelo proprietário do dispositivo</string>
|
||||||
@@ -205,9 +206,12 @@
|
|||||||
<string name="repo_install_title">Instalar %1$s %2$s(%3$d)</string>
|
<string name="repo_install_title">Instalar %1$s %2$s(%3$d)</string>
|
||||||
<string name="download">Baixar</string>
|
<string name="download">Baixar</string>
|
||||||
<string name="reboot">Reiniciar</string>
|
<string name="reboot">Reiniciar</string>
|
||||||
|
<string name="close">Fechar</string>
|
||||||
<string name="release_notes">Notas da atualização</string>
|
<string name="release_notes">Notas da atualização</string>
|
||||||
<string name="flashing">Flashando…</string>
|
<string name="flashing">Flashando…</string>
|
||||||
|
<string name="running">Executando…</string>
|
||||||
<string name="done">Concluído!</string>
|
<string name="done">Concluído!</string>
|
||||||
|
<string name="done_action">Ação de execução de %1$s concluída</string>
|
||||||
<string name="failure">Falhou!</string>
|
<string name="failure">Falhou!</string>
|
||||||
<string name="hide_app_title">Ocultando o app do Magisk…</string>
|
<string name="hide_app_title">Ocultando o app do Magisk…</string>
|
||||||
<string name="open_link_failed_toast">Nenhum app encontrado para abrir o link</string>
|
<string name="open_link_failed_toast">Nenhum app encontrado para abrir o link</string>
|
||||||
|
@@ -105,6 +105,7 @@
|
|||||||
<string name="reboot_safe_mode">Modo de segurança</string>
|
<string name="reboot_safe_mode">Modo de segurança</string>
|
||||||
<string name="module_version_author">%1$s por %2$s</string>
|
<string name="module_version_author">%1$s por %2$s</string>
|
||||||
<string name="module_state_remove">Remover</string>
|
<string name="module_state_remove">Remover</string>
|
||||||
|
<string name="module_action">Ação</string>
|
||||||
<string name="module_state_restore">Restaurar</string>
|
<string name="module_state_restore">Restaurar</string>
|
||||||
<string name="module_action_install_external">Instalar a partir do armazenamento</string>
|
<string name="module_action_install_external">Instalar a partir do armazenamento</string>
|
||||||
<string name="update_available">Atualização disponível</string>
|
<string name="update_available">Atualização disponível</string>
|
||||||
@@ -173,7 +174,7 @@
|
|||||||
<string name="settings_doh_title">DNS sobre HTTPS</string>
|
<string name="settings_doh_title">DNS sobre HTTPS</string>
|
||||||
<string name="settings_doh_description">Solução alternativa para envenenamento de DNS em alguns países</string>
|
<string name="settings_doh_description">Solução alternativa para envenenamento de DNS em alguns países</string>
|
||||||
<string name="settings_random_name_title">Randomizar nome de saída</string>
|
<string name="settings_random_name_title">Randomizar nome de saída</string>
|
||||||
<string name="settings_random_name_description">Randomize o nome do arquivo de saída de imagens corrigidas e arquivos tar para evitar a detecção</string>
|
<string name="settings_random_name_description">Randomize o nome do arquivo de saída de imagens corrigidas e arquivos tar (*.tar) para evitar a detecção</string>
|
||||||
<string name="multiuser_mode">Modo multiusuário</string>
|
<string name="multiuser_mode">Modo multiusuário</string>
|
||||||
<string name="settings_owner_only">Somente proprietário do dispositivo</string>
|
<string name="settings_owner_only">Somente proprietário do dispositivo</string>
|
||||||
<string name="settings_owner_manage">Gerenciado pelo proprietário do dispositivo</string>
|
<string name="settings_owner_manage">Gerenciado pelo proprietário do dispositivo</string>
|
||||||
@@ -205,9 +206,12 @@
|
|||||||
<string name="repo_install_title">Instalar %1$s %2$s(%3$d)</string>
|
<string name="repo_install_title">Instalar %1$s %2$s(%3$d)</string>
|
||||||
<string name="download">Baixar</string>
|
<string name="download">Baixar</string>
|
||||||
<string name="reboot">Reiniciar</string>
|
<string name="reboot">Reiniciar</string>
|
||||||
|
<string name="close">Fechar</string>
|
||||||
<string name="release_notes">Notas da atualização</string>
|
<string name="release_notes">Notas da atualização</string>
|
||||||
<string name="flashing">Flashando…</string>
|
<string name="flashing">Flashando…</string>
|
||||||
|
<string name="running">Executando…</string>
|
||||||
<string name="done">Concluído!</string>
|
<string name="done">Concluído!</string>
|
||||||
|
<string name="done_action">Ação de execução de %1$s concluída</string>
|
||||||
<string name="failure">Falhou!</string>
|
<string name="failure">Falhou!</string>
|
||||||
<string name="hide_app_title">Ocultando o app do Magisk…</string>
|
<string name="hide_app_title">Ocultando o app do Magisk…</string>
|
||||||
<string name="open_link_failed_toast">Nenhum app encontrado para abrir o link</string>
|
<string name="open_link_failed_toast">Nenhum app encontrado para abrir o link</string>
|
||||||
|
@@ -74,7 +74,6 @@
|
|||||||
<string name="su_revoke_msg">Konfirmo për të hequr të drejtat e %1$s?</string>
|
<string name="su_revoke_msg">Konfirmo për të hequr të drejtat e %1$s?</string>
|
||||||
<string name="toast">Dolli</string>
|
<string name="toast">Dolli</string>
|
||||||
<string name="none">Asnjë</string>
|
<string name="none">Asnjë</string>
|
||||||
|
|
||||||
<string name="superuser_toggle_notification">Njoftimet</string>
|
<string name="superuser_toggle_notification">Njoftimet</string>
|
||||||
<string name="superuser_toggle_revoke">Të drejtat</string>
|
<string name="superuser_toggle_revoke">Të drejtat</string>
|
||||||
<string name="superuser_policy_none">Asnjë aplikacion nuk ka kërkuar akoma akses për super-përdoruesin.</string>
|
<string name="superuser_policy_none">Asnjë aplikacion nuk ka kërkuar akoma akses për super-përdoruesin.</string>
|
||||||
@@ -91,8 +90,6 @@
|
|||||||
<string name="selinux_context">Konteksti SELinux: %s</string>
|
<string name="selinux_context">Konteksti SELinux: %s</string>
|
||||||
<string name="supp_group">Grupi suplementar: %s</string>
|
<string name="supp_group">Grupi suplementar: %s</string>
|
||||||
|
|
||||||
<!--SafetyNet-->
|
|
||||||
|
|
||||||
<!--MagiskHide-->
|
<!--MagiskHide-->
|
||||||
<string name="show_system_app">Shfaq aplikacionet e sistemit</string>
|
<string name="show_system_app">Shfaq aplikacionet e sistemit</string>
|
||||||
<string name="show_os_app">Shfaq aplikacionet e sistemit operativ</string>
|
<string name="show_os_app">Shfaq aplikacionet e sistemit operativ</string>
|
||||||
@@ -109,6 +106,7 @@
|
|||||||
<string name="reboot_safe_mode">Rinis në safe mode</string>
|
<string name="reboot_safe_mode">Rinis në safe mode</string>
|
||||||
<string name="module_version_author">%1$s nga %2$s</string>
|
<string name="module_version_author">%1$s nga %2$s</string>
|
||||||
<string name="module_state_remove">Hiqe</string>
|
<string name="module_state_remove">Hiqe</string>
|
||||||
|
<string name="module_action">Veprim</string>
|
||||||
<string name="module_state_restore">Rikëthe</string>
|
<string name="module_state_restore">Rikëthe</string>
|
||||||
<string name="module_action_install_external">Instaloni nga sdcard</string>
|
<string name="module_action_install_external">Instaloni nga sdcard</string>
|
||||||
<string name="update_available">Përditësimi në dispozicion</string>
|
<string name="update_available">Përditësimi në dispozicion</string>
|
||||||
@@ -207,9 +205,12 @@
|
|||||||
<string name="repo_install_title">Instalo %1$s %2$s(%3$d)</string>
|
<string name="repo_install_title">Instalo %1$s %2$s(%3$d)</string>
|
||||||
<string name="download">Shkarko</string>
|
<string name="download">Shkarko</string>
|
||||||
<string name="reboot">Rinis</string>
|
<string name="reboot">Rinis</string>
|
||||||
|
<string name="close">Mbylle</string>
|
||||||
<string name="release_notes">Shënimet e lëshimit</string>
|
<string name="release_notes">Shënimet e lëshimit</string>
|
||||||
<string name="flashing">Duke flashuar…</string>
|
<string name="flashing">Duke flashuar…</string>
|
||||||
|
<string name="running">Duke vepruar...</string>
|
||||||
<string name="done">U krye!</string>
|
<string name="done">U krye!</string>
|
||||||
|
<string name="done_action">Veprimi i ekzekutimit të %1$s u krye</string>
|
||||||
<string name="failure">Dështoi!</string>
|
<string name="failure">Dështoi!</string>
|
||||||
<string name="hide_app_title">Fshehja e aplikacionit Magisk…</string>
|
<string name="hide_app_title">Fshehja e aplikacionit Magisk…</string>
|
||||||
<string name="open_link_failed_toast">Nuk u gjet asnjë aplikacion për të hapur lidhjen</string>
|
<string name="open_link_failed_toast">Nuk u gjet asnjë aplikacion për të hapur lidhjen</string>
|
||||||
|
@@ -12,21 +12,21 @@
|
|||||||
|
|
||||||
<!--Home-->
|
<!--Home-->
|
||||||
<string name="no_connection">Bağlantı yok</string>
|
<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="loading">Yükleniyor…</string>
|
||||||
<string name="update">Güncelle</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="hide">Gizle</string>
|
||||||
<string name="home_package">Paket</string>
|
<string name="home_package">Paket</string>
|
||||||
<string name="home_app_title">Uygulama</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_support_title">Bizi Destekleyin</string>
|
||||||
<string name="home_follow_title">Bizi Takip Edin</string>
|
<string name="home_follow_title">Bizi Takip Edin</string>
|
||||||
<string name="home_item_source">Kaynak</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_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">Durum</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="home_latest_version">En Son Sürüm</string>
|
||||||
<string name="invalid_update_channel">Geçersiz Güncelleme Kanalı</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_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>
|
<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_options_title">Seçenekler</string>
|
||||||
<string name="install_method_title">Yöntem</string>
|
<string name="install_method_title">Yöntem</string>
|
||||||
<string name="install_next">Sonraki</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="manager_download_install">İndirmek ve yüklemek için basın</string>
|
||||||
<string name="direct_install">Doğrudan Kurulum (Önerilir)</string>
|
<string name="direct_install">Doğrudan Yükleme (Önerilir)</string>
|
||||||
<string name="install_inactive_slot">Etkin Olmayan Yuvaya Yükle (OTA\'dan Sonra)</string>
|
<string name="install_inactive_slot">Etkin Olmayan Slot\'a Yükle (OTA Sonrası)</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="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="setup_title">Ek Kurulum</string>
|
||||||
<string name="select_patch_file">Bir Dosya Seç ve Yama Yap</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="reboot_delay_toast">5 saniye içinde yeniden başlatılıyor…</string>
|
||||||
<string name="flash_screen_title">Yükleniyor</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="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="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="deny">Reddet</string>
|
||||||
<string name="prompt">Sor</string>
|
<string name="prompt">İstem</string>
|
||||||
<string name="grant">İzin ver</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="su_warning">Cihazınıza tam erişim sağlar.\nEmin değilseniz reddedin!</string>
|
||||||
<string name="forever">Daima</string>
|
<string name="forever">Daima</string>
|
||||||
<string name="once">Bir kez</string>
|
<string name="once">Bir kez</string>
|
||||||
<string name="tenmin">10 dakika</string>
|
<string name="tenmin">10 dakika</string>
|
||||||
<string name="twentymin">20 dakika</string>
|
<string name="twentymin">20 dakika</string>
|
||||||
<string name="thirtymin">30 dakika</string>
|
<string name="thirtymin">30 dakika</string>
|
||||||
<string name="sixtymin">60 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_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ı izni reddedildi</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ı izni verildi</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ı izni reddedildi</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_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_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_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_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_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="su_revoke_msg">%1$s uygulamasının süper kullanıcı haklarını iptal etmek istediğinize emin misiniz?</string>
|
||||||
<string name="toast">Tost</string>
|
<string name="toast">Bildirim</string>
|
||||||
<string name="none">Hiçbiri</string>
|
<string name="none">Yok</string>
|
||||||
|
|
||||||
<string name="superuser_toggle_notification">Bildirimler</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>
|
<string name="superuser_policy_none">Henüz hiçbir uygulama Süper Kullanıcı izni istemedi.</string>
|
||||||
|
|
||||||
<!--Logs-->
|
<!--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_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 garip</string>
|
<string name="log_data_magisk_none">Magisk günlükleri boş, bu tuhaf</string>
|
||||||
<string name="menuSaveLog">Günlüğü kaydet</string>
|
<string name="menuSaveLog">Günlüğü kaydet</string>
|
||||||
<string name="menuClearLog">Günlüğü şimdi temizle</string>
|
<string name="menuClearLog">Günlüğü şimdi temizle</string>
|
||||||
<string name="logs_cleared">Günlük kaydı başarıyla temizlendi</string>
|
<string name="logs_cleared">Günlük kaydı başarıyla temizlendi</string>
|
||||||
<string name="pid">PID: %1$d</string>
|
<string name="pid">PID: %1$d</string>
|
||||||
<string name="target_uid">Hedef UID: %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="target_pid">Mount ns hedef PID: %s</string>
|
||||||
<string name="selinux_context">SELinux içeriği: %s</string>
|
<string name="selinux_context">SELinux bağlamı: %s</string>
|
||||||
<string name="supp_group">Ek grup: %s</string>
|
<string name="supp_group">Ek grup: %s</string>
|
||||||
|
|
||||||
<!--SafetyNet-->
|
<!--SafetyNet-->
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
<!--MagiskHide-->
|
<!--MagiskHide-->
|
||||||
<string name="show_system_app">Sistem uygulamalarını göster</string>
|
<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="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>
|
<string name="hide_search">Ara</string>
|
||||||
|
|
||||||
<!--Module-->
|
<!--Module-->
|
||||||
@@ -106,13 +106,14 @@
|
|||||||
<string name="reboot_bootloader">Önyükleyici modunda yeniden başlat</string>
|
<string name="reboot_bootloader">Önyükleyici modunda yeniden başlat</string>
|
||||||
<string name="reboot_download">İndirme 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_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_version_author">%1$s / %2$s</string>
|
||||||
<string name="module_state_remove">Kaldır</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="module_action_install_external">Depolamadan yükle</string>
|
||||||
<string name="update_available">Güncelleme Mevcut</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_riru">Modül, %1$s etkin olduğu için 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_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="zygisk_module_unloaded">Uyumsuzluk nedeniyle Zygisk modülü yüklenmedi</string>
|
||||||
<string name="module_empty">Yüklü modül yok</string>
|
<string name="module_empty">Yüklü modül yok</string>
|
||||||
<string name="confirm_install">%1$s modülü yüklensin mi?</string>
|
<string name="confirm_install">%1$s modülü yüklensin mi?</string>
|
||||||
@@ -121,39 +122,39 @@
|
|||||||
<!--Settings-->
|
<!--Settings-->
|
||||||
<string name="settings_dark_mode_title">Tema Modu</string>
|
<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_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_system">Sistemi Takip Et</string>
|
||||||
<string name="settings_dark_mode_dark">Daima Koyu</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_title">İndirme Yolu</string>
|
||||||
<string name="settings_download_path_message">Dosyalar %1$s konumuna kaydedilecek</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_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_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="settings_restore_app_summary">Uygulamayı göster ve orijinal APK\'yı geri yükle</string>
|
||||||
<string name="language">Dil</string>
|
<string name="language">Dil</string>
|
||||||
<string name="system_default">(Sistem Varsayılanı)</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_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_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_beta">Beta</string>
|
||||||
<string name="settings_update_custom">Özel</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_update_custom_msg">Özel kanal URL\'si girin</string>
|
||||||
<string name="settings_zygisk_summary">Zygisk arka plan programında Magisk\'in bazı bölümlerini çalıştır</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_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_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_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_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_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_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_app_name_error">Geçersiz format</string>
|
||||||
<string name="settings_su_app_adb">Uygulamalar ve ADB</string>
|
<string name="settings_su_app_adb">Uygulamalar ve ADB</string>
|
||||||
<string name="settings_su_app">Yalnızca uygulamalar</string>
|
<string name="settings_su_app">Sadece Uygulamalar</string>
|
||||||
<string name="settings_su_adb">Yalnızca ADB</string>
|
<string name="settings_su_adb">Sadece ADB</string>
|
||||||
<string name="settings_su_disable">Devre dışı</string>
|
<string name="settings_su_disable">Devre Dışı</string>
|
||||||
<string name="settings_su_request_10">10 saniye</string>
|
<string name="settings_su_request_10">10 saniye</string>
|
||||||
<string name="settings_su_request_15">15 saniye</string>
|
<string name="settings_su_request_15">15 saniye</string>
|
||||||
<string name="settings_su_request_20">20 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="auto_response">Otomatik Yanıt</string>
|
||||||
<string name="request_timeout">İstek Zaman Aşımı</string>
|
<string name="request_timeout">İstek Zaman Aşımı</string>
|
||||||
<string name="superuser_notification">Süper Kullanıcı Bildirimi</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_title">Yükseltme sonrası yeniden doğrulama yap</string>
|
||||||
<string name="settings_su_reauth_summary">Uygulamaları yükselttikten sonra Süper Kullanıcı izinlerini tekrar iste</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">Sahte Ekran (Tapjacking) Koruması</string>
|
<string name="settings_su_tapjack_title">Tapjacking Koruması</string>
|
||||||
<string name="settings_su_tapjack_summary">Süper Kullanıcı bilgi istemi iletişim kutusu, herhangi bir başka pencere veya yer paylaşımı tarafından engellendiğinde girişe yanıt vermeyecektir.</string>
|
<string name="settings_su_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ğrulaması</string>
|
<string name="settings_su_auth_title">Kullanıcı Kimlik Doğrulama</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_summary">Süper Kullanıcı isteklerinde 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_auth_insecure">Cihazda yapılandırılmış bir kimlik doğrulama yöntemi yok</string>
|
||||||
<string name="settings_customization">Özelleştir</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="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">HTTPS üzerinden DNS</string>
|
<string name="settings_doh_title">DNS üzerinden HTTPS</string>
|
||||||
<string name="settings_doh_description">Bazı ülkelerde DNS zehirlenmesine geçici çözüm</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="multiuser_mode">Çok Kullanıcılı Mod</string>
|
||||||
<string name="settings_owner_only">Yalnızca Cihaz Sahibi</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="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_only_summary">Yalnızca sahip kök (root) erişimine sahiptir</string>
|
||||||
<string name="owner_manage_summary">Kök erişimini yalnızca sahip yönetebilir ve istek istemlerini alabilir</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 kuralları vardır</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="mount_namespace_mode">Bağlama Ad Alanı Modu</string>
|
||||||
<string name="settings_ns_global">Küresel Ad Alanı</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_requester">Ad Alanını Devral</string>
|
||||||
<string name="settings_ns_isolate">İzole Edilmiş Ad Alanı</string>
|
<string name="settings_ns_isolate">İzolasyon Ad Alanı</string>
|
||||||
<string name="global_summary">Tüm kök oturumları, global bağlama ad alanını kullanır</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 oturumları, istek sahibinin ad alanını devralır</string>
|
<string name="requester_summary">Kök (root) oturumları isteyicisinin ad alanını devralacak</string>
|
||||||
<string name="isolate_summary">Her kök oturumun kendi izole edilmiş ad alanı olacaktır</string>
|
<string name="isolate_summary">Her kök (root) oturumu kendi izole ad alanına sahip olacak</string>
|
||||||
|
|
||||||
<!--Notifications-->
|
<!--Notifications-->
|
||||||
<string name="update_channel">Magisk Güncellemeleri</string>
|
<string name="update_channel">Magisk Güncellemeleri</string>
|
||||||
<string name="progress_channel">İlerleme Bildirimleri</string>
|
<string name="progress_channel">İlerleme Bildirimleri</string>
|
||||||
<string name="updated_channel">Güncelleme Tamamlandı</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="download_file_error">Dosya indirilirken hata oluştu</string>
|
||||||
<string name="magisk_update_title">Magisk Güncellemesi Mevcut!</string>
|
<string name="magisk_update_title">Magisk Güncellemesi Mevcut!</string>
|
||||||
<string name="updated_title">Magisk Güncellendi</string>
|
<string name="updated_title">Magisk Güncellendi</string>
|
||||||
@@ -204,41 +207,41 @@
|
|||||||
|
|
||||||
<!--Toasts, Dialogs-->
|
<!--Toasts, Dialogs-->
|
||||||
<string name="yes">Mevcut</string>
|
<string name="yes">Mevcut</string>
|
||||||
<string name="no">Mevcut değil</string>
|
<string name="no">Mevcut Değil</string>
|
||||||
<string name="repo_install_title">%1$s %2$s(%3$d) yükle</string>
|
<string name="repo_install_title">%1$s %2$s(%3$d) Kur</string>
|
||||||
<string name="download">İndir</string>
|
<string name="download">İndir</string>
|
||||||
<string name="reboot">Yeniden başlat</string>
|
<string name="reboot">Yeniden Başlat</string>
|
||||||
<string name="release_notes">Sürüm notları</string>
|
<string name="release_notes">Sürüm Notları</string>
|
||||||
<string name="flashing">Flaşlanıyor…</string>
|
<string name="flashing">Yükleniyor...</string>
|
||||||
<string name="done">Tamamlandı!</string>
|
<string name="done">Tamamlandı!</string>
|
||||||
<string name="failure">Başarısız!</string>
|
<string name="failure">Başarısız!</string>
|
||||||
<string name="hide_app_title">Magisk uygulaması gizleniyor…</string>
|
<string name="hide_app_title">Magisk uygulaması gizleniyor…</string>
|
||||||
<string name="open_link_failed_toast">Bağlantıyı açacak uygulama bulunamadı</string>
|
<string name="open_link_failed_toast">Bağlantıyı açmak için uygulama bulunamadı</string>
|
||||||
<string name="complete_uninstall">Kaldırmayı Tamamla</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">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_done">Geri yükleme tamamlandı!</string>
|
||||||
<string name="restore_fail">Stok yedeği mevcut değil!</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="setup_fail">Kurulum başarısız oldu</string>
|
||||||
<string name="env_fix_title">Ek Kurulum Gerekiyor</string>
|
<string name="env_fix_title">Ek Ayar 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_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ış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="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 çalıştırılıyor…</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_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_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_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 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_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üklenmiş. Lütfen uygulamayı dahili depolamaya taşıyın.</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">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_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="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="external_rw_permission_denied">Bu işlevselliği etkinleştirmek için depolama izni verin</string>
|
||||||
<string name="post_notifications_denied">Bu işlevi etkinleştirmek için bildirim izni veriniz.</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şlevi etkinleştirmek için "Bilinmeyen uygulamaları yükle" ayarına izin veriniz.</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_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="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 eylemi gerçekleştirecek uygulama bulunamadı</string>
|
<string name="app_not_found">Bu işlemi gerçekleştirecek uygulama bulunamadı</string>
|
||||||
<string name="reboot_apply_change">Değişiklikleri uygulamak için yeniden başlatın</string>
|
<string name="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>
|
</resources>
|
||||||
|
@@ -109,6 +109,7 @@
|
|||||||
<string name="reboot_safe_mode">安全模式</string>
|
<string name="reboot_safe_mode">安全模式</string>
|
||||||
<string name="module_version_author">%1$s,作者 %2$s</string>
|
<string name="module_version_author">%1$s,作者 %2$s</string>
|
||||||
<string name="module_state_remove">移除</string>
|
<string name="module_state_remove">移除</string>
|
||||||
|
<string name="module_action">操作</string>
|
||||||
<string name="module_state_restore">还原</string>
|
<string name="module_state_restore">还原</string>
|
||||||
<string name="module_action_install_external">从本地安装</string>
|
<string name="module_action_install_external">从本地安装</string>
|
||||||
<string name="update_available">可更新</string>
|
<string name="update_available">可更新</string>
|
||||||
@@ -176,6 +177,8 @@
|
|||||||
<string name="setting_add_shortcut_summary">在隐藏后难以识别名称和图标的情况下,添加快捷方式到桌面</string>
|
<string name="setting_add_shortcut_summary">在隐藏后难以识别名称和图标的情况下,添加快捷方式到桌面</string>
|
||||||
<string name="settings_doh_title">安全 DNS(DoH)</string>
|
<string name="settings_doh_title">安全 DNS(DoH)</string>
|
||||||
<string name="settings_doh_description">解决某些地区的 DNS 污染问题</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_only">仅设备所有者</string>
|
||||||
@@ -209,9 +212,12 @@
|
|||||||
<string name="repo_install_title">安装 %1$s %2$s(%3$d)</string>
|
<string name="repo_install_title">安装 %1$s %2$s(%3$d)</string>
|
||||||
<string name="download">下载</string>
|
<string name="download">下载</string>
|
||||||
<string name="reboot">重启</string>
|
<string name="reboot">重启</string>
|
||||||
|
<string name="close">关闭</string>
|
||||||
<string name="release_notes">发布说明</string>
|
<string name="release_notes">发布说明</string>
|
||||||
<string name="flashing">正在刷入</string>
|
<string name="flashing">正在刷入</string>
|
||||||
|
<string name="running">运行中……</string>
|
||||||
<string name="done">完成!</string>
|
<string name="done">完成!</string>
|
||||||
|
<string name="done_action">%1$s 操作运行完成</string>
|
||||||
<string name="failure">失败</string>
|
<string name="failure">失败</string>
|
||||||
<string name="hide_app_title">正在隐藏 Magisk 应用</string>
|
<string name="hide_app_title">正在隐藏 Magisk 应用</string>
|
||||||
<string name="open_link_failed_toast">找不到能打开此链接的应用</string>
|
<string name="open_link_failed_toast">找不到能打开此链接的应用</string>
|
||||||
|
@@ -109,6 +109,7 @@
|
|||||||
<string name="reboot_safe_mode">Safe mode</string>
|
<string name="reboot_safe_mode">Safe mode</string>
|
||||||
<string name="module_version_author">%1$s by %2$s</string>
|
<string name="module_version_author">%1$s by %2$s</string>
|
||||||
<string name="module_state_remove">Remove</string>
|
<string name="module_state_remove">Remove</string>
|
||||||
|
<string name="module_action">Action</string>
|
||||||
<string name="module_state_restore">Restore</string>
|
<string name="module_state_restore">Restore</string>
|
||||||
<string name="module_action_install_external">Install from storage</string>
|
<string name="module_action_install_external">Install from storage</string>
|
||||||
<string name="update_available">Update Available</string>
|
<string name="update_available">Update Available</string>
|
||||||
@@ -211,9 +212,12 @@
|
|||||||
<string name="repo_install_title">Install %1$s %2$s(%3$d)</string>
|
<string name="repo_install_title">Install %1$s %2$s(%3$d)</string>
|
||||||
<string name="download">Download</string>
|
<string name="download">Download</string>
|
||||||
<string name="reboot">Reboot</string>
|
<string name="reboot">Reboot</string>
|
||||||
|
<string name="close">Close</string>
|
||||||
<string name="release_notes">Release notes</string>
|
<string name="release_notes">Release notes</string>
|
||||||
<string name="flashing">Flashing…</string>
|
<string name="flashing">Flashing…</string>
|
||||||
|
<string name="running">Running…</string>
|
||||||
<string name="done">Done!</string>
|
<string name="done">Done!</string>
|
||||||
|
<string name="done_action">Done running action of %1$s</string>
|
||||||
<string name="failure">Failed!</string>
|
<string name="failure">Failed!</string>
|
||||||
<string name="hide_app_title">Hiding the Magisk app…</string>
|
<string name="hide_app_title">Hiding the Magisk app…</string>
|
||||||
<string name="open_link_failed_toast">No app found to open the link</string>
|
<string name="open_link_failed_toast">No app found to open the link</string>
|
||||||
|
@@ -1,13 +1,22 @@
|
|||||||
package com.topjohnwu.magisk;
|
package com.topjohnwu.magisk;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
|
||||||
public class ProviderInstaller {
|
public class ProviderInstaller {
|
||||||
|
|
||||||
|
private static final String GMS_PACKAGE_NAME = "com.google.android.gms";
|
||||||
|
|
||||||
public static boolean install(Context context) {
|
public static boolean install(Context context) {
|
||||||
try {
|
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
|
// 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);
|
Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
|
||||||
gms.getClassLoader()
|
gms.getClassLoader()
|
||||||
.loadClass("com.google.android.gms.common.security.ProviderInstallerImpl")
|
.loadClass("com.google.android.gms.common.security.ProviderInstallerImpl")
|
||||||
|
@@ -6,7 +6,7 @@ plugins {
|
|||||||
lsparanoid {
|
lsparanoid {
|
||||||
seed = if (RAND_SEED != 0) RAND_SEED else null
|
seed = if (RAND_SEED != 0) RAND_SEED else null
|
||||||
includeDependencies = true
|
includeDependencies = true
|
||||||
global = true
|
classFilter = { true }
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="upgrade_msg">عليك الترقية ماجـيسك Manager لإكمال تهيئة التطبيق.هل اكمل؟</string>
|
<string name="upgrade_msg">عليك الترقية Magisk لإكمال تهيئة التطبيق. هل تريد التنزيل والتثبيت؟</string>
|
||||||
<string name="no_internet_msg">يرجى الاتصال بالانترنيت! ترقية ماجـيسك مطلوب...</string>
|
<string name="no_internet_msg">يرجى اللإتصال بالإنترنت! ترقية Magisk مطلوبة.</string>
|
||||||
<string name="dling">جارٍ التنزيل</string>
|
<string name="dling">جارٍ التنزيل</string>
|
||||||
|
<string name="relaunch_app">يرجى إعادة تشغيل التطبيق يدوياً</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
627
build.py
627
build.py
@@ -5,6 +5,7 @@ import lzma
|
|||||||
import multiprocessing
|
import multiprocessing
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import stat
|
import stat
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -38,6 +39,7 @@ def vprint(str):
|
|||||||
print(str)
|
print(str)
|
||||||
|
|
||||||
|
|
||||||
|
# Environment checks and detection
|
||||||
is_windows = os.name == "nt"
|
is_windows = os.name == "nt"
|
||||||
EXE_EXT = ".exe" if is_windows else ""
|
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
|
# We can't do ANSI color codes in terminal on Windows without colorama
|
||||||
no_color = True
|
no_color = True
|
||||||
|
|
||||||
# Environment checks
|
|
||||||
if not sys.version_info >= (3, 8):
|
if not sys.version_info >= (3, 8):
|
||||||
error("Requires Python 3.8+")
|
error("Requires Python 3.8+")
|
||||||
|
|
||||||
@@ -63,42 +64,40 @@ except KeyError:
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
error("Please set Android SDK path to environment variable ANDROID_HOME")
|
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()
|
cpu_count = multiprocessing.cpu_count()
|
||||||
os_name = platform.system().lower()
|
os_name = platform.system().lower()
|
||||||
|
|
||||||
archs = ["armeabi-v7a", "x86", "arm64-v8a", "x86_64", "riscv64"]
|
# Common constants
|
||||||
triples = [
|
support_abis = {
|
||||||
"armv7a-linux-androideabi",
|
"armeabi-v7a": "thumbv7neon-linux-androideabi",
|
||||||
"i686-linux-android",
|
"x86": "i686-linux-android",
|
||||||
"aarch64-linux-android",
|
"arm64-v8a": "aarch64-linux-android",
|
||||||
"x86_64-linux-android",
|
"x86_64": "x86_64-linux-android",
|
||||||
"riscv64-linux-android",
|
"riscv64": "riscv64-linux-android",
|
||||||
]
|
}
|
||||||
default_targets = ["magisk", "magiskinit", "magiskboot", "magiskpolicy"]
|
default_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"}
|
||||||
support_targets = default_targets + ["resetprop"]
|
support_targets = default_targets | {"resetprop"}
|
||||||
rust_targets = ["magisk", "magiskinit", "magiskboot", "magiskpolicy"]
|
rust_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"}
|
||||||
|
|
||||||
|
# Common paths
|
||||||
ndk_root = sdk_path / "ndk"
|
ndk_root = sdk_path / "ndk"
|
||||||
ndk_path = ndk_root / "magisk"
|
ndk_path = ndk_root / "magisk"
|
||||||
ndk_build = ndk_path / "ndk-build"
|
ndk_build = ndk_path / "ndk-build"
|
||||||
rust_bin = ndk_path / "toolchains" / "rust" / "bin"
|
rust_bin = ndk_path / "toolchains" / "rust" / "bin"
|
||||||
llvm_bin = ndk_path / "toolchains" / "llvm" / "prebuilt" / f"{os_name}-x86_64" / "bin"
|
llvm_bin = ndk_path / "toolchains" / "llvm" / "prebuilt" / f"{os_name}-x86_64" / "bin"
|
||||||
cargo = rust_bin / f"cargo{EXE_EXT}"
|
cargo = rust_bin / "cargo"
|
||||||
gradlew = Path("gradlew" + (".bat" if is_windows else "")).resolve()
|
gradlew = Path.cwd() / "gradlew"
|
||||||
adb_path = sdk_path / "platform-tools" / f"adb{EXE_EXT}"
|
adb_path = sdk_path / "platform-tools" / "adb"
|
||||||
native_gen_path = Path("native", "out", "generated").resolve()
|
native_gen_path = Path("native", "out", "generated").resolve()
|
||||||
|
|
||||||
# Global vars
|
# Global vars
|
||||||
config = {}
|
config = {}
|
||||||
STDOUT = None
|
args = {}
|
||||||
build_tools = None
|
build_abis = {}
|
||||||
|
|
||||||
|
###################
|
||||||
|
# Helper functions
|
||||||
|
###################
|
||||||
|
|
||||||
|
|
||||||
def mv(source: Path, target: Path):
|
def mv(source: Path, target: Path):
|
||||||
@@ -137,20 +136,26 @@ def rm_on_error(func, path, _):
|
|||||||
|
|
||||||
def rm_rf(path: Path):
|
def rm_rf(path: Path):
|
||||||
vprint(f"rm -rf {path}")
|
vprint(f"rm -rf {path}")
|
||||||
|
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)
|
shutil.rmtree(path, ignore_errors=False, onerror=rm_on_error)
|
||||||
|
|
||||||
|
|
||||||
def execv(cmd, env=None):
|
def execv(cmds: list, env=None):
|
||||||
return subprocess.run(cmd, stdout=STDOUT, env=env)
|
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):
|
def cmd_out(cmds: list):
|
||||||
return subprocess.run(cmd, shell=True, stdout=STDOUT)
|
|
||||||
|
|
||||||
|
|
||||||
def cmd_out(cmd, env=None):
|
|
||||||
return (
|
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()
|
.stdout.strip()
|
||||||
.decode("utf-8")
|
.decode("utf-8")
|
||||||
)
|
)
|
||||||
@@ -160,51 +165,9 @@ def xz(data):
|
|||||||
return lzma.compress(data, preset=9, check=lzma.CHECK_NONE)
|
return lzma.compress(data, preset=9, check=lzma.CHECK_NONE)
|
||||||
|
|
||||||
|
|
||||||
def parse_props(file):
|
###############
|
||||||
props = {}
|
# Build Native
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
def clean_elf():
|
def clean_elf():
|
||||||
@@ -225,94 +188,127 @@ def clean_elf():
|
|||||||
elf_cleaner,
|
elf_cleaner,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
args = [elf_cleaner, "--api-level", "23"]
|
cmds = [elf_cleaner, "--api-level", "23"]
|
||||||
args.extend(
|
cmds.extend(glob.glob("native/out/*/magisk"))
|
||||||
Path("native", "out", arch, bin)
|
cmds.extend(glob.glob("native/out/*/magiskpolicy"))
|
||||||
for arch in archs
|
execv(cmds)
|
||||||
for bin in ["magisk", "magiskpolicy"]
|
|
||||||
)
|
|
||||||
execv(args)
|
|
||||||
|
|
||||||
|
|
||||||
def run_ndk_build(args, flags):
|
def run_ndk_build(cmds: list):
|
||||||
os.chdir("native")
|
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:
|
if args.verbose > 1:
|
||||||
flags = "V=1 " + flags
|
cmds.append("V=1")
|
||||||
proc = system(f"{ndk_build} {flags} -j{cpu_count}")
|
if not args.release:
|
||||||
|
cmds.append("MAGISK_DEBUG=1")
|
||||||
|
proc = execv([ndk_build, *cmds])
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
error("Build binary failed!")
|
error("Build binary failed!")
|
||||||
os.chdir("..")
|
os.chdir("..")
|
||||||
for arch in archs:
|
|
||||||
for tgt in support_targets + ["libinit-ld.so"]:
|
for arch in build_abis.keys():
|
||||||
source = Path("native", "libs", arch, tgt)
|
arch_dir = Path("native", "libs", arch)
|
||||||
target = Path("native", "out", arch, tgt)
|
out_dir = Path("native", "out", arch)
|
||||||
|
for source in arch_dir.iterdir():
|
||||||
|
target = out_dir / source.name
|
||||||
mv(source, target)
|
mv(source, target)
|
||||||
|
|
||||||
|
|
||||||
|
def build_cpp_src(targets: set):
|
||||||
|
dump_flag_header()
|
||||||
|
|
||||||
|
cmds = []
|
||||||
|
clean = False
|
||||||
|
|
||||||
|
if "magisk" in targets:
|
||||||
|
cmds.append("B_MAGISK=1")
|
||||||
|
clean = True
|
||||||
|
|
||||||
|
if "magiskpolicy" in targets:
|
||||||
|
cmds.append("B_POLICY=1")
|
||||||
|
clean = True
|
||||||
|
|
||||||
|
if "magiskinit" in targets:
|
||||||
|
cmds.append("B_PRELOAD=1")
|
||||||
|
|
||||||
|
if "resetprop" in targets:
|
||||||
|
cmds.append("B_PROP=1")
|
||||||
|
|
||||||
|
if cmds:
|
||||||
|
run_ndk_build(cmds)
|
||||||
|
|
||||||
|
cmds.clear()
|
||||||
|
|
||||||
|
if "magiskinit" in targets:
|
||||||
|
cmds.append("B_INIT=1")
|
||||||
|
|
||||||
|
if "magiskboot" in targets:
|
||||||
|
cmds.append("B_BOOT=1")
|
||||||
|
|
||||||
|
if cmds:
|
||||||
|
cmds.append("B_CRT0=1")
|
||||||
|
run_ndk_build(cmds)
|
||||||
|
|
||||||
|
if clean:
|
||||||
|
clean_elf()
|
||||||
|
|
||||||
|
|
||||||
def run_cargo(cmds):
|
def run_cargo(cmds):
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
env["PATH"] = f'{rust_bin}{os.pathsep}{env["PATH"]}'
|
env["PATH"] = f'{rust_bin}{os.pathsep}{env["PATH"]}'
|
||||||
env["CARGO_BUILD_RUSTC"] = str(rust_bin / f"rustc{EXE_EXT}")
|
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)
|
return execv([cargo, *cmds], env)
|
||||||
|
|
||||||
|
|
||||||
def run_cargo_build(args):
|
def build_rust_src(targets: set):
|
||||||
native_out = Path("..", "out")
|
targets = targets.copy()
|
||||||
native_out.mkdir(mode=0o755, exist_ok=True)
|
if "resetprop" in targets:
|
||||||
|
|
||||||
targets = set(args.target) & set(rust_targets)
|
|
||||||
if "resetprop" in args.target:
|
|
||||||
targets.add("magisk")
|
targets.add("magisk")
|
||||||
|
targets = targets & rust_targets
|
||||||
if len(targets) == 0:
|
if not targets:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Start building the actual build commands
|
os.chdir(Path("native", "src"))
|
||||||
|
|
||||||
|
# Start building the build commands
|
||||||
cmds = ["build", "-p", ""]
|
cmds = ["build", "-p", ""]
|
||||||
rust_out = "debug"
|
|
||||||
if args.release:
|
if args.release:
|
||||||
cmds.append("-r")
|
cmds.append("-r")
|
||||||
rust_out = "release"
|
profile = "release"
|
||||||
|
else:
|
||||||
|
profile = "debug"
|
||||||
if args.verbose == 0:
|
if args.verbose == 0:
|
||||||
cmds.append("-q")
|
cmds.append("-q")
|
||||||
elif args.verbose > 1:
|
elif args.verbose > 1:
|
||||||
cmds.append("--verbose")
|
cmds.append("--verbose")
|
||||||
|
|
||||||
|
for triple in build_abis.values():
|
||||||
cmds.append("--target")
|
cmds.append("--target")
|
||||||
cmds.append("")
|
cmds.append(triple)
|
||||||
|
|
||||||
for arch, triple in zip(archs, triples):
|
for tgt in targets:
|
||||||
rust_triple = (
|
cmds[2] = tgt
|
||||||
"thumbv7neon-linux-androideabi" if triple.startswith("armv7") else triple
|
|
||||||
)
|
|
||||||
cmds[-1] = rust_triple
|
|
||||||
|
|
||||||
for target in targets:
|
|
||||||
cmds[2] = target
|
|
||||||
proc = run_cargo(cmds)
|
proc = run_cargo(cmds)
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
error("Build binary failed!")
|
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 = native_out / arch
|
||||||
arch_out.mkdir(mode=0o755, exist_ok=True)
|
arch_out.mkdir(mode=0o755, exist_ok=True)
|
||||||
for tgt in targets:
|
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"
|
target = arch_out / f"lib{tgt}-rs.a"
|
||||||
mv(source, target)
|
mv(source, target)
|
||||||
|
|
||||||
|
|
||||||
def run_cargo_cmd(args):
|
|
||||||
global STDOUT
|
|
||||||
STDOUT = None
|
|
||||||
if len(args.commands) >= 1 and args.commands[0] == "--":
|
|
||||||
args.commands = args.commands[1:]
|
|
||||||
os.chdir(Path("native", "src"))
|
|
||||||
run_cargo(args.commands)
|
|
||||||
os.chdir(Path("..", ".."))
|
|
||||||
|
|
||||||
|
|
||||||
def write_if_diff(file_name: Path, text: str):
|
def write_if_diff(file_name: Path, text: str):
|
||||||
do_write = True
|
do_write = True
|
||||||
if file_name.exists():
|
if file_name.exists():
|
||||||
@@ -324,25 +320,6 @@ def write_if_diff(file_name: Path, text: str):
|
|||||||
f.write(text)
|
f.write(text)
|
||||||
|
|
||||||
|
|
||||||
def binary_dump(src, var_name, compressor=xz):
|
|
||||||
out_str = f"constexpr unsigned char {var_name}[] = {{"
|
|
||||||
for i, c in enumerate(compressor(src.read())):
|
|
||||||
if i % 16 == 0:
|
|
||||||
out_str += "\n"
|
|
||||||
out_str += f"0x{c:02X},"
|
|
||||||
out_str += "\n};\n"
|
|
||||||
return out_str
|
|
||||||
|
|
||||||
|
|
||||||
def dump_bin_header(args):
|
|
||||||
native_gen_path.mkdir(mode=0o755, parents=True, exist_ok=True)
|
|
||||||
for arch in archs:
|
|
||||||
preload = Path("native", "out", arch, "libinit-ld.so")
|
|
||||||
with open(preload, "rb") as src:
|
|
||||||
text = binary_dump(src, "init_ld_xz")
|
|
||||||
write_if_diff(Path(native_gen_path, f"{arch}_binaries.h"), text)
|
|
||||||
|
|
||||||
|
|
||||||
def dump_flag_header():
|
def dump_flag_header():
|
||||||
flag_txt = textwrap.dedent(
|
flag_txt = textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@@ -361,7 +338,7 @@ def dump_flag_header():
|
|||||||
write_if_diff(Path(native_gen_path, "flags.h"), flag_txt)
|
write_if_diff(Path(native_gen_path, "flags.h"), flag_txt)
|
||||||
|
|
||||||
|
|
||||||
def build_binary(args):
|
def build_native():
|
||||||
# Verify NDK install
|
# Verify NDK install
|
||||||
try:
|
try:
|
||||||
with open(Path(ndk_path, "ONDK_VERSION"), "r") as ondk_ver:
|
with open(Path(ndk_path, "ONDK_VERSION"), "r") as ondk_ver:
|
||||||
@@ -369,65 +346,29 @@ def build_binary(args):
|
|||||||
except:
|
except:
|
||||||
error('Unmatched NDK. Please install/upgrade NDK with "build.py ndk"')
|
error('Unmatched NDK. Please install/upgrade NDK with "build.py ndk"')
|
||||||
|
|
||||||
if "target" not in vars(args):
|
if "targets" not in vars(args) or not args.targets:
|
||||||
vars(args)["target"] = []
|
targets = default_targets
|
||||||
|
|
||||||
if args.target:
|
|
||||||
args.target = set(args.target) & set(support_targets)
|
|
||||||
if not args.target:
|
|
||||||
return
|
|
||||||
else:
|
else:
|
||||||
args.target = default_targets
|
targets = set(args.targets) & support_targets
|
||||||
|
if not targets:
|
||||||
|
return
|
||||||
|
|
||||||
header("* Building binaries: " + " ".join(args.target))
|
header("* Building: " + " ".join(targets))
|
||||||
|
|
||||||
os.chdir(Path("native", "src"))
|
if sccache := shutil.which("sccache"):
|
||||||
run_cargo_build(args)
|
os.environ["RUSTC_WRAPPER"] = sccache
|
||||||
os.chdir(Path("..", ".."))
|
os.environ["NDK_CCACHE"] = sccache
|
||||||
|
os.environ["CARGO_INCREMENTAL"] = "0"
|
||||||
|
if ccache := shutil.which("ccache"):
|
||||||
|
os.environ["NDK_CCACHE"] = ccache
|
||||||
|
|
||||||
dump_flag_header()
|
build_rust_src(targets)
|
||||||
|
build_cpp_src(targets)
|
||||||
|
|
||||||
flag = ""
|
|
||||||
clean = False
|
|
||||||
|
|
||||||
if "magisk" in args.target:
|
############
|
||||||
flag += " B_MAGISK=1"
|
# Build App
|
||||||
clean = True
|
############
|
||||||
|
|
||||||
if "magiskpolicy" in args.target:
|
|
||||||
flag += " B_POLICY=1"
|
|
||||||
clean = True
|
|
||||||
|
|
||||||
if "magiskinit" in args.target:
|
|
||||||
flag += " B_PRELOAD=1"
|
|
||||||
|
|
||||||
if "resetprop" in args.target:
|
|
||||||
flag += " B_PROP=1"
|
|
||||||
|
|
||||||
if flag:
|
|
||||||
run_ndk_build(args, flag)
|
|
||||||
|
|
||||||
flag = ""
|
|
||||||
|
|
||||||
if "magiskinit" in args.target:
|
|
||||||
# magiskinit embeds preload.so
|
|
||||||
dump_bin_header(args)
|
|
||||||
flag += " B_INIT=1"
|
|
||||||
|
|
||||||
if "magiskboot" in args.target:
|
|
||||||
flag += " B_BOOT=1"
|
|
||||||
|
|
||||||
if flag:
|
|
||||||
flag += " B_CRT0=1"
|
|
||||||
run_ndk_build(args, flag)
|
|
||||||
|
|
||||||
if clean:
|
|
||||||
clean_elf()
|
|
||||||
|
|
||||||
# BusyBox is built with different API level
|
|
||||||
|
|
||||||
if "busybox" in args.target:
|
|
||||||
run_ndk_build(args, "B_BB=1")
|
|
||||||
|
|
||||||
|
|
||||||
def find_jdk():
|
def find_jdk():
|
||||||
@@ -462,7 +403,7 @@ def find_jdk():
|
|||||||
return env
|
return env
|
||||||
|
|
||||||
|
|
||||||
def build_apk(args, module):
|
def build_apk(module: str):
|
||||||
env = find_jdk()
|
env = find_jdk()
|
||||||
|
|
||||||
build_type = "Release" if args.release else "Debug"
|
build_type = "Release" if args.release else "Debug"
|
||||||
@@ -488,9 +429,9 @@ def build_apk(args, module):
|
|||||||
header(f"Output: {target}")
|
header(f"Output: {target}")
|
||||||
|
|
||||||
|
|
||||||
def build_app(args):
|
def build_app():
|
||||||
header("* Building the Magisk app")
|
header("* Building the Magisk app")
|
||||||
build_apk(args, ":app:apk")
|
build_apk(":app:apk")
|
||||||
|
|
||||||
build_type = "release" if args.release else "debug"
|
build_type = "release" if args.release else "debug"
|
||||||
|
|
||||||
@@ -506,28 +447,32 @@ def build_app(args):
|
|||||||
cp(source, target)
|
cp(source, target)
|
||||||
|
|
||||||
|
|
||||||
def build_stub(args):
|
def build_stub():
|
||||||
header("* Building the stub app")
|
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
|
||||||
if args.target:
|
################
|
||||||
args.target = set(args.target) & support_targets
|
|
||||||
if "native" in args.target:
|
|
||||||
args.target.add("cpp")
|
def cleanup():
|
||||||
args.target.add("rust")
|
support_targets = {"native", "cpp", "rust", "app"}
|
||||||
|
if args.targets:
|
||||||
|
targets = set(args.targets) & support_targets
|
||||||
|
if "native" in targets:
|
||||||
|
targets.add("cpp")
|
||||||
|
targets.add("rust")
|
||||||
else:
|
else:
|
||||||
args.target = support_targets
|
targets = support_targets
|
||||||
|
|
||||||
if "cpp" in args.target:
|
if "cpp" in targets:
|
||||||
header("* Cleaning C++")
|
header("* Cleaning C++")
|
||||||
rm_rf(Path("native", "libs"))
|
rm_rf(Path("native", "libs"))
|
||||||
rm_rf(Path("native", "obj"))
|
rm_rf(Path("native", "obj"))
|
||||||
rm_rf(Path("native", "out"))
|
|
||||||
|
|
||||||
if "rust" in args.target:
|
if "rust" in targets:
|
||||||
header("* Cleaning Rust")
|
header("* Cleaning Rust")
|
||||||
rm_rf(Path("native", "src", "target"))
|
rm_rf(Path("native", "src", "target"))
|
||||||
rm(Path("native", "src", "boot", "proto", "mod.rs"))
|
rm(Path("native", "src", "boot", "proto", "mod.rs"))
|
||||||
@@ -535,21 +480,34 @@ def cleanup(args):
|
|||||||
for rs_gen in glob.glob("native/**/*-rs.*pp", recursive=True):
|
for rs_gen in glob.glob("native/**/*-rs.*pp", recursive=True):
|
||||||
rm(rs_gen)
|
rm(rs_gen)
|
||||||
|
|
||||||
if "java" in args.target:
|
if "native" in targets:
|
||||||
header("* Cleaning java")
|
rm_rf(Path("native", "out"))
|
||||||
execv(
|
|
||||||
[
|
if "app" in targets:
|
||||||
gradlew,
|
header("* Cleaning app")
|
||||||
":app:apk:clean",
|
execv([gradlew, ":app:clean"], env=find_jdk())
|
||||||
":app:core:clean",
|
|
||||||
":app:shared:clean",
|
|
||||||
":app:stub: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"]
|
ndk_ver = config["ondkVersion"]
|
||||||
url = f"https://github.com/topjohnwu/ondk/releases/download/{ndk_ver}/ondk-{ndk_ver}-{os_name}.tar.xz"
|
url = f"https://github.com/topjohnwu/ondk/releases/download/{ndk_ver}/ondk-{ndk_ver}-{os_name}.tar.xz"
|
||||||
ndk_archive = url.split("/")[-1]
|
ndk_archive = url.split("/")[-1]
|
||||||
@@ -568,7 +526,7 @@ def setup_ndk(args):
|
|||||||
mv(ondk_path, ndk_path)
|
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"])
|
abi = cmd_out([adb_path, "shell", "getprop", "ro.product.cpu.abi"])
|
||||||
if not abi:
|
if not abi:
|
||||||
error("Cannot detect emulator ABI")
|
error("Cannot detect emulator ABI")
|
||||||
@@ -596,37 +554,37 @@ def push_files(args, script):
|
|||||||
error("adb push failed!")
|
error("adb push failed!")
|
||||||
|
|
||||||
|
|
||||||
def setup_avd(args):
|
def setup_avd():
|
||||||
if not args.skip:
|
if not args.skip:
|
||||||
build_all(args)
|
build_all()
|
||||||
|
|
||||||
header("* Setting up emulator")
|
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"])
|
proc = execv([adb_path, "shell", "sh", "/data/local/tmp/avd_magisk.sh"])
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
error("avd_magisk.sh failed!")
|
error("avd_magisk.sh failed!")
|
||||||
|
|
||||||
|
|
||||||
def patch_avd_file(args):
|
def patch_avd_file():
|
||||||
if not args.skip:
|
if not args.skip:
|
||||||
args.release = False
|
build_all()
|
||||||
build_all(args)
|
|
||||||
|
|
||||||
args.target = Path(args.target)
|
input = Path(args.image)
|
||||||
src_file = f"/data/local/tmp/{args.target.name}"
|
|
||||||
out_file = f"{src_file}.magisk"
|
|
||||||
if args.output:
|
if args.output:
|
||||||
args.output = Path(args.output)
|
output = Path(args.output)
|
||||||
else:
|
else:
|
||||||
args.output = args.target.parent / f"{args.target.name}.magisk"
|
output = input.parent / f"{input.name}.magisk"
|
||||||
|
|
||||||
header(f"* Patching {args.target.name}")
|
src_file = f"/data/local/tmp/{input.name}"
|
||||||
|
out_file = f"{src_file}.magisk"
|
||||||
|
|
||||||
push_files(args, Path("scripts", "avd_patch.sh"))
|
header(f"* Patching {input.name}")
|
||||||
|
|
||||||
proc = execv([adb_path, "push", args.target, "/data/local/tmp"])
|
push_files(Path("scripts", "avd_patch.sh"))
|
||||||
|
|
||||||
|
proc = execv([adb_path, "push", input, "/data/local/tmp"])
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
error("adb push failed!")
|
error("adb push failed!")
|
||||||
|
|
||||||
@@ -634,19 +592,14 @@ def patch_avd_file(args):
|
|||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
error("avd_patch.sh failed!")
|
error("avd_patch.sh failed!")
|
||||||
|
|
||||||
proc = execv([adb_path, "pull", out_file, args.output])
|
proc = execv([adb_path, "pull", out_file, output])
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
error("adb pull failed!")
|
error("adb pull failed!")
|
||||||
|
|
||||||
header(f"Output: {args.output}")
|
header(f"Output: {output}")
|
||||||
|
|
||||||
|
|
||||||
def build_all(args):
|
def setup_rustup():
|
||||||
build_binary(args)
|
|
||||||
build_app(args)
|
|
||||||
|
|
||||||
|
|
||||||
def setup_rustup(args):
|
|
||||||
wrapper_dir = Path(args.wrapper_dir)
|
wrapper_dir = Path(args.wrapper_dir)
|
||||||
rm_rf(wrapper_dir)
|
rm_rf(wrapper_dir)
|
||||||
wrapper_dir.mkdir(mode=0o755, parents=True, exist_ok=True)
|
wrapper_dir.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||||
@@ -662,10 +615,10 @@ def setup_rustup(args):
|
|||||||
# Build rustup_wrapper
|
# Build rustup_wrapper
|
||||||
wrapper_src = Path("tools", "rustup_wrapper")
|
wrapper_src = Path("tools", "rustup_wrapper")
|
||||||
cargo_toml = wrapper_src / "Cargo.toml"
|
cargo_toml = wrapper_src / "Cargo.toml"
|
||||||
execv(
|
cmds = ["build", "--release", f"--manifest-path={cargo_toml}"]
|
||||||
[cargo, "build", "--release", f"--manifest-path={cargo_toml}"]
|
if args.verbose > 1:
|
||||||
+ (["--verbose"] if args.verbose > 1 else [])
|
cmds.append("--verbose")
|
||||||
)
|
run_cargo(cmds)
|
||||||
|
|
||||||
# Replace rustup with wrapper
|
# Replace rustup with wrapper
|
||||||
wrapper = wrapper_dir / (f"rustup{EXE_EXT}")
|
wrapper = wrapper_dir / (f"rustup{EXE_EXT}")
|
||||||
@@ -674,77 +627,149 @@ def setup_rustup(args):
|
|||||||
wrapper.chmod(0o755)
|
wrapper.chmod(0o755)
|
||||||
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Magisk build script")
|
##################
|
||||||
parser.set_defaults(func=lambda x: None)
|
# Config and args
|
||||||
parser.add_argument(
|
##################
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
def load_config():
|
||||||
|
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)
|
||||||
|
|
||||||
|
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"}
|
||||||
|
|
||||||
|
triples = map(support_abis.get, archs)
|
||||||
|
|
||||||
|
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"
|
"-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(
|
||||||
parser.add_argument(
|
"-v", "--verbose", action="count", default=0, help="verbose output"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
"-c",
|
"-c",
|
||||||
"--config",
|
"--config",
|
||||||
default="config.prop",
|
default="config.prop",
|
||||||
help="custom config file (default: config.prop)",
|
help="custom config file (default: config.prop)",
|
||||||
)
|
)
|
||||||
subparsers = parser.add_subparsers(title="actions")
|
subparsers = parser.add_subparsers(title="actions")
|
||||||
|
|
||||||
all_parser = subparsers.add_parser("all", help="build everything")
|
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")
|
native_parser = subparsers.add_parser("native", help="build native binaries")
|
||||||
binary_parser.add_argument(
|
native_parser.add_argument(
|
||||||
"target",
|
"targets",
|
||||||
nargs="*",
|
nargs="*",
|
||||||
help=f"{', '.join(support_targets)}, \
|
help=f"{', '.join(support_targets)}, \
|
||||||
or empty for defaults ({', '.join(default_targets)})",
|
or empty for defaults ({', '.join(default_targets)})",
|
||||||
)
|
)
|
||||||
binary_parser.set_defaults(func=build_binary)
|
|
||||||
|
|
||||||
cargo_parser = subparsers.add_parser("cargo", help="run cargo with proper environment")
|
app_parser = subparsers.add_parser("app", help="build the Magisk app")
|
||||||
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")
|
stub_parser = subparsers.add_parser("stub", help="build the stub app")
|
||||||
rustup_parser.add_argument("wrapper_dir", help="path to setup rustup wrapper binaries")
|
|
||||||
rustup_parser.set_defaults(func=setup_rustup)
|
|
||||||
|
|
||||||
app_parser = subparsers.add_parser("app", help="build the Magisk app")
|
clean_parser = subparsers.add_parser("clean", help="cleanup")
|
||||||
app_parser.set_defaults(func=build_app)
|
clean_parser.add_argument(
|
||||||
|
"targets", nargs="*", help="native, cpp, rust, java, or empty to clean all"
|
||||||
|
)
|
||||||
|
|
||||||
stub_parser = subparsers.add_parser("stub", help="build the stub app")
|
ndk_parser = subparsers.add_parser("ndk", help="setup Magisk NDK")
|
||||||
stub_parser.set_defaults(func=build_stub)
|
|
||||||
|
|
||||||
avd_parser = subparsers.add_parser("emulator", help="setup AVD for development")
|
emu_parser = subparsers.add_parser("emulator", help="setup AVD for development")
|
||||||
avd_parser.add_argument(
|
emu_parser.add_argument(
|
||||||
"-s", "--skip", action="store_true", help="skip building binaries and the app"
|
"-s", "--skip", action="store_true", help="skip building binaries and the app"
|
||||||
)
|
)
|
||||||
avd_parser.set_defaults(func=setup_avd)
|
|
||||||
|
|
||||||
avd_patch_parser = subparsers.add_parser(
|
avd_patch_parser = subparsers.add_parser(
|
||||||
"avd_patch", help="patch AVD ramdisk.img or init_boot.img"
|
"avd_patch", help="patch AVD ramdisk.img or init_boot.img"
|
||||||
)
|
)
|
||||||
avd_patch_parser.add_argument("target", help="path to ramdisk.img or init_boot.img")
|
avd_patch_parser.add_argument("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("output", help="optional output file name", nargs="?")
|
||||||
avd_patch_parser.add_argument(
|
avd_patch_parser.add_argument(
|
||||||
"-s", "--skip", action="store_true", help="skip building binaries and the app"
|
"-s", "--skip", action="store_true", help="skip building binaries and the app"
|
||||||
)
|
)
|
||||||
avd_patch_parser.set_defaults(func=patch_avd_file)
|
|
||||||
|
|
||||||
clean_parser = subparsers.add_parser("clean", help="cleanup")
|
cargo_parser = subparsers.add_parser(
|
||||||
clean_parser.add_argument(
|
"cargo", help="call 'cargo' commands against the project"
|
||||||
"target", nargs="*", help="native, cpp, rust, java, or empty to clean all"
|
)
|
||||||
)
|
cargo_parser.add_argument("commands", nargs=argparse.REMAINDER)
|
||||||
clean_parser.set_defaults(func=cleanup)
|
|
||||||
|
|
||||||
ndk_parser = subparsers.add_parser("ndk", help="setup Magisk NDK")
|
rustup_parser = subparsers.add_parser("rustup", help="setup rustup wrapper")
|
||||||
ndk_parser.set_defaults(func=setup_ndk)
|
rustup_parser.add_argument(
|
||||||
|
"wrapper_dir", help="path to setup rustup wrapper binaries"
|
||||||
|
)
|
||||||
|
|
||||||
if len(sys.argv) == 1:
|
# 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()
|
parser.print_help()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
args = parser.parse_args()
|
return parser.parse_args()
|
||||||
load_config(args)
|
|
||||||
|
|
||||||
# Call corresponding functions
|
|
||||||
args.func(args)
|
args = parse_args()
|
||||||
|
load_config()
|
||||||
|
vars(args)["force_out"] = False
|
||||||
|
args.func()
|
||||||
|
@@ -25,10 +25,10 @@ tasks.withType<KotlinCompile>().configureEach {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("gradle-plugin", "2.0.0"))
|
implementation(kotlin("gradle-plugin", libs.versions.kotlin.get()))
|
||||||
implementation("com.android.tools.build:gradle:8.5.1")
|
implementation(libs.android.gradle.plugin)
|
||||||
implementation("com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:2.0.0-1.0.23")
|
implementation(libs.ksp.plugin)
|
||||||
implementation("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.7")
|
implementation(libs.navigation.safe.args.plugin)
|
||||||
implementation("org.lsposed.lsparanoid:gradle-plugin:0.5.2")
|
implementation(libs.lsparanoid.plugin)
|
||||||
implementation("org.eclipse.jgit:org.eclipse.jgit:6.10.0.202406032230-r")
|
implementation(libs.jgit)
|
||||||
}
|
}
|
||||||
|
7
buildSrc/settings.gradle.kts
Normal file
7
buildSrc/settings.gradle.kts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
dependencyResolutionManagement {
|
||||||
|
versionCatalogs {
|
||||||
|
create("libs") {
|
||||||
|
from(files("../gradle/libs.versions.toml"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -8,6 +8,8 @@ import java.util.Properties
|
|||||||
|
|
||||||
private val props = Properties()
|
private val props = Properties()
|
||||||
private var commitHash = ""
|
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 {
|
object Config {
|
||||||
operator fun get(key: String): String? {
|
operator fun get(key: String): String? {
|
||||||
@@ -20,6 +22,10 @@ object Config {
|
|||||||
val version: String get() = get("version") ?: commitHash
|
val version: String get() = get("version") ?: commitHash
|
||||||
val versionCode: Int get() = get("magisk.versionCode")!!.toInt()
|
val versionCode: Int get() = get("magisk.versionCode")!!.toInt()
|
||||||
val stubVersion: String get() = get("magisk.stubVersion")!!
|
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> {
|
class MagiskPlugin : Plugin<Project> {
|
||||||
|
@@ -69,18 +69,18 @@ private val Project.androidComponents
|
|||||||
|
|
||||||
fun Project.setupCommon() {
|
fun Project.setupCommon() {
|
||||||
androidBase {
|
androidBase {
|
||||||
compileSdkVersion(34)
|
compileSdkVersion(35)
|
||||||
buildToolsVersion = "34.0.0"
|
buildToolsVersion = "34.0.0"
|
||||||
ndkPath = "$sdkDirectory/ndk/magisk"
|
ndkPath = "$sdkDirectory/ndk/magisk"
|
||||||
ndkVersion = "27.0.11902837"
|
ndkVersion = "27.0.12077973"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk = 23
|
minSdk = 23
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
sourceCompatibility = JavaVersion.VERSION_21
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_21
|
||||||
}
|
}
|
||||||
|
|
||||||
packagingOptions {
|
packagingOptions {
|
||||||
@@ -108,31 +108,33 @@ fun Project.setupCommon() {
|
|||||||
|
|
||||||
tasks.withType<KotlinCompile> {
|
tasks.withType<KotlinCompile> {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
jvmTarget = JvmTarget.JVM_17
|
jvmTarget = JvmTarget.JVM_21
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const val BUSYBOX_DOWNLOAD_URL =
|
const val BUSYBOX_DOWNLOAD_URL =
|
||||||
"https://github.com/topjohnwu/magisk-files/releases/download/files/busybox-1.36.1.0.zip"
|
"https://github.com/topjohnwu/magisk-files/releases/download/files/busybox-1.36.1.1.zip"
|
||||||
const val BUSYBOX_ZIP_CHECKSUM =
|
const val BUSYBOX_ZIP_CHECKSUM =
|
||||||
"ea4f3019b0087dcb68130b32ab59dc2db0ee0af11d8396124a94c4231c5ea441"
|
"b4d0551feabaf314e53c79316c980e8f66432e9fb91a69dbbf10a93564b40951"
|
||||||
|
|
||||||
fun Project.setupCoreLib() {
|
fun Project.setupCoreLib() {
|
||||||
setupCommon()
|
setupCommon()
|
||||||
|
|
||||||
|
val abiList = Config.abiList
|
||||||
|
|
||||||
val syncLibs by tasks.registering(Sync::class) {
|
val syncLibs by tasks.registering(Sync::class) {
|
||||||
into("src/main/jniLibs")
|
into("src/main/jniLibs")
|
||||||
for (abi in arrayOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64", "riscv64")) {
|
for (abi in abiList) {
|
||||||
into(abi) {
|
into(abi) {
|
||||||
from(rootProject.file("native/out/$abi")) {
|
from(rootProject.file("native/out/$abi")) {
|
||||||
include("magiskboot", "magiskinit", "magiskpolicy", "magisk")
|
include("magiskboot", "magiskinit", "magiskpolicy", "magisk", "libinit-ld.so")
|
||||||
rename { "lib$it.so" }
|
rename { if (it.endsWith(".so")) it else "lib$it.so" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onlyIf {
|
onlyIf {
|
||||||
if (inputs.sourceFiles.files.size != 20)
|
if (inputs.sourceFiles.files.size != abiList.size * 5)
|
||||||
throw StopExecutionException("Please build binaries first! (./build.py binary)")
|
throw StopExecutionException("Please build binaries first! (./build.py binary)")
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@@ -158,6 +160,7 @@ fun Project.setupCoreLib() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
from(zipTree(bb))
|
from(zipTree(bb))
|
||||||
|
include(abiList.map { "$it/libbusybox.so" })
|
||||||
into("src/main/jniLibs")
|
into("src/main/jniLibs")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,7 +296,7 @@ fun Project.setupAppCommon() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
targetSdk = 34
|
targetSdk = 35
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
@@ -372,8 +375,8 @@ fun Project.setupStub() {
|
|||||||
val outAppClassDir = layout.buildDirectory.file("generated/source/app/${variantLowered}").get().asFile
|
val outAppClassDir = layout.buildDirectory.file("generated/source/app/${variantLowered}").get().asFile
|
||||||
val outResDir = layout.buildDirectory.dir("generated/source/res/${variantLowered}").get().asFile
|
val outResDir = layout.buildDirectory.dir("generated/source/res/${variantLowered}").get().asFile
|
||||||
val aapt = File(androidApp.sdkDirectory, "build-tools/${androidApp.buildToolsVersion}/aapt2")
|
val aapt = File(androidApp.sdkDirectory, "build-tools/${androidApp.buildToolsVersion}/aapt2")
|
||||||
val apk = layout.buildDirectory.file("intermediates/processed_res/" +
|
val apk = layout.buildDirectory.file("intermediates/linked_resources_binary_format/" +
|
||||||
"${variantLowered}/process${variantCapped}Resources/out/resources-${variantLowered}.ap_").get().asFile
|
"${variantLowered}/process${variantCapped}Resources/linked-resources-binary-format-${variantLowered}.ap_").get().asFile
|
||||||
|
|
||||||
val genManifestTask = tasks.register("generate${variantCapped}ObfuscatedClass") {
|
val genManifestTask = tasks.register("generate${variantCapped}ObfuscatedClass") {
|
||||||
inputs.property("seed", RAND_SEED)
|
inputs.property("seed", RAND_SEED)
|
||||||
@@ -414,8 +417,8 @@ fun Project.setupStub() {
|
|||||||
registerJavaGeneratingTask(processResourcesTask, outResDir)
|
registerJavaGeneratingTask(processResourcesTask, outResDir)
|
||||||
}
|
}
|
||||||
// Override optimizeReleaseResources task
|
// Override optimizeReleaseResources task
|
||||||
val apk = layout.buildDirectory.file("intermediates/processed_res/" +
|
val apk = layout.buildDirectory.file("intermediates/linked_resources_binary_format/" +
|
||||||
"release/processReleaseResources/out/resources-release.ap_").get().asFile
|
"release/processReleaseResources/linked-resources-binary-format-release.ap_").get().asFile
|
||||||
val optRes = layout.buildDirectory.file("intermediates/optimized_processed_res/" +
|
val optRes = layout.buildDirectory.file("intermediates/optimized_processed_res/" +
|
||||||
"release/optimizeReleaseResources/resources-release-optimize.ap_").get().asFile
|
"release/optimizeReleaseResources/resources-release-optimize.ap_").get().asFile
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
|
@@ -9,6 +9,10 @@ version=string
|
|||||||
# Output path. Default: out
|
# Output path. Default: out
|
||||||
outdir=string
|
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
|
# Signing configs for signing zips and APKs
|
||||||
# These 4 variables has to be either all set or not
|
# These 4 variables has to be either all set or not
|
||||||
|
@@ -1,5 +1,29 @@
|
|||||||
# Magisk Changelog
|
# Magisk Changelog
|
||||||
|
|
||||||
|
### v28.0
|
||||||
|
|
||||||
|
- [General] Support 16k page size
|
||||||
|
- [General] Add basic support for RISC-V (not built in releases)
|
||||||
|
- [General] Use a minimal libc to build static executables (`magiskinit` and `magiskboot`) for smaller sizes
|
||||||
|
- [Core] Remove unnecessary mirror for magic mount
|
||||||
|
- [Core] Update boot image detection logic to support more devices
|
||||||
|
- [MagiskInit] Rewrite 2SI logic for injecting `magiskinit` as `init`
|
||||||
|
- [MagiskInit] Update preinit partition detection
|
||||||
|
- [Zygisk] Update internal JNI hooking implementation
|
||||||
|
- [MagiskPolicy] Preserve sepolicy config flag after patching
|
||||||
|
- [MagiskPolicy] Optimize patching rules to reduce the amount of new rules being injected
|
||||||
|
- [DenyList] Support enforcing denylist when Zygisk is disabled
|
||||||
|
- [Resetprop] Improve implementation to workaround several property modification detections
|
||||||
|
- [Resetprop] Update to properly work with property overlays
|
||||||
|
- [App] Major internal code refactoring
|
||||||
|
- [App] Support patching Samsung firmware with images larger than 8GiB
|
||||||
|
- [App] Use user-initiated job instead of foreground services on Android 14
|
||||||
|
- [App] Support Android 13+ built-in per-app language preferences
|
||||||
|
- [App] Add `action.sh` support to allow modules to define an action triggered from UI
|
||||||
|
- [MagiskBoot] Support spliting kernel images without decompression
|
||||||
|
- [MagiskBoot] Properly support vendor boot images
|
||||||
|
- [MagiskBoot] Disable Samsung PROCA from kernel image
|
||||||
|
|
||||||
### v27.0
|
### v27.0
|
||||||
|
|
||||||
- [Zygisk] Introduce new code injection mechanism
|
- [Zygisk] Introduce new code injection mechanism
|
||||||
|
@@ -54,6 +54,7 @@ A Magisk module is a folder placed in `/data/adb/modules` with the structure bel
|
|||||||
│ ├── post-fs-data.sh <--- This script will be executed in post-fs-data
|
│ ├── post-fs-data.sh <--- This script will be executed in post-fs-data
|
||||||
│ ├── service.sh <--- This script will be executed in late_start service
|
│ ├── service.sh <--- This script will be executed in late_start service
|
||||||
| ├── uninstall.sh <--- This script will be executed when Magisk removes your module
|
| ├── uninstall.sh <--- This script will be executed when Magisk removes your module
|
||||||
|
| ├── action.sh <--- This script will be executed when user click the action button in Magisk app
|
||||||
│ ├── system.prop <--- Properties in this file will be loaded as system properties by resetprop
|
│ ├── system.prop <--- Properties in this file will be loaded as system properties by resetprop
|
||||||
│ ├── sepolicy.rule <--- Additional custom sepolicy rules
|
│ ├── sepolicy.rule <--- Additional custom sepolicy rules
|
||||||
│ │
|
│ │
|
||||||
@@ -231,7 +232,7 @@ The list above will result in the following files being created: `$MODPATH/syste
|
|||||||
In Magisk, you can run boot scripts in 2 different modes: **post-fs-data** and **late_start service** mode.
|
In Magisk, you can run boot scripts in 2 different modes: **post-fs-data** and **late_start service** mode.
|
||||||
|
|
||||||
- post-fs-data mode
|
- post-fs-data mode
|
||||||
- This stage is BLOCKING. The boot process is paused before execution is done, or 10 seconds have passed.
|
- This stage is BLOCKING. The boot process is paused before execution is done, or 40 seconds have passed.
|
||||||
- Scripts run before any modules are mounted. This allows a module developer to dynamically adjust their modules before it gets mounted.
|
- Scripts run before any modules are mounted. This allows a module developer to dynamically adjust their modules before it gets mounted.
|
||||||
- This stage happens before Zygote is started, which pretty much means everything in Android
|
- This stage happens before Zygote is started, which pretty much means everything in Android
|
||||||
- **WARNING:** using `setprop` will deadlock the boot process! Please use `resetprop -n <prop_name> <prop_value>` instead.
|
- **WARNING:** using `setprop` will deadlock the boot process! Please use `resetprop -n <prop_name> <prop_value>` instead.
|
||||||
|
25
docs/releases/28000.md
Normal file
25
docs/releases/28000.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
## 2024.10.10 Magisk v28.0
|
||||||
|
|
||||||
|
- [General] Support 16k page size
|
||||||
|
- [General] Add basic support for RISC-V (not built in releases)
|
||||||
|
- [General] Use a minimal libc to build static executables (`magiskinit` and `magiskboot`) for smaller sizes
|
||||||
|
- [Core] Remove unnecessary mirror for magic mount
|
||||||
|
- [Core] Update boot image detection logic to support more devices
|
||||||
|
- [MagiskInit] Rewrite 2SI logic for injecting `magiskinit` as `init`
|
||||||
|
- [MagiskInit] Update preinit partition detection
|
||||||
|
- [Zygisk] Update internal JNI hooking implementation
|
||||||
|
- [MagiskPolicy] Preserve sepolicy config flag after patching
|
||||||
|
- [MagiskPolicy] Optimize patching rules to reduce the amount of new rules being injected
|
||||||
|
- [DenyList] Support enforcing denylist when Zygisk is disabled
|
||||||
|
- [Resetprop] Improve implementation to workaround several property modification detections
|
||||||
|
- [Resetprop] Update to properly work with property overlays
|
||||||
|
- [App] Major internal code refactoring
|
||||||
|
- [App] Support patching Samsung firmware with images larger than 8GiB
|
||||||
|
- [App] Use user-initiated job instead of foreground services on Android 14
|
||||||
|
- [App] Support Android 13+ built-in per-app language preferences
|
||||||
|
- [App] Add `action.sh` support to allow modules to define an action triggered from UI
|
||||||
|
- [MagiskBoot] Support spliting kernel images without decompression
|
||||||
|
- [MagiskBoot] Properly support vendor boot images
|
||||||
|
- [MagiskBoot] Disable Samsung PROCA from kernel image
|
||||||
|
|
||||||
|
### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)
|
@@ -1,5 +1,6 @@
|
|||||||
# Release Notes
|
# Release Notes
|
||||||
|
|
||||||
|
- [v28.0](28000.md)
|
||||||
- [v27.0](27000.md)
|
- [v27.0](27000.md)
|
||||||
- [v26.4](26400.md)
|
- [v26.4](26400.md)
|
||||||
- [v26.3](26300.md)
|
- [v26.3](26300.md)
|
||||||
|
@@ -41,7 +41,9 @@ Supported actions:
|
|||||||
|
|
||||||
repack [-n] <origbootimg> [outbootimg]
|
repack [-n] <origbootimg> [outbootimg]
|
||||||
Repack boot image components using files from the current directory
|
Repack boot image components using files from the current directory
|
||||||
to [outbootimg], or 'new-boot.img' if not specified.
|
to [outbootimg], or 'new-boot.img' if not specified. Current directory
|
||||||
|
should only contain required files for [outbootimg], or incorrect
|
||||||
|
[outbootimg] may be produced.
|
||||||
<origbootimg> is the original boot image used to unpack the components.
|
<origbootimg> is the original boot image used to unpack the components.
|
||||||
By default, each component will be automatically compressed using its
|
By default, each component will be automatically compressed using its
|
||||||
corresponding format detected in <origbootimg>. If a component file
|
corresponding format detected in <origbootimg>. If a component file
|
||||||
|
@@ -20,6 +20,9 @@ org.gradle.parallel=true
|
|||||||
# Enable build cache
|
# Enable build cache
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
|
|
||||||
|
# Use K2 in kapt
|
||||||
|
kapt.use.k2=true
|
||||||
|
|
||||||
# Android
|
# Android
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.injected.testOnly=false
|
android.injected.testOnly=false
|
||||||
@@ -27,5 +30,5 @@ android.nonFinalResIds=false
|
|||||||
|
|
||||||
# Magisk
|
# Magisk
|
||||||
magisk.stubVersion=40
|
magisk.stubVersion=40
|
||||||
magisk.versionCode=27005
|
magisk.versionCode=28001
|
||||||
magisk.ondkVersion=r27.2
|
magisk.ondkVersion=r27.4
|
||||||
|
66
gradle/libs.versions.toml
Normal file
66
gradle/libs.versions.toml
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
[versions]
|
||||||
|
kotlin = "2.0.20"
|
||||||
|
android = "8.7.0"
|
||||||
|
ksp = "2.0.20-1.0.25"
|
||||||
|
rikka = "1.3.0"
|
||||||
|
navigation = "2.8.2"
|
||||||
|
libsu = "6.0.0"
|
||||||
|
moshi = "1.15.1"
|
||||||
|
okhttp = "4.12.0"
|
||||||
|
retrofit = "2.11.0"
|
||||||
|
room = "2.6.1"
|
||||||
|
|
||||||
|
[libraries]
|
||||||
|
bcpkix = { module = "org.bouncycastle:bcpkix-jdk18on", version = "1.78.1" }
|
||||||
|
commons-compress = { module = "org.apache.commons:commons-compress", version = "1.27.1" }
|
||||||
|
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
|
||||||
|
retrofit-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" }
|
||||||
|
retrofit-scalars = { module = "com.squareup.retrofit2:converter-scalars", version.ref = "retrofit" }
|
||||||
|
markwon-core = { module = "io.noties.markwon:core", version = "4.6.2" }
|
||||||
|
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
||||||
|
okhttp-dnsoverhttps = { module = "com.squareup.okhttp3:okhttp-dnsoverhttps", version.ref = "okhttp" }
|
||||||
|
okhttp-logging = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" }
|
||||||
|
moshi = { module = "com.squareup.moshi:moshi", version.ref = "moshi" }
|
||||||
|
moshi-codegen = { module = "com.squareup.moshi:moshi-kotlin-codegen", version.ref = "moshi" }
|
||||||
|
timber = { module = "com.jakewharton.timber:timber", version = "5.0.1" }
|
||||||
|
jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version = "6.10.0.202406032230-r" }
|
||||||
|
|
||||||
|
# AndroidX
|
||||||
|
activity = { module = "androidx.activity:activity", version = "1.9.2" }
|
||||||
|
appcompat = { module = "androidx.appcompat:appcompat", version = "1.7.0" }
|
||||||
|
core-ktx = { module = "androidx.core:core-ktx", version = "1.13.1" }
|
||||||
|
core-splashscreen = { module = "androidx.core:core-splashscreen", version = "1.0.1" }
|
||||||
|
constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.1.4" }
|
||||||
|
fragment-ktx = { module = "androidx.fragment:fragment-ktx", version = "1.8.4" }
|
||||||
|
navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "navigation" }
|
||||||
|
navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version.ref = "navigation" }
|
||||||
|
profileinstaller = { module = "androidx.profileinstaller:profileinstaller", version = "1.4.1" }
|
||||||
|
recyclerview = { module = "androidx.recyclerview:recyclerview", version = "1.3.2" }
|
||||||
|
room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
|
||||||
|
room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
|
||||||
|
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
|
||||||
|
swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version = "1.1.0" }
|
||||||
|
transition = { module = "androidx.transition:transition", version = "1.5.1" }
|
||||||
|
collection-ktx = { module = "androidx.collection:collection-ktx", version = "1.4.4" }
|
||||||
|
lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version = "2.8.6" }
|
||||||
|
material = { module = "com.google.android.material:material", version = "1.12.0" }
|
||||||
|
jdk-libs = { module = "com.android.tools:desugar_jdk_libs_nio", version = "2.1.2" }
|
||||||
|
|
||||||
|
# topjohnwu
|
||||||
|
indeterminate-checkbox = { module = "com.github.topjohnwu:indeterminate-checkbox", version = "1.0.7" }
|
||||||
|
libsu-core = { module = "com.github.topjohnwu.libsu:core", version.ref = "libsu" }
|
||||||
|
libsu-service = { module = "com.github.topjohnwu.libsu:service", version.ref = "libsu" }
|
||||||
|
libsu-nio = { module = "com.github.topjohnwu.libsu:nio", version.ref = "libsu" }
|
||||||
|
|
||||||
|
# Rikka
|
||||||
|
rikka-recyclerview = { module = "dev.rikka.rikkax.recyclerview:recyclerview-ktx", version = "1.3.2" }
|
||||||
|
rikka-layoutinflater = { module = "dev.rikka.rikkax.layoutinflater:layoutinflater", version.ref = "rikka" }
|
||||||
|
rikka-insets = { module = "dev.rikka.rikkax.insets:insets", version.ref = "rikka" }
|
||||||
|
|
||||||
|
# Build plugins
|
||||||
|
android-gradle-plugin = { module = "com.android.tools.build:gradle", version.ref = "android" }
|
||||||
|
ksp-plugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
|
||||||
|
navigation-safe-args-plugin = { module = "androidx.navigation:navigation-safe-args-gradle-plugin", version.ref = "navigation" }
|
||||||
|
lsparanoid-plugin = { module = "org.lsposed.lsparanoid:gradle-plugin", version = "0.6.0" }
|
||||||
|
|
||||||
|
[plugins]
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
@@ -1,7 +1,10 @@
|
|||||||
[build]
|
[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.
|
# The actual compilation will have the target overriden by command-line.
|
||||||
target = "aarch64-linux-android"
|
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]
|
[unstable]
|
||||||
build-std = ["std", "panic_abort"]
|
build-std = ["std", "panic_abort"]
|
||||||
|
2
native/src/.gitignore
vendored
2
native/src/.gitignore
vendored
@@ -1,2 +0,0 @@
|
|||||||
test.cpp
|
|
||||||
target/
|
|
@@ -1,7 +1,5 @@
|
|||||||
APP_BUILD_SCRIPT := src/Android.mk
|
APP_BUILD_SCRIPT := src/Android.mk
|
||||||
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 riscv64
|
APP_CFLAGS := -Wall -Oz -fomit-frame-pointer
|
||||||
APP_CFLAGS := -Wall -Oz -fomit-frame-pointer -flto
|
|
||||||
APP_LDFLAGS := -flto -Wl,--icf=all
|
|
||||||
APP_CPPFLAGS := -std=c++23
|
APP_CPPFLAGS := -std=c++23
|
||||||
APP_STL := none
|
APP_STL := none
|
||||||
APP_PLATFORM := android-23
|
APP_PLATFORM := android-23
|
||||||
@@ -9,11 +7,25 @@ APP_THIN_ARCHIVE := true
|
|||||||
APP_STRIP_MODE := none
|
APP_STRIP_MODE := none
|
||||||
APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true
|
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
|
ifdef B_CRT0
|
||||||
|
|
||||||
# Disable all security and debugging features
|
# 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
|
# 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
|
endif
|
||||||
|
340
native/src/Cargo.lock
generated
340
native/src/Cargo.lock
generated
@@ -32,9 +32,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.2.0"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base"
|
name = "base"
|
||||||
@@ -66,27 +66,27 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ded684142010808eb980d9974ef794da2bcf97d13396143b1515e9f0fb4a10e"
|
checksum = "17092d478f4fadfb35a7e082f62e49f0907fdf048801d9d706277e34f9df8a78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crypto-common",
|
"crypto-common",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.15.0"
|
version = "1.16.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15"
|
checksum = "102087e286b4677862ea56cf8fc58bb2cdfa8725c40ffb80fe3a008eb7f2fc83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck_derive",
|
"bytemuck_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck_derive"
|
name = "bytemuck_derive"
|
||||||
version = "1.6.0"
|
version = "1.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60"
|
checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -101,9 +101,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.90"
|
version = "1.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
|
checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@@ -123,9 +123,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const-oid"
|
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7e3352a27098ba6b09546e5f13b15165e6a88b5c2723afecb3ea9576b27e3ea"
|
checksum = "9adcf94f05e094fca3005698822ec791cb4433ced416afda1c5ca3b8dfc05a2f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const_format"
|
name = "const_format"
|
||||||
@@ -158,9 +158,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-bigint"
|
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1943d7beadd9ce2b25f3bae73b9e9336fccc1edf38bdec1ed58d3aa183989e11"
|
checksum = "e43027691f1c055da3da4f7d96af09fcec420d435d5616e51f29afd0811c56a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hybrid-array",
|
"hybrid-array",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
@@ -171,9 +171,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-common"
|
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b7aa2ec04f5120b830272a481e8d9d8ba4dda140d2cda59b0f1110d5eb93c38e"
|
checksum = "8c070b79a496dccd931229780ad5bbedd535ceff6c3565605a8e440e18e1aa2b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"hybrid-array",
|
"hybrid-array",
|
||||||
@@ -182,7 +182,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx"
|
name = "cxx"
|
||||||
version = "1.0.115"
|
version = "1.0.124"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cxxbridge-flags",
|
"cxxbridge-flags",
|
||||||
@@ -191,7 +191,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-gen"
|
name = "cxx-gen"
|
||||||
version = "0.7.115"
|
version = "0.7.124"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"codespan-reporting",
|
"codespan-reporting",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -201,11 +201,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-flags"
|
name = "cxxbridge-flags"
|
||||||
version = "1.0.115"
|
version = "1.0.124"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-macro"
|
name = "cxxbridge-macro"
|
||||||
version = "1.0.115"
|
version = "1.0.124"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -214,9 +214,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "der"
|
name = "der"
|
||||||
version = "0.8.0-pre.0"
|
version = "0.8.0-rc.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b489fd2221710c1dd46637d66b984161fb66134f81437a8489800306bcc2ecea"
|
checksum = "05d9c07d3bd80cf0935ce478d07edf7e7a5b158446757f988f3e62082227b700"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"const-oid",
|
"const-oid",
|
||||||
"der_derive",
|
"der_derive",
|
||||||
@@ -227,9 +227,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "der_derive"
|
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd1ee9778ac378876dc78f546d2821fae40a1b69ec8d82f3745392d69ff89ce6"
|
checksum = "2c46c0d3c8dba679a95cc7caf42fe6220338e28c9d7c09e0a458e6f6156c06e7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -238,9 +238,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.11.0-pre.8"
|
version = "0.11.0-pre.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "065d93ead7c220b85d5b4be4795d8398eac4ff68b5ee63895de0a3c1fb6edf25"
|
checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer",
|
"block-buffer",
|
||||||
"const-oid",
|
"const-oid",
|
||||||
@@ -250,9 +250,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ecdsa"
|
name = "ecdsa"
|
||||||
version = "0.17.0-pre.5"
|
version = "0.17.0-pre.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7e045ee5c360512162782f3d4cb07d2f4ce8c4ef9bf7c77ec16d1cf60b3d5ca"
|
checksum = "fad051af2b2d2f356d716138c76775929be913deb5b4ea217cd2613535936bef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"der",
|
"der",
|
||||||
"digest",
|
"digest",
|
||||||
@@ -264,9 +264,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "elliptic-curve"
|
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a1775af172997a40c14854c3a9fde9e03e5772084b334b6a0bb18bf7f93ac16"
|
checksum = "4ed8e96bb573517f42470775f8ef1b9cd7595de52ba7a8e19c48325a92c8fe4f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base16ct",
|
"base16ct",
|
||||||
"crypto-bigint",
|
"crypto-bigint",
|
||||||
@@ -301,15 +301,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flagset"
|
name = "flagset"
|
||||||
version = "0.4.5"
|
version = "0.4.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdeb3aa5e95cf9aabc17f060cfa0ced7b83f042390760ca53bf09df9968acaa1"
|
checksum = "b3ea1ec5f8307826a5b71094dd91fc04d4ae75d5709b20ad351c7fb4815c86ec"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.12"
|
version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
|
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -329,27 +329,27 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hkdf"
|
name = "hkdf"
|
||||||
version = "0.13.0-pre.3"
|
version = "0.13.0-pre.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd5d615ab5c462f96c309b3a00b19f373025a4981312f717f9df5bbd0201530c"
|
checksum = "00176ff81091018d42ff82e8324f8e5adb0b7e0468d1358f653972562dbff031"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hmac",
|
"hmac",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hmac"
|
name = "hmac"
|
||||||
version = "0.13.0-pre.3"
|
version = "0.13.0-pre.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ffd790a0795ee332ed3e8959e5b177beb70d7112eb7d345428ec17427897d5ce"
|
checksum = "e4b1fb14e4df79f9406b434b60acef9f45c26c50062cccf1346c6103b8c47d58"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hybrid-array"
|
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53668f5da5a41d9eaf4bf7064be46d1ebe6a4e1ceed817f387587b18f2b51047"
|
checksum = "4d306b679262030ad8813a82d4915fc04efff97776e4db7f8eb5137039d56400"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
@@ -357,18 +357,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"spin",
|
"spin",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.153"
|
version = "0.2.155"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
@@ -378,9 +378,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.21"
|
version = "0.4.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "magisk"
|
name = "magisk"
|
||||||
@@ -443,9 +443,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.2"
|
version = "2.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "minimal-lexical"
|
||||||
@@ -502,9 +502,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-iter"
|
name = "num-iter"
|
||||||
version = "0.1.44"
|
version = "0.1.45"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9"
|
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
@@ -513,9 +513,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.18"
|
version = "0.2.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"libm",
|
"libm",
|
||||||
@@ -523,8 +523,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "p256"
|
name = "p256"
|
||||||
version = "0.14.0-pre.0"
|
version = "0.14.0-pre.1"
|
||||||
source = "git+https://github.com/RustCrypto/elliptic-curves.git?rev=5d1c252c2defb5808f55329f3e2955ca72d7f8b5#5d1c252c2defb5808f55329f3e2955ca72d7f8b5"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2c32c18a74d9dda1314d2f945fb3e274848822f63f264a9e4d3f783e29b3bc1f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ecdsa",
|
"ecdsa",
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
@@ -534,8 +535,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "p384"
|
name = "p384"
|
||||||
version = "0.14.0-pre"
|
version = "0.14.0-pre.1"
|
||||||
source = "git+https://github.com/RustCrypto/elliptic-curves.git?rev=5d1c252c2defb5808f55329f3e2955ca72d7f8b5#5d1c252c2defb5808f55329f3e2955ca72d7f8b5"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "99acc40dbfad9cc3dc102828f5678c8ca14f0cbf3a1f56f74c2875b5a84427af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ecdsa",
|
"ecdsa",
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
@@ -545,8 +547,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "p521"
|
name = "p521"
|
||||||
version = "0.14.0-pre"
|
version = "0.14.0-pre.1"
|
||||||
source = "git+https://github.com/RustCrypto/elliptic-curves.git?rev=5d1c252c2defb5808f55329f3e2955ca72d7f8b5#5d1c252c2defb5808f55329f3e2955ca72d7f8b5"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ec5d919bea930a34a522bb1c95a89f559925deab255db2c2ffa174fc48df664"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base16ct",
|
"base16ct",
|
||||||
"ecdsa",
|
"ecdsa",
|
||||||
@@ -568,18 +571,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pem-rfc7468"
|
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "76a65e1c27d1680f8805b3f8c9949f08d6aa5d6cbd088c9896e64a53821dc27d"
|
checksum = "b6c1cde4770761bf6bd336f947b9ac1fe700b0a4ec5867cf66cf08597fe89e8c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64ct",
|
"base64ct",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkcs1"
|
name = "pkcs1"
|
||||||
version = "0.8.0-pre.0"
|
version = "0.8.0-rc.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4f6af6e88ac39402f67488e22faa9eb15cf065f520cf4a09419393691a6d0133"
|
checksum = "0d2f4c73d459a85331915baebd5082dce5ee8ef16fd9a1ca75559ac91e66a9ee"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"der",
|
"der",
|
||||||
"pkcs8",
|
"pkcs8",
|
||||||
@@ -588,9 +591,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkcs8"
|
name = "pkcs8"
|
||||||
version = "0.11.0-pre.0"
|
version = "0.11.0-rc.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "935c09e0aecb0cb8f8907b57438b19a068cb74a25189b06724f061170b2465ff"
|
checksum = "66180445f1dce533620a7743467ef85fe1c5e80cdaf7c7053609d7a2fbcdae20"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"der",
|
"der",
|
||||||
"spki",
|
"spki",
|
||||||
@@ -598,28 +601,33 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.17"
|
version = "0.2.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "primefield"
|
name = "primefield"
|
||||||
version = "0.14.0-pre"
|
version = "0.14.0-pre.0"
|
||||||
source = "git+https://github.com/RustCrypto/elliptic-curves.git?rev=5d1c252c2defb5808f55329f3e2955ca72d7f8b5#5d1c252c2defb5808f55329f3e2955ca72d7f8b5"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3f2ce0fa9cccdaf216230d151ce51a15298aef50ad76081a830128ecbc6428a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "primeorder"
|
name = "primeorder"
|
||||||
version = "0.14.0-pre.0"
|
version = "0.14.0-pre.1"
|
||||||
source = "git+https://github.com/RustCrypto/elliptic-curves.git?rev=5d1c252c2defb5808f55329f3e2955ca72d7f8b5#5d1c252c2defb5808f55329f3e2955ca72d7f8b5"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9bed0c431186675ad845922b903d28c7faa2b634a6d130fb7b50bb289f5a4d52"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.79"
|
version = "1.0.86"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
@@ -634,9 +642,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.35"
|
version = "1.0.36"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@@ -672,9 +680,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rfc6979"
|
name = "rfc6979"
|
||||||
version = "0.5.0-pre.3"
|
version = "0.5.0-pre.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "045972f2f66b9467a2f6834b7fd0f9b23ca214b4a8700b880c36edb726e96da6"
|
checksum = "871ee76a3eee98b0f805e5d1caf26929f4565073c580c053a55f886fc15dea49"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hmac",
|
"hmac",
|
||||||
"subtle",
|
"subtle",
|
||||||
@@ -682,9 +690,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rsa"
|
name = "rsa"
|
||||||
version = "0.10.0-pre.1"
|
version = "0.10.0-pre.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43e0089f12e510517c97e1adc17d0f8374efbabdd021dfb7645d6619f85633e9"
|
checksum = "57e864e43f5d003321ab452feea6450f9611d7be6726489b4ec051da34774c62"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"const-oid",
|
"const-oid",
|
||||||
"digest",
|
"digest",
|
||||||
@@ -703,9 +711,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sec1"
|
name = "sec1"
|
||||||
version = "0.8.0-pre.1"
|
version = "0.8.0-rc.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "02dc081ed777a3bab68583b52ffb8221677b6e90d483b320963a247e2c07f328"
|
checksum = "32c98827dc6ed0ea1707286a3d14b4ad4e25e2643169cbf111568a46ff5b09f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base16ct",
|
"base16ct",
|
||||||
"der",
|
"der",
|
||||||
@@ -717,18 +725,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.197"
|
version = "1.0.204"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.197"
|
version = "1.0.204"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -737,9 +745,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.11.0-pre.3"
|
version = "0.11.0-pre.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3885de8cb916f223718c1ccd47a840b91f806333e76002dc5cb3862154b4fed3"
|
checksum = "9540978cef7a8498211c1b1c14e5ce920fe5bd524ea84f4a3d72d4602515ae93"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
@@ -748,9 +756,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.11.0-pre.3"
|
version = "0.11.0-pre.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f33549bf3064b62478926aa89cbfc7c109aab66ae8f0d5d2ef839e482cc30d6"
|
checksum = "540c0893cce56cdbcfebcec191ec8e0f470dd1889b6e7a0b503e310a94a168f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
@@ -759,9 +767,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signature"
|
name = "signature"
|
||||||
version = "2.3.0-pre.3"
|
version = "2.3.0-pre.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1700c22ba9ce32c7b0a1495068a906c3552e7db386af7cf865162e0dea498523"
|
checksum = "054d71959c7051b9042c26af337f05cc930575ed2604d7d3ced3158383e59734"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
"rand_core",
|
"rand_core",
|
||||||
@@ -781,15 +789,15 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
version = "0.5.2"
|
version = "0.9.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spki"
|
name = "spki"
|
||||||
version = "0.8.0-pre.0"
|
version = "0.8.0-rc.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cb2b56670f5ef52934c97efad30bf42585de0c33ec3e2a886e38b80d2db67243"
|
checksum = "ee3fb1c675852398475928637b3ebbdd7e1d0cc24d27b3bbc81788b4eb51e310"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64ct",
|
"base64ct",
|
||||||
"der",
|
"der",
|
||||||
@@ -797,15 +805,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.5.0"
|
version = "2.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.58"
|
version = "2.0.72"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
|
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -823,18 +831,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.58"
|
version = "1.0.63"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
|
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.58"
|
version = "1.0.63"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -876,9 +884,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.1.11"
|
version = "0.1.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
@@ -892,41 +900,92 @@ version = "0.11.0+wasi-snapshot-preview1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
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]]
|
[[package]]
|
||||||
name = "winapi-util"
|
name = "winapi-util"
|
||||||
version = "0.1.6"
|
version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "windows-sys"
|
||||||
version = "0.4.0"
|
version = "0.59.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
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]]
|
[[package]]
|
||||||
name = "x509-cert"
|
name = "x509-cert"
|
||||||
version = "0.3.0-pre"
|
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 = [
|
dependencies = [
|
||||||
"const-oid",
|
"const-oid",
|
||||||
"der",
|
"der",
|
||||||
@@ -935,10 +994,31 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeroize"
|
name = "zerocopy"
|
||||||
version = "1.7.0"
|
version = "0.7.35"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
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 = [
|
dependencies = [
|
||||||
"zeroize_derive",
|
"zeroize_derive",
|
||||||
]
|
]
|
||||||
|
@@ -13,16 +13,16 @@ num-derive = "0.4"
|
|||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
size = "0.4"
|
size = "0.4"
|
||||||
sha1 = "0.11.0-pre.3"
|
sha1 = "0.11.0-pre.4"
|
||||||
sha2 = "=0.11.0-pre.3"
|
sha2 = "=0.11.0-pre.4"
|
||||||
digest = "0.11.0-pre.8"
|
digest = "0.11.0-pre.9"
|
||||||
#p256 = "0.14"
|
p256 = "0.14.0-pre.1"
|
||||||
#p384 = "0.14"
|
p384 = "0.14.0-pre.1"
|
||||||
#p521 = "0.14"
|
p521 = "0.14.0-pre.1"
|
||||||
rsa = "0.10.0-pre.1"
|
rsa = "0.10.0-pre.2"
|
||||||
#x509-cert = "0.3"
|
#x509-cert = "0.3"
|
||||||
der = "0.8.0-pre.0"
|
der = "0.8.0-rc.0"
|
||||||
bytemuck = "1.14"
|
bytemuck = "1.16"
|
||||||
fdt = "0.1"
|
fdt = "0.1"
|
||||||
const_format = "0.2"
|
const_format = "0.2"
|
||||||
|
|
||||||
@@ -40,29 +40,17 @@ default-features = false
|
|||||||
git = "https://github.com/tafia/quick-protobuf.git"
|
git = "https://github.com/tafia/quick-protobuf.git"
|
||||||
rev = "2f37d5a65504de7d716b5b28fd82219501a901a9"
|
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]
|
[workspace.dependencies.x509-cert]
|
||||||
git = "https://github.com/RustCrypto/formats.git"
|
git = "https://github.com/RustCrypto/formats.git"
|
||||||
rev = "809df65b20d61e88afb7f514b5cfdd3d1958a40f"
|
rev = "9c0e851c6db9c2c8a2601840d46375afde2663fb"
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = "z"
|
opt-level = "z"
|
||||||
lto = true
|
lto = "thin"
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = "z"
|
opt-level = "z"
|
||||||
lto = true
|
lto = "fat"
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
@@ -7,7 +7,7 @@ LOCAL_MODULE := libbase
|
|||||||
LOCAL_C_INCLUDES := \
|
LOCAL_C_INCLUDES := \
|
||||||
src/include \
|
src/include \
|
||||||
$(LOCAL_PATH)/include \
|
$(LOCAL_PATH)/include \
|
||||||
$(LOCAL_PATH)/../external/cxx-rs/include \
|
src/external/cxx-rs/include \
|
||||||
out/generated
|
out/generated
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
|
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
|
||||||
LOCAL_EXPORT_STATIC_LIBRARIES := libcxx
|
LOCAL_EXPORT_STATIC_LIBRARIES := libcxx
|
||||||
|
@@ -108,7 +108,7 @@ impl StringExt for String {
|
|||||||
fn nul_terminate(&mut self) -> &mut [u8] {
|
fn nul_terminate(&mut self) -> &mut [u8] {
|
||||||
self.reserve(1);
|
self.reserve(1);
|
||||||
// SAFETY: the string is reserved to have enough capacity to fit in the null byte
|
// 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 {
|
unsafe {
|
||||||
let buf = slice::from_raw_parts_mut(self.as_mut_ptr(), self.len() + 1);
|
let buf = slice::from_raw_parts_mut(self.as_mut_ptr(), self.len() + 1);
|
||||||
*buf.get_unchecked_mut(self.len()) = b'\0';
|
*buf.get_unchecked_mut(self.len()) = b'\0';
|
||||||
@@ -122,7 +122,7 @@ impl StringExt for PathBuf {
|
|||||||
fn nul_terminate(&mut self) -> &mut [u8] {
|
fn nul_terminate(&mut self) -> &mut [u8] {
|
||||||
self.reserve(1);
|
self.reserve(1);
|
||||||
// SAFETY: the PathBuf is reserved to have enough capacity to fit in the null byte
|
// 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 {
|
unsafe {
|
||||||
let bytes: &mut [u8] = mem::transmute(self.as_mut_os_str().as_bytes());
|
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);
|
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)?;
|
CStr::from_bytes_with_nul(buf)?;
|
||||||
str::from_utf8(buf)?;
|
str::from_utf8(buf)?;
|
||||||
// Both condition checked
|
// 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 {
|
pub fn from_string(s: &mut String) -> &mut Utf8CStr {
|
||||||
|
@@ -4,9 +4,9 @@ use std::io;
|
|||||||
use std::os::fd::{BorrowedFd, OwnedFd, RawFd};
|
use std::os::fd::{BorrowedFd, OwnedFd, RawFd};
|
||||||
|
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use cxx::private::c_char;
|
use libc::{c_char, mode_t};
|
||||||
use libc::mode_t;
|
|
||||||
|
|
||||||
|
use crate::files::map_file_at;
|
||||||
pub(crate) use crate::xwrap::*;
|
pub(crate) use crate::xwrap::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
clone_attr, cstr, fclone_attr, fd_path, map_fd, map_file, slice_from_ptr, CxxResultExt,
|
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 [])
|
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] {
|
pub(crate) fn map_fd_for_cxx(fd: RawFd, sz: usize, rw: bool) -> &'static mut [u8] {
|
||||||
unsafe {
|
unsafe {
|
||||||
map_fd(BorrowedFd::borrow_raw(fd), sz, rw)
|
map_fd(BorrowedFd::borrow_raw(fd), sz, rw)
|
||||||
|
@@ -117,6 +117,14 @@ mmap_data::mmap_data(const char *name, bool rw) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mmap_data::mmap_data(int dirfd, const char *name, bool rw) {
|
||||||
|
auto slice = rust::map_file_at(dirfd, name, rw);
|
||||||
|
if (!slice.empty()) {
|
||||||
|
_buf = slice.data();
|
||||||
|
_sz = slice.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mmap_data::mmap_data(int fd, size_t sz, bool rw) {
|
mmap_data::mmap_data(int fd, size_t sz, bool rw) {
|
||||||
auto slice = rust::map_fd(fd, sz, rw);
|
auto slice = rust::map_fd(fd, sz, rw);
|
||||||
if (!slice.empty()) {
|
if (!slice.empty()) {
|
||||||
|
@@ -26,6 +26,7 @@ struct mmap_data : public byte_data {
|
|||||||
ALLOW_MOVE_ONLY(mmap_data)
|
ALLOW_MOVE_ONLY(mmap_data)
|
||||||
|
|
||||||
explicit mmap_data(const char *name, bool rw = false);
|
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(int fd, size_t sz, bool rw = false);
|
||||||
~mmap_data();
|
~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);
|
ssize_t canonical_path(const char * __restrict__ path, char * __restrict__ buf, size_t bufsiz);
|
||||||
bool rm_rf(const char *path);
|
bool rm_rf(const char *path);
|
||||||
bool frm_rf(int dirfd);
|
bool frm_rf(int dirfd);
|
||||||
void cp_afc(const char *src, const char *dest);
|
bool cp_afc(const char *src, const char *dest);
|
||||||
void mv_path(const char *src, const char *dest);
|
bool mv_path(const char *src, const char *dest);
|
||||||
void link_path(const char *src, const char *dest);
|
bool link_path(const char *src, const char *dest);
|
||||||
void clone_attr(const char *src, const char *dest);
|
bool clone_attr(const char *src, const char *dest);
|
||||||
void fclone_attr(int src, int dest);
|
bool fclone_attr(int src, int dest);
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
|
@@ -856,6 +856,14 @@ impl MappedFile {
|
|||||||
Ok(MappedFile(map_file(path, true)?))
|
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> {
|
pub fn create(fd: BorrowedFd, sz: usize, rw: bool) -> io::Result<MappedFile> {
|
||||||
Ok(MappedFile(map_fd(fd, sz, rw)?))
|
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
|
// 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]> {
|
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")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
const BLKGETSIZE64: u32 = 0x80081272;
|
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;
|
const BLKGETSIZE64: u32 = 0x80041272;
|
||||||
|
|
||||||
let flag = if rw { O_RDWR } else { O_RDONLY };
|
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 sz = if attr.is_block_device() {
|
||||||
let mut sz = 0_u64;
|
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
|
sz
|
||||||
} else {
|
} else {
|
||||||
attr.st.st_size as u64
|
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]> {
|
pub(crate) fn map_fd(fd: BorrowedFd, sz: usize, rw: bool) -> io::Result<&'static mut [u8]> {
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
#if defined(__arm__)
|
|
||||||
#include <armeabi-v7a_binaries.h>
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
#include <arm64-v8a_binaries.h>
|
|
||||||
#elif defined(__i386__)
|
|
||||||
#include <x86_binaries.h>
|
|
||||||
#elif defined(__x86_64__)
|
|
||||||
#include <x86_64_binaries.h>
|
|
||||||
#elif defined(__riscv)
|
|
||||||
#include <riscv64_binaries.h>
|
|
||||||
#else
|
|
||||||
#error Unsupported ABI
|
|
||||||
#endif
|
|
@@ -61,6 +61,8 @@ pub mod ffi {
|
|||||||
fn fd_path_for_cxx(fd: i32, buf: &mut [u8]) -> isize;
|
fn fd_path_for_cxx(fd: i32, buf: &mut [u8]) -> isize;
|
||||||
#[cxx_name = "map_file"]
|
#[cxx_name = "map_file"]
|
||||||
fn map_file_for_cxx(path: Utf8CStrRef, rw: bool) -> &'static mut [u8];
|
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"]
|
#[cxx_name = "map_fd"]
|
||||||
fn map_fd_for_cxx(fd: i32, sz: usize, rw: bool) -> &'static mut [u8];
|
fn map_fd_for_cxx(fd: i32, sz: usize, rw: bool) -> &'static mut [u8];
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#include <bit>
|
#include <bit>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <span>
|
||||||
|
|
||||||
#include <base.hpp>
|
#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());
|
fprintf(stderr, "%-*s [%u]\n", PADDING, "RECOV_DTBO_SZ", recovery_dtbo_size());
|
||||||
if (ver == 2 || is_vendor())
|
if (ver == 2 || is_vendor())
|
||||||
fprintf(stderr, "%-*s [%u]\n", PADDING, "DTB_SZ", dtb_size());
|
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()) {
|
if (uint32_t os_ver = os_version()) {
|
||||||
int a,b,c,y,m = 0;
|
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)
|
#define CMD_MATCH(s) BUFFER_MATCH(h->cmdline, s)
|
||||||
|
|
||||||
const pair<const uint8_t *, dyn_img_hdr *>
|
pair<const uint8_t *, dyn_img_hdr *> boot_img::create_hdr(const uint8_t *addr, format_t type) {
|
||||||
boot_img::create_hdr(const uint8_t *addr, format_t type) {
|
|
||||||
if (type == AOSP_VENDOR) {
|
if (type == AOSP_VENDOR) {
|
||||||
fprintf(stderr, "VENDOR_BOOT_HDR\n");
|
fprintf(stderr, "VENDOR_BOOT_HDR\n");
|
||||||
auto h = reinterpret_cast<const boot_img_hdr_vnd_v3*>(addr);
|
auto h = reinterpret_cast<const boot_img_hdr_vnd_v3*>(addr);
|
||||||
@@ -346,12 +348,25 @@ const pair<const uint8_t *, dyn_img_hdr *>
|
|||||||
addr += ACCLAIM_PRE_HEADER_SZ;
|
addr += ACCLAIM_PRE_HEADER_SZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// addr could be adjusted
|
|
||||||
return make_pair(addr, make_hdr(addr));
|
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() \
|
#define assert_off() \
|
||||||
if ((base_addr + off) > (map.buf() + map.sz())) { \
|
if ((base_addr + off) > (map.buf() + map_end)) { \
|
||||||
fprintf(stderr, "Corrupted boot image!\n"); \
|
fprintf(stderr, "Corrupted boot image!\n"); \
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
@@ -362,14 +377,6 @@ off += hdr->name##_size(); \
|
|||||||
off = align_to(off, hdr->page_size()); \
|
off = align_to(off, hdr->page_size()); \
|
||||||
assert_off();
|
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) {
|
bool boot_img::parse_image(const uint8_t *p, format_t type) {
|
||||||
auto [base_addr, hdr] = create_hdr(p, type);
|
auto [base_addr, hdr] = create_hdr(p, type);
|
||||||
if (hdr == nullptr) {
|
if (hdr == nullptr) {
|
||||||
@@ -388,6 +395,7 @@ bool boot_img::parse_image(const uint8_t *p, format_t type) {
|
|||||||
|
|
||||||
hdr->print();
|
hdr->print();
|
||||||
|
|
||||||
|
size_t map_end = align_to(map.sz(), getpagesize());
|
||||||
size_t off = hdr->hdr_space();
|
size_t off = hdr->hdr_space();
|
||||||
get_block(kernel);
|
get_block(kernel);
|
||||||
get_block(ramdisk);
|
get_block(ramdisk);
|
||||||
@@ -395,16 +403,13 @@ bool boot_img::parse_image(const uint8_t *p, format_t type) {
|
|||||||
get_block(extra);
|
get_block(extra);
|
||||||
get_block(recovery_dtbo);
|
get_block(recovery_dtbo);
|
||||||
get_block(dtb);
|
get_block(dtb);
|
||||||
|
get_block(signature);
|
||||||
auto ignore_addr = base_addr + off;
|
get_block(vendor_ramdisk_table);
|
||||||
get_ignore(signature)
|
get_block(bootconfig);
|
||||||
get_ignore(vendor_ramdisk_table)
|
|
||||||
get_ignore(bootconfig)
|
|
||||||
|
|
||||||
payload = byte_view(base_addr, off);
|
payload = byte_view(base_addr, off);
|
||||||
auto tail_addr = 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_end - tail_addr);
|
||||||
tail = byte_view(tail_addr, map.buf() + map.sz() - tail_addr);
|
|
||||||
|
|
||||||
if (auto size = hdr->kernel_size()) {
|
if (auto size = hdr->kernel_size()) {
|
||||||
if (int dtb_off = find_dtb_offset(kernel, size); dtb_off > 0) {
|
if (int dtb_off = find_dtb_offset(kernel, size); dtb_off > 0) {
|
||||||
@@ -458,13 +463,28 @@ bool boot_img::parse_image(const uint8_t *p, format_t type) {
|
|||||||
fprintf(stderr, "%-*s [%s]\n", PADDING, "KERNEL_FMT", fmt2name[k_fmt]);
|
fprintf(stderr, "%-*s [%s]\n", PADDING, "KERNEL_FMT", fmt2name[k_fmt]);
|
||||||
}
|
}
|
||||||
if (auto size = hdr->ramdisk_size()) {
|
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
|
// v4 vendor boot contains multiple ramdisks
|
||||||
// Do not try to mess with it for now
|
using table_entry = const vendor_ramdisk_table_entry_v4;
|
||||||
r_fmt = UNKNOWN;
|
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 {
|
} else {
|
||||||
r_fmt = check_fmt_lg(ramdisk, size);
|
r_fmt = check_fmt_lg(ramdisk, size);
|
||||||
}
|
|
||||||
if (r_fmt == MTK) {
|
if (r_fmt == MTK) {
|
||||||
fprintf(stderr, "MTK_RAMDISK_HDR\n");
|
fprintf(stderr, "MTK_RAMDISK_HDR\n");
|
||||||
flags[MTK_RAMDISK] = true;
|
flags[MTK_RAMDISK] = true;
|
||||||
@@ -477,6 +497,7 @@ bool boot_img::parse_image(const uint8_t *p, format_t type) {
|
|||||||
}
|
}
|
||||||
fprintf(stderr, "%-*s [%s]\n", PADDING, "RAMDISK_FMT", fmt2name[r_fmt]);
|
fprintf(stderr, "%-*s [%s]\n", PADDING, "RAMDISK_FMT", fmt2name[r_fmt]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (auto size = hdr->extra_size()) {
|
if (auto size = hdr->extra_size()) {
|
||||||
e_fmt = check_fmt_lg(extra, size);
|
e_fmt = check_fmt_lg(extra, size);
|
||||||
fprintf(stderr, "%-*s [%s]\n", PADDING, "EXTRA_FMT", fmt2name[e_fmt]);
|
fprintf(stderr, "%-*s [%s]\n", PADDING, "EXTRA_FMT", fmt2name[e_fmt]);
|
||||||
@@ -561,7 +582,30 @@ int unpack(const char *image, bool skip_decomp, bool hdr) {
|
|||||||
dump(boot.kernel_dtb.buf(), boot.kernel_dtb.sz(), KER_DTB_FILE);
|
dump(boot.kernel_dtb.buf(), boot.kernel_dtb.sz(), KER_DTB_FILE);
|
||||||
|
|
||||||
// Dump ramdisk
|
// 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) {
|
if (boot.hdr->ramdisk_size() != 0) {
|
||||||
int fd = creat(RAMDISK_FILE, 0644);
|
int fd = creat(RAMDISK_FILE, 0644);
|
||||||
decompress(boot.r_fmt, fd, boot.ramdisk, boot.hdr->ramdisk_size());
|
decompress(boot.r_fmt, fd, boot.ramdisk, boot.hdr->ramdisk_size());
|
||||||
@@ -591,6 +635,9 @@ int unpack(const char *image, bool skip_decomp, bool hdr) {
|
|||||||
// Dump dtb
|
// Dump dtb
|
||||||
dump(boot.dtb, boot.hdr->dtb_size(), DTB_FILE);
|
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;
|
return boot.flags[CHROMEOS_FLAG] ? 2 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -620,6 +667,7 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
hdr->ramdisk_size() = 0;
|
hdr->ramdisk_size() = 0;
|
||||||
hdr->second_size() = 0;
|
hdr->second_size() = 0;
|
||||||
hdr->dtb_size() = 0;
|
hdr->dtb_size() = 0;
|
||||||
|
hdr->bootconfig_size() = 0;
|
||||||
|
|
||||||
if (access(HEADER_FILE, R_OK) == 0)
|
if (access(HEADER_FILE, R_OK) == 0)
|
||||||
hdr->load_hdr_file();
|
hdr->load_hdr_file();
|
||||||
@@ -703,7 +751,40 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
// Copy MTK headers
|
// Copy MTK headers
|
||||||
xwrite(fd, boot.r_hdr, sizeof(mtk_hdr));
|
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);
|
mmap_data m(RAMDISK_FILE);
|
||||||
auto r_fmt = boot.r_fmt;
|
auto r_fmt = boot.r_fmt;
|
||||||
if (!skip_comp && !hdr->is_vendor() && hdr->header_version() == 4 && r_fmt != LZ4_LEGACY) {
|
if (!skip_comp && !hdr->is_vendor() && hdr->header_version() == 4 && r_fmt != LZ4_LEGACY) {
|
||||||
@@ -754,10 +835,22 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
file_align();
|
file_align();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Directly copy ignored blobs
|
// Copy boot signature
|
||||||
if (boot.ignore.sz()) {
|
if (boot.hdr->signature_size()) {
|
||||||
// ignore.sz() should already be aligned
|
xwrite(fd, boot.signature, boot.hdr->signature_size());
|
||||||
xwrite(fd, boot.ignore.buf(), boot.ignore.sz());
|
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
|
// Proprietary stuffs
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <cstdint>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <cxx.h>
|
#include <cxx.h>
|
||||||
@@ -111,15 +111,21 @@ struct AvbVBMetaImageHeader {
|
|||||||
#define VENDOR_RAMDISK_NAME_SIZE 32
|
#define VENDOR_RAMDISK_NAME_SIZE 32
|
||||||
#define VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE 16
|
#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:
|
* image is as follows:
|
||||||
*
|
*
|
||||||
* +-----------------+
|
* +-----------------+
|
||||||
* | boot header | 1 page
|
* | boot header | 1 page
|
||||||
* +-----------------+
|
* +-----------------+
|
||||||
* | kernel | n pages
|
* | kernel | m pages
|
||||||
* +-----------------+
|
* +-----------------+
|
||||||
* | ramdisk | m pages
|
* | ramdisk | n pages
|
||||||
* +-----------------+
|
* +-----------------+
|
||||||
* | second stage | o pages
|
* | second stage | o pages
|
||||||
* +-----------------+
|
* +-----------------+
|
||||||
@@ -130,8 +136,8 @@ struct AvbVBMetaImageHeader {
|
|||||||
* | dtb | q pages
|
* | dtb | q pages
|
||||||
* +-----------------+
|
* +-----------------+
|
||||||
*
|
*
|
||||||
* n = (kernel_size + page_size - 1) / page_size
|
* m = (kernel_size + page_size - 1) / page_size
|
||||||
* m = (ramdisk_size + page_size - 1) / page_size
|
* n = (ramdisk_size + page_size - 1) / page_size
|
||||||
* o = (second_size + page_size - 1) / page_size
|
* o = (second_size + page_size - 1) / page_size
|
||||||
* p = (recovery_dtbo_size + page_size - 1) / page_size
|
* p = (recovery_dtbo_size + page_size - 1) / page_size
|
||||||
* q = (dtb_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];
|
char extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
|
||||||
} __attribute__((packed));
|
} __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:
|
* 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_size; /* size in bytes for the ramdisk image */
|
||||||
uint32_t ramdisk_offset; /* offset to the ramdisk image in vendor ramdisk section */
|
uint32_t ramdisk_offset; /* offset to the ramdisk image in vendor ramdisk section */
|
||||||
uint32_t ramdisk_type; /* type of the ramdisk */
|
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
|
// Hardware identifiers describing the board, soc or platform which this
|
||||||
// ramdisk is intended to be loaded on.
|
// ramdisk is intended to be loaded on.
|
||||||
@@ -376,8 +383,12 @@ struct dyn_img_hdr {
|
|||||||
|
|
||||||
// v4 specific
|
// v4 specific
|
||||||
decl_val(signature_size, 32)
|
decl_val(signature_size, 32)
|
||||||
|
|
||||||
|
// v4 vendor specific
|
||||||
decl_val(vendor_ramdisk_table_size, 32)
|
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() {
|
virtual ~dyn_img_hdr() {
|
||||||
free(raw);
|
free(raw);
|
||||||
@@ -554,7 +565,9 @@ struct dyn_img_vnd_v4 : public dyn_img_vnd_v3 {
|
|||||||
impl_cls(vnd_v4)
|
impl_cls(vnd_v4)
|
||||||
|
|
||||||
impl_val(vendor_ramdisk_table_size)
|
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
|
#undef __impl_cls
|
||||||
@@ -591,7 +604,7 @@ struct boot_img {
|
|||||||
const mmap_data map;
|
const mmap_data map;
|
||||||
|
|
||||||
// Android image header
|
// Android image header
|
||||||
const dyn_img_hdr *hdr;
|
const dyn_img_hdr *hdr = nullptr;
|
||||||
|
|
||||||
// Flags to indicate the state of current boot image
|
// Flags to indicate the state of current boot image
|
||||||
std::bitset<BOOT_FLAGS_MAX> flags;
|
std::bitset<BOOT_FLAGS_MAX> flags;
|
||||||
@@ -607,9 +620,9 @@ struct boot_img {
|
|||||||
|
|
||||||
// Layout of the memory mapped region
|
// 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.
|
// | tail | Data after payload. Usually contains signature/AVB information.
|
||||||
// +---------+
|
// +---------+
|
||||||
@@ -618,8 +631,8 @@ struct boot_img {
|
|||||||
byte_view tail;
|
byte_view tail;
|
||||||
|
|
||||||
// MTK headers
|
// MTK headers
|
||||||
const mtk_hdr *k_hdr;
|
const mtk_hdr *k_hdr = nullptr;
|
||||||
const mtk_hdr *r_hdr;
|
const mtk_hdr *r_hdr = nullptr;
|
||||||
|
|
||||||
// The pointers/values after parse_image
|
// The pointers/values after parse_image
|
||||||
// +---------------+
|
// +---------------+
|
||||||
@@ -629,23 +642,26 @@ struct boot_img {
|
|||||||
// +---------------+
|
// +---------------+
|
||||||
// | z_info.tail | z_info.tail.sz()
|
// | z_info.tail | z_info.tail.sz()
|
||||||
// +---------------+
|
// +---------------+
|
||||||
const zimage_hdr *z_hdr;
|
const zimage_hdr *z_hdr = nullptr;
|
||||||
struct {
|
struct {
|
||||||
uint32_t hdr_sz;
|
uint32_t hdr_sz;
|
||||||
byte_view tail;
|
byte_view tail;
|
||||||
} z_info;
|
} z_info;
|
||||||
|
|
||||||
// AVB structs
|
// AVB structs
|
||||||
const AvbFooter *avb_footer;
|
const AvbFooter *avb_footer = nullptr;
|
||||||
const AvbVBMetaImageHeader *vbmeta;
|
const AvbVBMetaImageHeader *vbmeta = nullptr;
|
||||||
|
|
||||||
// Pointers to blocks defined in header
|
// Pointers to blocks defined in header
|
||||||
const uint8_t *kernel;
|
const uint8_t *kernel = nullptr;
|
||||||
const uint8_t *ramdisk;
|
const uint8_t *ramdisk = nullptr;
|
||||||
const uint8_t *second;
|
const uint8_t *second = nullptr;
|
||||||
const uint8_t *extra;
|
const uint8_t *extra = nullptr;
|
||||||
const uint8_t *recovery_dtbo;
|
const uint8_t *recovery_dtbo = nullptr;
|
||||||
const uint8_t *dtb;
|
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
|
// dtb embedded in kernel
|
||||||
byte_view kernel_dtb;
|
byte_view kernel_dtb;
|
||||||
@@ -657,7 +673,7 @@ struct boot_img {
|
|||||||
~boot_img();
|
~boot_img();
|
||||||
|
|
||||||
bool parse_image(const uint8_t *addr, format_t type);
|
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 FFI
|
||||||
rust::Slice<const uint8_t> get_payload() const { return payload; }
|
rust::Slice<const uint8_t> get_payload() const { return payload; }
|
||||||
|
@@ -175,9 +175,8 @@ Supported commands:
|
|||||||
extract [ENTRY OUT]
|
extract [ENTRY OUT]
|
||||||
Extract ENTRY to OUT, or extract all entries to current directory
|
Extract ENTRY to OUT, or extract all entries to current directory
|
||||||
test
|
test
|
||||||
Test the cpio's status
|
Test the cpio's status. Return values:
|
||||||
Return value is 0 or bitwise or-ed of following values:
|
0:stock 1:Magisk 2:unsupported
|
||||||
0x1:Magisk 0x2:unsupported
|
|
||||||
patch
|
patch
|
||||||
Apply ramdisk patches
|
Apply ramdisk patches
|
||||||
Configure with env variables: KEEPVERITY KEEPFORCEENCRYPT
|
Configure with env variables: KEEPVERITY KEEPFORCEENCRYPT
|
||||||
@@ -544,7 +543,6 @@ impl Cpio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn test(&self) -> i32 {
|
fn test(&self) -> i32 {
|
||||||
let mut ret = 0;
|
|
||||||
for file in [
|
for file in [
|
||||||
"sbin/launch_daemonsu.sh",
|
"sbin/launch_daemonsu.sh",
|
||||||
"sbin/su",
|
"sbin/su",
|
||||||
@@ -561,11 +559,10 @@ impl Cpio {
|
|||||||
"overlay/init.magisk.rc",
|
"overlay/init.magisk.rc",
|
||||||
] {
|
] {
|
||||||
if self.exists(file) {
|
if self.exists(file) {
|
||||||
ret |= MAGISK_PATCHED;
|
return MAGISK_PATCHED;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restore(&mut self) -> LoggedResult<()> {
|
fn restore(&mut self) -> LoggedResult<()> {
|
||||||
|
@@ -7,11 +7,13 @@
|
|||||||
#define HEADER_FILE "header"
|
#define HEADER_FILE "header"
|
||||||
#define KERNEL_FILE "kernel"
|
#define KERNEL_FILE "kernel"
|
||||||
#define RAMDISK_FILE "ramdisk.cpio"
|
#define RAMDISK_FILE "ramdisk.cpio"
|
||||||
|
#define VND_RAMDISK_DIR "vendor_ramdisk"
|
||||||
#define SECOND_FILE "second"
|
#define SECOND_FILE "second"
|
||||||
#define EXTRA_FILE "extra"
|
#define EXTRA_FILE "extra"
|
||||||
#define KER_DTB_FILE "kernel_dtb"
|
#define KER_DTB_FILE "kernel_dtb"
|
||||||
#define RECV_DTBO_FILE "recovery_dtbo"
|
#define RECV_DTBO_FILE "recovery_dtbo"
|
||||||
#define DTB_FILE "dtb"
|
#define DTB_FILE "dtb"
|
||||||
|
#define BOOTCONFIG_FILE "bootconfig"
|
||||||
#define NEW_BOOT "new-boot.img"
|
#define NEW_BOOT "new-boot.img"
|
||||||
|
|
||||||
int unpack(const char *image, bool skip_decomp = false, bool hdr = false);
|
int unpack(const char *image, bool skip_decomp = false, bool hdr = false);
|
||||||
|
@@ -7,8 +7,12 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#ifdef USE_CRT0
|
#ifdef USE_CRT0
|
||||||
__asm__(".global vfprintf \n vfprintf = musl_vfprintf");
|
__BEGIN_DECLS
|
||||||
__asm__(".global vsscanf \n vsscanf = tfp_vsscanf");
|
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
|
#endif
|
||||||
|
|
||||||
static void print_formats() {
|
static void print_formats() {
|
||||||
@@ -40,7 +44,9 @@ Supported actions:
|
|||||||
|
|
||||||
repack [-n] <origbootimg> [outbootimg]
|
repack [-n] <origbootimg> [outbootimg]
|
||||||
Repack boot image components using files from the current directory
|
Repack boot image components using files from the current directory
|
||||||
to [outbootimg], or 'new-boot.img' if not specified.
|
to [outbootimg], or 'new-boot.img' if not specified. Current directory
|
||||||
|
should only contain required files for [outbootimg], or incorrect
|
||||||
|
[outbootimg] may be produced.
|
||||||
<origbootimg> is the original boot image used to unpack the components.
|
<origbootimg> is the original boot image used to unpack the components.
|
||||||
By default, each component will be automatically compressed using its
|
By default, each component will be automatically compressed using its
|
||||||
corresponding format detected in <origbootimg>. If a component file
|
corresponding format detected in <origbootimg>. If a component file
|
||||||
@@ -142,6 +148,8 @@ int main(int argc, char *argv[]) {
|
|||||||
unlink(EXTRA_FILE);
|
unlink(EXTRA_FILE);
|
||||||
unlink(RECV_DTBO_FILE);
|
unlink(RECV_DTBO_FILE);
|
||||||
unlink(DTB_FILE);
|
unlink(DTB_FILE);
|
||||||
|
unlink(BOOTCONFIG_FILE);
|
||||||
|
rm_rf(VND_RAMDISK_DIR);
|
||||||
} else if (argc > 2 && action == "sha1") {
|
} else if (argc > 2 && action == "sha1") {
|
||||||
uint8_t sha1[20];
|
uint8_t sha1[20];
|
||||||
{
|
{
|
||||||
|
@@ -25,6 +25,18 @@ static bool magisk_env() {
|
|||||||
|
|
||||||
LOGI("* Initializing Magisk environment\n");
|
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
|
// Directories in /data/adb
|
||||||
chmod(SECURE_DIR, 0700);
|
chmod(SECURE_DIR, 0700);
|
||||||
xmkdir(DATABIN, 0755);
|
xmkdir(DATABIN, 0755);
|
||||||
|
@@ -392,21 +392,6 @@ static void daemon_entry() {
|
|||||||
ssprintf(path, sizeof(path), "%s/" ROOTOVL, tmp);
|
ssprintf(path, sizeof(path), "%s/" ROOTOVL, tmp);
|
||||||
rm_rf(path);
|
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);
|
fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||||
sockaddr_un addr = {.sun_family = AF_LOCAL};
|
sockaddr_un addr = {.sun_family = AF_LOCAL};
|
||||||
ssprintf(addr.sun_path, sizeof(addr.sun_path), "%s/" MAIN_SOCKET, tmp);
|
ssprintf(addr.sun_path, sizeof(addr.sun_path), "%s/" MAIN_SOCKET, tmp);
|
||||||
|
@@ -24,20 +24,12 @@ static sqlite3 *mDB = nullptr;
|
|||||||
#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
|
#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
|
||||||
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
|
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
|
||||||
|
|
||||||
static int (*sqlite3_open_v2)(
|
using sqlite3_callback = int (*)(void*, int, char**, char**);
|
||||||
const char *filename,
|
static int (*sqlite3_open_v2)(const char *filename, sqlite3 **ppDb, int flags, const char *zVfs);
|
||||||
sqlite3 **ppDb,
|
|
||||||
int flags,
|
|
||||||
const char *zVfs);
|
|
||||||
static const char *(*sqlite3_errmsg)(sqlite3 *db);
|
static const char *(*sqlite3_errmsg)(sqlite3 *db);
|
||||||
static int (*sqlite3_close)(sqlite3 *db);
|
static int (*sqlite3_close)(sqlite3 *db);
|
||||||
static void (*sqlite3_free)(void *v);
|
static void (*sqlite3_free)(void *v);
|
||||||
static int (*sqlite3_exec)(
|
static int (*sqlite3_exec)(sqlite3 *db, const char *sql, sqlite3_callback fn, void *v, char **errmsg);
|
||||||
sqlite3 *db,
|
|
||||||
const char *sql,
|
|
||||||
int (*callback)(void*, int, char**, char**),
|
|
||||||
void *v,
|
|
||||||
char **errmsg);
|
|
||||||
|
|
||||||
// Internal Android linker APIs
|
// Internal Android linker APIs
|
||||||
|
|
||||||
@@ -135,51 +127,69 @@ static int ver_cb(void *ver, int, char **data, char **) {
|
|||||||
return 0;
|
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())
|
if (!dload_sqlite())
|
||||||
return strdup("Cannot load libsqlite.so");
|
return "Cannot load libsqlite.so";
|
||||||
|
|
||||||
int ret = sqlite3_open_v2(MAGISKDB, &db,
|
int ret = sqlite3_open_v2(MAGISKDB, &db,
|
||||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, nullptr);
|
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, nullptr);
|
||||||
if (ret)
|
if (ret)
|
||||||
return strdup(sqlite3_errmsg(db));
|
return sqlite3_errmsg(db);
|
||||||
int ver = 0;
|
int ver = 0;
|
||||||
bool upgrade = false;
|
bool upgrade = false;
|
||||||
char *err = nullptr;
|
sql_exe_ret(db, "PRAGMA user_version", ver_cb, &ver);
|
||||||
sqlite3_exec(db, "PRAGMA user_version", ver_cb, &ver, &err);
|
|
||||||
err_ret(err);
|
|
||||||
if (ver > DB_VERSION) {
|
if (ver > DB_VERSION) {
|
||||||
// Don't support downgrading database
|
// Don't support downgrading database
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
return strdup("Downgrading database is not supported");
|
return "Downgrading database is not supported";
|
||||||
}
|
}
|
||||||
|
|
||||||
auto create_policy = [&] {
|
auto create_policy = [&] {
|
||||||
sqlite3_exec(db,
|
return sql_exec(db,
|
||||||
"CREATE TABLE IF NOT EXISTS policies "
|
"CREATE TABLE IF NOT EXISTS policies "
|
||||||
"(uid INT, policy INT, until INT, logging INT, "
|
"(uid INT, policy INT, until INT, logging INT, "
|
||||||
"notification INT, PRIMARY KEY(uid))",
|
"notification INT, PRIMARY KEY(uid))",
|
||||||
nullptr, nullptr, &err);
|
nullptr, nullptr);
|
||||||
};
|
};
|
||||||
auto create_settings = [&] {
|
auto create_settings = [&] {
|
||||||
sqlite3_exec(db,
|
return sql_exec(db,
|
||||||
"CREATE TABLE IF NOT EXISTS settings "
|
"CREATE TABLE IF NOT EXISTS settings "
|
||||||
"(key TEXT, value INT, PRIMARY KEY(key))",
|
"(key TEXT, value INT, PRIMARY KEY(key))",
|
||||||
nullptr, nullptr, &err);
|
nullptr, nullptr);
|
||||||
};
|
};
|
||||||
auto create_strings = [&] {
|
auto create_strings = [&] {
|
||||||
sqlite3_exec(db,
|
return sql_exec(db,
|
||||||
"CREATE TABLE IF NOT EXISTS strings "
|
"CREATE TABLE IF NOT EXISTS strings "
|
||||||
"(key TEXT, value TEXT, PRIMARY KEY(key))",
|
"(key TEXT, value TEXT, PRIMARY KEY(key))",
|
||||||
nullptr, nullptr, &err);
|
nullptr, nullptr);
|
||||||
};
|
};
|
||||||
auto create_denylist = [&] {
|
auto create_denylist = [&] {
|
||||||
sqlite3_exec(db,
|
return sql_exec(db,
|
||||||
"CREATE TABLE IF NOT EXISTS denylist "
|
"CREATE TABLE IF NOT EXISTS denylist "
|
||||||
"(package_name TEXT, process TEXT, PRIMARY KEY(package_name, process))",
|
"(package_name TEXT, process TEXT, PRIMARY KEY(package_name, process))",
|
||||||
nullptr, nullptr, &err);
|
nullptr, nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Database changelog:
|
// Database changelog:
|
||||||
@@ -194,21 +204,17 @@ static char *open_and_init_db(sqlite3 *&db) {
|
|||||||
// 12: rebuild table `policies` to drop column `package_name`
|
// 12: rebuild table `policies` to drop column `package_name`
|
||||||
|
|
||||||
if (/* 0, 1, 2, 3, 4, 5, 6 */ ver <= 6) {
|
if (/* 0, 1, 2, 3, 4, 5, 6 */ ver <= 6) {
|
||||||
create_policy();
|
fn_run_ret(create_policy);
|
||||||
err_ret(err);
|
fn_run_ret(create_settings);
|
||||||
create_settings();
|
fn_run_ret(create_strings);
|
||||||
err_ret(err);
|
fn_run_ret(create_denylist);
|
||||||
create_strings();
|
|
||||||
err_ret(err);
|
|
||||||
create_denylist();
|
|
||||||
err_ret(err);
|
|
||||||
|
|
||||||
// Directly jump to latest
|
// Directly jump to latest
|
||||||
ver = DB_VERSION;
|
ver = DB_VERSION;
|
||||||
upgrade = true;
|
upgrade = true;
|
||||||
}
|
}
|
||||||
if (ver == 7) {
|
if (ver == 7) {
|
||||||
sqlite3_exec(db,
|
sql_exe_ret(db,
|
||||||
"BEGIN TRANSACTION;"
|
"BEGIN TRANSACTION;"
|
||||||
"ALTER TABLE hidelist RENAME TO hidelist_tmp;"
|
"ALTER TABLE hidelist RENAME TO hidelist_tmp;"
|
||||||
"CREATE TABLE IF NOT EXISTS hidelist "
|
"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;"
|
"INSERT INTO hidelist SELECT process as package_name, process FROM hidelist_tmp;"
|
||||||
"DROP TABLE hidelist_tmp;"
|
"DROP TABLE hidelist_tmp;"
|
||||||
"COMMIT;",
|
"COMMIT;",
|
||||||
nullptr, nullptr, &err);
|
nullptr, nullptr);
|
||||||
err_ret(err);
|
|
||||||
// Directly jump to version 9
|
// Directly jump to version 9
|
||||||
ver = 9;
|
ver = 9;
|
||||||
upgrade = true;
|
upgrade = true;
|
||||||
}
|
}
|
||||||
if (ver == 8) {
|
if (ver == 8) {
|
||||||
sqlite3_exec(db,
|
sql_exe_ret(db,
|
||||||
"BEGIN TRANSACTION;"
|
"BEGIN TRANSACTION;"
|
||||||
"ALTER TABLE hidelist RENAME TO hidelist_tmp;"
|
"ALTER TABLE hidelist RENAME TO hidelist_tmp;"
|
||||||
"CREATE TABLE IF NOT EXISTS hidelist "
|
"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;"
|
"INSERT INTO hidelist SELECT * FROM hidelist_tmp;"
|
||||||
"DROP TABLE hidelist_tmp;"
|
"DROP TABLE hidelist_tmp;"
|
||||||
"COMMIT;",
|
"COMMIT;",
|
||||||
nullptr, nullptr, &err);
|
nullptr, nullptr);
|
||||||
err_ret(err);
|
|
||||||
ver = 9;
|
ver = 9;
|
||||||
upgrade = true;
|
upgrade = true;
|
||||||
}
|
}
|
||||||
if (ver == 9) {
|
if (ver == 9) {
|
||||||
sqlite3_exec(db, "DROP TABLE IF EXISTS logs", nullptr, nullptr, &err);
|
sql_exe_ret(db, "DROP TABLE IF EXISTS logs", nullptr, nullptr);
|
||||||
err_ret(err);
|
|
||||||
ver = 10;
|
ver = 10;
|
||||||
upgrade = true;
|
upgrade = true;
|
||||||
}
|
}
|
||||||
if (ver == 10) {
|
if (ver == 10) {
|
||||||
sqlite3_exec(db,
|
sql_exe_ret(db,
|
||||||
"DROP TABLE IF EXISTS hidelist;"
|
"DROP TABLE IF EXISTS hidelist;"
|
||||||
"DELETE FROM settings WHERE key='magiskhide';",
|
"DELETE FROM settings WHERE key='magiskhide';",
|
||||||
nullptr, nullptr, &err);
|
nullptr, nullptr);
|
||||||
err_ret(err);
|
fn_run_ret(create_denylist);
|
||||||
create_denylist();
|
|
||||||
err_ret(err);
|
|
||||||
ver = 11;
|
ver = 11;
|
||||||
upgrade = true;
|
upgrade = true;
|
||||||
}
|
}
|
||||||
if (ver == 11) {
|
if (ver == 11) {
|
||||||
sqlite3_exec(db,
|
sql_exe_ret(db,
|
||||||
"BEGIN TRANSACTION;"
|
"BEGIN TRANSACTION;"
|
||||||
"ALTER TABLE policies RENAME TO policies_tmp;"
|
"ALTER TABLE policies RENAME TO policies_tmp;"
|
||||||
"CREATE TABLE IF NOT EXISTS policies "
|
"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;"
|
"SELECT uid, policy, until, logging, notification FROM policies_tmp;"
|
||||||
"DROP TABLE policies_tmp;"
|
"DROP TABLE policies_tmp;"
|
||||||
"COMMIT;",
|
"COMMIT;",
|
||||||
nullptr, nullptr, &err);
|
nullptr, nullptr);
|
||||||
err_ret(err);
|
|
||||||
ver = 12;
|
ver = 12;
|
||||||
upgrade = true;
|
upgrade = true;
|
||||||
}
|
}
|
||||||
@@ -274,28 +274,25 @@ static char *open_and_init_db(sqlite3 *&db) {
|
|||||||
// Set version
|
// Set version
|
||||||
char query[32];
|
char query[32];
|
||||||
sprintf(query, "PRAGMA user_version=%d", ver);
|
sprintf(query, "PRAGMA user_version=%d", ver);
|
||||||
sqlite3_exec(db, query, nullptr, nullptr, &err);
|
sql_exe_ret(db, query, nullptr, nullptr);
|
||||||
err_ret(err);
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
char *db_exec(const char *sql) {
|
db_result db_exec(const char *sql) {
|
||||||
char *err = nullptr;
|
|
||||||
if (mDB == nullptr) {
|
if (mDB == nullptr) {
|
||||||
err = open_and_init_db(mDB);
|
auto res = open_and_init_db(mDB);
|
||||||
db_err_cmd(err,
|
if (res.check_err()) {
|
||||||
// Open fails, remove and reconstruct
|
// Open fails, remove and reconstruct
|
||||||
unlink(MAGISKDB);
|
unlink(MAGISKDB);
|
||||||
err = open_and_init_db(mDB);
|
res = open_and_init_db(mDB);
|
||||||
err_ret(err);
|
if (!res) return res;
|
||||||
);
|
}
|
||||||
}
|
}
|
||||||
if (mDB) {
|
if (mDB) {
|
||||||
sqlite3_exec(mDB, sql, nullptr, nullptr, &err);
|
sql_exe_ret(mDB, sql, nullptr, nullptr);
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sqlite_db_row_callback(void *cb, int col_num, char **data, char **col_name) {
|
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;
|
return func(row) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *db_exec(const char *sql, const db_row_cb &fn) {
|
db_result db_exec(const char *sql, const db_row_cb &fn) {
|
||||||
char *err = nullptr;
|
|
||||||
if (mDB == nullptr) {
|
if (mDB == nullptr) {
|
||||||
err = open_and_init_db(mDB);
|
auto res = open_and_init_db(mDB);
|
||||||
db_err_cmd(err,
|
if (res.check_err()) {
|
||||||
// Open fails, remove and reconstruct
|
// Open fails, remove and reconstruct
|
||||||
unlink(MAGISKDB);
|
unlink(MAGISKDB);
|
||||||
err = open_and_init_db(mDB);
|
res = open_and_init_db(mDB);
|
||||||
err_ret(err);
|
if (!res) return res;
|
||||||
);
|
}
|
||||||
}
|
}
|
||||||
if (mDB) {
|
if (mDB) {
|
||||||
sqlite3_exec(mDB, sql, sqlite_db_row_callback, (void *) &fn, &err);
|
sql_exe_ret(mDB, sql, sqlite_db_row_callback, (void *) &fn);
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_db_settings(db_settings &cfg, int key) {
|
int get_db_settings(db_settings &cfg, int key) {
|
||||||
char *err = nullptr;
|
db_result res;
|
||||||
auto settings_cb = [&](db_row &row) -> bool {
|
auto settings_cb = [&](db_row &row) -> bool {
|
||||||
cfg[row["key"]] = parse_int(row["value"]);
|
cfg[row["key"]] = parse_int(row["value"]);
|
||||||
DBLOGV("query %s=[%s]\n", row["key"].data(), row["value"].data());
|
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) {
|
if (key >= 0) {
|
||||||
char query[128];
|
char query[128];
|
||||||
ssprintf(query, sizeof(query), "SELECT * FROM settings WHERE key='%s'", DB_SETTING_KEYS[key]);
|
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 {
|
} else {
|
||||||
err = db_exec("SELECT * FROM settings", settings_cb);
|
res = db_exec("SELECT * FROM settings", settings_cb);
|
||||||
}
|
}
|
||||||
db_err_cmd(err, return 1);
|
return res.check_err() ? 1 : 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int set_db_settings(int key, int value) {
|
int set_db_settings(int key, int value) {
|
||||||
char *err;
|
|
||||||
char sql[128];
|
char sql[128];
|
||||||
ssprintf(sql, sizeof(sql), "INSERT OR REPLACE INTO settings VALUES ('%s', %d)",
|
ssprintf(sql, sizeof(sql), "INSERT OR REPLACE INTO settings VALUES ('%s', %d)",
|
||||||
DB_SETTING_KEYS[key], value);
|
DB_SETTING_KEYS[key], value);
|
||||||
err = db_exec(sql);
|
return db_exec(sql).check_err() ? 1 : 0;
|
||||||
db_err_cmd(err, return 1)
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_db_strings(db_strings &str, int key) {
|
int get_db_strings(db_strings &str, int key) {
|
||||||
char *err = nullptr;
|
db_result res;
|
||||||
auto string_cb = [&](db_row &row) -> bool {
|
auto string_cb = [&](db_row &row) -> bool {
|
||||||
str[row["key"]] = row["value"];
|
str[row["key"]] = row["value"];
|
||||||
DBLOGV("query %s=[%s]\n", row["key"].data(), row["value"].data());
|
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) {
|
if (key >= 0) {
|
||||||
char query[128];
|
char query[128];
|
||||||
ssprintf(query, sizeof(query), "SELECT * FROM strings WHERE key='%s'", DB_STRING_KEYS[key]);
|
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 {
|
} else {
|
||||||
err = db_exec("SELECT * FROM strings", string_cb);
|
res = db_exec("SELECT * FROM strings", string_cb);
|
||||||
}
|
}
|
||||||
db_err_cmd(err, return 1);
|
return res.check_err() ? 1 : 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rm_db_strings(int key) {
|
void rm_db_strings(int key) {
|
||||||
char *err;
|
|
||||||
char query[128];
|
char query[128];
|
||||||
ssprintf(query, sizeof(query), "DELETE FROM strings WHERE key == '%s'", DB_STRING_KEYS[key]);
|
ssprintf(query, sizeof(query), "DELETE FROM strings WHERE key == '%s'", DB_STRING_KEYS[key]);
|
||||||
err = db_exec(query);
|
db_exec(query).check_err();
|
||||||
db_err_cmd(err, return);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void exec_sql(int client) {
|
void exec_sql(owned_fd client) {
|
||||||
run_finally f([=]{ close(client); });
|
|
||||||
string sql = read_string(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;
|
string out;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto it : row) {
|
for (auto it : row) {
|
||||||
@@ -391,18 +378,9 @@ void exec_sql(int client) {
|
|||||||
out += '=';
|
out += '=';
|
||||||
out += it.second;
|
out += it.second;
|
||||||
}
|
}
|
||||||
write_string(client, out);
|
write_string(fd, out);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
write_int(client, 0);
|
write_int(client, 0);
|
||||||
db_err_cmd(err, return; );
|
res.check_err();
|
||||||
}
|
|
||||||
|
|
||||||
bool db_err(char *e) {
|
|
||||||
if (e) {
|
|
||||||
LOGE("sqlite3_exec: %s\n", e);
|
|
||||||
sqlite3_free(e);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
@@ -201,7 +201,7 @@ void scan_deny_apps() {
|
|||||||
LOGI("denylist rm: [%s]\n", it->first.data());
|
LOGI("denylist rm: [%s]\n", it->first.data());
|
||||||
ssprintf(sql, sizeof(sql), "DELETE FROM denylist WHERE package_name='%s'",
|
ssprintf(sql, sizeof(sql), "DELETE FROM denylist WHERE package_name='%s'",
|
||||||
it->first.data());
|
it->first.data());
|
||||||
db_err(db_exec(sql));
|
db_exec(sql).check_err();
|
||||||
it = pkg_to_procs.erase(it);
|
it = pkg_to_procs.erase(it);
|
||||||
} else {
|
} else {
|
||||||
update_app_id(app_id, it->first, false);
|
update_app_id(app_id, it->first, false);
|
||||||
@@ -222,11 +222,12 @@ static bool ensure_data() {
|
|||||||
LOGI("denylist: initializing internal data structures\n");
|
LOGI("denylist: initializing internal data structures\n");
|
||||||
|
|
||||||
default_new(pkg_to_procs_);
|
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());
|
add_hide_set(row["package_name"].data(), row["process"].data());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
db_err_cmd(err, goto error)
|
if (res.check_err())
|
||||||
|
goto error;
|
||||||
|
|
||||||
default_new(app_id_to_pkgs_);
|
default_new(app_id_to_pkgs_);
|
||||||
scan_deny_apps();
|
scan_deny_apps();
|
||||||
@@ -262,9 +263,7 @@ static int add_list(const char *pkg, const char *proc) {
|
|||||||
char sql[4096];
|
char sql[4096];
|
||||||
ssprintf(sql, sizeof(sql),
|
ssprintf(sql, sizeof(sql),
|
||||||
"INSERT INTO denylist (package_name, process) VALUES('%s', '%s')", pkg, proc);
|
"INSERT INTO denylist (package_name, process) VALUES('%s', '%s')", pkg, proc);
|
||||||
char *err = db_exec(sql);
|
return db_exec(sql).check_err() ? DenyResponse::ERROR : DenyResponse::OK;
|
||||||
db_err_cmd(err, return DenyResponse::ERROR)
|
|
||||||
return DenyResponse::OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_list(int client) {
|
int add_list(int client) {
|
||||||
@@ -308,9 +307,7 @@ static int rm_list(const char *pkg, const char *proc) {
|
|||||||
else
|
else
|
||||||
ssprintf(sql, sizeof(sql),
|
ssprintf(sql, sizeof(sql),
|
||||||
"DELETE FROM denylist WHERE package_name='%s' AND process='%s'", pkg, proc);
|
"DELETE FROM denylist WHERE package_name='%s' AND process='%s'", pkg, proc);
|
||||||
char *err = db_exec(sql);
|
return db_exec(sql).check_err() ? DenyResponse::ERROR : DenyResponse::OK;
|
||||||
db_err_cmd(err, return DenyResponse::ERROR)
|
|
||||||
return DenyResponse::OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int rm_list(int client) {
|
int rm_list(int client) {
|
||||||
|
@@ -124,14 +124,21 @@ struct su_access {
|
|||||||
|
|
||||||
using db_row = std::map<std::string_view, std::string_view>;
|
using db_row = std::map<std::string_view, std::string_view>;
|
||||||
using db_row_cb = std::function<bool(db_row&)>;
|
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 get_db_settings(db_settings &cfg, int key = -1);
|
||||||
int set_db_settings(int key, int value);
|
int set_db_settings(int key, int value);
|
||||||
int get_db_strings(db_strings &str, int key = -1);
|
int get_db_strings(db_strings &str, int key = -1);
|
||||||
void rm_db_strings(int key);
|
void rm_db_strings(int key);
|
||||||
void exec_sql(int client);
|
void exec_sql(owned_fd client);
|
||||||
char *db_exec(const char *sql);
|
db_result db_exec(const char *sql);
|
||||||
char *db_exec(const char *sql, const db_row_cb &fn);
|
db_result 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; }
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
#![feature(format_args_nl)]
|
#![feature(format_args_nl)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(option_take_if)]
|
|
||||||
#![allow(clippy::missing_safety_doc)]
|
#![allow(clippy::missing_safety_doc)]
|
||||||
|
|
||||||
use base::Utf8CStr;
|
use base::Utf8CStr;
|
||||||
@@ -10,7 +9,7 @@ use daemon::{daemon_entry, find_apk_path, get_magiskd, MagiskD};
|
|||||||
use logging::{
|
use logging::{
|
||||||
android_logging, magisk_logging, zygisk_close_logd, zygisk_get_logd, zygisk_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};
|
use resetprop::{persist_delete_prop, persist_get_prop, persist_get_props, persist_set_prop};
|
||||||
|
|
||||||
mod cert;
|
mod cert;
|
||||||
@@ -93,6 +92,7 @@ pub mod ffi {
|
|||||||
fn find_apk_path(pkg: Utf8CStrRef, data: &mut [u8]) -> usize;
|
fn find_apk_path(pkg: Utf8CStrRef, data: &mut [u8]) -> usize;
|
||||||
fn read_certificate(fd: i32, version: i32) -> Vec<u8>;
|
fn read_certificate(fd: i32, version: i32) -> Vec<u8>;
|
||||||
fn setup_mounts();
|
fn setup_mounts();
|
||||||
|
fn clean_mounts();
|
||||||
fn find_preinit_device() -> String;
|
fn find_preinit_device() -> String;
|
||||||
fn revert_unmount(pid: i32);
|
fn revert_unmount(pid: i32);
|
||||||
unsafe fn persist_get_prop(name: Utf8CStrRef, prop_cb: Pin<&mut PropCb>);
|
unsafe fn persist_get_prop(name: Utf8CStrRef, prop_cb: Pin<&mut PropCb>);
|
||||||
|
@@ -157,11 +157,9 @@ void tmpfs_node::mount() {
|
|||||||
if (!isa<tmpfs_node>(parent())) {
|
if (!isa<tmpfs_node>(parent())) {
|
||||||
auto worker_dir = worker_path();
|
auto worker_dir = worker_path();
|
||||||
mkdirs(worker_dir.data(), 0);
|
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());
|
clone_attr(exist() ? node_path().data() : parent()->node_path().data(), worker_dir.data());
|
||||||
dir_node::mount();
|
dir_node::mount();
|
||||||
VLOGD(replace() ? "replace" : "move", worker_dir.data(), node_path().data());
|
bind_mount(replace() ? "replace" : "move", worker_dir.data(), node_path().data());
|
||||||
xmount(worker_dir.data(), node_path().data(), nullptr, MS_MOVE, nullptr);
|
|
||||||
xmount(nullptr, node_path().data(), nullptr, MS_REMOUNT | MS_BIND | MS_RDONLY, nullptr);
|
xmount(nullptr, node_path().data(), nullptr, MS_REMOUNT | MS_BIND | MS_RDONLY, nullptr);
|
||||||
} else {
|
} else {
|
||||||
const string dest = worker_path();
|
const string dest = worker_path();
|
||||||
@@ -213,6 +211,8 @@ public:
|
|||||||
const string src = get_magisk_tmp() + "/magisk"s;
|
const string src = get_magisk_tmp() + "/magisk"s;
|
||||||
(void) is64bit;
|
(void) is64bit;
|
||||||
#endif
|
#endif
|
||||||
|
if (access(src.data(), F_OK))
|
||||||
|
return;
|
||||||
create_and_mount("zygisk", src, true);
|
create_and_mount("zygisk", src, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,10 +333,7 @@ void load_modules() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cleanup mounts
|
// cleanup mounts
|
||||||
ssprintf(buf, sizeof(buf), "%s/" WORKERDIR, get_magisk_tmp());
|
clean_mounts();
|
||||||
xumount2(buf, MNT_DETACH);
|
|
||||||
ssprintf(buf, sizeof(buf), "%s/" MODULEMNT, get_magisk_tmp());
|
|
||||||
xumount2(buf, MNT_DETACH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************
|
/************************
|
||||||
|
@@ -94,36 +94,40 @@ pub fn setup_mounts() {
|
|||||||
ptr::null(),
|
ptr::null(),
|
||||||
)
|
)
|
||||||
.as_os_err()?;
|
.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(),
|
module_mnt.as_ptr(),
|
||||||
ptr::null(),
|
libc::MNT_DETACH,
|
||||||
libc::MS_PRIVATE,
|
|
||||||
ptr::null(),
|
|
||||||
)
|
)
|
||||||
.as_os_err()?;
|
.as_os_err()?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Prepare worker
|
|
||||||
let worker_dir = FsPathBuf::new(&mut buf).join(magisk_tmp).join(WORKERDIR);
|
let worker_dir = FsPathBuf::new(&mut buf).join(magisk_tmp).join(WORKERDIR);
|
||||||
let _: LoggedResult<()> = try {
|
let _: LoggedResult<()> = try {
|
||||||
worker_dir.mkdir(0)?;
|
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::mount(
|
libc::mount(
|
||||||
worker_dir.as_ptr(),
|
ptr::null(),
|
||||||
worker_dir.as_ptr(),
|
worker_dir.as_ptr(),
|
||||||
ptr::null(),
|
ptr::null(),
|
||||||
libc::MS_BIND,
|
libc::MS_PRIVATE | libc::MS_REC,
|
||||||
ptr::null(),
|
ptr::null(),
|
||||||
)
|
)
|
||||||
.as_os_err()?;
|
.as_os_err()?;
|
||||||
libc::mount(
|
libc::umount2(
|
||||||
ptr::null(),
|
|
||||||
worker_dir.as_ptr(),
|
worker_dir.as_ptr(),
|
||||||
ptr::null(),
|
libc::MNT_DETACH,
|
||||||
libc::MS_PRIVATE,
|
|
||||||
ptr::null(),
|
|
||||||
)
|
)
|
||||||
.as_os_err()?;
|
.as_os_err()?;
|
||||||
}
|
}
|
||||||
@@ -201,12 +205,16 @@ pub fn find_preinit_device() -> String {
|
|||||||
let (_, preinit_info, _) = matched_info.select_nth_unstable_by(
|
let (_, preinit_info, _) = matched_info.select_nth_unstable_by(
|
||||||
0,
|
0,
|
||||||
|(ap, MountInfo { fs_type: at, .. }), (bp, MountInfo { fs_type: bt, .. })| match (
|
|(ap, MountInfo { fs_type: at, .. }), (bp, MountInfo { fs_type: bt, .. })| match (
|
||||||
|
ap,
|
||||||
|
bp,
|
||||||
at.as_str() == "ext4",
|
at.as_str() == "ext4",
|
||||||
bt.as_str() == "ext4",
|
bt.as_str() == "ext4",
|
||||||
) {
|
) {
|
||||||
// take ext4 over others (f2fs) because f2fs has a kernel bug that causes kernel panic
|
// metadata is not affected by f2fs kernel bug
|
||||||
(true, false) => Less,
|
(PartId::Metadata, _, _, true) | (_, PartId::Metadata, true, _) => ap.cmp(bp),
|
||||||
(false, true) => Greater,
|
// otherwise, take ext4 f2fs because f2fs has a kernel bug that causes kernel panic
|
||||||
|
(_, _, true, false) => Less,
|
||||||
|
(_, _, false, true) => Greater,
|
||||||
// if both has the same fs type, compare the mount point
|
// if both has the same fs type, compare the mount point
|
||||||
_ => ap.cmp(bp),
|
_ => ap.cmp(bp),
|
||||||
},
|
},
|
||||||
|
@@ -222,6 +222,7 @@ void install_module(const char *file) {
|
|||||||
setenv("OUTFD", "1", 1);
|
setenv("OUTFD", "1", 1);
|
||||||
setenv("ZIPFILE", zip, 1);
|
setenv("ZIPFILE", zip, 1);
|
||||||
setenv("ASH_STANDALONE", "1", 1);
|
setenv("ASH_STANDALONE", "1", 1);
|
||||||
|
setenv("MAGISKTMP", get_magisk_tmp(), 0);
|
||||||
free(zip);
|
free(zip);
|
||||||
|
|
||||||
int fd = xopen("/dev/null", O_RDONLY);
|
int fd = xopen("/dev/null", O_RDONLY);
|
||||||
|
@@ -63,11 +63,11 @@ void su_info::check_db() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (eval_uid > 0) {
|
if (eval_uid > 0) {
|
||||||
char query[256], *err;
|
char query[256];
|
||||||
ssprintf(query, sizeof(query),
|
ssprintf(query, sizeof(query),
|
||||||
"SELECT policy, logging, notification FROM policies "
|
"SELECT policy, logging, notification FROM policies "
|
||||||
"WHERE uid=%d AND (until=0 OR until>%li)", eval_uid, time(nullptr));
|
"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.policy = (policy_t) parse_int(row["policy"]);
|
||||||
access.log = parse_int(row["logging"]);
|
access.log = parse_int(row["logging"]);
|
||||||
access.notify = parse_int(row["notification"]);
|
access.notify = parse_int(row["notification"]);
|
||||||
@@ -75,7 +75,8 @@ void su_info::check_db() {
|
|||||||
access.policy, access.log, access.notify);
|
access.policy, access.log, access.notify);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
db_err_cmd(err, return);
|
if (res.check_err())
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to check our manager
|
// We need to check our manager
|
||||||
@@ -123,15 +124,16 @@ bool uid_granted_root(int uid) {
|
|||||||
|
|
||||||
bool granted = false;
|
bool granted = false;
|
||||||
|
|
||||||
char query[256], *err;
|
char query[256];
|
||||||
ssprintf(query, sizeof(query),
|
ssprintf(query, sizeof(query),
|
||||||
"SELECT policy FROM policies WHERE uid=%d AND (until=0 OR until>%li)",
|
"SELECT policy FROM policies WHERE uid=%d AND (until=0 OR until>%li)",
|
||||||
uid, time(nullptr));
|
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;
|
granted = parse_int(row["policy"]) == ALLOW;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
db_err_cmd(err, return false);
|
if (res.check_err())
|
||||||
|
return false;
|
||||||
|
|
||||||
return granted;
|
return granted;
|
||||||
}
|
}
|
||||||
@@ -140,9 +142,7 @@ void prune_su_access() {
|
|||||||
cached.reset();
|
cached.reset();
|
||||||
vector<bool> app_no_list = get_app_no_list();
|
vector<bool> app_no_list = get_app_no_list();
|
||||||
vector<int> rm_uids;
|
vector<int> rm_uids;
|
||||||
char query[256], *err;
|
auto res = db_exec("SELECT uid FROM policies", [&](db_row &row) -> bool {
|
||||||
strscpy(query, "SELECT uid FROM policies", sizeof(query));
|
|
||||||
err = db_exec(query, [&](db_row &row) -> bool {
|
|
||||||
int uid = parse_int(row["uid"]);
|
int uid = parse_int(row["uid"]);
|
||||||
int app_id = to_app_id(uid);
|
int app_id = to_app_id(uid);
|
||||||
if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
|
if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
|
||||||
@@ -154,11 +154,13 @@ void prune_su_access() {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
db_err_cmd(err, return);
|
if (res.check_err())
|
||||||
|
return;
|
||||||
|
|
||||||
for (int uid : rm_uids) {
|
for (int uid : rm_uids) {
|
||||||
|
char query[256];
|
||||||
ssprintf(query, sizeof(query), "DELETE FROM policies WHERE uid == %d", uid);
|
ssprintf(query, sizeof(query), "DELETE FROM policies WHERE uid == %d", uid);
|
||||||
db_err(db_exec(query));
|
db_exec(query).check_err();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
native/src/external/crt0
vendored
2
native/src/external/crt0
vendored
Submodule native/src/external/crt0 updated: 17233ab90e...795cab5ab6
2
native/src/external/cxx-rs
vendored
2
native/src/external/cxx-rs
vendored
Submodule native/src/external/cxx-rs updated: 16abd4d2b4...7535230afb
@@ -41,16 +41,16 @@ static string extract_quoted_str_until(chars<escapes...>, chars<breaks...>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse string into key value pairs.
|
// Parse string into key value pairs.
|
||||||
// The string format: [delim][key][padding]=[padding][value][delim]
|
// The string format: [delim][key][padding][eq][padding][value][delim]
|
||||||
template<char delim, char... padding>
|
template<char delim, char eq, char... padding>
|
||||||
static kv_pairs parse_impl(chars<padding...>, string_view str) {
|
static kv_pairs parse_impl(chars<padding...>, string_view str) {
|
||||||
kv_pairs kv;
|
kv_pairs kv;
|
||||||
char skip_array[] = {'=', padding...};
|
char skip_array[] = {eq, padding...};
|
||||||
string_view skip(skip_array, std::size(skip_array));
|
string_view skip(skip_array, std::size(skip_array));
|
||||||
bool quoted = false;
|
bool quoted = false;
|
||||||
for (size_t pos = 0u; pos < str.size(); pos = str.find_first_not_of(delim, pos)) {
|
for (size_t pos = 0u; pos < str.size(); pos = str.find_first_not_of(delim, pos)) {
|
||||||
auto key = extract_quoted_str_until(
|
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);
|
pos = str.find_first_not_of(skip, pos);
|
||||||
if (pos == string_view::npos || str[pos] == delim) {
|
if (pos == string_view::npos || str[pos] == delim) {
|
||||||
kv.emplace_back(key, "");
|
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) {
|
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) {
|
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)))
|
#define test_bit(bit, array) (array[bit / 8] & (1 << (bit % 8)))
|
||||||
@@ -207,8 +210,29 @@ void load_kernel_info(BootConfig *config) {
|
|||||||
config->print();
|
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() {
|
bool check_two_stage() {
|
||||||
if (access("/apex", F_OK) == 0)
|
if (access("/first_stage_ramdisk", F_OK) == 0)
|
||||||
|
return true;
|
||||||
|
if (access("/second_stage_resources", F_OK) == 0)
|
||||||
return true;
|
return true;
|
||||||
if (access("/system/bin/init", F_OK) == 0)
|
if (access("/system/bin/init", F_OK) == 0)
|
||||||
return true;
|
return true;
|
||||||
|
@@ -6,14 +6,18 @@
|
|||||||
#include <xz.h>
|
#include <xz.h>
|
||||||
|
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <embed.hpp>
|
|
||||||
|
|
||||||
#include "init.hpp"
|
#include "init.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#ifdef USE_CRT0
|
#ifdef USE_CRT0
|
||||||
__asm__(".global vfprintf \n vfprintf = tfp_vfprintf");
|
__BEGIN_DECLS
|
||||||
|
int tiny_vfprintf(FILE *stream, const char *format, va_list arg);
|
||||||
|
int vfprintf(FILE *stream, const char *format, va_list arg) {
|
||||||
|
return tiny_vfprintf(stream, format, arg);
|
||||||
|
}
|
||||||
|
__END_DECLS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool unxz(out_stream &strm, rust::Slice<const uint8_t> bytes) {
|
bool unxz(out_stream &strm, rust::Slice<const uint8_t> bytes) {
|
||||||
@@ -86,15 +90,17 @@ int main(int argc, char *argv[]) {
|
|||||||
} else {
|
} else {
|
||||||
// This will also mount /sys and /proc
|
// This will also mount /sys and /proc
|
||||||
load_kernel_info(&config);
|
load_kernel_info(&config);
|
||||||
|
bool recovery = access("/sbin/recovery", F_OK) == 0 ||
|
||||||
|
access("/system/bin/recovery", F_OK) == 0;
|
||||||
|
|
||||||
if (config.skip_initramfs)
|
if (config.force_normal_boot)
|
||||||
|
init = new FirstStageInit(argv, &config);
|
||||||
|
else if (!recovery && check_two_stage())
|
||||||
|
init = new FirstStageInit(argv, &config);
|
||||||
|
else if (config.skip_initramfs)
|
||||||
init = new LegacySARInit(argv, &config);
|
init = new LegacySARInit(argv, &config);
|
||||||
else if (config.force_normal_boot)
|
else if (recovery)
|
||||||
init = new FirstStageInit(argv, &config);
|
|
||||||
else if (access("/sbin/recovery", F_OK) == 0 || access("/system/bin/recovery", F_OK) == 0)
|
|
||||||
init = new RecoveryInit(argv, &config);
|
init = new RecoveryInit(argv, &config);
|
||||||
else if (check_two_stage())
|
|
||||||
init = new FirstStageInit(argv, &config);
|
|
||||||
else
|
else
|
||||||
init = new RootFSInit(argv, &config);
|
init = new RootFSInit(argv, &config);
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,7 @@ extern std::vector<std::string> mount_list;
|
|||||||
int magisk_proxy_main(int argc, char *argv[]);
|
int magisk_proxy_main(int argc, char *argv[]);
|
||||||
bool unxz(out_stream &strm, rust::Slice<const uint8_t> bytes);
|
bool unxz(out_stream &strm, rust::Slice<const uint8_t> bytes);
|
||||||
void load_kernel_info(BootConfig *config);
|
void load_kernel_info(BootConfig *config);
|
||||||
|
kv_pairs load_partition_map();
|
||||||
bool check_two_stage();
|
bool check_two_stage();
|
||||||
const char *backup_init();
|
const char *backup_init();
|
||||||
void restore_ramdisk_init();
|
void restore_ramdisk_init();
|
||||||
|
@@ -29,21 +29,23 @@ bool avd_hack = false;
|
|||||||
static void parse_device(devinfo *dev, const char *uevent) {
|
static void parse_device(devinfo *dev, const char *uevent) {
|
||||||
dev->partname[0] = '\0';
|
dev->partname[0] = '\0';
|
||||||
dev->devpath[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 {
|
parse_prop_file(uevent, [=](string_view key, string_view value) -> bool {
|
||||||
if (key == "MAJOR")
|
if (key == "MAJOR")
|
||||||
dev->major = parse_int(value.data());
|
dev->major = parse_int(value.data());
|
||||||
else if (key == "MINOR")
|
else if (key == "MINOR")
|
||||||
dev->minor = parse_int(value.data());
|
dev->minor = parse_int(value.data());
|
||||||
else if (key == "DEVNAME")
|
else if (key == "DEVNAME")
|
||||||
strcpy(dev->devname, value.data());
|
strscpy(dev->devname, value.data(), sizeof(dev->devname));
|
||||||
else if (key == "PARTNAME")
|
else if (key == "PARTNAME")
|
||||||
strcpy(dev->partname, value.data());
|
strscpy(dev->partname, value.data(), sizeof(dev->devname));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void collect_devices() {
|
static void collect_devices(const auto &partition_map) {
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
devinfo dev{};
|
devinfo dev{};
|
||||||
if (auto dir = xopen_dir("/sys/dev/block"); dir) {
|
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);
|
sprintf(path, "/sys/dev/block/%s/dm/name", entry->d_name);
|
||||||
if (access(path, F_OK) == 0) {
|
if (access(path, F_OK) == 0) {
|
||||||
auto name = rtrim(full_read(path));
|
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);
|
sprintf(path, "/sys/dev/block/%s", entry->d_name);
|
||||||
xrealpath(path, dev.devpath, sizeof(dev.devpath));
|
xrealpath(path, dev.devpath, sizeof(dev.devpath));
|
||||||
@@ -70,8 +78,9 @@ static struct {
|
|||||||
} blk_info;
|
} blk_info;
|
||||||
|
|
||||||
static dev_t setup_block() {
|
static dev_t setup_block() {
|
||||||
|
static const auto partition_map = load_partition_map();
|
||||||
if (dev_list.empty())
|
if (dev_list.empty())
|
||||||
collect_devices();
|
collect_devices(partition_map);
|
||||||
|
|
||||||
for (int tries = 0; tries < 3; ++tries) {
|
for (int tries = 0; tries < 3; ++tries) {
|
||||||
for (auto &dev : dev_list) {
|
for (auto &dev : dev_list) {
|
||||||
@@ -93,7 +102,7 @@ static dev_t setup_block() {
|
|||||||
// Wait 10ms and try again
|
// Wait 10ms and try again
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
dev_list.clear();
|
dev_list.clear();
|
||||||
collect_devices();
|
collect_devices(partition_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The requested partname does not exist
|
// The requested partname does not exist
|
||||||
@@ -191,8 +200,7 @@ mount_root:
|
|||||||
xmount("tmpfs", "/dev", "tmpfs", 0, "mode=755");
|
xmount("tmpfs", "/dev", "tmpfs", 0, "mode=755");
|
||||||
mount_list.emplace_back("/dev");
|
mount_list.emplace_back("/dev");
|
||||||
|
|
||||||
// Use the apex folder to determine whether 2SI (Android 10+)
|
bool is_two_stage = access("/system/bin/init", F_OK) == 0;
|
||||||
bool is_two_stage = access("/apex", F_OK) == 0;
|
|
||||||
LOGD("is_two_stage: [%d]\n", is_two_stage);
|
LOGD("is_two_stage: [%d]\n", is_two_stage);
|
||||||
|
|
||||||
// For API 28 AVD, it uses legacy SAR setup that requires
|
// For API 28 AVD, it uses legacy SAR setup that requires
|
||||||
@@ -236,6 +244,7 @@ void MagiskInit::setup_tmp(const char *path) {
|
|||||||
|
|
||||||
xmkdir(INTLROOT, 0711);
|
xmkdir(INTLROOT, 0711);
|
||||||
xmkdir(DEVICEDIR, 0711);
|
xmkdir(DEVICEDIR, 0711);
|
||||||
|
xmkdir(WORKERDIR, 0);
|
||||||
|
|
||||||
mount_preinit_dir(preinit_dev);
|
mount_preinit_dir(preinit_dev);
|
||||||
|
|
||||||
@@ -249,5 +258,21 @@ void MagiskInit::setup_tmp(const char *path) {
|
|||||||
|
|
||||||
xmount(".", path, nullptr, MS_BIND, nullptr);
|
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("/");
|
chdir("/");
|
||||||
}
|
}
|
||||||
|
@@ -12,10 +12,31 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static vector<string> rc_list;
|
static vector<string> rc_list;
|
||||||
|
static string magic_mount_list;
|
||||||
|
|
||||||
#define NEW_INITRC_DIR "/system/etc/init/hw"
|
#define NEW_INITRC_DIR "/system/etc/init/hw"
|
||||||
#define INIT_RC "init.rc"
|
#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) {
|
static void patch_rc_scripts(const char *src_path, const char *tmp_path, bool writable) {
|
||||||
auto src_dir = xopen_dir(src_path);
|
auto src_dir = xopen_dir(src_path);
|
||||||
if (!src_dir) return;
|
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()));
|
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) {
|
static void load_overlay_rc(const char *overlay) {
|
||||||
@@ -164,31 +222,10 @@ static void recreate_sbin(const char *mirror, bool use_bind_mount) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static string magic_mount_list;
|
|
||||||
|
|
||||||
static void magic_mount(const string &sdir, const string &ddir = "") {
|
|
||||||
auto dir = xopen_dir(sdir.data());
|
|
||||||
if (!dir) return;
|
|
||||||
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
|
||||||
string src = sdir + "/" + entry->d_name;
|
|
||||||
string dest = ddir + "/" + entry->d_name;
|
|
||||||
if (access(dest.data(), F_OK) == 0) {
|
|
||||||
if (entry->d_type == DT_DIR) {
|
|
||||||
// Recursive
|
|
||||||
magic_mount(src, dest);
|
|
||||||
} else {
|
|
||||||
LOGD("Mount [%s] -> [%s]\n", src.data(), dest.data());
|
|
||||||
xmount(src.data(), dest.data(), nullptr, MS_BIND, nullptr);
|
|
||||||
magic_mount_list += dest;
|
|
||||||
magic_mount_list += '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void extract_files(bool sbin) {
|
static void extract_files(bool sbin) {
|
||||||
const char *magisk_xz = sbin ? "/sbin/magisk.xz" : "magisk.xz";
|
const char *magisk_xz = sbin ? "/sbin/magisk.xz" : "magisk.xz";
|
||||||
const char *stub_xz = sbin ? "/sbin/stub.xz" : "stub.xz";
|
const char *stub_xz = sbin ? "/sbin/stub.xz" : "stub.xz";
|
||||||
|
const char *init_ld_xz = sbin ? "/sbin/init-ld.xz" : "init-ld.xz";
|
||||||
|
|
||||||
if (access(magisk_xz, F_OK) == 0) {
|
if (access(magisk_xz, F_OK) == 0) {
|
||||||
mmap_data magisk(magisk_xz);
|
mmap_data magisk(magisk_xz);
|
||||||
@@ -206,6 +243,14 @@ static void extract_files(bool sbin) {
|
|||||||
unxz(ch, stub);
|
unxz(ch, stub);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
if (access(init_ld_xz, F_OK) == 0) {
|
||||||
|
mmap_data init_ld(init_ld_xz);
|
||||||
|
unlink(init_ld_xz);
|
||||||
|
int fd = xopen("init-ld", O_WRONLY | O_CREAT, 0);
|
||||||
|
fd_stream ch(fd);
|
||||||
|
unxz(ch, init_ld);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MagiskInit::parse_config_file() {
|
void MagiskInit::parse_config_file() {
|
||||||
@@ -279,16 +324,19 @@ void MagiskInit::patch_ro_root() {
|
|||||||
patch_rc_scripts("/", tmp_dir.data(), false);
|
patch_rc_scripts("/", tmp_dir.data(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract magisk
|
// Extract overlay archives
|
||||||
extract_files(false);
|
extract_files(false);
|
||||||
|
|
||||||
// Oculus Go will use a special sepolicy if unlocked
|
// Oculus Go will use a special sepolicy if unlocked
|
||||||
if (access("/sepolicy.unlocked", F_OK) == 0) {
|
if (access("/sepolicy.unlocked", F_OK) == 0) {
|
||||||
patch_sepolicy("/sepolicy.unlocked", ROOTOVL "/sepolicy.unlocked");
|
patch_sepolicy("/sepolicy.unlocked", ROOTOVL "/sepolicy.unlocked");
|
||||||
} else if ((access(SPLIT_PLAT_CIL, F_OK) != 0 && access("/sepolicy", F_OK) == 0) ||
|
} else {
|
||||||
!hijack_sepolicy()) {
|
bool patch = access(SPLIT_PLAT_CIL, F_OK) != 0 && access("/sepolicy", F_OK) == 0;
|
||||||
|
if (patch || !hijack_sepolicy()) {
|
||||||
patch_sepolicy("/sepolicy", ROOTOVL "/sepolicy");
|
patch_sepolicy("/sepolicy", ROOTOVL "/sepolicy");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
unlink("init-ld");
|
||||||
|
|
||||||
// Mount rootdir
|
// Mount rootdir
|
||||||
magic_mount(ROOTOVL);
|
magic_mount(ROOTOVL);
|
||||||
@@ -338,12 +386,14 @@ void MagiskInit::patch_rw_root() {
|
|||||||
setup_tmp(PRE_TMPDIR);
|
setup_tmp(PRE_TMPDIR);
|
||||||
chdir(PRE_TMPDIR);
|
chdir(PRE_TMPDIR);
|
||||||
|
|
||||||
// Extract magisk
|
// Extract overlay archives
|
||||||
extract_files(true);
|
extract_files(true);
|
||||||
|
|
||||||
if ((!treble && access("/sepolicy", F_OK) == 0) || !hijack_sepolicy()) {
|
bool patch = !treble && access("/sepolicy", F_OK) == 0;
|
||||||
|
if (patch || !hijack_sepolicy()) {
|
||||||
patch_sepolicy("/sepolicy", "/sepolicy");
|
patch_sepolicy("/sepolicy", "/sepolicy");
|
||||||
}
|
}
|
||||||
|
unlink("init-ld");
|
||||||
|
|
||||||
chdir("/");
|
chdir("/");
|
||||||
|
|
||||||
|
@@ -14,7 +14,6 @@ pub fn inject_magisk_rc(fd: RawFd, tmp_dir: &Utf8CStr) {
|
|||||||
file,
|
file,
|
||||||
r#"
|
r#"
|
||||||
on post-fs-data
|
on post-fs-data
|
||||||
start logd
|
|
||||||
exec {0} 0 0 -- {1}/magisk --post-fs-data
|
exec {0} 0 0 -- {1}/magisk --post-fs-data
|
||||||
|
|
||||||
on property:vold.decrypt=trigger_restart_framework
|
on property:vold.decrypt=trigger_restart_framework
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <consts.hpp>
|
#include <consts.hpp>
|
||||||
#include <sepolicy.hpp>
|
#include <sepolicy.hpp>
|
||||||
#include <embed.hpp>
|
|
||||||
|
|
||||||
#include "init.hpp"
|
#include "init.hpp"
|
||||||
|
|
||||||
@@ -31,16 +30,6 @@ void MagiskInit::patch_sepolicy(const char *in, const char *out) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_preload() {
|
|
||||||
int fd = xopen("/dev/preload.so", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
|
|
||||||
if (fd < 0)
|
|
||||||
return;
|
|
||||||
fd_stream ch(fd);
|
|
||||||
if (!unxz(ch, byte_view(init_ld_xz, sizeof(init_ld_xz))))
|
|
||||||
return;
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MOCK_COMPAT SELINUXMOCK "/compatible"
|
#define MOCK_COMPAT SELINUXMOCK "/compatible"
|
||||||
#define MOCK_LOAD SELINUXMOCK "/load"
|
#define MOCK_LOAD SELINUXMOCK "/load"
|
||||||
#define MOCK_ENFORCE SELINUXMOCK "/enforce"
|
#define MOCK_ENFORCE SELINUXMOCK "/enforce"
|
||||||
@@ -53,7 +42,7 @@ bool MagiskInit::hijack_sepolicy() {
|
|||||||
// This meant that instead of going through convoluted methods trying to alter
|
// This meant that instead of going through convoluted methods trying to alter
|
||||||
// and block init's control flow, we can just LD_PRELOAD and replace the
|
// and block init's control flow, we can just LD_PRELOAD and replace the
|
||||||
// security_load_policy function with our own implementation.
|
// security_load_policy function with our own implementation.
|
||||||
dump_preload();
|
cp_afc("init-ld", "/dev/preload.so");
|
||||||
setenv("LD_PRELOAD", "/dev/preload.so", 1);
|
setenv("LD_PRELOAD", "/dev/preload.so", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,18 +89,10 @@ bool MagiskInit::hijack_sepolicy() {
|
|||||||
|
|
||||||
// Read all custom rules into memory
|
// Read all custom rules into memory
|
||||||
string rules;
|
string rules;
|
||||||
if (auto dir = xopen_dir("/data/" PREINITMIRR)) {
|
auto rule = "/data/" PREINITMIRR "/sepolicy.rule";
|
||||||
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
if (xaccess(rule, R_OK) == 0) {
|
||||||
auto name = "/data/" PREINITMIRR "/"s + entry->d_name;
|
LOGD("Loading custom sepolicy patch: [%s]\n", rule);
|
||||||
auto rule_file = name + "/sepolicy.rule";
|
rules = full_read(rule);
|
||||||
if (xaccess(rule_file.data(), R_OK) == 0 &&
|
|
||||||
access((name + "/disable").data(), F_OK) != 0 &&
|
|
||||||
access((name + "/remove").data(), F_OK) != 0) {
|
|
||||||
LOGD("Load custom sepolicy patch: [%s]\n", rule_file.data());
|
|
||||||
full_read(rule_file.data(), rules);
|
|
||||||
rules += '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Create a new process waiting for init operations
|
// Create a new process waiting for init operations
|
||||||
if (xfork()) {
|
if (xfork()) {
|
||||||
|
@@ -118,10 +118,6 @@ impl SepolicyExt for sepolicy {
|
|||||||
|
|
||||||
fn load_rules_from_reader<T: BufRead>(mut self: Pin<&mut sepolicy>, reader: &mut T) {
|
fn load_rules_from_reader<T: BufRead>(mut self: Pin<&mut sepolicy>, reader: &mut T) {
|
||||||
reader.foreach_lines(|line| {
|
reader.foreach_lines(|line| {
|
||||||
let line = line.trim();
|
|
||||||
if line.is_empty() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
parse_statement(self.as_mut(), line);
|
parse_statement(self.as_mut(), line);
|
||||||
true
|
true
|
||||||
});
|
});
|
||||||
|
@@ -271,6 +271,10 @@ bool sepol_impl::add_rule(const char *s, const char *t, const char *c, const cha
|
|||||||
#define ioctl_func(x) (x & 0xFF)
|
#define ioctl_func(x) (x & 0xFF)
|
||||||
|
|
||||||
void sepol_impl::add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls, const Xperm &p, int effect) {
|
void sepol_impl::add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls, const Xperm &p, int effect) {
|
||||||
|
if (db->policyvers < POLICYDB_VERSION_XPERMS_IOCTL) {
|
||||||
|
LOGW("policy version %u does not support ioctl extended permissions rules\n", db->policyvers);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (src == nullptr) {
|
if (src == nullptr) {
|
||||||
for_each_attr(db->p_types.table, [&](type_datum_t *type) {
|
for_each_attr(db->p_types.table, [&](type_datum_t *type) {
|
||||||
add_xperm_rule(type, tgt, cls, p, effect);
|
add_xperm_rule(type, tgt, cls, p, effect);
|
||||||
|
@@ -3,7 +3,6 @@ use std::io::stderr;
|
|||||||
use std::{iter::Peekable, pin::Pin, vec::IntoIter};
|
use std::{iter::Peekable, pin::Pin, vec::IntoIter};
|
||||||
|
|
||||||
use base::{error, warn, FmtAdaptor};
|
use base::{error, warn, FmtAdaptor};
|
||||||
|
|
||||||
use crate::ffi::Xperm;
|
use crate::ffi::Xperm;
|
||||||
use crate::sepolicy;
|
use crate::sepolicy;
|
||||||
|
|
||||||
@@ -436,15 +435,16 @@ fn extract_token<'a>(s: &'a str, tokens: &mut Vec<Token<'a>>) {
|
|||||||
fn tokenize_statement(statement: &str) -> Vec<Token> {
|
fn tokenize_statement(statement: &str) -> Vec<Token> {
|
||||||
let mut tokens = Vec::new();
|
let mut tokens = Vec::new();
|
||||||
for s in statement.split_whitespace() {
|
for s in statement.split_whitespace() {
|
||||||
if s.starts_with('#') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
extract_token(s, &mut tokens);
|
extract_token(s, &mut tokens);
|
||||||
}
|
}
|
||||||
tokens
|
tokens
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_statement(sepolicy: Pin<&mut sepolicy>, statement: &str) {
|
pub fn parse_statement(sepolicy: Pin<&mut sepolicy>, statement: &str) {
|
||||||
|
let statement = statement.trim();
|
||||||
|
if statement.is_empty() || statement.starts_with('#') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let mut tokens = tokenize_statement(statement).into_iter().peekable();
|
let mut tokens = tokenize_statement(statement).into_iter().peekable();
|
||||||
let result = exec_statement(sepolicy, &mut tokens);
|
let result = exec_statement(sepolicy, &mut tokens);
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
|
@@ -2,10 +2,14 @@
|
|||||||
# Magisk app internal scripts
|
# Magisk app internal scripts
|
||||||
##################################
|
##################################
|
||||||
|
|
||||||
|
# $1 = delay
|
||||||
|
# $2 = command
|
||||||
run_delay() {
|
run_delay() {
|
||||||
(sleep $1; $2)&
|
(sleep $1; $2)&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# $1 = version string
|
||||||
|
# $2 = version code
|
||||||
env_check() {
|
env_check() {
|
||||||
for file in busybox magiskboot magiskinit util_functions.sh boot_patch.sh; do
|
for file in busybox magiskboot magiskinit util_functions.sh boot_patch.sh; do
|
||||||
[ -f "$MAGISKBIN/$file" ] || return 1
|
[ -f "$MAGISKBIN/$file" ] || return 1
|
||||||
@@ -21,6 +25,8 @@ env_check() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# $1 = dir to copy
|
||||||
|
# $2 = destination (optional)
|
||||||
cp_readlink() {
|
cp_readlink() {
|
||||||
if [ -z $2 ]; then
|
if [ -z $2 ]; then
|
||||||
cd $1
|
cd $1
|
||||||
@@ -39,6 +45,7 @@ cp_readlink() {
|
|||||||
cd /
|
cd /
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# $1 = install dir
|
||||||
fix_env() {
|
fix_env() {
|
||||||
# Cleanup and make dirs
|
# Cleanup and make dirs
|
||||||
rm -rf $MAGISKBIN/*
|
rm -rf $MAGISKBIN/*
|
||||||
@@ -49,6 +56,8 @@ fix_env() {
|
|||||||
chown -R 0:0 $MAGISKBIN
|
chown -R 0:0 $MAGISKBIN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# $1 = install dir
|
||||||
|
# $2 = boot partition
|
||||||
direct_install() {
|
direct_install() {
|
||||||
echo "- Flashing new boot image"
|
echo "- Flashing new boot image"
|
||||||
flash_image $1/new-boot.img $2
|
flash_image $1/new-boot.img $2
|
||||||
@@ -70,6 +79,7 @@ direct_install() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# $1 = uninstaller zip
|
||||||
run_uninstaller() {
|
run_uninstaller() {
|
||||||
rm -rf /dev/tmp
|
rm -rf /dev/tmp
|
||||||
mkdir -p /dev/tmp/install
|
mkdir -p /dev/tmp/install
|
||||||
@@ -77,24 +87,16 @@ run_uninstaller() {
|
|||||||
INSTALLER=/dev/tmp/install sh /dev/tmp/install/assets/uninstaller.sh dummy 1 "$1"
|
INSTALLER=/dev/tmp/install sh /dev/tmp/install/assets/uninstaller.sh dummy 1 "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# $1 = boot partition
|
||||||
restore_imgs() {
|
restore_imgs() {
|
||||||
[ -z $SHA1 ] && return 1
|
local SHA1=$(grep_prop SHA1 $MAGISKTMP/.magisk/config)
|
||||||
local BACKUPDIR=/data/magisk_backup_$SHA1
|
local BACKUPDIR=/data/magisk_backup_$SHA1
|
||||||
[ -d $BACKUPDIR ] || return 1
|
[ -d $BACKUPDIR ] || return 1
|
||||||
|
|
||||||
get_flags
|
|
||||||
find_boot_image
|
|
||||||
|
|
||||||
for name in dtb dtbo; do
|
|
||||||
[ -f $BACKUPDIR/${name}.img.gz ] || continue
|
|
||||||
local IMAGE=$(find_block $name$SLOT)
|
|
||||||
[ -z $IMAGE ] && continue
|
|
||||||
flash_image $BACKUPDIR/${name}.img.gz $IMAGE
|
|
||||||
done
|
|
||||||
[ -f $BACKUPDIR/boot.img.gz ] || return 1
|
[ -f $BACKUPDIR/boot.img.gz ] || return 1
|
||||||
flash_image $BACKUPDIR/boot.img.gz $BOOTIMAGE
|
flash_image $BACKUPDIR/boot.img.gz $1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# $1 = path to bootctl executable
|
||||||
post_ota() {
|
post_ota() {
|
||||||
cd /data/adb
|
cd /data/adb
|
||||||
cp -f $1 bootctl
|
cp -f $1 bootctl
|
||||||
@@ -131,6 +133,8 @@ EOF
|
|||||||
cd /
|
cd /
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# $1 = APK
|
||||||
|
# $2 = package name
|
||||||
adb_pm_install() {
|
adb_pm_install() {
|
||||||
local tmp=/data/local/tmp/temp.apk
|
local tmp=/data/local/tmp/temp.apk
|
||||||
cp -f "$1" $tmp
|
cp -f "$1" $tmp
|
||||||
@@ -189,6 +193,15 @@ printvar() {
|
|||||||
eval echo $1=\$$1
|
eval echo $1=\$$1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run_action() {
|
||||||
|
local MODID="$1"
|
||||||
|
cd "/data/adb/modules/$MODID"
|
||||||
|
sh ./action.sh
|
||||||
|
local RES=$?
|
||||||
|
cd /
|
||||||
|
return $RES
|
||||||
|
}
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
# Non-root util_functions
|
# Non-root util_functions
|
||||||
##########################
|
##########################
|
||||||
@@ -232,7 +245,6 @@ app_init() {
|
|||||||
check_boot_ramdisk && RAMDISKEXIST=true
|
check_boot_ramdisk && RAMDISKEXIST=true
|
||||||
get_flags >/dev/null
|
get_flags >/dev/null
|
||||||
run_migrations >/dev/null
|
run_migrations >/dev/null
|
||||||
SHA1=$(grep_prop SHA1 $MAGISKTMP/.magisk/config)
|
|
||||||
check_encryption
|
check_encryption
|
||||||
|
|
||||||
# Dump variables
|
# Dump variables
|
||||||
|
@@ -71,13 +71,14 @@ export KEEPFORCEENCRYPT=true
|
|||||||
echo "KEEPVERITY=$KEEPVERITY" > config
|
echo "KEEPVERITY=$KEEPVERITY" > config
|
||||||
echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
|
echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
|
||||||
echo "PREINITDEVICE=$(./magisk --preinit-device)" >> config
|
echo "PREINITDEVICE=$(./magisk --preinit-device)" >> config
|
||||||
# For API 28, we also patch advancedFeatures.ini to disable SAR
|
# For API 28, we also manually disable SystemAsRoot
|
||||||
# Manually override skip_initramfs by setting RECOVERYMODE=true
|
# Explicitly override skip_initramfs by setting RECOVERYMODE=true
|
||||||
[ $API = "28" ] && echo 'RECOVERYMODE=true' >> config
|
[ $API = "28" ] && echo 'RECOVERYMODE=true' >> config
|
||||||
cat config
|
cat config
|
||||||
|
|
||||||
./magiskboot compress=xz magisk magisk.xz
|
./magiskboot compress=xz magisk magisk.xz
|
||||||
./magiskboot compress=xz stub.apk stub.xz
|
./magiskboot compress=xz stub.apk stub.xz
|
||||||
|
./magiskboot compress=xz init-ld init-ld.xz
|
||||||
|
|
||||||
./magiskboot cpio ramdisk.cpio \
|
./magiskboot cpio ramdisk.cpio \
|
||||||
"add 0750 init magiskinit" \
|
"add 0750 init magiskinit" \
|
||||||
@@ -85,12 +86,13 @@ cat config
|
|||||||
"mkdir 0750 overlay.d/sbin" \
|
"mkdir 0750 overlay.d/sbin" \
|
||||||
"add 0644 overlay.d/sbin/magisk.xz magisk.xz" \
|
"add 0644 overlay.d/sbin/magisk.xz magisk.xz" \
|
||||||
"add 0644 overlay.d/sbin/stub.xz stub.xz" \
|
"add 0644 overlay.d/sbin/stub.xz stub.xz" \
|
||||||
|
"add 0644 overlay.d/sbin/init-ld.xz init-ld.xz" \
|
||||||
"patch" \
|
"patch" \
|
||||||
"backup ramdisk.cpio.orig" \
|
"backup ramdisk.cpio.orig" \
|
||||||
"mkdir 000 .backup" \
|
"mkdir 000 .backup" \
|
||||||
"add 000 .backup/.magisk config"
|
"add 000 .backup/.magisk config"
|
||||||
|
|
||||||
rm -f ramdisk.cpio.orig config magisk*.xz stub.xz
|
rm -f ramdisk.cpio.orig config *.xz
|
||||||
if $IS_RAMDISK; then
|
if $IS_RAMDISK; then
|
||||||
./magiskboot compress=gzip ramdisk.cpio "$OUTPUT_FILE"
|
./magiskboot compress=gzip ramdisk.cpio "$OUTPUT_FILE"
|
||||||
else
|
else
|
||||||
|
@@ -10,6 +10,7 @@ emu_pid=
|
|||||||
atd_min_api=30
|
atd_min_api=30
|
||||||
atd_max_api=34
|
atd_max_api=34
|
||||||
lsposed_min_api=27
|
lsposed_min_api=27
|
||||||
|
lsposed_max_api=34
|
||||||
huge_ram_min_api=26
|
huge_ram_min_api=26
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
@@ -67,29 +68,24 @@ test_emu() {
|
|||||||
|
|
||||||
print_title "* Testing $pkg ($variant)"
|
print_title "* Testing $pkg ($variant)"
|
||||||
|
|
||||||
if [ -n "$AVD_TEST_VERBOSE" ]; then
|
if [ -n "$AVD_TEST_LOG" ]; then
|
||||||
"$emu" @test $emu_args &
|
"$emu" @test $emu_args > kernel.log 2>&1 &
|
||||||
emu_pid=$!
|
|
||||||
adb logcat &
|
|
||||||
else
|
else
|
||||||
"$emu" @test $emu_args 2>/dev/null &
|
"$emu" @test $emu_args > /dev/null 2>&1 &
|
||||||
emu_pid=$!
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
emu_pid=$!
|
||||||
wait_emu wait_for_boot
|
wait_emu wait_for_boot
|
||||||
|
|
||||||
test_setup $variant
|
test_setup $variant
|
||||||
|
|
||||||
# Install LSPosed
|
# 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
|
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
|
echo 'PATH=$PATH:/debug_ramdisk magisk --install-module /data/local/tmp/lsposed.zip' | adb shell /system/xbin/su
|
||||||
fi
|
fi
|
||||||
|
|
||||||
adb reboot
|
adb reboot
|
||||||
if [ -n "$AVD_TEST_VERBOSE" ]; then
|
|
||||||
adb logcat &
|
|
||||||
fi
|
|
||||||
wait_emu wait_for_boot
|
wait_emu wait_for_boot
|
||||||
|
|
||||||
test_app
|
test_app
|
||||||
@@ -147,9 +143,6 @@ run_test() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
emu_args="$emu_args_base -memory $memory"
|
emu_args="$emu_args_base -memory $memory"
|
||||||
if [ -n "$AVD_TEST_VERBOSE" ]; then
|
|
||||||
emu_args="$emu_args -show-kernel"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Setup emulator
|
# Setup emulator
|
||||||
"$sdk" --channel=3 $pkg
|
"$sdk" --channel=3 $pkg
|
||||||
@@ -157,12 +150,15 @@ run_test() {
|
|||||||
|
|
||||||
# Launch stock emulator
|
# Launch stock emulator
|
||||||
print_title "* Launching $pkg"
|
print_title "* Launching $pkg"
|
||||||
"$emu" @test $emu_args 2>/dev/null &
|
"$emu" @test $emu_args >/dev/null 2>&1 &
|
||||||
emu_pid=$!
|
emu_pid=$!
|
||||||
wait_emu wait_for_bootanim
|
wait_emu wait_for_bootanim
|
||||||
|
|
||||||
# Update arguments for Magisk runs
|
# Update arguments for Magisk runs
|
||||||
emu_args="$emu_args -ramdisk magisk_patched.img -feature -SystemAsRoot"
|
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
|
# Patch and test debug build
|
||||||
./build.py avd_patch -s "$ramdisk" magisk_patched.img
|
./build.py avd_patch -s "$ramdisk" magisk_patched.img
|
||||||
@@ -210,7 +206,7 @@ fi
|
|||||||
|
|
||||||
yes | "$sdk" --licenses > /dev/null
|
yes | "$sdk" --licenses > /dev/null
|
||||||
curl -L $lsposed_url -o out/lsposed.zip
|
curl -L $lsposed_url -o out/lsposed.zip
|
||||||
"$sdk" --channel=3 tools platform-tools emulator
|
"$sdk" --channel=3 platform-tools emulator
|
||||||
|
|
||||||
if [ -n "$1" ]; then
|
if [ -n "$1" ]; then
|
||||||
run_test $1 $2
|
run_test $1 $2
|
||||||
@@ -221,7 +217,7 @@ else
|
|||||||
# Android 15 Beta
|
# Android 15 Beta
|
||||||
run_test 35 google_apis
|
run_test 35 google_apis
|
||||||
# Run 16k page tests
|
# Run 16k page tests
|
||||||
run_test VanillaIceCream google_apis_ps16k
|
run_test 35 google_apis_ps16k
|
||||||
fi
|
fi
|
||||||
|
|
||||||
"$avd" delete avd -n test
|
"$avd" delete avd -n test
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
# magiskinit binary The binary to replace /init.
|
# magiskinit binary The binary to replace /init.
|
||||||
# magisk binary The magisk binary.
|
# magisk binary The magisk binary.
|
||||||
# magiskboot binary A tool to manipulate boot images.
|
# magiskboot binary A tool to manipulate boot images.
|
||||||
|
# init-ld binary The library that will be LD_PRELOAD of /init
|
||||||
# stub.apk binary The stub Magisk app to embed into ramdisk.
|
# stub.apk binary The stub Magisk app to embed into ramdisk.
|
||||||
# chromeos folder This folder includes the utility and keys to sign
|
# chromeos folder This folder includes the utility and keys to sign
|
||||||
# (optional) chromeos boot images. Only used for Pixel C.
|
# (optional) chromeos boot images. Only used for Pixel C.
|
||||||
@@ -118,14 +119,16 @@ else
|
|||||||
STATUS=0
|
STATUS=0
|
||||||
SKIP_BACKUP="#"
|
SKIP_BACKUP="#"
|
||||||
fi
|
fi
|
||||||
case $((STATUS & 3)) in
|
case $STATUS in
|
||||||
0 ) # Stock boot
|
0 )
|
||||||
|
# Stock boot
|
||||||
ui_print "- Stock boot image detected"
|
ui_print "- Stock boot image detected"
|
||||||
SHA1=$(./magiskboot sha1 "$BOOTIMAGE" 2>/dev/null)
|
SHA1=$(./magiskboot sha1 "$BOOTIMAGE" 2>/dev/null)
|
||||||
cat $BOOTIMAGE > stock_boot.img
|
cat $BOOTIMAGE > stock_boot.img
|
||||||
cp -af ramdisk.cpio ramdisk.cpio.orig 2>/dev/null
|
cp -af ramdisk.cpio ramdisk.cpio.orig 2>/dev/null
|
||||||
;;
|
;;
|
||||||
1 ) # Magisk patched
|
1 )
|
||||||
|
# Magisk patched
|
||||||
ui_print "- Magisk patched boot image detected"
|
ui_print "- Magisk patched boot image detected"
|
||||||
./magiskboot cpio ramdisk.cpio \
|
./magiskboot cpio ramdisk.cpio \
|
||||||
"extract .backup/.magisk config.orig" \
|
"extract .backup/.magisk config.orig" \
|
||||||
@@ -133,7 +136,8 @@ case $((STATUS & 3)) in
|
|||||||
cp -af ramdisk.cpio ramdisk.cpio.orig
|
cp -af ramdisk.cpio ramdisk.cpio.orig
|
||||||
rm -f stock_boot.img
|
rm -f stock_boot.img
|
||||||
;;
|
;;
|
||||||
2 ) # Unsupported
|
2 )
|
||||||
|
# Unsupported
|
||||||
ui_print "! Boot image patched by unsupported programs"
|
ui_print "! Boot image patched by unsupported programs"
|
||||||
abort "! Please restore back to stock boot image"
|
abort "! Please restore back to stock boot image"
|
||||||
;;
|
;;
|
||||||
@@ -161,6 +165,7 @@ $BOOTMODE && [ -z "$PREINITDEVICE" ] && PREINITDEVICE=$(./magisk --preinit-devic
|
|||||||
# Compress to save precious ramdisk space
|
# Compress to save precious ramdisk space
|
||||||
./magiskboot compress=xz magisk magisk.xz
|
./magiskboot compress=xz magisk magisk.xz
|
||||||
./magiskboot compress=xz stub.apk stub.xz
|
./magiskboot compress=xz stub.apk stub.xz
|
||||||
|
./magiskboot compress=xz init-ld init-ld.xz
|
||||||
|
|
||||||
echo "KEEPVERITY=$KEEPVERITY" > config
|
echo "KEEPVERITY=$KEEPVERITY" > config
|
||||||
echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
|
echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
|
||||||
@@ -177,13 +182,14 @@ fi
|
|||||||
"mkdir 0750 overlay.d/sbin" \
|
"mkdir 0750 overlay.d/sbin" \
|
||||||
"add 0644 overlay.d/sbin/magisk.xz magisk.xz" \
|
"add 0644 overlay.d/sbin/magisk.xz magisk.xz" \
|
||||||
"add 0644 overlay.d/sbin/stub.xz stub.xz" \
|
"add 0644 overlay.d/sbin/stub.xz stub.xz" \
|
||||||
|
"add 0644 overlay.d/sbin/init-ld.xz init-ld.xz" \
|
||||||
"patch" \
|
"patch" \
|
||||||
"$SKIP_BACKUP backup ramdisk.cpio.orig" \
|
"$SKIP_BACKUP backup ramdisk.cpio.orig" \
|
||||||
"mkdir 000 .backup" \
|
"mkdir 000 .backup" \
|
||||||
"add 000 .backup/.magisk config" \
|
"add 000 .backup/.magisk config" \
|
||||||
|| abort "! Unable to patch ramdisk"
|
|| abort "! Unable to patch ramdisk"
|
||||||
|
|
||||||
rm -f ramdisk.cpio.orig config magisk*.xz stub.xz
|
rm -f ramdisk.cpio.orig config *.xz
|
||||||
|
|
||||||
#################
|
#################
|
||||||
# Binary Patches
|
# Binary Patches
|
||||||
@@ -214,6 +220,13 @@ if [ -f kernel ]; then
|
|||||||
# After: [mov w2, #-32768]
|
# After: [mov w2, #-32768]
|
||||||
./magiskboot hexpatch kernel 821B8012 E2FF8F12 && PATCHEDKERNEL=true
|
./magiskboot hexpatch kernel 821B8012 E2FF8F12 && PATCHEDKERNEL=true
|
||||||
|
|
||||||
|
# Disable Samsung PROCA
|
||||||
|
# proca_config -> proca_magisk
|
||||||
|
./magiskboot hexpatch kernel \
|
||||||
|
70726F63615F636F6E66696700 \
|
||||||
|
70726F63615F6D616769736B00 \
|
||||||
|
&& PATCHEDKERNEL=true
|
||||||
|
|
||||||
# Force kernel to load rootfs for legacy SAR devices
|
# Force kernel to load rootfs for legacy SAR devices
|
||||||
# skip_initramfs -> want_initramfs
|
# skip_initramfs -> want_initramfs
|
||||||
$LEGACYSAR && ./magiskboot hexpatch kernel \
|
$LEGACYSAR && ./magiskboot hexpatch kernel \
|
||||||
|
@@ -19,7 +19,7 @@ run_cvd_bin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setup_env() {
|
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
|
sudo dpkg -i ./cuttlefish-base_*_*64.deb || sudo apt-get install -f
|
||||||
rm cuttlefish-base_*_*64.deb
|
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
|
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() {
|
download_cf() {
|
||||||
local branch=$1
|
local branch=$1
|
||||||
local target=$2
|
local device=$2
|
||||||
|
|
||||||
if [ -z $branch ]; then
|
if [ -z $branch ]; then
|
||||||
branch='aosp-main'
|
branch='aosp-main'
|
||||||
fi
|
fi
|
||||||
if [ -z $target ]; then
|
if [ -z $device ]; then
|
||||||
target='aosp_cf_x86_64_phone-trunk_staging-userdebug'
|
device='aosp_cf_x86_64_phone'
|
||||||
fi
|
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 | \
|
local build_id=$(curl -sL https://ci.android.com/builds/branches/${branch}/status.json | \
|
||||||
jq -r ".targets[] | select(.name == \"$target\") | .last_known_good_build")
|
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 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"
|
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 -L $sys_img_url -o aosp_cf_phone-img.zip
|
||||||
curl -LO $host_pkg_url
|
curl -LO $host_pkg_url
|
||||||
rm -rf $CF_HOME
|
rm -rf $CF_HOME
|
||||||
|
244
scripts/release.sh
Executable file
244
scripts/release.sh
Executable file
@@ -0,0 +1,244 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# On macOS, gsed is required (brew install gnu-sed)
|
||||||
|
# Required tools: jq, gh
|
||||||
|
# The GitHub cli (gh) has to be properly authenticated
|
||||||
|
|
||||||
|
# These variables can be modified as needed
|
||||||
|
MAGISK_FILES=../magisk-files
|
||||||
|
CONFIG=config.prop
|
||||||
|
NOTES=notes.md
|
||||||
|
|
||||||
|
# These are constants, do not modify
|
||||||
|
GCONFIG=gradle.properties
|
||||||
|
README=README.MD
|
||||||
|
BUILDCMD="./build.py -c $CONFIG"
|
||||||
|
CWD=$(pwd)
|
||||||
|
|
||||||
|
grep_prop() {
|
||||||
|
local REGEX="s/^$1=//p"
|
||||||
|
shift
|
||||||
|
local FILES=$@
|
||||||
|
sed -n "$REGEX" $FILES | head -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_version_config() {
|
||||||
|
# Make sure version is not commented out and exists
|
||||||
|
sed -i "s:^# version=:version=:g" $CONFIG
|
||||||
|
if ! grep -qE '^version=' $CONFIG; then
|
||||||
|
echo 'version=' >> $CONFIG
|
||||||
|
fi
|
||||||
|
# Make sure abiList is not set when building for release
|
||||||
|
sed -i "s:^abiList=:# abiList=:g" $CONFIG
|
||||||
|
}
|
||||||
|
|
||||||
|
disable_version_config() {
|
||||||
|
# Comment out version config
|
||||||
|
sed -i "s:^version=:# version=:g" $CONFIG
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 = tag
|
||||||
|
update_readme_stable() {
|
||||||
|
sed -i "s:badge/Magisk-v.*:badge/Magisk-${1}-blue)](https\://github.com/topjohnwu/Magisk/releases/tag/$1):g" $README
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 = tag
|
||||||
|
update_readme_beta() {
|
||||||
|
sed -i "s:badge/Magisk%20Beta.*:badge/Magisk%20Beta-${1}-blue)](https\://github.com/topjohnwu/Magisk/releases/tag/$1):g" $README
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 = tag
|
||||||
|
update_readme_canary() {
|
||||||
|
sed -i "s:badge/Magisk-Canary.*:badge/Magisk-Canary-red)](https\://github.com/topjohnwu/Magisk/releases/tag/$1):g" $README
|
||||||
|
}
|
||||||
|
|
||||||
|
gen_link() {
|
||||||
|
echo "https://github.com/topjohnwu/Magisk/releases/download/$1/$2"
|
||||||
|
}
|
||||||
|
|
||||||
|
update_canary_json() {
|
||||||
|
local ver=$(grep_prop version $CONFIG)
|
||||||
|
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||||
|
local tag="canary-$code"
|
||||||
|
local json
|
||||||
|
|
||||||
|
json=$MAGISK_FILES/canary.json
|
||||||
|
jq ".magisk.version=\"$ver\"|.magisk.versionCode=\"$code\"|
|
||||||
|
.magisk.link=\"$(gen_link $tag app-release.apk)\"|
|
||||||
|
.magisk.note=\"$(gen_link $tag notes.md)\"" $json > ${json}.tmp
|
||||||
|
mv ${json}.tmp $json
|
||||||
|
|
||||||
|
json=$MAGISK_FILES/debug.json
|
||||||
|
jq ".magisk.version=\"$ver\"|.magisk.versionCode=\"$code\"|
|
||||||
|
.magisk.link=\"$(gen_link $tag app-debug.apk)\"|
|
||||||
|
.magisk.note=\"$(gen_link $tag notes.md)\"" $json > ${json}.tmp
|
||||||
|
mv ${json}.tmp $json
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 = json path
|
||||||
|
update_release_json() {
|
||||||
|
local json=$1
|
||||||
|
local ver=$(grep_prop version $CONFIG)
|
||||||
|
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||||
|
|
||||||
|
jq ".magisk.version=\"$ver\"|.magisk.versionCode=\"$code\"|
|
||||||
|
.magisk.link=\"$(gen_link v${ver} Magisk-v${ver}.apk)\"|
|
||||||
|
.magisk.note=\"https://topjohnwu.github.io/Magisk/releases/${code}.md\"" $json > ${json}.tmp
|
||||||
|
mv ${json}.tmp $json
|
||||||
|
}
|
||||||
|
|
||||||
|
build_canary() {
|
||||||
|
# Update version code
|
||||||
|
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||||
|
code=$((code + 1))
|
||||||
|
local tag="canary-$code"
|
||||||
|
sed -i "s:versionCode=.*:versionCode=${code}:g" $GCONFIG
|
||||||
|
update_readme_canary $tag
|
||||||
|
|
||||||
|
# Commit version code changes
|
||||||
|
git add -u .
|
||||||
|
git status
|
||||||
|
git commit -m "Release new canary build"
|
||||||
|
git tag $tag
|
||||||
|
|
||||||
|
# Update version name
|
||||||
|
local ver=$(git rev-parse --short=8 HEAD)
|
||||||
|
sed -i "s:version=.*:version=${ver}:g" $CONFIG
|
||||||
|
sed -i "s:## Magisk (.*:## Magisk (${ver}) (${code}):g" $NOTES
|
||||||
|
|
||||||
|
# Update and commit JSON
|
||||||
|
update_canary_json
|
||||||
|
cd $MAGISK_FILES
|
||||||
|
git add -u .
|
||||||
|
git status
|
||||||
|
git commit -m "Update Canary Channel: Upstream to $ver"
|
||||||
|
cd $CWD
|
||||||
|
|
||||||
|
# Build
|
||||||
|
$BUILDCMD clean
|
||||||
|
$BUILDCMD all
|
||||||
|
$BUILDCMD -r all
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 = ver, $2 = stable?
|
||||||
|
build_release() {
|
||||||
|
# Update version configs
|
||||||
|
local ver=$1
|
||||||
|
local stable=$2
|
||||||
|
local code=$(echo - | awk "{ print $ver * 1000 }")
|
||||||
|
local tag="v$ver"
|
||||||
|
sed -i "s:versionCode=.*:versionCode=${code}:g" $GCONFIG
|
||||||
|
sed -i "s:version=.*:version=${ver}:g" $CONFIG
|
||||||
|
|
||||||
|
# Update and commit JSON
|
||||||
|
if $stable; then
|
||||||
|
update_readme_stable $tag
|
||||||
|
update_readme_beta $tag
|
||||||
|
update_release_json $MAGISK_FILES/stable.json
|
||||||
|
cp -vf $MAGISK_FILES/stable.json $MAGISK_FILES/beta.json
|
||||||
|
else
|
||||||
|
update_readme_beta $tag
|
||||||
|
update_release_json $MAGISK_FILES/beta.json
|
||||||
|
fi
|
||||||
|
cd $MAGISK_FILES
|
||||||
|
git add -u .
|
||||||
|
git status
|
||||||
|
git commit -m "Release Magisk v$ver"
|
||||||
|
cd $CWD
|
||||||
|
|
||||||
|
# Commit version code changes
|
||||||
|
git add -u .
|
||||||
|
git status
|
||||||
|
git commit -m "Release Magisk v$ver"
|
||||||
|
git tag $tag
|
||||||
|
|
||||||
|
# Build
|
||||||
|
$BUILDCMD clean
|
||||||
|
$BUILDCMD -r all
|
||||||
|
}
|
||||||
|
|
||||||
|
stable() {
|
||||||
|
[ -z $1 ] && exit 1
|
||||||
|
local ver=$1
|
||||||
|
build_release $ver true
|
||||||
|
}
|
||||||
|
|
||||||
|
beta() {
|
||||||
|
[ -z $1 ] && exit 1
|
||||||
|
local ver=$1
|
||||||
|
build_release $ver false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub() {
|
||||||
|
gh auth status
|
||||||
|
|
||||||
|
local latest_tag=$(git describe --abbrev=0 --tags)
|
||||||
|
local ver=$(grep_prop version $CONFIG)
|
||||||
|
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||||
|
local out=$(grep_prop outdir $CONFIG)
|
||||||
|
local tag title
|
||||||
|
|
||||||
|
if [ -z $out ]; then
|
||||||
|
out=out
|
||||||
|
fi
|
||||||
|
|
||||||
|
git push origin master
|
||||||
|
git push --tags
|
||||||
|
|
||||||
|
if [ $(($code % 100)) -ne 0 ]; then
|
||||||
|
tag="canary-$code"
|
||||||
|
title="Magisk ($ver) ($code)"
|
||||||
|
|
||||||
|
# Assert tag format
|
||||||
|
[ $latest_tag = $tag ]
|
||||||
|
|
||||||
|
# Publish release
|
||||||
|
tail -n +3 $NOTES > release.md
|
||||||
|
gh release create --verify-tag $tag -p -t "$title" -F release.md $out/app-release.apk $out/app-debug.apk $NOTES
|
||||||
|
else
|
||||||
|
tag="v$ver"
|
||||||
|
title="Magisk v$ver"
|
||||||
|
|
||||||
|
# Assert tag format
|
||||||
|
[ $latest_tag = $tag ]
|
||||||
|
|
||||||
|
# Publish release
|
||||||
|
tail -n +3 docs/releases/$code.md > release.md
|
||||||
|
gh release create --verify-tag $tag -t "$title" -F release.md "$out/app-release.apk#Magisk-v${ver}.apk"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f release.md
|
||||||
|
cd $MAGISK_FILES
|
||||||
|
git push origin master
|
||||||
|
cd $CWD
|
||||||
|
}
|
||||||
|
|
||||||
|
revert() {
|
||||||
|
local latest_tag=$(git describe --abbrev=0 --tags)
|
||||||
|
|
||||||
|
git tag -d $latest_tag
|
||||||
|
git reset --hard HEAD~
|
||||||
|
cd $MAGISK_FILES
|
||||||
|
git reset --hard HEAD~
|
||||||
|
cd $CWD
|
||||||
|
}
|
||||||
|
|
||||||
|
# Use GNU sed on macOS
|
||||||
|
if command -v gsed >/dev/null; then
|
||||||
|
function sed() { gsed "$@"; }
|
||||||
|
export -f sed
|
||||||
|
fi
|
||||||
|
|
||||||
|
git pull
|
||||||
|
|
||||||
|
trap disable_version_config EXIT
|
||||||
|
enable_version_config
|
||||||
|
case $1 in
|
||||||
|
"canary" ) build_canary ;;
|
||||||
|
"stable" ) stable $2 ;;
|
||||||
|
"beta" ) beta $2 ;;
|
||||||
|
"pub" ) pub ;;
|
||||||
|
"revert" ) revert ;;
|
||||||
|
* ) exit 1 ;;
|
||||||
|
esac
|
@@ -207,7 +207,7 @@ find_block() {
|
|||||||
for BLOCK in "$@"; do
|
for BLOCK in "$@"; do
|
||||||
DEVICE=$(find /dev/block \( -type b -o -type c -o -type l \) -iname $BLOCK | head -n 1) 2>/dev/null
|
DEVICE=$(find /dev/block \( -type b -o -type c -o -type l \) -iname $BLOCK | head -n 1) 2>/dev/null
|
||||||
if [ ! -z $DEVICE ]; then
|
if [ ! -z $DEVICE ]; then
|
||||||
readlink -f $DEVICE
|
echo $DEVICE
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -226,7 +226,7 @@ find_block() {
|
|||||||
for DEV in "$@"; do
|
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
|
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
|
if [ ! -z $DEVICE ]; then
|
||||||
readlink -f $DEVICE
|
echo $DEVICE
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -370,14 +370,20 @@ get_flags() {
|
|||||||
find_boot_image() {
|
find_boot_image() {
|
||||||
BOOTIMAGE=
|
BOOTIMAGE=
|
||||||
if $RECOVERYMODE; then
|
if $RECOVERYMODE; then
|
||||||
BOOTIMAGE=$(find_block "recovery_ramdisk$SLOT" "recovery$SLOT" "sos")
|
BOOTIMAGE=$(find_block "recovery$SLOT" "sos")
|
||||||
elif [ ! -z $SLOT ]; then
|
elif [ -e "/dev/block/by-name/init_boot$SLOT" ] && [ "$(uname -r | cut -d. -f1)" -ge 5 ] && uname -r | grep -Evq "android12-|^5\.4"; then
|
||||||
BOOTIMAGE=$(find_block "ramdisk$SLOT" "recovery_ramdisk$SLOT" "init_boot$SLOT" "boot$SLOT")
|
# 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
|
else
|
||||||
BOOTIMAGE=$(find_block ramdisk recovery_ramdisk kern-a android_boot kernel bootimg init_boot boot lnx boot_a)
|
# Fallback for all legacy and non-standard devices
|
||||||
fi
|
BOOTIMAGE=$(find_block ramdisk kern-a android_boot kernel bootimg boot lnx boot_a)
|
||||||
if [ "$BOOTIMAGE" = "init_boot$SLOT" ]; then
|
|
||||||
uname -r | grep -q "android12-" && BOOTIMAGE="boot$SLOT"
|
|
||||||
fi
|
fi
|
||||||
if [ -z $BOOTIMAGE ]; then
|
if [ -z $BOOTIMAGE ]; then
|
||||||
# Lets see what fstabs tells me
|
# Lets see what fstabs tells me
|
||||||
@@ -524,7 +530,7 @@ check_data() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
run_migrations() {
|
run_migrations() {
|
||||||
local LOCSHA1
|
local SHA1
|
||||||
local TARGET
|
local TARGET
|
||||||
# Legacy app installation
|
# Legacy app installation
|
||||||
local BACKUP=$MAGISKBIN/stock_boot*.gz
|
local BACKUP=$MAGISKBIN/stock_boot*.gz
|
||||||
@@ -536,22 +542,23 @@ run_migrations() {
|
|||||||
# Legacy backup
|
# Legacy backup
|
||||||
for gz in /data/stock_boot*.gz; do
|
for gz in /data/stock_boot*.gz; do
|
||||||
[ -f $gz ] || break
|
[ -f $gz ] || break
|
||||||
LOCSHA1=$(basename $gz | sed -e 's/stock_boot_//' -e 's/.img.gz//')
|
SHA1=$(basename $gz | sed -e 's/stock_boot_//' -e 's/.img.gz//')
|
||||||
[ -z $LOCSHA1 ] && break
|
[ -z $SHA1 ] && break
|
||||||
mkdir /data/magisk_backup_${LOCSHA1} 2>/dev/null
|
mkdir /data/magisk_backup_${SHA1} 2>/dev/null
|
||||||
mv $gz /data/magisk_backup_${LOCSHA1}/boot.img.gz
|
mv $gz /data/magisk_backup_${SHA1}/boot.img.gz
|
||||||
done
|
done
|
||||||
|
|
||||||
# Stock backups
|
# Stock backups
|
||||||
LOCSHA1=$SHA1
|
SHA1=
|
||||||
for name in boot dtb dtbo dtbs; do
|
for name in boot dtb dtbo dtbs; do
|
||||||
BACKUP=$MAGISKBIN/stock_${name}.img
|
BACKUP=$MAGISKBIN/stock_${name}.img
|
||||||
[ -f $BACKUP ] || continue
|
[ -f $BACKUP ] || continue
|
||||||
if [ $name = 'boot' ]; then
|
if [ $name = 'boot' ]; then
|
||||||
LOCSHA1=$($MAGISKBIN/magiskboot sha1 $BACKUP)
|
SHA1=$($MAGISKBIN/magiskboot sha1 $BACKUP)
|
||||||
mkdir /data/magisk_backup_${LOCSHA1} 2>/dev/null
|
mkdir /data/magisk_backup_${SHA1} 2>/dev/null
|
||||||
fi
|
fi
|
||||||
TARGET=/data/magisk_backup_${LOCSHA1}/${name}.img
|
[ -z $SHA1 ] && break
|
||||||
|
TARGET=/data/magisk_backup_${SHA1}/${name}.img
|
||||||
cp $BACKUP $TARGET
|
cp $BACKUP $TARGET
|
||||||
rm -f $BACKUP
|
rm -f $BACKUP
|
||||||
gzip -9f $TARGET
|
gzip -9f $TARGET
|
||||||
|
Reference in New Issue
Block a user