mirror of
https://github.com/topjohnwu/Magisk
synced 2025-10-27 04:02:14 +01:00
Compare commits
89 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 |
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -10,7 +10,7 @@
|
||||
*.cmd text eol=crlf
|
||||
|
||||
# Denote all files that are truly binary and should not be modified.
|
||||
binaries/** binary
|
||||
chromeos/** binary
|
||||
*.jar binary
|
||||
*.exe binary
|
||||
*.apk binary
|
||||
|
||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -1,22 +1,7 @@
|
||||
obj/
|
||||
libs/
|
||||
*.zip
|
||||
*.jks
|
||||
|
||||
# Copied binaries
|
||||
zip_static/arm/*
|
||||
zip_static/arm64/*
|
||||
zip_static/x86/*
|
||||
zip_static/x64/*
|
||||
zip_static/chromeos/*
|
||||
uninstaller/arm/*
|
||||
uninstaller/arm64/*
|
||||
uninstaller/x86/*
|
||||
uninstaller/x64/*
|
||||
uninstaller/chromeos/*
|
||||
ziptools/zipadjust
|
||||
|
||||
# Generated scripts
|
||||
uninstaller/common/
|
||||
zip_static/common/*.sh
|
||||
zip_static/common/*.rc
|
||||
zip_static/META-INF/com/google/android/update-binary
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -10,3 +10,6 @@
|
||||
[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)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
182
build.cmd
182
build.cmd
@@ -1,182 +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 ************************
|
||||
CALL :mkcp libs\armeabi-v7a\* zip_static\arm
|
||||
CALL :mkcp libs\arm64-v8a\* zip_static\arm64
|
||||
CALL :mkcp libs\x86\* zip_static\x86
|
||||
CALL :mkcp libs\x86_64\* zip_static\x64
|
||||
CALL :mkcp libs\armeabi-v7a\magiskboot uninstaller\arm
|
||||
CALL :mkcp libs\arm64-v8a\magiskboot uninstaller\arm64
|
||||
CALL :mkcp libs\x86\magiskboot uninstaller\x86
|
||||
CALL :mkcp libs\x86_64\magiskboot uninstaller\x64
|
||||
EXIT /B %ERRORLEVEL%
|
||||
|
||||
:clean
|
||||
SET OK=y
|
||||
ECHO ************************
|
||||
ECHO * Cleaning up
|
||||
ECHO ************************
|
||||
CALL ndk-build clean
|
||||
2>NUL RMDIR /S /Q zip_static\arm
|
||||
2>NUL RMDIR /S /Q zip_static\arm64
|
||||
2>NUL RMDIR /S /Q zip_static\x86
|
||||
2>NUL RMDIR /S /Q zip_static\x64
|
||||
2>NUL RMDIR /S /Q zip_static\chromeos
|
||||
2>NUL DEL zip_static\META-INF\com\google\android\update-binary
|
||||
2>NUL DEL zip_static\common\*.sh
|
||||
2>NUL DEL zip_static\common\*.rc
|
||||
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
|
||||
2>NUL RMDIR /S /Q uninstaller\chromeos
|
||||
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\magiskboot" 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 * Copying Files
|
||||
ECHO ************************
|
||||
COPY /Y scripts\custom_ramdisk_patch.sh zip_static\common\custom_ramdisk_patch.sh
|
||||
COPY /Y scripts\init.magisk.rc zip_static\common\init.magisk.rc
|
||||
COPY /Y binaries\busybox-arm zip_static\arm\busybox
|
||||
COPY /Y binaries\busybox-arm64 zip_static\arm64\busybox
|
||||
COPY /Y binaries\busybox-x86 zip_static\x86\busybox
|
||||
COPY /Y binaries\busybox-x64 zip_static\x64\busybox
|
||||
CALL :mkcp binaries\chromeos zip_static\chromeos
|
||||
ECHO ************************
|
||||
ECHO * Zipping Magisk v%~1
|
||||
ECHO ************************
|
||||
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\magiskboot" CALL :error "Missing binaries! Please run '%me% build' before zipping!"
|
||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||
ECHO ************************
|
||||
ECHO * Copying Files
|
||||
ECHO ************************
|
||||
CALL :mkcp scripts\magisk_uninstaller.sh uninstaller\common
|
||||
COPY /Y binaries\busybox-arm uninstaller\arm\busybox
|
||||
COPY /Y binaries\busybox-arm64 uninstaller\arm64\busybox
|
||||
COPY /Y binaries\busybox-x86 uninstaller\x86\busybox
|
||||
COPY /Y binaries\busybox-x64 uninstaller\x64\busybox
|
||||
CALL :mkcp binaries\chromeos uninstaller\chromeos
|
||||
ECHO ************************
|
||||
ECHO * Zipping uninstaller
|
||||
ECHO ************************
|
||||
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
|
||||
172
build.sh
172
build.sh
@@ -1,172 +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
|
||||
rm -rfv zip_static/arm
|
||||
rm -rfv zip_static/arm64
|
||||
rm -rfv zip_static/x86
|
||||
rm -rfv zip_static/x64
|
||||
rm -rfv zip_static/chromeos
|
||||
rm -rfv zip_static/META-INF/com/google/android/update-binary
|
||||
rm -rfv zip_static/common/*.sh
|
||||
rm -rfv zip_static/common/*.rc
|
||||
rm -rfv uninstaller/common
|
||||
rm -rfv uninstaller/arm
|
||||
rm -rfv uninstaller/arm64
|
||||
rm -rfv uninstaller/x86
|
||||
rm -rfv uninstaller/x64
|
||||
rm -rfv uninstaller/chromeos
|
||||
}
|
||||
|
||||
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/magiskboot uninstaller/arm
|
||||
mkcp "libs/arm64-v8a/*" zip_static/arm64
|
||||
mkcp libs/arm64-v8a/magiskboot uninstaller/arm64
|
||||
mkcp "libs/x86/*" zip_static/x86
|
||||
mkcp libs/x86/magiskboot uninstaller/x86
|
||||
mkcp "libs/x86_64/*" zip_static/x64
|
||||
mkcp libs/x86_64/magiskboot uninstaller/x64
|
||||
}
|
||||
|
||||
zip_package() {
|
||||
[ ! -f "zip_static/arm/magiskboot" ] && 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 "* Copying files"
|
||||
echo "************************"
|
||||
cp -afv scripts/custom_ramdisk_patch.sh zip_static/common/custom_ramdisk_patch.sh
|
||||
cp -afv scripts/init.magisk.rc zip_static/common/init.magisk.rc
|
||||
cp -afv binaries/busybox-arm zip_static/arm/busybox
|
||||
cp -afv binaries/busybox-arm64 zip_static/arm64/busybox
|
||||
cp -afv binaries/busybox-x86 zip_static/x86/busybox
|
||||
cp -afv binaries/busybox-x64 zip_static/x64/busybox
|
||||
cp -afv binaries/chromeos/. zip_static/chromeos
|
||||
echo "************************"
|
||||
echo "* Zipping Magisk v$1"
|
||||
echo "************************"
|
||||
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/magiskboot" ] && error "Missing binaries!! Please run '$0 build' before zipping"
|
||||
echo "************************"
|
||||
echo "* Copying files"
|
||||
echo "************************"
|
||||
mkcp scripts/magisk_uninstaller.sh uninstaller/common
|
||||
cp -afv binaries/busybox-arm uninstaller/arm/busybox
|
||||
cp -afv binaries/busybox-arm64 uninstaller/arm64/busybox
|
||||
cp -afv binaries/busybox-x86 uninstaller/x86/busybox
|
||||
cp -afv binaries/busybox-x64 uninstaller/x64/busybox
|
||||
cp -afv binaries/chromeos/. zip_static/chromeos
|
||||
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,7 +1,65 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := magisk
|
||||
LOCAL_STATIC_LIBRARIES := libsepol
|
||||
LOCAL_SHARED_LIBRARIES := libsqlite libselinux
|
||||
|
||||
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
|
||||
include jni/magiskhide/Android.mk
|
||||
include jni/resetprop/Android.mk
|
||||
include jni/magiskpolicy/Android.mk
|
||||
include jni/su/Android.mk
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
APP_ABI := x86 x86_64 armeabi-v7a arm64-v8a
|
||||
APP_PLATFORM := android-21
|
||||
APP_UNIFIED_HEADERS := true
|
||||
APP_CPPFLAGS += -std=c++11
|
||||
|
||||
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
|
||||
@@ -4,12 +4,24 @@ 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
|
||||
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)
|
||||
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
#define LZ4_LEGACY_BLOCKSIZE 0x800000
|
||||
|
||||
static void write_file(const int fd, const void *buf, const size_t size, const char *filename) {
|
||||
if (write(fd, buf, size) != size)
|
||||
error(1, "Error in writing %s", filename);
|
||||
xwrite(fd, buf, size);
|
||||
}
|
||||
|
||||
static void report(const int mode, const char* filename) {
|
||||
@@ -52,11 +51,11 @@ void gzip(int mode, const char* filename, const unsigned char* buf, size_t size)
|
||||
ret = deflateInit2(&strm, 9, Z_DEFLATED, windowBits | ZLIB_GZIP, memLevel, Z_DEFAULT_STRATEGY);
|
||||
break;
|
||||
default:
|
||||
error(1, "Unsupported gzip mode!");
|
||||
LOGE(1, "Unsupported gzip mode!\n");
|
||||
}
|
||||
|
||||
if (ret != Z_OK)
|
||||
error(1, "Unable to init zlib stream");
|
||||
LOGE(1, "Unable to init zlib stream\n");
|
||||
|
||||
do {
|
||||
strm.next_in = buf + pos;
|
||||
@@ -81,7 +80,7 @@ void gzip(int mode, const char* filename, const unsigned char* buf, size_t size)
|
||||
break;
|
||||
}
|
||||
if (ret == Z_STREAM_ERROR)
|
||||
error(1, "Error when running gzip");
|
||||
LOGE(1, "Error when running gzip\n");
|
||||
|
||||
have = CHUNK - strm.avail_out;
|
||||
write_file(fd, out, have, filename);
|
||||
@@ -132,12 +131,12 @@ void lzma(int mode, const char* filename, const unsigned char* buf, size_t size)
|
||||
ret = lzma_alone_encoder(&strm, &opt);
|
||||
break;
|
||||
default:
|
||||
error(1, "Unsupported lzma mode!");
|
||||
LOGE(1, "Unsupported lzma mode!\n");
|
||||
}
|
||||
|
||||
|
||||
if (ret != LZMA_OK)
|
||||
error(1, "Unable to init lzma stream");
|
||||
LOGE(1, "Unable to init lzma stream\n");
|
||||
|
||||
do {
|
||||
strm.next_in = buf + pos;
|
||||
@@ -159,7 +158,7 @@ void lzma(int mode, const char* filename, const unsigned char* buf, size_t size)
|
||||
} while (strm.avail_out == 0 && ret == LZMA_OK);
|
||||
|
||||
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
|
||||
error(1, "LZMA error %d!", ret);
|
||||
LOGE(1, "LZMA error %d!\n", ret);
|
||||
|
||||
} while (pos < size);
|
||||
|
||||
@@ -189,11 +188,11 @@ void lz4(int mode, const char* filename, const unsigned char* buf, size_t size)
|
||||
ret = LZ4F_createCompressionContext(&cctx, LZ4F_VERSION);
|
||||
break;
|
||||
default:
|
||||
error(1, "Unsupported lz4 mode!");
|
||||
LOGE(1, "Unsupported lz4 mode!\n");
|
||||
}
|
||||
|
||||
if (LZ4F_isError(ret))
|
||||
error(1, "Context creation error: %s\n", LZ4F_getErrorName(ret));
|
||||
LOGE(1, "Context creation error: %s\n", LZ4F_getErrorName(ret));
|
||||
|
||||
// Allocate out buffer
|
||||
switch(mode) {
|
||||
@@ -202,7 +201,7 @@ void lz4(int mode, const char* filename, const unsigned char* buf, size_t size)
|
||||
read = CHUNK;
|
||||
ret = LZ4F_getFrameInfo(dctx, &info, buf, &read);
|
||||
if (LZ4F_isError(ret))
|
||||
error(1, "LZ4F_getFrameInfo error: %s\n", LZ4F_getErrorName(ret));
|
||||
LOGE(1, "LZ4F_getFrameInfo error: %s\n", LZ4F_getErrorName(ret));
|
||||
switch (info.blockSizeID) {
|
||||
case LZ4F_default:
|
||||
case LZ4F_max64KB: outCapacity = 1 << 16; break;
|
||||
@@ -210,7 +209,7 @@ void lz4(int mode, const char* filename, const unsigned char* buf, size_t size)
|
||||
case LZ4F_max1MB: outCapacity = 1 << 20; break;
|
||||
case LZ4F_max4MB: outCapacity = 1 << 22; break;
|
||||
default:
|
||||
error(1, "Impossible unless more block sizes are allowed\n");
|
||||
LOGE(1, "Impossible unless more block sizes are allowed\n");
|
||||
}
|
||||
pos += read;
|
||||
break;
|
||||
@@ -219,15 +218,13 @@ void lz4(int mode, const char* filename, const unsigned char* buf, size_t size)
|
||||
break;
|
||||
}
|
||||
|
||||
out = malloc(outCapacity);
|
||||
if (!out)
|
||||
error(1, "LZ4 malloc error!");
|
||||
out = xmalloc(outCapacity);
|
||||
|
||||
// Write header
|
||||
if (mode == 1) {
|
||||
have = ret = LZ4F_compressBegin(cctx, out, size, NULL);
|
||||
if (LZ4F_isError(ret))
|
||||
error(1, "Failed to start compression: error %s\n", LZ4F_getErrorName(ret));
|
||||
LOGE(1, "Failed to start compression: error %s\n", LZ4F_getErrorName(ret));
|
||||
write_file(fd, out, have, filename);
|
||||
}
|
||||
|
||||
@@ -250,7 +247,7 @@ void lz4(int mode, const char* filename, const unsigned char* buf, size_t size)
|
||||
break;
|
||||
}
|
||||
if (LZ4F_isError(ret))
|
||||
error(1, "LZ4 coding error: %s\n", LZ4F_getErrorName(ret));
|
||||
LOGE(1, "LZ4 coding error: %s\n", LZ4F_getErrorName(ret));
|
||||
|
||||
write_file(fd, out, have, filename);
|
||||
// Update status
|
||||
@@ -267,7 +264,7 @@ void lz4(int mode, const char* filename, const unsigned char* buf, size_t size)
|
||||
case 1:
|
||||
have = ret = LZ4F_compressEnd(cctx, out, outCapacity, NULL);
|
||||
if (LZ4F_isError(ret))
|
||||
error(1, "Failed to end compression: error %s\n", LZ4F_getErrorName(ret));
|
||||
LOGE(1, "Failed to end compression: error %s\n", LZ4F_getErrorName(ret));
|
||||
|
||||
write_file(fd, out, have, filename);
|
||||
|
||||
@@ -300,11 +297,11 @@ void bzip2(int mode, const char* filename, const unsigned char* buf, size_t size
|
||||
ret = BZ2_bzCompressInit(&strm, 9, 0, 0);
|
||||
break;
|
||||
default:
|
||||
error(1, "Unsupported bzip2 mode!");
|
||||
LOGE(1, "Unsupported bzip2 mode!\n");
|
||||
}
|
||||
|
||||
if (ret != BZ_OK)
|
||||
error(1, "Unable to init bzlib stream");
|
||||
LOGE(1, "Unable to init bzlib stream\n");
|
||||
|
||||
do {
|
||||
strm.next_in = (char *) buf + pos;
|
||||
@@ -361,22 +358,19 @@ void lz4_legacy(int mode, const char* filename, const unsigned char* buf, size_t
|
||||
|
||||
switch(mode) {
|
||||
case 0:
|
||||
out = malloc(LZ4_LEGACY_BLOCKSIZE);
|
||||
out = xmalloc(LZ4_LEGACY_BLOCKSIZE);
|
||||
// Skip magic
|
||||
pos += 4;
|
||||
break;
|
||||
case 1:
|
||||
out = malloc(LZ4_COMPRESSBOUND(LZ4_LEGACY_BLOCKSIZE));
|
||||
out = xmalloc(LZ4_COMPRESSBOUND(LZ4_LEGACY_BLOCKSIZE));
|
||||
// Write magic
|
||||
write_file(fd, "\x02\x21\x4c\x18", 4, filename);
|
||||
break;
|
||||
default:
|
||||
error(1, "Unsupported lz4_legacy mode!");
|
||||
LOGE(1, "Unsupported lz4_legacy mode!\n");
|
||||
}
|
||||
|
||||
if (!out)
|
||||
error(1, "lz4_legacy malloc error");
|
||||
|
||||
do {
|
||||
switch(mode) {
|
||||
case 0:
|
||||
@@ -386,10 +380,10 @@ void lz4_legacy(int mode, const char* filename, const unsigned char* buf, size_t
|
||||
block_size += ((unsigned)buf[pos + 3])<<24;
|
||||
pos += 4;
|
||||
if (block_size > LZ4_COMPRESSBOUND(LZ4_LEGACY_BLOCKSIZE))
|
||||
error(1, "lz4_legacy block size too large!");
|
||||
LOGE(1, "lz4_legacy block size too large!\n");
|
||||
have = LZ4_decompress_safe((const char*) (buf + pos), out, block_size, LZ4_LEGACY_BLOCKSIZE);
|
||||
if (have < 0)
|
||||
error(1, "Cannot decode lz4_legacy block");
|
||||
LOGE(1, "Cannot decode lz4_legacy block\n");
|
||||
pos += block_size;
|
||||
break;
|
||||
case 1:
|
||||
@@ -399,7 +393,7 @@ void lz4_legacy(int mode, const char* filename, const unsigned char* buf, size_t
|
||||
insize = LZ4_LEGACY_BLOCKSIZE;
|
||||
have = LZ4_compress_default((const char*) (buf + pos), out, insize, LZ4_COMPRESSBOUND(LZ4_LEGACY_BLOCKSIZE));
|
||||
if (have == 0)
|
||||
error(1, "lz4_legacy compression error");
|
||||
LOGE(1, "lz4_legacy compression error\n");
|
||||
pos += insize;
|
||||
block_size_le[0] = (unsigned char)have;
|
||||
block_size_le[1] = (unsigned char)(have >> 8);
|
||||
@@ -496,7 +490,7 @@ void decomp_file(char *from, const char *to) {
|
||||
char *ext;
|
||||
ext = strrchr(from, '.');
|
||||
if (ext == NULL)
|
||||
error(1, "Bad filename extention");
|
||||
LOGE(1, "Bad filename extention\n");
|
||||
|
||||
// File type and extension should match
|
||||
switch (type) {
|
||||
@@ -522,7 +516,7 @@ void decomp_file(char *from, const char *to) {
|
||||
ok = 0;
|
||||
break;
|
||||
default:
|
||||
error(1, "Provided file \'%s\' is not a supported archive format", from);
|
||||
LOGE(1, "Provided file \'%s\' is not a supported archive format\n", from);
|
||||
}
|
||||
if (ok) {
|
||||
// If all match, strip out the suffix
|
||||
@@ -536,7 +530,7 @@ void decomp_file(char *from, const char *to) {
|
||||
unlink(from);
|
||||
}
|
||||
} else {
|
||||
error(1, "Bad filename extention \'%s\'", ext);
|
||||
LOGE(1, "Bad filename extention \'%s\'\n", ext);
|
||||
}
|
||||
munmap(file, size);
|
||||
}
|
||||
@@ -556,7 +550,11 @@ void comp_file(const char *method, const char *from, const char *to) {
|
||||
} else if (strcmp(method, "bzip2") == 0) {
|
||||
type = BZIP2;
|
||||
} else {
|
||||
error(1, "Only support following methods: " SUP_LIST);
|
||||
fprintf(stderr, "Only support following methods: ");
|
||||
for (int i = 0; SUP_LIST[i]; ++i)
|
||||
fprintf(stderr, "%s ", SUP_LIST[i]);
|
||||
fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
}
|
||||
unsigned char *file;
|
||||
size_t size;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,151 +0,0 @@
|
||||
|
||||
#ifndef _ELF_H_
|
||||
#define _ELF_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
** ELF structure
|
||||
**
|
||||
** +-----------------+
|
||||
** | ELF magic | | 4 bytes
|
||||
** +------------ +
|
||||
** | ELF class | | 1 byte
|
||||
** +------------ +
|
||||
** | ELF header |
|
||||
** +-----------------+
|
||||
** ~
|
||||
** +-----------------+
|
||||
** | program header | kernel info
|
||||
** +-----------------+
|
||||
** | program header | ramdisk info
|
||||
** +-----------------+
|
||||
** | program header | dtb info
|
||||
** +-----------------+
|
||||
** | program header | (possible) cmdline info
|
||||
** +-----------------+
|
||||
** ~
|
||||
** +-----------------+
|
||||
** | section header | cmdline info
|
||||
** +-----------------+
|
||||
** ~
|
||||
** +-----------------+
|
||||
** | |
|
||||
** | Data |
|
||||
** | |
|
||||
** +-----------------+
|
||||
|
||||
*/
|
||||
|
||||
typedef uint32_t elf32_addr;
|
||||
typedef uint16_t elf32_half;
|
||||
typedef uint32_t elf32_off;
|
||||
typedef uint32_t elf32_word;
|
||||
|
||||
typedef uint64_t elf64_addr;
|
||||
typedef uint16_t elf64_half;
|
||||
typedef uint64_t elf64_off;
|
||||
typedef uint32_t elf64_word;
|
||||
typedef uint64_t elf64_xword;
|
||||
|
||||
#define ELF_MAGIC "\x7f""ELF"
|
||||
#define ELF_MAGIC_SIZE 4
|
||||
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define EI_VERSION 6
|
||||
#define EI_OSABI 7
|
||||
#define EI_PAD 8
|
||||
|
||||
#define ELFCLASSNONE 0
|
||||
#define ELFCLASS32 1
|
||||
#define ELFCLASS64 2
|
||||
#define ELFCLASSNUM 3
|
||||
|
||||
#define ET_EXEC 2
|
||||
#define EM_ARM 40
|
||||
#define EI_NIDENT 16
|
||||
|
||||
typedef struct elf32_ehdr {
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
elf32_half e_type;
|
||||
elf32_half e_machine;
|
||||
elf32_word e_version;
|
||||
elf32_addr e_entry; /* Entry point */
|
||||
elf32_off e_phoff;
|
||||
elf32_off e_shoff;
|
||||
elf32_word e_flags;
|
||||
elf32_half e_ehsize;
|
||||
elf32_half e_phentsize;
|
||||
elf32_half e_phnum;
|
||||
elf32_half e_shentsize;
|
||||
elf32_half e_shnum;
|
||||
elf32_half e_shstrndx;
|
||||
} elf32_ehdr;
|
||||
|
||||
typedef struct elf64_ehdr {
|
||||
unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
|
||||
elf64_half e_type;
|
||||
elf64_half e_machine;
|
||||
elf64_word e_version;
|
||||
elf64_addr e_entry; /* Entry point virtual address */
|
||||
elf64_off e_phoff; /* Program header table file offset */
|
||||
elf64_off e_shoff; /* Section header table file offset */
|
||||
elf64_word e_flags;
|
||||
elf64_half e_ehsize;
|
||||
elf64_half e_phentsize;
|
||||
elf64_half e_phnum;
|
||||
elf64_half e_shentsize;
|
||||
elf64_half e_shnum;
|
||||
elf64_half e_shstrndx;
|
||||
} elf64_ehdr;
|
||||
|
||||
typedef struct elf32_phdr {
|
||||
elf32_word p_type;
|
||||
elf32_off p_offset;
|
||||
elf32_addr p_vaddr;
|
||||
elf32_addr p_paddr;
|
||||
elf32_word p_filesz;
|
||||
elf32_word p_memsz;
|
||||
elf32_word p_flags;
|
||||
elf32_word p_align;
|
||||
} elf32_phdr;
|
||||
|
||||
typedef struct elf64_phdr {
|
||||
elf64_word p_type;
|
||||
elf64_word p_flags;
|
||||
elf64_off p_offset; /* Segment file offset */
|
||||
elf64_addr p_vaddr; /* Segment virtual address */
|
||||
elf64_addr p_paddr; /* Segment physical address */
|
||||
elf64_xword p_filesz; /* Segment size in file */
|
||||
elf64_xword p_memsz; /* Segment size in memory */
|
||||
elf64_xword p_align; /* Segment alignment, file & memory */
|
||||
} elf64_phdr;
|
||||
|
||||
typedef struct elf32_shdr {
|
||||
elf32_word s_name;
|
||||
elf32_word s_type;
|
||||
elf32_word s_flags;
|
||||
elf32_addr s_addr;
|
||||
elf32_off s_offset;
|
||||
elf32_word s_size;
|
||||
elf32_word s_link;
|
||||
elf32_word s_info;
|
||||
elf32_word s_addralign;
|
||||
elf32_word s_entsize;
|
||||
} elf32_shdr;
|
||||
|
||||
typedef struct elf64_shdr {
|
||||
elf64_word s_name; /* Section name, index in string tbl */
|
||||
elf64_word s_type; /* Type of section */
|
||||
elf64_xword s_flags; /* Miscellaneous section attributes */
|
||||
elf64_addr s_addr; /* Section virtual addr at execution */
|
||||
elf64_off s_offset; /* Section file offset */
|
||||
elf64_xword s_size; /* Size of section in bytes */
|
||||
elf64_word s_link; /* Index of another section */
|
||||
elf64_word s_info; /* Additional section information */
|
||||
elf64_xword s_addralign; /* Section alignment */
|
||||
elf64_xword s_entsize; /* Entry size if section holds table */
|
||||
} elf64_shdr;
|
||||
|
||||
#endif
|
||||
@@ -14,8 +14,8 @@ void hexpatch(const char *image, const char *from, const char *to) {
|
||||
size_t filesize;
|
||||
unsigned char *file, *pattern, *patch;
|
||||
mmap_rw(image, &file, &filesize);
|
||||
pattern = malloc(patternsize);
|
||||
patch = malloc(patchsize);
|
||||
pattern = xmalloc(patternsize);
|
||||
patch = xmalloc(patchsize);
|
||||
hex2byte(from, pattern);
|
||||
hex2byte(to, patch);
|
||||
for (size_t i = 0; i < filesize - patternsize; ++i) {
|
||||
|
||||
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
|
||||
@@ -8,28 +8,34 @@
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bootimg.h"
|
||||
#include "sha1.h"
|
||||
#include "magisk.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define CHROMEOS_MAGIC "CHROMEOS"
|
||||
#define CHROMEOS_MAGIC_SIZE 8
|
||||
#define CHROMEOS_MAGIC "CHROMEOS"
|
||||
#define ELF32_MAGIC "\x7f""ELF\x01"
|
||||
#define ELF64_MAGIC "\x7f""ELF\x02"
|
||||
|
||||
#define KERNEL_FILE "kernel"
|
||||
#define RAMDISK_FILE "ramdisk.cpio"
|
||||
#define SECOND_FILE "second"
|
||||
#define DTB_FILE "dtb"
|
||||
#define NEW_BOOT "new-boot.img"
|
||||
#define KERNEL_FILE "kernel"
|
||||
#define RAMDISK_FILE "ramdisk.cpio"
|
||||
#define SECOND_FILE "second"
|
||||
#define DTB_FILE "dtb"
|
||||
#define NEW_BOOT "new-boot.img"
|
||||
|
||||
#define str(a) #a
|
||||
#define xstr(a) str(a)
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN,
|
||||
CHROMEOS,
|
||||
AOSP,
|
||||
ELF,
|
||||
ELF32,
|
||||
ELF64,
|
||||
GZIP,
|
||||
LZOP,
|
||||
XZ,
|
||||
@@ -37,8 +43,7 @@ typedef enum {
|
||||
BZIP2,
|
||||
LZ4,
|
||||
LZ4_LEGACY,
|
||||
MTK,
|
||||
QCDT,
|
||||
MTK
|
||||
} file_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -54,45 +59,20 @@ typedef enum {
|
||||
RESTORE
|
||||
} command_t;
|
||||
|
||||
#define SUP_LIST "gzip, xz, lzma, bzip2, lz4, lz4_legacy"
|
||||
#define SUP_NUM 6
|
||||
|
||||
// Cannot declare in header, but place a copy here for convenience
|
||||
// char *SUP_EXT_LIST[SUP_NUM] = { "gz", "xz", "lzma", "bz2", "lz4", "lz4" };
|
||||
// file_t SUP_TYPE_LIST[SUP_NUM] = { GZIP, XZ, LZMA, BZIP2, LZ4, LZ4_LEGACY };
|
||||
extern char *SUP_EXT_LIST[SUP_NUM];
|
||||
extern file_t SUP_TYPE_LIST[SUP_NUM];
|
||||
|
||||
// Vector
|
||||
typedef struct vector {
|
||||
size_t size;
|
||||
size_t cap;
|
||||
void **data;
|
||||
} vector;
|
||||
void vec_init(vector *v);
|
||||
void vec_push_back(vector *v, void *p);
|
||||
void vec_sort(vector *v, int (*compar)(const void *, const void *));
|
||||
void vec_destroy(vector *v);
|
||||
|
||||
#define vec_size(v) (v)->size
|
||||
#define vec_cap(v) (v)->cap
|
||||
#define vec_entry(v) (v)->data
|
||||
// vec_for_each(vector *v, void *e)
|
||||
#define vec_for_each(v, e) \
|
||||
e = (v)->data[0]; \
|
||||
for (size_t _i = 0; _i < (v)->size; ++_i, e = (v)->data[_i])
|
||||
extern char *SUP_LIST[];
|
||||
extern char *SUP_EXT_LIST[];
|
||||
extern file_t SUP_TYPE_LIST[];
|
||||
|
||||
// Global variables
|
||||
extern unsigned char *kernel, *ramdisk, *second, *dtb, *extra;
|
||||
extern boot_img_hdr hdr;
|
||||
extern file_t boot_type, ramdisk_type, dtb_type;
|
||||
extern file_t ramdisk_type;
|
||||
extern int mtk_kernel, mtk_ramdisk;
|
||||
|
||||
// Main entries
|
||||
void unpack(const char *image);
|
||||
void repack(const char* orig_image, const char* out_image);
|
||||
void hexpatch(const char *image, const char *from, const char *to);
|
||||
void error(int rc, const char *msg, ...);
|
||||
void parse_img(unsigned char *orig, size_t size);
|
||||
int cpio_commands(const char *command, int argc, char *argv[]);
|
||||
void cleanup();
|
||||
|
||||
@@ -5,65 +5,61 @@
|
||||
*********************/
|
||||
|
||||
static void usage(char *arg0) {
|
||||
fprintf(stderr, "%s --unpack <bootimg>\n", arg0);
|
||||
fprintf(stderr, " Unpack <bootimg> to kernel, ramdisk.cpio, (second), (dtb) into the\n current directory\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --repack <origbootimg> [outbootimg]\n", arg0);
|
||||
fprintf(stderr, " Repack kernel, ramdisk.cpio[.ext], second, dtb... from current directory\n");
|
||||
fprintf(stderr, " to [outbootimg], or new-boot.img if not specified.\n");
|
||||
fprintf(stderr, " It will compress ramdisk.cpio with the same method used in <origbootimg>\n");
|
||||
fprintf(stderr, " if exists, or attempt to find ramdisk.cpio.[ext], and repack\n");
|
||||
fprintf(stderr, " directly with the compressed ramdisk file\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --hexpatch <file> <hexpattern1> <hexpattern2>\n", arg0);
|
||||
fprintf(stderr, " Search <hexpattern1> in <file>, and replace with <hexpattern2>\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --cpio-<cmd> <incpio> [flags...] [params...]\n", arg0);
|
||||
fprintf(stderr, " Do cpio related cmds to <incpio> (modifications are done directly)\n Supported commands:\n");
|
||||
fprintf(stderr, " --cpio-rm <incpio> [-r] <entry>\n Remove entry from cpio, flag -r to remove recursively\n");
|
||||
fprintf(stderr, " --cpio-mkdir <incpio> <mode> <entry>\n Create directory as an <entry>\n");
|
||||
fprintf(stderr, " --cpio-add <incpio> <mode> <entry> <infile>\n Add <infile> as an <entry>; replaces <entry> if already exists\n");
|
||||
fprintf(stderr, " --cpio-extract <incpio> <entry> <outfile>\n Extract <entry> to <outfile>\n");
|
||||
fprintf(stderr, " --cpio-test <incpio>\n Return value: 0/not patched 1/Magisk 2/SuperSU\n");
|
||||
fprintf(stderr, " --cpio-patch-dmverity <incpio>\n Remove dm-verity\n");
|
||||
fprintf(stderr, " --cpio-patch-forceencrypt <incpio>\n Change forceencrypt flag to encryptable\n");
|
||||
fprintf(stderr, " --cpio-backup <incpio> <origcpio>\n Create ramdisk backups into <incpio> from <origcpio>\n");
|
||||
fprintf(stderr, " --cpio-restore <incpio>\n Restore ramdisk from ramdisk backup within <incpio>\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --compress[=method] <infile> [outfile]\n", arg0);
|
||||
fprintf(stderr, " Compress <infile> with [method] (default: gzip), optionally to [outfile]\n Supported methods: " SUP_LIST "\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --decompress <infile> [outfile]\n", arg0);
|
||||
fprintf(stderr, " Detect method and decompress <infile>, optionally to [outfile]\n Supported methods: " SUP_LIST "\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --sha1 <file>\n", arg0);
|
||||
fprintf(stderr, " Print the SHA1 checksum for <file>\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --cleanup\n", arg0);
|
||||
fprintf(stderr, " Cleanup the current working directory\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr,
|
||||
"%s --unpack <bootimg>\n"
|
||||
" Unpack <bootimg> to kernel, ramdisk.cpio, (second), (dtb) into the\n current directory\n"
|
||||
"\n"
|
||||
"%s --repack <origbootimg> [outbootimg]\n"
|
||||
" Repack kernel, ramdisk.cpio[.ext], second, dtb... from current directory\n"
|
||||
" to [outbootimg], or new-boot.img if not specified.\n"
|
||||
" It will compress ramdisk.cpio with the same method used in <origbootimg>\n"
|
||||
" if exists, or attempt to find ramdisk.cpio.[ext], and repack\n"
|
||||
" directly with the compressed ramdisk file\n"
|
||||
"\n"
|
||||
"%s --hexpatch <file> <hexpattern1> <hexpattern2>\n"
|
||||
" Search <hexpattern1> in <file>, and replace with <hexpattern2>\n"
|
||||
"\n"
|
||||
"%s --cpio-<cmd> <incpio> [flags...] [params...]\n"
|
||||
" Do cpio related cmds to <incpio> (modifications are done directly)\n Supported commands:\n"
|
||||
" --cpio-rm <incpio> [-r] <entry>\n Remove entry from cpio, flag -r to remove recursively\n"
|
||||
" --cpio-mkdir <incpio> <mode> <entry>\n Create directory as an <entry>\n"
|
||||
" --cpio-add <incpio> <mode> <entry> <infile>\n Add <infile> as an <entry>; replaces <entry> if already exists\n"
|
||||
" --cpio-extract <incpio> <entry> <outfile>\n Extract <entry> to <outfile>\n"
|
||||
" --cpio-test <incpio>\n Return value: 0/not patched 1/Magisk 2/SuperSU\n"
|
||||
" --cpio-patch-dmverity <incpio>\n Remove dm-verity\n"
|
||||
" --cpio-patch-forceencrypt <incpio>\n Change forceencrypt flag to encryptable\n"
|
||||
" --cpio-backup <incpio> <origcpio>\n Create ramdisk backups into <incpio> from <origcpio>\n"
|
||||
" --cpio-restore <incpio>\n Restore ramdisk from ramdisk backup within <incpio>\n"
|
||||
"\n"
|
||||
"%s --compress[=method] <infile> [outfile]\n"
|
||||
" Compress <infile> with [method] (default: gzip), optionally to [outfile]\n Supported methods: "
|
||||
, arg0, arg0, arg0, arg0, arg0);
|
||||
for (int i = 0; SUP_LIST[i]; ++i)
|
||||
fprintf(stderr, "%s ", SUP_LIST[i]);
|
||||
fprintf(stderr,
|
||||
"\n"
|
||||
"\n"
|
||||
"%s --decompress <infile> [outfile]\n"
|
||||
" Detect method and decompress <infile>, optionally to [outfile]\n Supported methods: "
|
||||
, arg0);
|
||||
for (int i = 0; SUP_LIST[i]; ++i)
|
||||
fprintf(stderr, "%s ", SUP_LIST[i]);
|
||||
fprintf(stderr,
|
||||
"\n"
|
||||
"\n"
|
||||
"%s --sha1 <file>\n"
|
||||
" Print the SHA1 checksum for <file>\n"
|
||||
"\n"
|
||||
"%s --cleanup\n"
|
||||
" Cleanup the current working directory\n"
|
||||
"\n"
|
||||
, arg0, arg0);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void error(int rc, const char *msg, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
vfprintf(stderr, msg, ap);
|
||||
fprintf(stderr,"\n\n");
|
||||
va_end(ap);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
printf("MagiskBoot (by topjohnwu) - Boot Image Modification Tool\n\n");
|
||||
printf("MagiskBoot v" xstr(MAGISK_VERSION) " (by topjohnwu) - Boot Image Modification Tool\n\n");
|
||||
|
||||
if (argc > 1 && strcmp(argv[1], "--cleanup") == 0) {
|
||||
cleanup();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user