mirror of
https://github.com/topjohnwu/Magisk
synced 2025-10-27 04:02:14 +01:00
Compare commits
154 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b4baad78b | ||
|
|
201e32d4c4 | ||
|
|
0980cb6eb5 | ||
|
|
f75d23363b | ||
|
|
6c0ba66f17 | ||
|
|
f32ce7392e | ||
|
|
8bf382adad | ||
|
|
541ba357bb | ||
|
|
b6578b52e3 | ||
|
|
fb01c43ece | ||
|
|
b9a012c6e3 | ||
|
|
17684ed8a8 | ||
|
|
1b6b3b2cd5 | ||
|
|
acd8567586 | ||
|
|
e780c76c93 | ||
|
|
532c6caddf | ||
|
|
ef8d9be633 | ||
|
|
2cdbcc5666 | ||
|
|
c282a8f328 | ||
|
|
b9eab39541 | ||
|
|
20903784a4 | ||
|
|
3ec9ff7467 | ||
|
|
17d3a87b1f | ||
|
|
14c5c60863 | ||
|
|
70a80090c4 | ||
|
|
b6cb5d09cb | ||
|
|
69cfde4516 | ||
|
|
bdc83da098 | ||
|
|
f872a122a9 | ||
|
|
aa92e4cbd0 | ||
|
|
e603877a17 | ||
|
|
bb96477779 | ||
|
|
543ee79720 | ||
|
|
ea8cd98361 | ||
|
|
58849f28a8 | ||
|
|
d66c284bed | ||
|
|
693848280b | ||
|
|
396afaa181 | ||
|
|
05ed29133b | ||
|
|
a31c1e8084 | ||
|
|
21891230f2 | ||
|
|
47da76c5a5 | ||
|
|
6017ff2318 | ||
|
|
e16d604d0d | ||
|
|
d3d5703f3f | ||
|
|
62fe92d922 | ||
|
|
512e7be74f | ||
|
|
727abbea8f | ||
|
|
76f81ece62 | ||
|
|
495654f9ff | ||
|
|
95fec2100e | ||
|
|
623a879797 | ||
|
|
4c96d23f48 | ||
|
|
9bc8f6e9d7 | ||
|
|
e00e6509ee | ||
|
|
be5739508b | ||
|
|
38c867ea94 | ||
|
|
2a985ce6c0 | ||
|
|
e4f3fb36f3 | ||
|
|
b2f8792873 | ||
|
|
2065133e2d | ||
|
|
86da87f254 | ||
|
|
102a7f8723 | ||
|
|
e9afc15719 | ||
|
|
08527dde9b | ||
|
|
d9c3a3c9a9 | ||
|
|
fe89f9e55e | ||
|
|
73802aabac | ||
|
|
bc66733289 | ||
|
|
f4c93b2251 | ||
|
|
c079c598f2 | ||
|
|
8a2f0063d4 | ||
|
|
dfe4b33f2f | ||
|
|
2f7cfa7ab2 | ||
|
|
bdcb813ee6 | ||
|
|
f0751007f3 | ||
|
|
6ad993704c | ||
|
|
796c3009c7 | ||
|
|
144ff5e716 | ||
|
|
054a1e5ea4 | ||
|
|
a223f6056e | ||
|
|
a1fd7704e0 | ||
|
|
b94227efc9 | ||
|
|
3a7e782c07 | ||
|
|
8f6b33d790 | ||
|
|
f476daa041 | ||
|
|
acfde9458d | ||
|
|
82e969627a | ||
|
|
40766b3375 | ||
|
|
d274e45587 | ||
|
|
0a0eb3f710 | ||
|
|
81d054a525 | ||
|
|
2e185f4ec9 | ||
|
|
67f347f880 | ||
|
|
81542fc6a8 | ||
|
|
5aced279d6 | ||
|
|
3f016f785f | ||
|
|
a6427d081e | ||
|
|
8c7fbe20f9 | ||
|
|
469aba8ed0 | ||
|
|
6e8e4ad5da | ||
|
|
2f33d654e4 | ||
|
|
760b6385f1 | ||
|
|
91527500f9 | ||
|
|
e87d989ca3 | ||
|
|
64d61bae08 | ||
|
|
9862265465 | ||
|
|
624b7616d0 | ||
|
|
d53f33bed8 | ||
|
|
02e039d792 | ||
|
|
9f9333315e | ||
|
|
0d10b812fe | ||
|
|
b4fe4f3d10 | ||
|
|
ba93fcbda0 | ||
|
|
88d19a4ca4 | ||
|
|
af7b9ea898 | ||
|
|
09cd0468cf | ||
|
|
529aa754f5 | ||
|
|
3c7e865555 | ||
|
|
7877ac0c3b | ||
|
|
1442e29d0e | ||
|
|
9a7e9b736e | ||
|
|
c421e45fa0 | ||
|
|
8833d21ac3 | ||
|
|
1a3c522c94 | ||
|
|
c55aa92d4f | ||
|
|
212a303347 | ||
|
|
3f3568d8af | ||
|
|
1e3bcfc8cd | ||
|
|
a4ce9f6f05 | ||
|
|
65dc99744e | ||
|
|
c6d4740b0c | ||
|
|
9f91c8b59d | ||
|
|
2b3b087c29 | ||
|
|
e08d46aa76 | ||
|
|
feccc97a14 | ||
|
|
77eec3d21d | ||
|
|
ecaafd1b70 | ||
|
|
0d51997e46 | ||
|
|
463cbceb07 | ||
|
|
1437c5c63f | ||
|
|
52f1d50902 | ||
|
|
a839cb787e | ||
|
|
f621fb2060 | ||
|
|
2ccd8b8838 | ||
|
|
7ef0746c52 | ||
|
|
6f609f0dd7 | ||
|
|
ee2a30470a | ||
|
|
e11fb2c09e | ||
|
|
c6e9270590 | ||
|
|
3e2e171407 | ||
|
|
332f531a10 | ||
|
|
bae2c9bc63 | ||
|
|
5ac68f8df8 |
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -10,8 +10,7 @@
|
||||
*.cmd text eol=crlf
|
||||
|
||||
# Denote all files that are truly binary and should not be modified.
|
||||
busybox binary
|
||||
futility binary
|
||||
chromeos/** binary
|
||||
*.jar binary
|
||||
*.exe binary
|
||||
*.apk binary
|
||||
|
||||
22
.gitignore
vendored
22
.gitignore
vendored
@@ -1,25 +1,7 @@
|
||||
obj/
|
||||
libs/
|
||||
*.zip
|
||||
*.jks
|
||||
|
||||
# Generated binaries
|
||||
zip_static/arm/*
|
||||
zip_static/arm64/*
|
||||
zip_static/x86/*
|
||||
zip_static/x64/*
|
||||
uninstaller/arm/*
|
||||
uninstaller/arm64/*
|
||||
uninstaller/x86/*
|
||||
uninstaller/x64/*
|
||||
# Copied binaries
|
||||
ziptools/zipadjust
|
||||
|
||||
# Generated scripts
|
||||
uninstaller/common/
|
||||
zip_static/common/magic_mask.sh
|
||||
zip_static/common/magisksu.sh
|
||||
zip_static/common/init.magisk.rc
|
||||
zip_static/common/custom_ramdisk_patch.sh
|
||||
zip_static/META-INF/com/google/android/update-binary
|
||||
|
||||
# Leave all busybox!
|
||||
!busybox
|
||||
|
||||
17
.gitmodules
vendored
17
.gitmodules
vendored
@@ -1,12 +1,15 @@
|
||||
[submodule "jni/sepolicy-inject"]
|
||||
path = jni/sepolicy-inject
|
||||
url = https://github.com/topjohnwu/sepolicy-inject
|
||||
[submodule "jni/resetprop"]
|
||||
path = jni/resetprop
|
||||
url = https://github.com/topjohnwu/resetprop.git
|
||||
[submodule "jni/selinux"]
|
||||
path = jni/selinux
|
||||
url = https://github.com/topjohnwu/selinux.git
|
||||
[submodule "jni/su"]
|
||||
path = jni/su
|
||||
url = https://github.com/topjohnwu/Superuser.git
|
||||
url = https://github.com/topjohnwu/MagiskSU.git
|
||||
[submodule "jni/ndk-compression"]
|
||||
path = jni/ndk-compression
|
||||
url = https://github.com/topjohnwu/ndk-compression.git
|
||||
[submodule "jni/magiskpolicy"]
|
||||
path = jni/magiskpolicy
|
||||
url = https://github.com/topjohnwu/magiskpolicy.git
|
||||
[submodule "MagiskManager"]
|
||||
path = MagiskManager
|
||||
url = https://github.com/topjohnwu/MagiskManager.git
|
||||
|
||||
1
MagiskManager
Submodule
1
MagiskManager
Submodule
Submodule MagiskManager added at d3ff482c9b
85
README.MD
85
README.MD
@@ -1,11 +1,78 @@
|
||||
# Magisk
|
||||
###Static binaries included:
|
||||
* Busybox: http://forum.xda-developers.com/android/software-hacking/tool-busybox-flashable-archs-t3348543
|
||||
|
||||
###How to build Magisk
|
||||
1. Download and install NDK
|
||||
2. Add the NDK directory into PATH
|
||||
To check if the PATH is set correctly, try calling `which ndk-build` (`where ndk-build` on Windows) and see if it shows the NDK directory
|
||||
3. Unix-like users (e.g. Linux & MacOS) please execute `build.sh` through shell
|
||||
Windows users please execute `build.cmd` through cmd
|
||||
4. The scripts will show you further details
|
||||
## How to build Magisk
|
||||
|
||||
#### Building has been tested on 3 major platforms:
|
||||
|
||||
***macOS 10.12.5***
|
||||
***Ubuntu 17.04 x64***
|
||||
***Windows 10 Creators Update x64***
|
||||
|
||||
#### Environment Requirements
|
||||
|
||||
1. Python 3 **(>= 3.5)**: `python3` (or in some cases `python`) should be accessible
|
||||
2. Java runtime: `java` should be accessible
|
||||
3. (Unix only) C compiler: `gcc` should be accessible
|
||||
4. Android SDK: `ANDROID_HOME` environment variable should point to the Android SDK folder
|
||||
5. NDK: Install NDK using `sdkmanager`, or through Android SDK Manager
|
||||
6. Android build-tools: Should have build-tools version matching `MagiskManager/app/build.gradle` installed
|
||||
|
||||
#### Instructions and Notes
|
||||
|
||||
1. The python build script uses ANSI color codes to change the color of the terminal output. For Windows, this **only** works on Windows 10, as previous Windows console do not support them. If you insist to use an older Windows version, a quick Google search should provide many workarounds
|
||||
2. After installing the latest Python 3 on Windows (allow the installer to add Python to PATH, or you'll have to manually set the environment), instead of calling `python3` like most Unix environment, you should call `python` in shell (cmd or Powershell both OK). You can double check the version by `python --version`
|
||||
3. The build script will do several checks, it will refuse to run if the environment doesn't meet the requirements
|
||||
4. For further instructions, please check the built in help message by `python3 build.py -h`
|
||||
(Unix users can simply `./build.py -h`, Windows users, as mentioned, call `python` instead)
|
||||
5. Each action has its own help message, access them by commands like `python3 build.py all -h`
|
||||
6. To build Magisk for release (enabled through the `--release` flag, the script builds in debug mode by default), you will need to provide a Java keystore file, and place it in `release_signature.jks` to sign Magisk Manager APK for release builds. For more information, check out [Google's Official Documentation](https://developer.android.com/studio/publish/app-signing.html#signing-manually)
|
||||
7. To properly setup the Android SDK environment, the easiest way is to use Android Studio and open Magisk Manager. If gradle sync passed, your build-tools etc. should be set properly. You can also access SDK Manager GUI within Android Studio to download NDK. Don't forget to add Android Studio's SDK path into environment variable ANDROID_HOME.
|
||||
|
||||
## License
|
||||
|
||||
Magisk, including all subprojects (git submodule) is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
## Credits
|
||||
|
||||
**MagiskManager** (`MagiskManager`)
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* All contributors and translators
|
||||
|
||||
**MagiskSU** (`jni/su`)
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
|
||||
* Copyright 2013, Koushik Dutta (@koush)
|
||||
* Copyright 2010, Adam Shanks (@ChainsDD)
|
||||
* Copyright 2008, Zinx Verituse (@zinxv)
|
||||
|
||||
**MagiskPolicy** (`jni/magiskpolicy`)
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
|
||||
* Copyright 2015, Joshua Brindle (@joshua_brindle)
|
||||
|
||||
**MagiskHide** (`jni/magiskhide`)
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2016, Pierre-Hugues Husson (phh@phh.me) (original hidesu)
|
||||
|
||||
**resetprop** (`jni/resetprop`)
|
||||
* Copyright 2016-2017 John Wu (@topjohnwu)
|
||||
* Copyright 2016 nkk71 (nkk71x@gmail.com)
|
||||
|
||||
**SELinux** (`jni/selinux`)
|
||||
* Makefile for NDK: Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* It is maintained by many developers in SELinux project, copyright belongs to them
|
||||
|
||||
**ndk-compression** (`jni/ndk-compression`)
|
||||
* Makefile for NDK: Copyright 2017, John Wu (@topjohnwu)
|
||||
* Each library has its own copyright message in each directories
|
||||
|
||||
**Others Not Mentioned**
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
|
||||
167
build.cmd
167
build.cmd
@@ -1,167 +0,0 @@
|
||||
@ECHO OFF
|
||||
SETLOCAL ENABLEEXTENSIONS
|
||||
SET me=%~nx0
|
||||
SET parent=%~dp0
|
||||
SET tab=
|
||||
SET OK=
|
||||
|
||||
CD %parent%
|
||||
|
||||
call :%~1 "%~2"
|
||||
IF NOT DEFINED OK CALL :usage
|
||||
|
||||
EXIT /B %ERRORLEVEL%
|
||||
|
||||
:usage
|
||||
ECHO %me% all ^<version name^>
|
||||
ECHO %tab%Build binaries, zip, and sign Magisk
|
||||
ECHO %tab%This is equlivant to first ^<build^>, then ^<zip^>
|
||||
ECHO %me% clean
|
||||
ECHO %tab%Cleanup compiled / generated files
|
||||
ECHO %me% build
|
||||
ECHO %tab%Build the binaries with ndk
|
||||
ECHO %me% zip ^<version name^>
|
||||
ECHO %tab%Zip and sign Magisk
|
||||
ECHO %me% uninstaller
|
||||
ECHO %tab%Zip and sign the uninstaller
|
||||
EXIT /B 1
|
||||
|
||||
:all
|
||||
SET OK=y
|
||||
IF [%~1] == [] (
|
||||
CALL :error "Missing version number"
|
||||
CALL :usage
|
||||
EXIT /B %ERRORLEVEL%
|
||||
)
|
||||
CALL :build
|
||||
CALL :zip "%~1"
|
||||
EXIT /B %ERRORLEVEL%
|
||||
|
||||
:build
|
||||
SET OK=y
|
||||
ECHO ************************
|
||||
ECHO * Building binaries
|
||||
ECHO ************************
|
||||
FOR /F "tokens=* USEBACKQ" %%F IN (`where ndk-build`) DO (
|
||||
IF [%%F] == [] (
|
||||
CALL :error "Please add ndk-build to PATH!"
|
||||
EXIT /B 1
|
||||
)
|
||||
)
|
||||
CALL ndk-build -j4 || CALL :error "Magisk binary tools build failed...."
|
||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||
ECHO ************************
|
||||
ECHO * Copying binaries
|
||||
ECHO ************************
|
||||
COPY /Y libs\armeabi-v7a\* zip_static\arm
|
||||
COPY /Y libs\arm64-v8a\* zip_static\arm64
|
||||
COPY /Y libs\x86\* zip_static\x86
|
||||
COPY /Y libs\x86_64\* zip_static\x64
|
||||
CALL :mkcp libs\armeabi-v7a\bootimgtools uninstaller\arm
|
||||
CALL :mkcp libs\arm64-v8a\bootimgtools uninstaller\arm64
|
||||
CALL :mkcp libs\x86\bootimgtools uninstaller\x86
|
||||
CALL :mkcp libs\x86_64\bootimgtools uninstaller\x64
|
||||
EXIT /B %ERRORLEVEL%
|
||||
|
||||
:clean
|
||||
SET OK=y
|
||||
ECHO ************************
|
||||
ECHO * Cleaning up
|
||||
ECHO ************************
|
||||
CALL ndk-build clean
|
||||
forfiles /P zip_static\arm /C "cmd /C IF NOT @file == \"busybox\" DEL @file"
|
||||
forfiles /P zip_static\arm64 /C "cmd /C IF NOT @file == \"busybox\" DEL @file"
|
||||
forfiles /P zip_static\x86 /C "cmd /C IF NOT @file == \"busybox\" DEL @file"
|
||||
forfiles /P zip_static\x64 /C "cmd /C IF NOT @file == \"busybox\" DEL @file"
|
||||
2>NUL DEL zip_static\META-INF\com\google\android\update-binary
|
||||
2>NUL DEL zip_static\common\custom_ramdisk_patch.sh
|
||||
2>NUL DEL zip_static\common\magisksu.sh
|
||||
2>NUL DEL zip_static\common\init.magisk.rc
|
||||
2>NUL DEL zip_static\common\magic_mask.sh
|
||||
2>NUL RMDIR /S /Q uninstaller\common
|
||||
2>NUL RMDIR /S /Q uninstaller\arm
|
||||
2>NUL RMDIR /S /Q uninstaller\arm64
|
||||
2>NUL RMDIR /S /Q uninstaller\x86
|
||||
2>NUL RMDIR /S /Q uninstaller\x64
|
||||
EXIT /B 0
|
||||
|
||||
:zip
|
||||
SET OK=y
|
||||
IF [%~1] == [] (
|
||||
CALL :error "Missing version number"
|
||||
CALL :usage
|
||||
EXIT /B %ERRORLEVEL%
|
||||
)
|
||||
IF NOT EXIST "zip_static\arm\bootimgtools" CALL :error "Missing binaries! Please run '%me% build' before zipping!"
|
||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||
ECHO ************************
|
||||
ECHO * Adding version info
|
||||
ECHO ************************
|
||||
powershell.exe -nologo -noprofile -command "(gc -Raw scripts\flash_script.sh) -replace 'MAGISK_VERSION_STUB', 'Magisk v%~1 Boot Image Patcher' | sc zip_static\META-INF\com\google\android\update-binary"
|
||||
powershell.exe -nologo -noprofile -command "(gc -Raw scripts\magic_mask.sh) -replace 'MAGISK_VERSION_STUB', 'setprop magisk.version \"%~1\"' | sc zip_static\common\magic_mask.sh"
|
||||
ECHO ************************
|
||||
ECHO * Zipping Magisk v%~1
|
||||
ECHO ************************
|
||||
COPY /Y scripts\custom_ramdisk_patch.sh zip_static\common\custom_ramdisk_patch.sh
|
||||
COPY /Y scripts\magisksu.sh zip_static\common\magisksu.sh
|
||||
COPY /Y scripts\init.magisk.rc zip_static\common\init.magisk.rc
|
||||
CD zip_static
|
||||
2>NUL DEL "..\Magisk-v%~1.zip"
|
||||
..\ziptools\win_bin\zip "..\Magisk-v%~1.zip" -r .
|
||||
CD ..\
|
||||
CALL :sign_zip "Magisk-v%~1.zip"
|
||||
EXIT /B %ERRORLEVEL%
|
||||
|
||||
:uninstaller
|
||||
SET OK=y
|
||||
IF NOT EXIST "uninstaller\arm\bootimgtools" CALL :error "Missing binaries! Please run '%me% build' before zipping!"
|
||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||
ECHO ************************
|
||||
ECHO * Zipping uninstaller
|
||||
ECHO ************************
|
||||
CALL :mkcp scripts\magisk_uninstaller.sh uninstaller\common
|
||||
FOR /F "tokens=* USEBACKQ" %%F IN (`ziptools\win_bin\date "+%%Y%%m%%d"`) DO (set timestamp=%%F)
|
||||
CD uninstaller
|
||||
2>NUL DEL "../Magisk-uninstaller-%timestamp%.zip"
|
||||
..\ziptools\win_bin\zip "../Magisk-uninstaller-%timestamp%.zip" -r .
|
||||
CD ..\
|
||||
CALL :sign_zip "Magisk-uninstaller-%timestamp%.zip"
|
||||
EXIT /B %ERRORLEVEL%
|
||||
|
||||
:sign_zip
|
||||
IF NOT EXIST "ziptools\win_bin\zipadjust.exe" (
|
||||
ECHO ************************
|
||||
ECHO * Compiling ZipAdjust
|
||||
ECHO ************************
|
||||
gcc -o ziptools\win_bin\zipadjust ziptools\src\*.c -lz || CALL :error "ZipAdjust Build failed...."
|
||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||
)
|
||||
SET basename="%~1"
|
||||
SET basename="%basename:.zip=%"
|
||||
ECHO ************************
|
||||
ECHO * First sign %~1
|
||||
ECHO ************************
|
||||
java -jar "ziptools\signapk.jar" "ziptools\test.certificate.x509.pem" "ziptools\test.key.pk8" "%~1" "%basename:"=%-firstsign.zip"
|
||||
ECHO ************************
|
||||
ECHO * Adjusting %~1
|
||||
ECHO ************************
|
||||
ziptools\win_bin\zipadjust "%basename:"=%-firstsign.zip" "%basename:"=%-adjusted.zip"
|
||||
ECHO ************************
|
||||
ECHO * Final sign %~1
|
||||
ECHO ************************
|
||||
java -jar "ziptools\minsignapk.jar" "ziptools\test.certificate.x509.pem" "ziptools\test.key.pk8" "%basename:"=%-adjusted.zip" "%basename:"=%-signed.zip"
|
||||
|
||||
MOVE /Y "%basename:"=%-signed.zip" "%~1"
|
||||
DEL "%basename:"=%-adjusted.zip" "%basename:"=%-firstsign.zip"
|
||||
EXIT /B %ERRORLEVEL%
|
||||
|
||||
:mkcp
|
||||
2>NUL MKDIR "%~2"
|
||||
2>NUL COPY /Y "%~1" "%~2"
|
||||
EXIT /B 0
|
||||
|
||||
:error
|
||||
ECHO.
|
||||
ECHO ! %~1
|
||||
ECHO.
|
||||
EXIT /B 1
|
||||
156
build.sh
156
build.sh
@@ -1,156 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
usage() {
|
||||
echo "$0 all <version name>"
|
||||
echo -e "\tBuild binaries, zip, and sign Magisk"
|
||||
echo -e "\tThis is equlivant to first <build>, then <zip>"
|
||||
echo "$0 clean"
|
||||
echo -e "\tCleanup compiled / generated files"
|
||||
echo "$0 build"
|
||||
echo -e "\tBuild the binaries with ndk"
|
||||
echo "$0 zip <version name>"
|
||||
echo -e "\tZip and sign Magisk"
|
||||
echo "$0 uninstaller"
|
||||
echo -e "\tZip and sign the uninstaller"
|
||||
exit 1
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
echo "************************"
|
||||
echo "* Cleaning up"
|
||||
echo "************************"
|
||||
ndk-build clean 2>/dev/null
|
||||
ls zip_static/arm/* | grep -v "busybox" | xargs rm -rfv
|
||||
ls zip_static/arm64/* | grep -v "busybox" | xargs rm -rfv
|
||||
ls zip_static/x86/* | grep -v "busybox" | xargs rm -rfv
|
||||
ls zip_static/x64/* | grep -v "busybox" | xargs rm -rfv
|
||||
rm -rfv zip_static/META-INF/com/google/android/update-binary
|
||||
rm -rfv zip_static/common/custom_ramdisk_patch.sh
|
||||
rm -rfv zip_static/common/magisksu.sh
|
||||
rm -rfv zip_static/common/init.magisk.rc
|
||||
rm -rfv zip_static/common/magic_mask.sh
|
||||
rm -rfv uninstaller/common
|
||||
rm -rfv uninstaller/arm
|
||||
rm -rfv uninstaller/arm64
|
||||
rm -rfv uninstaller/x86
|
||||
rm -rfv uninstaller/x64
|
||||
}
|
||||
|
||||
mkcp() {
|
||||
[ ! -d "$2" ] && mkdir -p "$2"
|
||||
cp -afv $1 $2
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "\n! $1\n"
|
||||
exit 1
|
||||
}
|
||||
|
||||
build_bin() {
|
||||
echo "************************"
|
||||
echo "* Building binaries"
|
||||
echo "************************"
|
||||
[ -z `which ndk-build` ] && error "Please add ndk-build to PATH!"
|
||||
ndk-build -j4 || error "Magisk binary tools build failed...."
|
||||
echo "************************"
|
||||
echo "* Copying binaries"
|
||||
echo "************************"
|
||||
mkcp "libs/armeabi-v7a/*" zip_static/arm
|
||||
mkcp libs/armeabi-v7a/bootimgtools uninstaller/arm
|
||||
mkcp "libs/arm64-v8a/*" zip_static/arm64
|
||||
mkcp libs/arm64-v8a/bootimgtools uninstaller/arm64
|
||||
mkcp "libs/x86/*" zip_static/x86
|
||||
mkcp libs/x86/bootimgtools uninstaller/x86
|
||||
mkcp "libs/x86_64/*" zip_static/x64
|
||||
mkcp libs/x86_64/bootimgtools uninstaller/x64
|
||||
}
|
||||
|
||||
zip_package() {
|
||||
[ ! -f "zip_static/arm/bootimgtools" ] && error "Missing binaries!! Please run '$0 build' before zipping"
|
||||
echo "************************"
|
||||
echo "* Adding version info"
|
||||
echo "************************"
|
||||
sed "s/MAGISK_VERSION_STUB/Magisk v$1 Boot Image Patcher/g" scripts/flash_script.sh > zip_static/META-INF/com/google/android/update-binary
|
||||
sed "s/MAGISK_VERSION_STUB/setprop magisk.version \"$1\"/g" scripts/magic_mask.sh > zip_static/common/magic_mask.sh
|
||||
echo "************************"
|
||||
echo "* Zipping Magisk v$1"
|
||||
echo "************************"
|
||||
cp -afv scripts/custom_ramdisk_patch.sh zip_static/common/custom_ramdisk_patch.sh
|
||||
cp -afv scripts/magisksu.sh zip_static/common/magisksu.sh
|
||||
cp -afv scripts/init.magisk.rc zip_static/common/init.magisk.rc
|
||||
cd zip_static
|
||||
find . -type f -exec chmod 644 {} \;
|
||||
find . -type d -exec chmod 755 {} \;
|
||||
rm -rf "../Magisk-v$1.zip"
|
||||
zip "../Magisk-v$1.zip" -r .
|
||||
cd ../
|
||||
sign_zip "Magisk-v$1.zip"
|
||||
}
|
||||
|
||||
zip_uninstaller() {
|
||||
[ ! -f "uninstaller/arm/bootimgtools" ] && error "Missing binaries!! Please run '$0 build' before zipping"
|
||||
echo "************************"
|
||||
echo "* Zipping uninstaller"
|
||||
echo "************************"
|
||||
mkcp scripts/magisk_uninstaller.sh uninstaller/common
|
||||
cd uninstaller
|
||||
find . -type f -exec chmod 644 {} \;
|
||||
find . -type d -exec chmod 755 {} \;
|
||||
TIMESTAMP=`date "+%Y%m%d"`
|
||||
rm -rf "../Magisk-uninstaller-$TIMESTAMP.zip"
|
||||
zip "../Magisk-uninstaller-$TIMESTAMP.zip" -r .
|
||||
cd ../
|
||||
sign_zip "Magisk-uninstaller-$TIMESTAMP.zip"
|
||||
}
|
||||
|
||||
sign_zip() {
|
||||
if [ ! -f "ziptools/zipadjust" ]; then
|
||||
echo "************************"
|
||||
echo "* Compiling ZipAdjust"
|
||||
echo "************************"
|
||||
gcc -o ziptools/zipadjust ziptools/src/*.c -lz || error "ZipAdjust Build failed...."
|
||||
chmod 755 ziptools/zipadjust
|
||||
fi
|
||||
echo "************************"
|
||||
echo "* First sign $1"
|
||||
echo "************************"
|
||||
java -jar "ziptools/signapk.jar" "ziptools/test.certificate.x509.pem" "ziptools/test.key.pk8" "$1" "${1%.*}-firstsign.zip"
|
||||
echo "************************"
|
||||
echo "* Adjusting $1"
|
||||
echo "************************"
|
||||
ziptools/zipadjust "${1%.*}-firstsign.zip" "${1%.*}-adjusted.zip"
|
||||
echo "************************"
|
||||
echo "* Final sign $1"
|
||||
echo "************************"
|
||||
java -jar "ziptools/minsignapk.jar" "ziptools/test.certificate.x509.pem" "ziptools/test.key.pk8" "${1%.*}-adjusted.zip" "${1%.*}-signed.zip"
|
||||
|
||||
mv "${1%.*}-signed.zip" "$1"
|
||||
rm "${1%.*}-adjusted.zip" "${1%.*}-firstsign.zip"
|
||||
}
|
||||
|
||||
DIR="$(cd "$(dirname "$0")"; pwd)"
|
||||
cd "$DIR"
|
||||
|
||||
case $1 in
|
||||
"all" )
|
||||
[ -z "$2" ] && echo -e "! Missing version number\n" && usage
|
||||
build_bin
|
||||
zip_package $2
|
||||
;;
|
||||
"clean" )
|
||||
cleanup
|
||||
;;
|
||||
"build" )
|
||||
build_bin
|
||||
;;
|
||||
"zip" )
|
||||
[ -z "$2" ] && echo -e "! Missing version number\n" && usage
|
||||
zip_package $2
|
||||
;;
|
||||
"uninstaller" )
|
||||
zip_uninstaller
|
||||
;;
|
||||
* )
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
@@ -1,10 +1,65 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include jni/bootimgtools/Android.mk
|
||||
include jni/magiskhide/Android.mk
|
||||
include jni/resetprop/Android.mk
|
||||
include jni/sepolicy-inject/Android.mk
|
||||
include jni/su/Android.mk
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := magisk
|
||||
LOCAL_STATIC_LIBRARIES := libsepol
|
||||
LOCAL_SHARED_LIBRARIES := libsqlite libselinux
|
||||
|
||||
include jni/selinux/libsepol/Android.mk
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(LOCAL_PATH)/utils \
|
||||
$(LOCAL_PATH)/daemon \
|
||||
$(LOCAL_PATH)/resetprop \
|
||||
$(LOCAL_PATH)/magiskpolicy \
|
||||
$(LOCAL_PATH)/selinux/libselinux/include \
|
||||
$(LOCAL_PATH)/selinux/libsepol/include \
|
||||
$(LOCAL_PATH)/sqlite3
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
main.c \
|
||||
utils/misc.c \
|
||||
utils/vector.c \
|
||||
utils/xwrap.c \
|
||||
utils/list.c \
|
||||
daemon/daemon.c \
|
||||
daemon/socket_trans.c \
|
||||
daemon/log_monitor.c \
|
||||
daemon/bootstages.c \
|
||||
magiskhide/magiskhide.c \
|
||||
magiskhide/hide_daemon.c \
|
||||
magiskhide/proc_monitor.c \
|
||||
magiskhide/pre_process.c \
|
||||
magiskhide/list_manager.c \
|
||||
magiskpolicy/magiskpolicy.c \
|
||||
magiskpolicy/rules.c \
|
||||
magiskpolicy/sepolicy.c \
|
||||
magiskpolicy/api.c \
|
||||
resetprop/resetprop.cpp \
|
||||
resetprop/system_properties.cpp \
|
||||
su/su.c \
|
||||
su/activity.c \
|
||||
su/db.c \
|
||||
su/misc.c \
|
||||
su/pts.c \
|
||||
su/su_daemon.c \
|
||||
su/su_socket.c
|
||||
|
||||
LOCAL_CFLAGS := -Wno-implicit-exception-spec-mismatch
|
||||
LOCAL_LDLIBS := -llog
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# Libraries
|
||||
include jni/selinux/libselinux/Android.mk
|
||||
include jni/selinux/libsepol/Android.mk
|
||||
include jni/sqlite3/Android.mk
|
||||
|
||||
#####################################################################
|
||||
# In order to build separate binaries, please comment out everything
|
||||
# starting from line 3 (including the 3 lines for libraries)
|
||||
# Then, uncomment the line you want below
|
||||
#####################################################################
|
||||
# include jni/resetprop/Android.mk
|
||||
# include jni/magiskpolicy/Android.mk
|
||||
|
||||
# Build magiskboot
|
||||
include jni/magiskboot/Android.mk
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
APP_ABI := x86 x86_64 armeabi-v7a arm64-v8a
|
||||
APP_PIE = true
|
||||
APP_PLATFORM := android-21
|
||||
APP_UNIFIED_HEADERS := true
|
||||
APP_CPPFLAGS += -std=c++11
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := bootimgtools
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_SRC_FILES := main.c extract.c repack.c hexpatch.c
|
||||
LOCAL_CFLAGS += -std=gnu11
|
||||
include $(BUILD_EXECUTABLE)
|
||||
@@ -1,149 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bootimg.h"
|
||||
|
||||
void dump(uint8_t *ptr, size_t size, char* filename) {
|
||||
unlink(filename);
|
||||
int ofd = open(filename, O_WRONLY|O_CREAT, 0644);
|
||||
assert(ofd >= 0);
|
||||
int ret = write(ofd, ptr, size);
|
||||
assert(ret == size);
|
||||
close(ofd);
|
||||
}
|
||||
|
||||
//TODO: Search for other header types
|
||||
void dump_ramdisk(uint8_t *ptr, size_t size) {
|
||||
//GZip header
|
||||
if(memcmp(ptr, "\x1f\x8b\x08\x00", 4) == 0) {
|
||||
dump(ptr, size, "ramdisk.gz");
|
||||
//MTK header
|
||||
} else if(memcmp(ptr, "\x88\x16\x88\x58", 4) == 0) {
|
||||
if(memcmp(ptr+8, "RECOVERY", 8)==0) {
|
||||
dump(ptr, 0, "ramdisk-mtk-recovery");
|
||||
} else if(memcmp(ptr+8, "ROOTFS\0\0", 8)==0) {
|
||||
dump(ptr, 0, "ramdisk-mtk-boot");
|
||||
} else {
|
||||
exit(1);
|
||||
}
|
||||
dump(ptr, 0, "ramdisk-mtk"); //Create an mtk flag
|
||||
dump_ramdisk(ptr+512, size-512);
|
||||
} else {
|
||||
//Since our first aim is to extract/repack ramdisk
|
||||
//Stop if we can't find it
|
||||
//Still dump it for debug purposes
|
||||
dump(ptr, size, "ramdisk");
|
||||
|
||||
fprintf(stderr, "Unknown ramdisk type\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void search_security_hdr(uint8_t *buf, size_t size) {
|
||||
if(memcmp(buf, "CHROMEOS", 8) == 0) {
|
||||
dump(buf, 0, "chromeos");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int search_security(uint8_t *buf, size_t size, int pos) {
|
||||
//Rockchip signature
|
||||
if(memcmp(buf+1024, "SIGN", 4) == 0) {
|
||||
//Rockchip signature AT LEAST means the bootloader will check the crc
|
||||
dump(buf, 0, "rkcrc"); //Create an flag to tell it
|
||||
|
||||
//And it's possible there is a security too
|
||||
return 1;
|
||||
}
|
||||
|
||||
//If we didn't parse the whole file, it is highly likely there is a boot signature
|
||||
if(pos < size) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* - At the moment we dump kernel + ramdisk + second + DT, it's likely we only want ramdisk
|
||||
* - Error-handling via assert() is perhaps not the best
|
||||
*/
|
||||
int extract(char *image) {
|
||||
|
||||
int fd = open(image, O_RDONLY);
|
||||
off_t size = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
uint8_t *orig = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
uint8_t *base = orig;
|
||||
assert(base);
|
||||
|
||||
search_security_hdr(base, size);
|
||||
|
||||
//We're searching for the header in the whole file, we could stop earlier.
|
||||
//At least HTC and nVidia have a signature header
|
||||
while(base<(orig+size)) {
|
||||
if(memcmp(base, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0)
|
||||
break;
|
||||
//We're searching every 256bytes, is it ok?
|
||||
base += 256;
|
||||
}
|
||||
assert(base < (orig+size));
|
||||
|
||||
struct boot_img_hdr *hdr = (struct boot_img_hdr*) base;
|
||||
assert(
|
||||
hdr->page_size == 2048 ||
|
||||
hdr->page_size == 4096 ||
|
||||
hdr->page_size == 16384
|
||||
);
|
||||
|
||||
long pos = hdr->page_size;
|
||||
dump(base+pos, hdr->kernel_size, "kernel");
|
||||
pos += hdr->kernel_size + hdr->page_size-1;
|
||||
pos &= ~(hdr->page_size-1L);
|
||||
|
||||
dump_ramdisk(base+pos, hdr->ramdisk_size);
|
||||
pos += hdr->ramdisk_size + hdr->page_size-1;
|
||||
pos &= ~(hdr->page_size-1L);
|
||||
|
||||
if(hdr->second_size) {
|
||||
assert( (pos+hdr->second_size) <= size);
|
||||
dump(base+pos, hdr->second_size, "second");
|
||||
pos += hdr->second_size + hdr->page_size-1;
|
||||
pos &= ~(hdr->page_size-1L);
|
||||
}
|
||||
|
||||
//This is non-standard, so we triple check
|
||||
if( hdr->unused[0] &&
|
||||
pos < size &&
|
||||
(pos+hdr->unused[0]) <= size) {
|
||||
|
||||
if(memcmp(base+pos, "QCDT", 4) == 0 ||
|
||||
memcmp(base+pos, "SPRD", 4) == 0 ||
|
||||
memcmp(base+pos, "DTBH", 4) == 0 ||
|
||||
memcmp(base+pos, "\xD0\x0D\xFE\xED", 4) == 0
|
||||
) {
|
||||
dump(base+pos, hdr->unused[0], "dt");
|
||||
pos += hdr->unused[0] + hdr->page_size-1;
|
||||
pos &= ~(hdr->page_size-1L);
|
||||
}
|
||||
}
|
||||
|
||||
//If we think we find some security-related infos in the boot.img
|
||||
//create a "secure" flag to warn the user it is dangerous
|
||||
if(search_security(base, size, pos)) {
|
||||
dump(base, 0, "secure");
|
||||
}
|
||||
|
||||
munmap(orig, size);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bootimg.h"
|
||||
|
||||
int hex2int(char c) {
|
||||
int first = c / 16 - 3;
|
||||
int second = c % 16;
|
||||
int result = first * 10 + second;
|
||||
if(result > 9) result--;
|
||||
return result;
|
||||
}
|
||||
|
||||
int hex2ascii(char c, char d) {
|
||||
int high = hex2int(c) * 16;
|
||||
int low = hex2int(d);
|
||||
return high+low;
|
||||
}
|
||||
|
||||
void hexstr2str(char *hex, char *str) {
|
||||
char buf = 0;
|
||||
for(int i = 0, length = strlen(hex); i < length; ++i){
|
||||
if(i % 2){
|
||||
str[i / 2] = hex2ascii(buf, hex[i]);
|
||||
} else{
|
||||
buf = hex[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int hexpatch(char * image, char *from, char *to) {
|
||||
int fd = open(image, O_RDWR), patternsize = strlen(from) / 2, patchsize = strlen(to) / 2;
|
||||
off_t filesize = lseek(fd, 0, SEEK_END);
|
||||
char *file, *pattern, *patch, *start;
|
||||
file = malloc(sizeof (char) * filesize);
|
||||
pattern = malloc(sizeof (char) * patternsize);
|
||||
patch = malloc(sizeof (char) * patchsize);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
read(fd, file, filesize);
|
||||
hexstr2str(from, pattern);
|
||||
hexstr2str(to, patch);
|
||||
for (off_t i = 0; i < filesize;) {
|
||||
int j;
|
||||
for (j = 0; j < patternsize; ++j) {
|
||||
if(file[i + j] != pattern[j]) break;
|
||||
}
|
||||
if (j == patternsize) {
|
||||
fprintf(stderr, "Pattern %s found!\nPatching to %s\n", from, to);
|
||||
lseek(fd, i, SEEK_SET);
|
||||
write(fd, patch, patchsize);
|
||||
}
|
||||
if(j == 0) j = 1;
|
||||
i += j;
|
||||
}
|
||||
free(file);
|
||||
free(pattern);
|
||||
free(patch);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bootimg.h"
|
||||
|
||||
/********************
|
||||
Patch Boot Image
|
||||
*********************/
|
||||
|
||||
int usage(char *arg0) {
|
||||
fprintf(stderr, "Boot Image Unpack/Repack Tool\n");
|
||||
fprintf(stderr, "%s --extract <bootimage>\n", arg0);
|
||||
fprintf(stderr, " Unpack <bootimage> into current directory\n\n");
|
||||
fprintf(stderr, "%s --repack <bootimage>\n", arg0);
|
||||
fprintf(stderr, " Repack kernel, dt, ramdisk... from current directory to new-image.img\n <bootimage> is the image you've just unpacked\n\n");
|
||||
fprintf(stderr, "%s --hexpatch <bootimage> <hexpattern1> <hexpattern2>\n", arg0);
|
||||
fprintf(stderr, " Search <hexpattern1> in <bootimage>, and replace with <hexpattern2>\n\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char ch;
|
||||
struct option long_options[] = {
|
||||
{"extract", required_argument, NULL, 'e'},
|
||||
{"repack", required_argument, NULL, 'r'},
|
||||
{"hexpatch", required_argument, NULL, 'p'},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
while ((ch = getopt_long(argc, argv, "e:r:p:", long_options, NULL)) != -1) {
|
||||
switch (ch) {
|
||||
case 'e':
|
||||
return extract(optarg);
|
||||
case 'r':
|
||||
return repack(optarg);
|
||||
case 'p':
|
||||
if (argc < 5) return usage(argv[0]);
|
||||
optind += 2;
|
||||
return hexpatch(argv[optind - 3], argv[optind - 2], argv[optind - 1]);
|
||||
default:
|
||||
return usage(argv[0]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bootimg.h"
|
||||
|
||||
off_t file_size(char *filename) {
|
||||
struct stat st;
|
||||
if(stat(filename, &st))
|
||||
exit(1);
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
int append_file(int ofd, char *filename, off_t pos) {
|
||||
lseek(ofd, pos, SEEK_SET);
|
||||
int fd = open(filename, O_RDONLY);
|
||||
int size = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
sendfile(ofd, fd, NULL, size);
|
||||
close(fd);
|
||||
return size;
|
||||
}
|
||||
|
||||
int append_ramdisk(int ofd, off_t pos) {
|
||||
if(access("ramdisk-mtk", R_OK) == 0) {
|
||||
char buf[512];
|
||||
off_t size = file_size("ramdisk.gz");
|
||||
memcpy(buf, "\x88\x16\x88\x58", 4);
|
||||
uint32_t v = size;
|
||||
memcpy(buf+4, &v, sizeof(v)); //Should convert to LE
|
||||
|
||||
//TODO: RECOVERY OR ROOTFS?
|
||||
char str[32];
|
||||
memset(str, 0, sizeof(str));
|
||||
if(access("ramdisk-mtk-boot", R_OK)==0) {
|
||||
strcpy(str, "ROOTFS");
|
||||
} else if(access("ramdisk-mtk-recovery", R_OK)==0) {
|
||||
strcpy(str, "RECOVERY");
|
||||
} else {
|
||||
exit(1);
|
||||
}
|
||||
memcpy(buf+8, str, sizeof(str));
|
||||
|
||||
memset(buf+8+sizeof(str), 0xff, 512-8-sizeof(str));
|
||||
|
||||
pwrite(ofd, buf, sizeof(buf), pos);
|
||||
|
||||
return append_file(ofd, "ramdisk.gz", pos + 512) + 512;
|
||||
} else if(access("ramdisk.gz", R_OK) == 0) {
|
||||
return append_file(ofd, "ramdisk.gz", pos);
|
||||
} else {
|
||||
return append_file(ofd, "ramdisk", pos);
|
||||
}
|
||||
}
|
||||
|
||||
void post_process(struct boot_img_hdr *hdr, int ofd, int pos) {
|
||||
if(access("rkcrc", R_OK) == 0) {
|
||||
fprintf(stderr, "Rockchip CRCs not supported yet\n");
|
||||
exit(1);
|
||||
}
|
||||
//Round up the file size
|
||||
ftruncate(ofd, pos);
|
||||
}
|
||||
|
||||
int repack(char *image) {
|
||||
|
||||
//TODO: Merge with extract.c?
|
||||
//{
|
||||
int ifd = open(image, O_RDONLY);
|
||||
off_t isize = lseek(ifd, 0, SEEK_END);
|
||||
lseek(ifd, 0, SEEK_SET);
|
||||
uint8_t *iorig = mmap(NULL, isize, PROT_READ, MAP_SHARED, ifd, 0);
|
||||
uint8_t *ibase = iorig;
|
||||
assert(ibase);
|
||||
|
||||
while(ibase<(iorig+isize)) {
|
||||
if(memcmp(ibase, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0)
|
||||
break;
|
||||
ibase += 256;
|
||||
}
|
||||
assert(ibase < (iorig+isize));
|
||||
//}
|
||||
//
|
||||
struct boot_img_hdr *ihdr = (struct boot_img_hdr*) ibase;
|
||||
assert(
|
||||
ihdr->page_size == 2048 ||
|
||||
ihdr->page_size == 4096 ||
|
||||
ihdr->page_size == 16384
|
||||
);
|
||||
|
||||
unlink("new-boot.img");
|
||||
int ofd = open("new-boot.img", O_RDWR|O_CREAT, 0644);
|
||||
ftruncate(ofd, ihdr->page_size);
|
||||
//Write back original header, we'll change it later
|
||||
write(ofd, ihdr, sizeof(*ihdr));
|
||||
|
||||
struct boot_img_hdr *hdr = mmap(NULL, sizeof(*ihdr), PROT_READ|PROT_WRITE, MAP_SHARED, ofd, 0);
|
||||
//First set everything to zero, so we know where we are at.
|
||||
hdr->kernel_size = 0;
|
||||
hdr->ramdisk_size = 0;
|
||||
hdr->second_size = 0;
|
||||
hdr->unused[0] = 0;
|
||||
memset(hdr->id, 0, sizeof(hdr->id)); //Setting id to 0 might be wrong?
|
||||
|
||||
int pos = hdr->page_size;
|
||||
int size = 0;
|
||||
|
||||
size = append_file(ofd, "kernel", pos);
|
||||
pos += size + hdr->page_size - 1;
|
||||
pos &= ~(hdr->page_size-1);
|
||||
hdr->kernel_size = size;
|
||||
|
||||
size = append_ramdisk(ofd, pos);
|
||||
pos += size + hdr->page_size - 1;
|
||||
pos &= ~(hdr->page_size-1);
|
||||
hdr->ramdisk_size = size;
|
||||
|
||||
if(access("second", R_OK) == 0) {
|
||||
size = append_file(ofd, "second", pos);
|
||||
pos += size + hdr->page_size - 1;
|
||||
pos &= ~(hdr->page_size-1);
|
||||
hdr->second_size = size;
|
||||
}
|
||||
|
||||
if(access("dt", R_OK) == 0) {
|
||||
size = append_file(ofd, "dt", pos);
|
||||
pos += size + hdr->page_size - 1;
|
||||
pos &= ~(hdr->page_size-1);
|
||||
hdr->unused[0] = size;
|
||||
}
|
||||
|
||||
post_process(hdr, ofd, pos);
|
||||
munmap(hdr, sizeof(*ihdr));
|
||||
close(ofd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
773
jni/daemon/bootstages.c
Normal file
773
jni/daemon/bootstages.c
Normal file
File diff suppressed because it is too large
Load Diff
208
jni/daemon/daemon.c
Normal file
208
jni/daemon/daemon.c
Normal file
@@ -0,0 +1,208 @@
|
||||
/* daemon.c - Magisk Daemon
|
||||
*
|
||||
* Start the daemon and wait for requests
|
||||
* Connect the daemon and send requests through sockets
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mount.h>
|
||||
#include <selinux/selinux.h>
|
||||
|
||||
#include "magisk.h"
|
||||
#include "utils.h"
|
||||
#include "daemon.h"
|
||||
#include "magiskpolicy.h"
|
||||
|
||||
pthread_t sepol_patch;
|
||||
int null_fd;
|
||||
|
||||
static void *request_handler(void *args) {
|
||||
// Setup the default error handler for threads
|
||||
err_handler = exit_thread;
|
||||
|
||||
int client = *((int *) args);
|
||||
free(args);
|
||||
client_request req = read_int(client);
|
||||
|
||||
struct ucred credentials;
|
||||
get_client_cred(client, &credentials);
|
||||
|
||||
switch (req) {
|
||||
case LAUNCH_MAGISKHIDE:
|
||||
case STOP_MAGISKHIDE:
|
||||
case ADD_HIDELIST:
|
||||
case RM_HIDELIST:
|
||||
case POST_FS:
|
||||
case POST_FS_DATA:
|
||||
case LATE_START:
|
||||
if (credentials.uid != 0) {
|
||||
write_int(client, ROOT_REQUIRED);
|
||||
close(client);
|
||||
return NULL;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (req) {
|
||||
case LAUNCH_MAGISKHIDE:
|
||||
launch_magiskhide(client);
|
||||
break;
|
||||
case STOP_MAGISKHIDE:
|
||||
stop_magiskhide(client);
|
||||
break;
|
||||
case ADD_HIDELIST:
|
||||
add_hide_list(client);
|
||||
break;
|
||||
case RM_HIDELIST:
|
||||
rm_hide_list(client);
|
||||
break;
|
||||
case SUPERUSER:
|
||||
su_daemon_receiver(client);
|
||||
break;
|
||||
case CHECK_VERSION:
|
||||
write_string(client, MAGISK_VER_STR);
|
||||
close(client);
|
||||
break;
|
||||
case CHECK_VERSION_CODE:
|
||||
write_int(client, MAGISK_VER_CODE);
|
||||
close(client);
|
||||
break;
|
||||
case POST_FS:
|
||||
post_fs(client);
|
||||
break;
|
||||
case POST_FS_DATA:
|
||||
post_fs_data(client);
|
||||
break;
|
||||
case LATE_START:
|
||||
late_start(client);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Just in case
|
||||
close(client);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Setup the address and return socket fd */
|
||||
static int setup_socket(struct sockaddr_un *sun) {
|
||||
int fd = xsocket(AF_LOCAL, SOCK_STREAM, 0);
|
||||
if (fcntl(fd, F_SETFD, FD_CLOEXEC))
|
||||
PLOGE("fcntl FD_CLOEXEC");
|
||||
|
||||
memset(sun, 0, sizeof(*sun));
|
||||
sun->sun_family = AF_LOCAL;
|
||||
memcpy(sun->sun_path, REQUESTOR_DAEMON_PATH, REQUESTOR_DAEMON_PATH_LEN);
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void *large_sepol_patch(void *args) {
|
||||
LOGD("sepol: Starting large patch thread\n");
|
||||
// Patch su to everything
|
||||
sepol_allow("su", ALL, ALL, ALL);
|
||||
dump_policydb(SELINUX_LOAD);
|
||||
LOGD("sepol: Large patch done\n");
|
||||
destroy_policydb();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void start_daemon(int client) {
|
||||
// Launch the daemon, create new session, set proper context
|
||||
if (getuid() != UID_ROOT || getgid() != UID_ROOT) {
|
||||
fprintf(stderr, "Starting daemon requires root: %s\n", strerror(errno));
|
||||
PLOGE("start daemon");
|
||||
}
|
||||
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
PLOGE("fork");
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// First close the client, it's useless for us
|
||||
close(client);
|
||||
xsetsid();
|
||||
setcon("u:r:su:s0");
|
||||
umask(022);
|
||||
null_fd = xopen("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
xdup2(null_fd, STDIN_FILENO);
|
||||
xdup2(null_fd, STDOUT_FILENO);
|
||||
xdup2(null_fd, STDERR_FILENO);
|
||||
|
||||
// Patch selinux with medium patch before we do anything
|
||||
load_policydb(SELINUX_POLICY);
|
||||
sepol_med_rules();
|
||||
dump_policydb(SELINUX_LOAD);
|
||||
|
||||
// Continue the larger patch in another thread, we will join later
|
||||
pthread_create(&sepol_patch, NULL, large_sepol_patch, NULL);
|
||||
|
||||
struct sockaddr_un sun;
|
||||
int fd = setup_socket(&sun);
|
||||
|
||||
xbind(fd, (struct sockaddr*) &sun, sizeof(sun));
|
||||
xlisten(fd, 10);
|
||||
|
||||
// Change process name
|
||||
strcpy(argv0, "magisk_daemon");
|
||||
// The root daemon should not do anything if an error occurs
|
||||
// It should stay intact under any circumstances
|
||||
err_handler = do_nothing;
|
||||
|
||||
LOGI("Magisk v" xstr(MAGISK_VERSION) " daemon started\n");
|
||||
|
||||
// Unlock all blocks for rw
|
||||
unlock_blocks();
|
||||
|
||||
// Setup links under /sbin
|
||||
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
|
||||
create_links(NULL, "/sbin");
|
||||
xchmod("/sbin", 0755);
|
||||
mkdir("/magisk", 0755);
|
||||
xchmod("/magisk", 0755);
|
||||
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
|
||||
|
||||
// Loop forever to listen for requests
|
||||
while(1) {
|
||||
int *client = xmalloc(sizeof(int));
|
||||
*client = xaccept(fd, NULL, NULL);
|
||||
// Just in case, set to close on exec
|
||||
fcntl(*client, F_SETFD, FD_CLOEXEC);
|
||||
pthread_t thread;
|
||||
xpthread_create(&thread, NULL, request_handler, client);
|
||||
// Detach the thread, we will never join it
|
||||
pthread_detach(thread);
|
||||
}
|
||||
}
|
||||
|
||||
/* Connect the daemon, and return a socketfd */
|
||||
int connect_daemon() {
|
||||
struct sockaddr_un sun;
|
||||
int fd = setup_socket(&sun);
|
||||
// LOGD("client: trying to connect socket\n");
|
||||
if (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) {
|
||||
/* If we cannot access the daemon, we start the daemon
|
||||
* since there is no clear entry point when the daemon should be started
|
||||
*/
|
||||
LOGD("client: connect fail, try launching new daemon process\n");
|
||||
start_daemon(fd);
|
||||
do {
|
||||
// Wait for 10ms
|
||||
usleep(10);
|
||||
} while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)));
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
79
jni/daemon/daemon.h
Normal file
79
jni/daemon/daemon.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* daemon.h - Utility functions for daemon-client communication
|
||||
*/
|
||||
|
||||
#ifndef _DAEMON_H_
|
||||
#define _DAEMON_H_
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
extern pthread_t sepol_patch;
|
||||
|
||||
// Commands require connecting to daemon
|
||||
typedef enum {
|
||||
DO_NOTHING = 0,
|
||||
LAUNCH_MAGISKHIDE,
|
||||
STOP_MAGISKHIDE,
|
||||
ADD_HIDELIST,
|
||||
RM_HIDELIST,
|
||||
SUPERUSER,
|
||||
CHECK_VERSION,
|
||||
CHECK_VERSION_CODE,
|
||||
POST_FS,
|
||||
POST_FS_DATA,
|
||||
LATE_START,
|
||||
TEST
|
||||
} client_request;
|
||||
|
||||
// Return codes for daemon
|
||||
typedef enum {
|
||||
DAEMON_ERROR = -1,
|
||||
DAEMON_SUCCESS = 0,
|
||||
ROOT_REQUIRED,
|
||||
HIDE_IS_ENABLED,
|
||||
HIDE_NOT_ENABLED,
|
||||
HIDE_ITEM_EXIST,
|
||||
HIDE_ITEM_NOT_EXIST,
|
||||
} daemon_response;
|
||||
|
||||
// daemon.c
|
||||
|
||||
void start_daemon(int client);
|
||||
int connect_daemon();
|
||||
|
||||
// socket_trans.c
|
||||
|
||||
int recv_fd(int sockfd);
|
||||
void send_fd(int sockfd, int fd);
|
||||
int read_int(int fd);
|
||||
void write_int(int fd, int val);
|
||||
char* read_string(int fd);
|
||||
void write_string(int fd, const char* val);
|
||||
|
||||
// log_monitor.c
|
||||
|
||||
void monitor_logs();
|
||||
|
||||
/***************
|
||||
* Boot Stages *
|
||||
***************/
|
||||
|
||||
void post_fs(int client);
|
||||
void post_fs_data(int client);
|
||||
void late_start(int client);
|
||||
|
||||
/**************
|
||||
* MagiskHide *
|
||||
**************/
|
||||
|
||||
void launch_magiskhide(int client);
|
||||
void stop_magiskhide(int client);
|
||||
void add_hide_list(int client);
|
||||
void rm_hide_list(int client);
|
||||
|
||||
/*************
|
||||
* Superuser *
|
||||
*************/
|
||||
|
||||
void su_daemon_receiver(int client);
|
||||
|
||||
#endif
|
||||
46
jni/daemon/log_monitor.c
Normal file
46
jni/daemon/log_monitor.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/* log_monitor.c - New thread to monitor logcat
|
||||
*
|
||||
* Open a new thread to call logcat and get logs with tag "Magisk"
|
||||
* Also, write the logs to a log file for debugging purpose
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "magisk.h"
|
||||
#include "utils.h"
|
||||
#include "daemon.h"
|
||||
|
||||
static void *logger_thread(void *args) {
|
||||
// Setup error handler
|
||||
err_handler = exit_thread;
|
||||
|
||||
rename(LOGFILE, LASTLOG);
|
||||
int log_fd, log_pid;
|
||||
|
||||
log_fd = xopen(LOGFILE, O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, 0644);
|
||||
|
||||
while (1) {
|
||||
// Start logcat
|
||||
char *const command[] = { "logcat", "-s", "Magisk", "-v", "thread", NULL };
|
||||
log_pid = run_command(0, &log_fd, "/system/bin/logcat", command);
|
||||
waitpid(log_pid, NULL, 0);
|
||||
// For some reason it went here, clear buffer and restart
|
||||
system("logcat -c");
|
||||
}
|
||||
|
||||
// Should never be here, but well...
|
||||
close(log_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Start a new thread to monitor logcat and dump to logfile */
|
||||
void monitor_logs() {
|
||||
pthread_t thread;
|
||||
xpthread_create(&thread, NULL, logger_thread, NULL);
|
||||
pthread_detach(thread);
|
||||
}
|
||||
148
jni/daemon/socket_trans.c
Normal file
148
jni/daemon/socket_trans.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/* socket_trans.c - Functions to transfer data through socket
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "magisk.h"
|
||||
#include "utils.h"
|
||||
#include "daemon.h"
|
||||
|
||||
/*
|
||||
* Receive a file descriptor from a Unix socket.
|
||||
* Contributed by @mkasick
|
||||
*
|
||||
* Returns the file descriptor on success, or -1 if a file
|
||||
* descriptor was not actually included in the message
|
||||
*
|
||||
* On error the function terminates by calling exit(-1)
|
||||
*/
|
||||
int recv_fd(int sockfd) {
|
||||
// Need to receive data from the message, otherwise don't care about it.
|
||||
char iovbuf;
|
||||
|
||||
struct iovec iov = {
|
||||
.iov_base = &iovbuf,
|
||||
.iov_len = 1,
|
||||
};
|
||||
|
||||
char cmsgbuf[CMSG_SPACE(sizeof(int))];
|
||||
|
||||
struct msghdr msg = {
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
.msg_control = cmsgbuf,
|
||||
.msg_controllen = sizeof(cmsgbuf),
|
||||
};
|
||||
|
||||
xrecvmsg(sockfd, &msg, MSG_WAITALL);
|
||||
|
||||
// Was a control message actually sent?
|
||||
switch (msg.msg_controllen) {
|
||||
case 0:
|
||||
// No, so the file descriptor was closed and won't be used.
|
||||
return -1;
|
||||
case sizeof(cmsgbuf):
|
||||
// Yes, grab the file descriptor from it.
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
||||
|
||||
if (cmsg == NULL ||
|
||||
cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
|
||||
cmsg->cmsg_level != SOL_SOCKET ||
|
||||
cmsg->cmsg_type != SCM_RIGHTS) {
|
||||
error:
|
||||
LOGE("unable to read fd");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
return *(int *)CMSG_DATA(cmsg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a file descriptor through a Unix socket.
|
||||
* Contributed by @mkasick
|
||||
*
|
||||
* On error the function terminates by calling exit(-1)
|
||||
*
|
||||
* fd may be -1, in which case the dummy data is sent,
|
||||
* but no control message with the FD is sent.
|
||||
*/
|
||||
void send_fd(int sockfd, int fd) {
|
||||
// Need to send some data in the message, this will do.
|
||||
struct iovec iov = {
|
||||
.iov_base = "",
|
||||
.iov_len = 1,
|
||||
};
|
||||
|
||||
struct msghdr msg = {
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
};
|
||||
|
||||
char cmsgbuf[CMSG_SPACE(sizeof(int))];
|
||||
|
||||
if (fd != -1) {
|
||||
// Is the file descriptor actually open?
|
||||
if (fcntl(fd, F_GETFD) == -1) {
|
||||
if (errno != EBADF) {
|
||||
PLOGE("unable to send fd");
|
||||
}
|
||||
// It's closed, don't send a control message or sendmsg will EBADF.
|
||||
} else {
|
||||
// It's open, send the file descriptor in a control message.
|
||||
msg.msg_control = cmsgbuf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf);
|
||||
|
||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
||||
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
|
||||
*(int *)CMSG_DATA(cmsg) = fd;
|
||||
}
|
||||
}
|
||||
|
||||
xsendmsg(sockfd, &msg, 0);
|
||||
}
|
||||
|
||||
int read_int(int fd) {
|
||||
int val;
|
||||
xxread(fd, &val, sizeof(int));
|
||||
return val;
|
||||
}
|
||||
|
||||
void write_int(int fd, int val) {
|
||||
if (fd < 0) return;
|
||||
xwrite(fd, &val, sizeof(int));
|
||||
}
|
||||
|
||||
char* read_string(int fd) {
|
||||
int len = read_int(fd);
|
||||
if (len > PATH_MAX || len < 0) {
|
||||
LOGE("invalid string length %d", len);
|
||||
exit(1);
|
||||
}
|
||||
char* val = xmalloc(sizeof(char) * (len + 1));
|
||||
xxread(fd, val, len);
|
||||
val[len] = '\0';
|
||||
return val;
|
||||
}
|
||||
|
||||
void write_string(int fd, const char* val) {
|
||||
if (fd < 0) return;
|
||||
int len = strlen(val);
|
||||
write_int(fd, len);
|
||||
xwrite(fd, val, len);
|
||||
}
|
||||
93
jni/magisk.h
Normal file
93
jni/magisk.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/* magisk.h - Top header
|
||||
*/
|
||||
|
||||
#ifndef _MAGISK_H_
|
||||
#define _MAGISK_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <android/log.h>
|
||||
|
||||
#define MAGISK_VER_STR xstr(MAGISK_VERSION) ":MAGISK"
|
||||
|
||||
#define str(a) #a
|
||||
#define xstr(a) str(a)
|
||||
|
||||
#define REQUESTOR_DAEMON_PATH "\0MAGISK"
|
||||
#define REQUESTOR_DAEMON_PATH_LEN 7
|
||||
|
||||
#define LOG_TAG "Magisk"
|
||||
|
||||
#ifndef ARG_MAX
|
||||
#define ARG_MAX 4096
|
||||
#endif
|
||||
|
||||
#define LOGFILE "/cache/magisk.log"
|
||||
#define LASTLOG "/cache/last_magisk.log"
|
||||
#define DEBUG_LOG "/data/magisk_debug.log"
|
||||
#define UNBLOCKFILE "/dev/.magisk.unblock"
|
||||
#define DISABLEFILE "/cache/.disable_magisk"
|
||||
#define UNINSTALLER "/cache/magisk_uninstaller.sh"
|
||||
#define MOUNTPOINT "/magisk"
|
||||
#define COREDIR MOUNTPOINT "/.core"
|
||||
#define HOSTSFILE COREDIR "/hosts"
|
||||
#define HIDELIST COREDIR "/hidelist"
|
||||
#define MAINIMG "/data/magisk.img"
|
||||
#define DATABIN "/data/magisk"
|
||||
#define MANAGERAPK DATABIN "/magisk.apk"
|
||||
#define MAGISKTMP "/dev/magisk"
|
||||
#define MIRRDIR MAGISKTMP "/mirror"
|
||||
#define DUMMDIR MAGISKTMP "/dummy"
|
||||
#define CACHEMOUNT "/cache/magisk_mount"
|
||||
|
||||
#define SELINUX_PATH "/sys/fs/selinux/"
|
||||
#define SELINUX_ENFORCE SELINUX_PATH "enforce"
|
||||
#define SELINUX_POLICY SELINUX_PATH "policy"
|
||||
#define SELINUX_LOAD SELINUX_PATH "load"
|
||||
|
||||
#define MAGISKHIDE_PROP "persist.magisk.hide"
|
||||
|
||||
// Global handler for PLOGE
|
||||
extern __thread void (*err_handler)(void);
|
||||
|
||||
// Common error handlers
|
||||
static inline void exit_proc() { exit(1); }
|
||||
static inline void exit_thread() { pthread_exit(NULL); }
|
||||
static inline void do_nothing() {}
|
||||
|
||||
// Dummy function to depress debug message
|
||||
static inline void stub(const char *fmt, ...) {}
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define LOGD(...) stub(__VA_ARGS__)
|
||||
#endif
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
||||
|
||||
#define PLOGE(fmt, args...) { LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)); err_handler(); }
|
||||
|
||||
extern char *argv0; /* For changing process name */
|
||||
|
||||
extern char *applet[];
|
||||
extern int (*applet_main[]) (int, char *[]);
|
||||
extern int null_fd;
|
||||
|
||||
// Multi-call entrypoints
|
||||
int magiskhide_main(int argc, char *argv[]);
|
||||
int magiskpolicy_main(int argc, char *argv[]);
|
||||
int su_client_main(int argc, char *argv[]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int resetprop_main(int argc, char *argv[]);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
31
jni/magiskboot/Android.mk
Normal file
31
jni/magiskboot/Android.mk
Normal file
@@ -0,0 +1,31 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := magiskboot
|
||||
LOCAL_STATIC_LIBRARIES := libz liblzma liblz4 libbz2
|
||||
LOCAL_C_INCLUDES := \
|
||||
jni/utils \
|
||||
jni/ndk-compression/zlib/ \
|
||||
jni/ndk-compression/xz/src/liblzma/api/ \
|
||||
jni/ndk-compression/lz4/lib/ \
|
||||
jni/ndk-compression/bzip2/
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
main.c \
|
||||
unpack.c \
|
||||
repack.c \
|
||||
hexpatch.c \
|
||||
parseimg.c \
|
||||
compress.c \
|
||||
utils.c \
|
||||
cpio.c \
|
||||
sha1.c \
|
||||
../utils/xwrap.c \
|
||||
../utils/vector.c
|
||||
LOCAL_CFLAGS += -DZLIB_CONST
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include jni/ndk-compression/zlib/Android.mk
|
||||
include jni/ndk-compression/xz/src/liblzma/Android.mk
|
||||
include jni/ndk-compression/lz4/lib/Android.mk
|
||||
include jni/ndk-compression/bzip2/Android.mk
|
||||
@@ -43,7 +43,14 @@ struct boot_img_hdr
|
||||
|
||||
uint32_t tags_addr; /* physical addr for kernel tags */
|
||||
uint32_t page_size; /* flash page size we assume */
|
||||
uint32_t unused[2]; /* future expansion: should be 0 */
|
||||
uint32_t dt_size; /* device tree in bytes */
|
||||
|
||||
/* operating system version and security patch level; for
|
||||
* version "A.B.C" and patch level "Y-M-D":
|
||||
* ver = A << 14 | B << 7 | C (7 bits for each of A, B, C)
|
||||
* lvl = ((Y - 2000) & 127) << 4 | M (7 bits for Y, 4 bits for M)
|
||||
* os_version = ver << 11 | lvl */
|
||||
uint32_t os_version;
|
||||
|
||||
uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */
|
||||
|
||||
@@ -66,10 +73,13 @@ struct boot_img_hdr
|
||||
** +-----------------+
|
||||
** | second stage | o pages
|
||||
** +-----------------+
|
||||
** | device tree | p pages
|
||||
** +-----------------+
|
||||
**
|
||||
** n = (kernel_size + page_size - 1) / page_size
|
||||
** m = (ramdisk_size + page_size - 1) / page_size
|
||||
** o = (second_size + page_size - 1) / page_size
|
||||
** p = (dt_size + page_size - 1) / page_size
|
||||
**
|
||||
** 0. all entities are page_size aligned in flash
|
||||
** 1. kernel and ramdisk are required (size != 0)
|
||||
@@ -83,8 +93,10 @@ struct boot_img_hdr
|
||||
** else: jump to kernel_addr
|
||||
*/
|
||||
|
||||
int extract(char *image);
|
||||
int repack(char *image);
|
||||
int hexpatch(char *image, char *from, char *to);
|
||||
typedef struct mtk_hdr {
|
||||
uint8_t magic[4]; /* MTK magic */
|
||||
uint32_t size; /* Size of the content */
|
||||
uint8_t name[32]; /* The type of the header */
|
||||
} mtk_hdr;
|
||||
|
||||
#endif
|
||||
569
jni/magiskboot/compress.c
Normal file
569
jni/magiskboot/compress.c
Normal file
File diff suppressed because it is too large
Load Diff
480
jni/magiskboot/cpio.c
Normal file
480
jni/magiskboot/cpio.c
Normal file
File diff suppressed because it is too large
Load Diff
42
jni/magiskboot/cpio.h
Normal file
42
jni/magiskboot/cpio.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef _CPIO_H_
|
||||
#define _CPIO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct cpio_file {
|
||||
// uint32_t ino;
|
||||
uint32_t mode;
|
||||
uint32_t uid;
|
||||
uint32_t gid;
|
||||
// uint32_t nlink;
|
||||
// uint32_t mtime;
|
||||
uint32_t filesize;
|
||||
// uint32_t devmajor;
|
||||
// uint32_t devminor;
|
||||
// uint32_t rdevmajor;
|
||||
// uint32_t rdevminor;
|
||||
uint32_t namesize;
|
||||
// uint32_t check;
|
||||
char *filename;
|
||||
char *data;
|
||||
int remove;
|
||||
} cpio_file;
|
||||
|
||||
typedef struct cpio_newc_header {
|
||||
char magic[6];
|
||||
char ino[8];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char nlink[8];
|
||||
char mtime[8];
|
||||
char filesize[8];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
char rdevmajor[8];
|
||||
char rdevminor[8];
|
||||
char namesize[8];
|
||||
char check[8];
|
||||
} cpio_newc_header;
|
||||
|
||||
#endif
|
||||
32
jni/magiskboot/hexpatch.c
Normal file
32
jni/magiskboot/hexpatch.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "magiskboot.h"
|
||||
|
||||
static void hex2byte(const char *hex, unsigned char *str) {
|
||||
char high, low;
|
||||
for (int i = 0, length = strlen(hex); i < length; i += 2) {
|
||||
high = toupper(hex[i]) - '0';
|
||||
low = toupper(hex[i + 1]) - '0';
|
||||
str[i / 2] = ((high > 9 ? high - 7 : high) << 4) + (low > 9 ? low - 7 : low);
|
||||
}
|
||||
}
|
||||
|
||||
void hexpatch(const char *image, const char *from, const char *to) {
|
||||
int patternsize = strlen(from) / 2, patchsize = strlen(to) / 2;
|
||||
size_t filesize;
|
||||
unsigned char *file, *pattern, *patch;
|
||||
mmap_rw(image, &file, &filesize);
|
||||
pattern = xmalloc(patternsize);
|
||||
patch = xmalloc(patchsize);
|
||||
hex2byte(from, pattern);
|
||||
hex2byte(to, patch);
|
||||
for (size_t i = 0; i < filesize - patternsize; ++i) {
|
||||
if (memcmp(file + i, pattern, patternsize) == 0) {
|
||||
printf("Pattern %s found!\nPatching to %s\n", from, to);
|
||||
memset(file + i, 0, patternsize);
|
||||
memcpy(file + i, patch, patchsize);
|
||||
i += patternsize - 1;
|
||||
}
|
||||
}
|
||||
munmap(file, filesize);
|
||||
free(pattern);
|
||||
free(patch);
|
||||
}
|
||||
10
jni/magiskboot/magisk.h
Normal file
10
jni/magiskboot/magisk.h
Normal file
@@ -0,0 +1,10 @@
|
||||
/* magisk.h - Let MagiskBoot use the same error handling API as main magisk program
|
||||
*/
|
||||
|
||||
#ifndef _MAGISK_H_
|
||||
#define _MAGISK_H_
|
||||
|
||||
#define LOGE(err, ...) { fprintf(stderr, __VA_ARGS__); exit(err); }
|
||||
#define PLOGE(fmt, args...) { fprintf(stderr, fmt " failed with %d: %s\n\n", ##args, errno, strerror(errno)); exit(1); }
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user