Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
687e3b13ea | ||
|
|
8c6bb383b7 | ||
|
|
bc592c1d13 | ||
|
|
968bd8be67 | ||
|
|
d8b8adb88c | ||
|
|
f42d820891 | ||
|
|
bc21a1fb71 | ||
|
|
3bc31374ac | ||
|
|
858e7bae2b | ||
|
|
8c02d120a2 | ||
|
|
07e353f4ff | ||
|
|
bb33d9e600 | ||
|
|
68eb0bdec9 | ||
|
|
32ee8e462c | ||
|
|
e79aa54b70 | ||
|
|
9a95652034 | ||
|
|
912c188b53 | ||
|
|
e9d0f615ba | ||
|
|
9136573596 | ||
|
|
2487ec94e6 | ||
|
|
811489f157 | ||
|
|
b438cc9335 | ||
|
|
1d3d30fa45 | ||
|
|
72b5985398 | ||
|
|
2db60e0a6b | ||
|
|
e710848345 | ||
|
|
8d6f3c2450 | ||
|
|
f863d127e7 | ||
|
|
a831110816 | ||
|
|
e97bdb53f4 | ||
|
|
fe1439fbac | ||
|
|
2bc30e5c22 | ||
|
|
7244c02a0d | ||
|
|
6c229ffa68 | ||
|
|
cdc5d983f3 | ||
|
|
96688e4dac | ||
|
|
28a945fee9 | ||
|
|
c7e777255a | ||
|
|
2dd4cf040e | ||
|
|
d1b9eca5eb | ||
|
|
594a67fe28 | ||
|
|
cddeaffada | ||
|
|
2a8898e7c3 | ||
|
|
ce3f3b09b4 | ||
|
|
fe4b3df7e9 | ||
|
|
25bdbcf526 | ||
|
|
df7eaa5598 | ||
|
|
bb7099376b | ||
|
|
0327fd9710 | ||
|
|
e645c6e465 | ||
|
|
78a3d36ccc | ||
|
|
3942858ccd | ||
|
|
03c8d716cc | ||
|
|
60181c4fcb | ||
|
|
c215447405 | ||
|
|
89330b89d8 | ||
|
|
a8f3718ed0 | ||
|
|
a78ba44709 | ||
|
|
ff110e3513 | ||
|
|
cfae6c63b5 | ||
|
|
dbfe49c56f | ||
|
|
98e21f9f5b | ||
|
|
83af0497e4 | ||
|
|
6ce37b44db | ||
|
|
9cb1cf756f | ||
|
|
ffa005e4ab | ||
|
|
af102e47f1 | ||
|
|
73064a816d | ||
|
|
9b4ae8fcc5 | ||
|
|
a1a2c52409 | ||
|
|
9a0b26e0b0 | ||
|
|
b805b96e16 | ||
|
|
590e7f7724 | ||
|
|
4d61e5e319 | ||
|
|
8c8a63ebfb | ||
|
|
e5e34797a8 | ||
|
|
8516ebe6f5 | ||
|
|
9f6205f47f | ||
|
|
8b2ec23a89 | ||
|
|
1816ca6b02 | ||
|
|
7394ff9346 | ||
|
|
bb5a6a1c28 | ||
|
|
b614b06736 | ||
|
|
7a376c9efc | ||
|
|
518f3d229f | ||
|
|
46c91f923d | ||
|
|
3a2262dfb3 | ||
|
|
ff7c38f8e9 | ||
|
|
4229ba364f | ||
|
|
ba8e7a211a | ||
|
|
6b41653a32 | ||
|
|
59c1125e72 | ||
|
|
b536046720 | ||
|
|
619b805894 | ||
|
|
8662537883 | ||
|
|
717890395b | ||
|
|
b7b4164f4f | ||
|
|
7e65296470 | ||
|
|
cd5f5d702f |
4
.gitignore
vendored
@@ -1,7 +1,9 @@
|
||||
out/
|
||||
obj/
|
||||
libs/
|
||||
*.zip
|
||||
*.jks
|
||||
*.apk
|
||||
|
||||
# Copied binaries
|
||||
# Built binaries
|
||||
ziptools/zipadjust
|
||||
|
||||
21
.gitmodules
vendored
@@ -1,18 +1,27 @@
|
||||
[submodule "jni/selinux"]
|
||||
path = jni/selinux
|
||||
path = jni/external/selinux
|
||||
url = https://github.com/topjohnwu/selinux.git
|
||||
[submodule "jni/su"]
|
||||
path = jni/su
|
||||
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
|
||||
path = java
|
||||
url = https://github.com/topjohnwu/MagiskManager.git
|
||||
[submodule "jni/busybox"]
|
||||
path = jni/busybox
|
||||
path = jni/external/busybox
|
||||
url = https://github.com/topjohnwu/ndk-busybox.git
|
||||
[submodule "jni/external/dtc"]
|
||||
path = jni/external/dtc
|
||||
url = https://github.com/dgibson/dtc
|
||||
[submodule "jni/external/lz4"]
|
||||
path = jni/external/lz4
|
||||
url = https://github.com/lz4/lz4.git
|
||||
[submodule "jni/external/bzip2"]
|
||||
path = jni/external/bzip2
|
||||
url = https://github.com/nemequ/bzip2.git
|
||||
[submodule "jni/external/xz"]
|
||||
path = jni/external/xz
|
||||
url = https://github.com/xz-mirror/xz.git
|
||||
|
||||
51
README.MD
@@ -2,34 +2,29 @@
|
||||
|
||||
## How to build Magisk
|
||||
|
||||
#### Building has been tested on 3 major platforms:
|
||||
#### Building has been tested on 3 major platforms: macOS, Ubuntu, Windows 10
|
||||
|
||||
**macOS 10.12**
|
||||
**Ubuntu 17.04 x64**
|
||||
**Windows 10 x64**
|
||||
|
||||
#### Environment Requirements
|
||||
### Environment Requirements
|
||||
|
||||
1. A 64-bit machine: `cmake` for Android is only available in 64-bit
|
||||
2. Python 3.5+: to run the build script
|
||||
3. Java Development Kit (JDK) 8: To compile Magisk Manager and sign zips
|
||||
4. C compiler (Unix only): To build `zipadjust`. Windows users can use the pre-built `zipadjust.exe`
|
||||
5. Android SDK: `ANDROID_HOME` environment variable should point to the Android SDK folder
|
||||
6. Android NDK: Install NDK via `sdkmanager`, or via Android SDK Manager in Android Studio
|
||||
2. Python 3.5+: run `build.py` script
|
||||
3. Java Development Kit (JDK) 8: Compile Magisk Manager and sign zips
|
||||
4. Latest Android SDK: `ANDROID_HOME` environment variable should point to the Android SDK folder
|
||||
5. Android NDK: Install NDK along with SDK (`$ANDROID_HOME/ndk-bundle`), or specify custom path `ANDROID_NDK`
|
||||
6. (Windows Only) Colorama: Install Colorama with `pip install colorama`, used for ANSI color codes
|
||||
7. (Unix only) C compiler: Build `zipadjust`. Windows users can use the pre-built `zipadjust.exe`
|
||||
|
||||
#### Instructions and Notes
|
||||
|
||||
1. The easiest way to setup a working environment is to open Magisk Manager with Android Studio. The IDE will download required components and construct the environment for you. Don't forget to set `ANDROID_HOME` environment variable to the SDK path.
|
||||
2. Windows users: while installing Python 3 on Windows, allow the installer to add Python to `PATH`, or you'll have to add it manually afterwards. By default, the Python executable is setup as `python`, not `python3` like most Unix environment. If you have both Python 2 and Python 3 installed, you'll have to deal with the executable name and `PATH` yourself. To double check the Python version, call `python --version`.
|
||||
3. To run the script, on Windows call `python build.py [args...]`; on Unix call `python3 build.py [args...]`, or simply `./build.py [args...]`. To see the built-in help message, call the script with `-h` as an argument. The `-h` option also works for each supported actions to see the help message for the specific action.
|
||||
4. By default, the script will build binaries and Magisk Manager in debug mode, which will enable verbose debugging messages. If you want to build Magisk Manager in release mode (through the flag `--release`), you will need to place your Java Keystore file in `release_signature.jks` to sign Magisk Manager's APK. For more information, check out [Google's Official Documentation](https://developer.android.com/studio/publish/app-signing.html#signing-manually).
|
||||
5. 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 use an older Windows version, a quick Google search should provide many workarounds.
|
||||
### Instructions and Notes
|
||||
1. Magisk can be built with the latest NDK (r16 as of writing), however official released binaries will be built with NDK r10e due to ELF incompatibilities with the binaries built from newer NDKs.
|
||||
2. The easiest way to setup a working environment is to open Magisk Manager with Android Studio. The IDE will download required components and construct the environment for you. Don't forget to set `ANDROID_HOME` environment variable to the SDK path.
|
||||
3. Run the script with `-h` as an argument to see the built-in help message. The `-h` option also works for each supported actions, e.g. `./build.py binary -h`
|
||||
4. By default, the script will build binaries and Magisk Manager in debug mode. If you want to build Magisk Manager in release mode (through the flag `--release`), you will need to place your Java Keystore file at `release_signature.jks` to sign Magisk Manager's APK. For more information, check out [Google's Official Documentation](https://developer.android.com/studio/publish/app-signing.html#signing-manually).
|
||||
|
||||
|
||||
## License
|
||||
|
||||
```
|
||||
Magisk, including all subprojects (git submodule) is free software:
|
||||
Magisk, including all git submodules are 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.
|
||||
@@ -45,7 +40,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
## Credits
|
||||
|
||||
**MagiskManager** (`MagiskManager`)
|
||||
**MagiskManager** (`java`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* All contributors and translators
|
||||
@@ -67,29 +62,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
**MagiskHide** (`jni/magiskhide`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2016, Pierre-Hugues Husson (phh@phh.me) (original hidesu)
|
||||
* Copyright 2016, Pierre-Hugues Husson (phh@phh.me)
|
||||
|
||||
**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)
|
||||
* Maintained by many developers in SELinux project
|
||||
|
||||
**ndk-compression** (`jni/ndk-compression`)
|
||||
|
||||
* Makefile for NDK: Copyright 2017, John Wu (@topjohnwu)
|
||||
* Each library has its own copyright message in corresponding directories
|
||||
|
||||
**ndk-busybox** (`jni/busybox`)
|
||||
**ndk-busybox** (`jni/external/busybox`)
|
||||
|
||||
* Makefile for NDK, generated by [ndk-busybox-kitchen](https://github.com/topjohnwu/ndk-busybox-kitchen): Copyright 2017, John Wu (@topjohnwu)
|
||||
* Patches for NDK: Many contributors along the way, all placed in [osm0sis/android-busybox-ndk](https://github.com/osm0sis/android-busybox-ndk)
|
||||
* The copyright message for busybox should be included in its own directory
|
||||
|
||||
**Others Not Mentioned**
|
||||
**Others Not Mentioned** (exclude `jni/external`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Magisk Documentations
|
||||
(Updated on 2017.8.16) ([Changelog](changelog.md))
|
||||
(Updated on 2017.9.28) ([Changelog](changelog.md))
|
||||
|
||||
## Table of Content
|
||||
## Table of Contents
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Procedure Diagram](https://cdn.rawgit.com/topjohnwu/Magisk/cc1809688299f1f8b5db494a234850852712c0c9/docs/procedures.html)
|
||||
@@ -19,6 +19,7 @@
|
||||
- [Modules and Templates](module_repo.md#magisk-module-format)
|
||||
- [Submit Modules to Repo](module_repo.md#submit-your-module-to-magisk-modules-repo)
|
||||
- [Tips and Tricks](tips.md)
|
||||
- [OTA Installation Tips](tips.md#ota-installation-tips)
|
||||
- [Remove Files](tips.md#remove-files)
|
||||
- [Remove Folders](tips.md#remove-folders)
|
||||
|
||||
|
||||
@@ -8,32 +8,27 @@ Command help message:
|
||||
|
||||
```
|
||||
Usage: magisk [applet [arguments]...]
|
||||
or: magisk --install [SOURCE] DIR
|
||||
if SOURCE not provided, will link itself
|
||||
or: magisk --list
|
||||
or: magisk --createimg IMG SIZE
|
||||
create ext4 image, SIZE is interpreted in MB
|
||||
or: magisk --imgsize IMG
|
||||
or: magisk --resizeimg IMG SIZE
|
||||
SIZE is interpreted in MB
|
||||
or: magisk --mountimg IMG PATH
|
||||
mount IMG to PATH and prints the loop device
|
||||
or: magisk --umountimg PATH LOOP
|
||||
or: magisk --[boot stage]
|
||||
start boot stage service
|
||||
or: magisk [options]
|
||||
or: applet [arguments]...
|
||||
or: magisk [options]...
|
||||
|
||||
Options:
|
||||
-c print current binary version
|
||||
-v print running daemon version
|
||||
-V print running daemon version code
|
||||
--list list all availible applets
|
||||
--install [SOURCE] DIR symlink all applets to DIR. SOURCE is optional
|
||||
--createimg IMG SIZE create ext4 image. SIZE is interpreted in MB
|
||||
--imgsize IMG report ext4 image used/total size
|
||||
--resizeimg IMG SIZE resize ext4 image. SIZE is interpreted in MB
|
||||
--mountimg IMG PATH mount IMG to PATH and prints the loop device
|
||||
--umountimg PATH LOOP unmount PATH and delete LOOP device
|
||||
--[boot stage] start boot stage service
|
||||
--unlock-blocks set BLKROSET flag to OFF for all block devices
|
||||
|
||||
Supported boot stages:
|
||||
post-fs, post-fs-data, service
|
||||
|
||||
Options:
|
||||
-c print client version
|
||||
-v print daemon version
|
||||
-V print daemon version code
|
||||
|
||||
Supported applets:
|
||||
su, resetprop, magiskpolicy, supolicy, sepolicy-inject, magiskhide
|
||||
su, resetprop, magiskpolicy, supolicy, magiskhide
|
||||
```
|
||||
|
||||
### su
|
||||
@@ -86,7 +81,7 @@ resetprop --delete NAME remove prop entry NAME
|
||||
```
|
||||
|
||||
### magiskpolicy
|
||||
(This tool is aliased to `supolicy` and `sepolicy-injection` for legacy reasons)
|
||||
(This tool is aliased to `supolicy` for compatibility)
|
||||
|
||||
A tool to patch `sepolicy`. **magiskpolicy** also comes with built-in rules to unleash restrictions to make Magisk work properly. `sepolicy` is a compiled binary containing SELinux rules; we directly patch rules in the binary format since we don't have access to the SELinux policy source (`*.te`) files.
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Changelog
|
||||
- 2017.8.16
|
||||
- Initial version for Magisk v13.5+
|
||||
- Initial version for Magisk v13.5
|
||||
- 2017.9.28
|
||||
- Update applets info to Magisk v14.1
|
||||
- Add OTA tips
|
||||
|
||||
BIN
docs/images/disable_auto_ota.png
Normal file
|
After Width: | Height: | Size: 245 KiB |
BIN
docs/images/flashfire.png
Normal file
|
After Width: | Height: | Size: 224 KiB |
BIN
docs/images/install_second_slot.png
Normal file
|
After Width: | Height: | Size: 237 KiB |
BIN
docs/images/ota_step2.png
Normal file
|
After Width: | Height: | Size: 176 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
BIN
docs/images/restore_boot.png
Normal file
|
After Width: | Height: | Size: 258 KiB |
@@ -61,7 +61,7 @@ If you want to share your module with others, you can submit your modules to [Ma
|
||||
|
||||
#### Once your module is live on the Modules Repo, the description of your repo should be the ID of your module. Please do NOT change the description, repeat, do NOT change the description.
|
||||
|
||||

|
||||

|
||||
|
||||
## Notes
|
||||
- The Module Template depends on external scripts, be aware of the minimal required Magisk version of the template.
|
||||
|
||||
51
docs/tips.md
1
java
Submodule
110
jni/Android.mk
@@ -1,77 +1,111 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
# Some handy paths
|
||||
EXT_PATH := jni/external
|
||||
SE_PATH := $(EXT_PATH)/selinux
|
||||
LIBSELINUX := $(SE_PATH)/libselinux/include
|
||||
LIBSEPOL := $(SE_PATH)/libsepol/include $(SE_PATH)/libsepol/cil/include
|
||||
LIBLZMA := $(EXT_PATH)/xz/src/liblzma/api
|
||||
LIBLZ4 := $(EXT_PATH)/lz4/lib
|
||||
LIBBZ2 := $(EXT_PATH)/bzip2
|
||||
LIBFDT := $(EXT_PATH)/dtc/libfdt
|
||||
|
||||
########################
|
||||
# Binaries
|
||||
########################
|
||||
|
||||
ifdef PRECOMPILE
|
||||
|
||||
# magisk main binary
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := magisk
|
||||
LOCAL_STATIC_LIBRARIES := libsepol
|
||||
LOCAL_SHARED_LIBRARIES := libsqlite libselinux
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(LOCAL_PATH)/include \
|
||||
$(LOCAL_PATH)/external \
|
||||
$(LOCAL_PATH)/selinux/libsepol/include
|
||||
jni/include \
|
||||
jni/external \
|
||||
$(LIBSELINUX)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
daemon/magisk.c \
|
||||
daemon/daemon.c \
|
||||
daemon/socket_trans.c \
|
||||
daemon/log_monitor.c \
|
||||
daemon/bootstages.c \
|
||||
core/magisk.c \
|
||||
core/daemon.c \
|
||||
core/log_monitor.c \
|
||||
core/bootstages.c \
|
||||
utils/misc.c \
|
||||
utils/vector.c \
|
||||
utils/xwrap.c \
|
||||
utils/list.c \
|
||||
utils/img.c \
|
||||
utils/file.c \
|
||||
magiskhide/magiskhide.c \
|
||||
magiskhide/proc_monitor.c \
|
||||
magiskhide/hide_utils.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_CPPFLAGS := -std=c++11
|
||||
LOCAL_CFLAGS := -DIS_DAEMON
|
||||
LOCAL_LDLIBS := -llog
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# precompile
|
||||
else
|
||||
|
||||
# magiskinit
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := magiskinit
|
||||
LOCAL_STATIC_LIBRARIES := libsepol liblzma
|
||||
LOCAL_C_INCLUDES := \
|
||||
jni/include \
|
||||
out/$(TARGET_ARCH_ABI) \
|
||||
$(LIBSEPOL) \
|
||||
$(LIBLZMA)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
core/magiskinit.c \
|
||||
utils/vector.c \
|
||||
utils/file.c \
|
||||
utils/xwrap.c \
|
||||
magiskpolicy/api.c \
|
||||
magiskpolicy/magiskpolicy.c \
|
||||
magiskpolicy/rules.c \
|
||||
magiskpolicy/sepolicy.c
|
||||
|
||||
LOCAL_CFLAGS := -DNO_SELINUX
|
||||
LOCAL_LDFLAGS := -static
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# magiskboot
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := magiskboot
|
||||
LOCAL_STATIC_LIBRARIES := libz liblzma liblz4 libbz2
|
||||
LOCAL_STATIC_LIBRARIES := liblzma liblz4 libbz2 libfdt
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(LOCAL_PATH)/magiskboot \
|
||||
$(LOCAL_PATH)/include \
|
||||
$(LOCAL_PATH)/ndk-compression/zlib \
|
||||
$(LOCAL_PATH)/ndk-compression/xz/src/liblzma/api \
|
||||
$(LOCAL_PATH)/ndk-compression/lz4/lib \
|
||||
$(LOCAL_PATH)/ndk-compression/bzip2
|
||||
jni/include \
|
||||
$(LIBLZMA) \
|
||||
$(LIBLZ4) \
|
||||
$(LIBBZ2) \
|
||||
$(LIBFDT)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
magiskboot/main.c \
|
||||
magiskboot/bootimg.c \
|
||||
magiskboot/hexpatch.c \
|
||||
magiskboot/compress.c \
|
||||
magiskboot/boot_utils.c \
|
||||
magiskboot/cpio.c \
|
||||
magiskboot/sha1.c \
|
||||
magiskboot/types.c \
|
||||
magiskboot/dtb.c \
|
||||
utils/xwrap.c \
|
||||
utils/vector.c \
|
||||
utils/list.c
|
||||
LOCAL_CFLAGS := -DZLIB_CONST
|
||||
utils/file.c \
|
||||
utils/vector.c
|
||||
|
||||
LOCAL_CFLAGS := -DNO_SELINUX
|
||||
LOCAL_LDLIBS := -lz
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# 32-bit static binaries
|
||||
@@ -81,27 +115,19 @@ ifneq ($(TARGET_ARCH_ABI), arm64-v8a)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := b64xz
|
||||
LOCAL_STATIC_LIBRARIES := liblzma
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/ndk-compression/xz/src/liblzma/api
|
||||
LOCAL_C_INCLUDES := $(LIBLZMA)
|
||||
LOCAL_SRC_FILES := b64xz.c
|
||||
LOCAL_LDFLAGS := -static
|
||||
include $(BUILD_EXECUTABLE)
|
||||
# Busybox
|
||||
include jni/busybox/Android.mk
|
||||
include jni/external/busybox/Android.mk
|
||||
endif
|
||||
endif
|
||||
|
||||
########################
|
||||
# Libraries
|
||||
########################
|
||||
# Precompile
|
||||
endif
|
||||
|
||||
# External shared libraries, include stub libselinux and libsqlite
|
||||
########################
|
||||
# Externals
|
||||
########################
|
||||
include jni/external/Android.mk
|
||||
|
||||
# libsepol, static library
|
||||
include jni/selinux/libsepol/Android.mk
|
||||
|
||||
# Compression libraries for magiskboot
|
||||
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
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
APP_ABI := x86 x86_64 armeabi-v7a arm64-v8a
|
||||
APP_PLATFORM := android-21
|
||||
APP_CFLAGS := $(MAGISK_FLAGS) -std=gnu99
|
||||
APP_CPPFLAGS := -std=c++11
|
||||
|
||||
334
jni/core/daemon.c
Normal file
155
jni/core/log_monitor.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/* log_monitor.c - New thread to monitor logcat
|
||||
*
|
||||
* A universal logcat monitor for many usages. Add listeners to the list,
|
||||
* and the pointer of the new log line will be sent through pipes to trigger
|
||||
* asynchronous events without polling
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "magisk.h"
|
||||
#include "utils.h"
|
||||
|
||||
int logcat_events[] = { -1, -1, -1 };
|
||||
extern int is_restart;
|
||||
|
||||
#ifdef MAGISK_DEBUG
|
||||
static int debug_log_pid, debug_log_fd;
|
||||
#endif
|
||||
|
||||
static void *logger_thread(void *args) {
|
||||
int log_fd = -1, log_pid;
|
||||
char line[4096];
|
||||
|
||||
LOGD("log_monitor: logger start");
|
||||
|
||||
while (1) {
|
||||
// Start logcat
|
||||
log_pid = exec_command(0, &log_fd, NULL, "logcat", "-b", "all" , "-v", "threadtime", "-s", "am_proc_start", "Magisk", NULL);
|
||||
while (fdgets(line, sizeof(line), log_fd)) {
|
||||
for (int i = 0; i < (sizeof(logcat_events) / sizeof(int)); ++i) {
|
||||
if (logcat_events[i] > 0) {
|
||||
char *s = strdup(line);
|
||||
xwrite(logcat_events[i], &s, sizeof(s));
|
||||
}
|
||||
}
|
||||
if (kill(log_pid, 0))
|
||||
break;
|
||||
}
|
||||
// Clear buffer if restart required
|
||||
exec_command_sync("logcat", "-b", "all", "-c", NULL);
|
||||
}
|
||||
|
||||
// Should never be here, but well...
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *magisk_log_thread(void *args) {
|
||||
int have_data = 0;
|
||||
|
||||
// Temp buffer for logs before we have data access
|
||||
struct vector logs;
|
||||
vec_init(&logs);
|
||||
|
||||
FILE *log;
|
||||
int pipefd[2];
|
||||
if (xpipe2(pipefd, O_CLOEXEC) == -1)
|
||||
return NULL;
|
||||
|
||||
// Register our listener
|
||||
logcat_events[LOG_EVENT] = pipefd[1];
|
||||
|
||||
LOGD("log_monitor: magisk log dumper start");
|
||||
|
||||
for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) {
|
||||
char *ss;
|
||||
if ((ss = strstr(line, " Magisk")) && (ss[-1] != 'D') && (ss[-1] != 'V')) {
|
||||
if (!have_data) {
|
||||
if ((have_data = check_data())) {
|
||||
// Dump buffered logs to file
|
||||
if (!is_restart)
|
||||
rename(LOGFILE, LASTLOG);
|
||||
log = xfopen(LOGFILE, "a");
|
||||
setbuf(log, NULL);
|
||||
char *tmp;
|
||||
vec_for_each(&logs, tmp) {
|
||||
fprintf(log, "%s", tmp);
|
||||
free(tmp);
|
||||
}
|
||||
vec_destroy(&logs);
|
||||
} else {
|
||||
vec_push_back(&logs, strdup(line));
|
||||
}
|
||||
}
|
||||
if (have_data)
|
||||
fprintf(log, "%s", line);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *debug_magisk_log_thread(void *args) {
|
||||
FILE *log = xfopen(DEBUG_LOG, "a");
|
||||
setbuf(log, NULL);
|
||||
int pipefd[2];
|
||||
if (xpipe2(pipefd, O_CLOEXEC) == -1)
|
||||
return NULL;
|
||||
|
||||
LOGD("log_monitor: debug log dumper start");
|
||||
|
||||
// Register our listener
|
||||
logcat_events[DEBUG_EVENT] = pipefd[1];
|
||||
|
||||
for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) {
|
||||
char *ss;
|
||||
if ((ss = strstr(line, "Magisk")))
|
||||
fprintf(log, "%s", line);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Start new threads to monitor logcat and dump to logfile */
|
||||
void monitor_logs() {
|
||||
pthread_t thread;
|
||||
|
||||
// Start log file dumper before monitor
|
||||
xpthread_create(&thread, NULL, magisk_log_thread, NULL);
|
||||
pthread_detach(thread);
|
||||
|
||||
// Start logcat monitor
|
||||
xpthread_create(&thread, NULL, logger_thread, NULL);
|
||||
pthread_detach(thread);
|
||||
|
||||
}
|
||||
|
||||
void start_debug_full_log() {
|
||||
#ifdef MAGISK_DEBUG
|
||||
// Log everything initially
|
||||
debug_log_fd = xopen(DEBUG_LOG, O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, 0644);
|
||||
debug_log_pid = exec_command(0, &debug_log_fd, NULL, "logcat", "-v", "threadtime", NULL);
|
||||
close(debug_log_fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
void stop_debug_full_log() {
|
||||
#ifdef MAGISK_DEBUG
|
||||
// Stop recording the boot logcat after every boot task is done
|
||||
kill(debug_log_pid, SIGTERM);
|
||||
waitpid(debug_log_pid, NULL, 0);
|
||||
// Start debug thread
|
||||
start_debug_log();
|
||||
#endif
|
||||
}
|
||||
|
||||
void start_debug_log() {
|
||||
#ifdef MAGISK_DEBUG
|
||||
pthread_t thread;
|
||||
// Start debug thread
|
||||
xpthread_create(&thread, NULL, debug_magisk_log_thread, NULL);
|
||||
pthread_detach(thread);
|
||||
#endif
|
||||
}
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "magisk.h"
|
||||
@@ -11,62 +13,64 @@
|
||||
char *argv0;
|
||||
|
||||
char *applet[] =
|
||||
{ "su", "resetprop", "magiskpolicy", "supolicy", "sepolicy-inject", "magiskhide", NULL };
|
||||
{ "su", "resetprop", "magiskhide", NULL };
|
||||
|
||||
int (*applet_main[]) (int, char *[]) =
|
||||
{ su_client_main, resetprop_main, magiskpolicy_main, magiskpolicy_main, magiskpolicy_main, magiskhide_main, NULL };
|
||||
{ su_client_main, resetprop_main, magiskhide_main, NULL };
|
||||
|
||||
// Global error hander function
|
||||
// Should be changed each thread/process
|
||||
__thread void (*err_handler)(void);
|
||||
int create_links(const char *bin, const char *path) {
|
||||
char self[PATH_MAX], linkpath[PATH_MAX];
|
||||
if (bin == NULL) {
|
||||
xreadlink("/proc/self/exe", self, sizeof(self));
|
||||
bin = self;
|
||||
}
|
||||
int ret = 0;
|
||||
for (int i = 0; applet[i]; ++i) {
|
||||
snprintf(linkpath, sizeof(linkpath), "%s/%s", path, applet[i]);
|
||||
unlink(linkpath);
|
||||
ret |= symlink(bin, linkpath);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void usage() {
|
||||
fprintf(stderr,
|
||||
"Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu) multi-call binary\n"
|
||||
"\n"
|
||||
"Usage: %s [applet [arguments]...]\n"
|
||||
" or: %s --install [SOURCE] DIR\n"
|
||||
" if SOURCE not provided, will link itself\n"
|
||||
" or: %s --list\n"
|
||||
" or: %s --createimg IMG SIZE\n"
|
||||
" create ext4 image, SIZE is interpreted in MB\n"
|
||||
" or: %s --imgsize IMG\n"
|
||||
" or: %s --resizeimg IMG SIZE\n"
|
||||
" SIZE is interpreted in MB\n"
|
||||
" or: %s --mountimg IMG PATH\n"
|
||||
" mount IMG to PATH and prints the loop device\n"
|
||||
" or: %s --umountimg PATH LOOP\n"
|
||||
" or: %s --[boot stage]\n"
|
||||
" start boot stage service\n"
|
||||
" or: %s [options]\n"
|
||||
" or: applet [arguments]...\n"
|
||||
"\n"
|
||||
"Supported boot stages:\n"
|
||||
" post-fs, post-fs-data, service\n"
|
||||
" or: %s [options]...\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -c print client version\n"
|
||||
" -v print daemon version\n"
|
||||
" -V print daemon version code\n"
|
||||
" -c print current binary version\n"
|
||||
" -v print running daemon version\n"
|
||||
" -V print running daemon version code\n"
|
||||
" --list list all availible applets\n"
|
||||
" --install [SOURCE] DIR symlink all applets to DIR. SOURCE is optional\n"
|
||||
" --createimg IMG SIZE create ext4 image. SIZE is interpreted in MB\n"
|
||||
" --imgsize IMG report ext4 image used/total size\n"
|
||||
" --resizeimg IMG SIZE resize ext4 image. SIZE is interpreted in MB\n"
|
||||
" --mountimg IMG PATH mount IMG to PATH and prints the loop device\n"
|
||||
" --umountimg PATH LOOP unmount PATH and delete LOOP device\n"
|
||||
" --[init service] start init service\n"
|
||||
" --unlock-blocks set BLKROSET flag to OFF for all block devices\n"
|
||||
" --restorecon fix selinux context on Magisk files and folders\n"
|
||||
" --clone-attr SRC DEST clone permission, owner, and selinux context\n"
|
||||
"\n"
|
||||
"Supported init services:\n"
|
||||
" daemon, post-fs, post-fs-data, service\n"
|
||||
"\n"
|
||||
"Supported applets:\n"
|
||||
, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0);
|
||||
, argv0, argv0);
|
||||
|
||||
for (int i = 0; applet[i]; ++i) {
|
||||
for (int i = 0; applet[i]; ++i)
|
||||
fprintf(stderr, i ? ", %s" : " %s", applet[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "\n\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
argv0 = argv[0];
|
||||
// Exit the whole app if error occurs by default
|
||||
err_handler = exit_proc;
|
||||
char * arg = strrchr(argv[0], '/');
|
||||
if (arg) ++arg;
|
||||
else arg = argv[0];
|
||||
if (strcmp(arg, "magisk") == 0) {
|
||||
if (strcmp(basename(argv[0]), "magisk") == 0) {
|
||||
if (argc < 2) usage();
|
||||
if (strcmp(argv[1], "-c") == 0) {
|
||||
printf("%s\n", MAGISK_VER_STR);
|
||||
@@ -133,6 +137,19 @@ int main(int argc, char *argv[]) {
|
||||
if (argc < 4) usage();
|
||||
umount_image(argv[2], argv[3]);
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "--unlock-blocks") == 0) {
|
||||
unlock_blocks();
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "--restorecon") == 0) {
|
||||
fix_filecon();
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "--clone-attr") == 0) {
|
||||
if (argc < 4) usage();
|
||||
clone_attr(argv[2], argv[3]);
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "--daemon") == 0) {
|
||||
// Start daemon, this process won't return
|
||||
start_daemon();
|
||||
} else if (strcmp(argv[1], "--post-fs") == 0) {
|
||||
int fd = connect_daemon();
|
||||
write_int(fd, POST_FS);
|
||||
@@ -149,16 +166,15 @@ int main(int argc, char *argv[]) {
|
||||
// It's calling applets
|
||||
--argc;
|
||||
++argv;
|
||||
arg = argv[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Applets
|
||||
for (int i = 0; applet[i]; ++i) {
|
||||
if (strcmp(arg, applet[i]) == 0)
|
||||
if (strcmp(basename(argv[0]), applet[i]) == 0)
|
||||
return (*applet_main[i])(argc, argv);
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: applet not found\n", arg);
|
||||
fprintf(stderr, "%s: applet not found\n", basename(argv[0]));
|
||||
return 1;
|
||||
}
|
||||
441
jni/core/magiskinit.c
Normal file
@@ -1,204 +0,0 @@
|
||||
/* 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;
|
||||
|
||||
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 LS_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 LS_HIDELIST:
|
||||
ls_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;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Setup the address and return socket fd */
|
||||
static int setup_socket(struct sockaddr_un *sun) {
|
||||
int fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
memset(sun, 0, sizeof(*sun));
|
||||
sun->sun_family = AF_LOCAL;
|
||||
memcpy(sun->sun_path, REQUESTOR_DAEMON_PATH, sizeof(REQUESTOR_DAEMON_PATH) - 1);
|
||||
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);
|
||||
int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
xdup2(fd, STDIN_FILENO);
|
||||
xdup2(fd, STDOUT_FILENO);
|
||||
xdup2(fd, STDERR_FILENO);
|
||||
close(fd);
|
||||
|
||||
// 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;
|
||||
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) "(" xstr(MAGISK_VER_CODE) ") 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);
|
||||
xmkdir("/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 = xaccept4(fd, NULL, NULL, SOCK_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);
|
||||
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;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/* 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
|
||||
log_pid = exec_command(0, &log_fd, NULL, "logcat", "-s", "Magisk", "-v", "thread", NULL);
|
||||
if (log_pid > 0)
|
||||
waitpid(log_pid, NULL, 0);
|
||||
// For some reason it went here, clear buffer and restart
|
||||
exec_command_sync("logcat", "-c", NULL);
|
||||
}
|
||||
|
||||
// Should never be here, but well...
|
||||
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);
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
/* 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);
|
||||
}
|
||||
148
jni/external/Android.mk
vendored
@@ -3,11 +3,155 @@ LOCAL_PATH:= $(call my-dir)
|
||||
# libsqlite.so (stub)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE:= libsqlite
|
||||
LOCAL_SRC_FILES := sqlite3_stub.c
|
||||
LOCAL_SRC_FILES := stubs/sqlite3_stub.c
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
# libselinux.so (stub)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE:= libselinux
|
||||
LOCAL_SRC_FILES := selinux_stub.c
|
||||
LOCAL_C_INCLUDES := $(LIBSELINUX)
|
||||
LOCAL_SRC_FILES := stubs/selinux_stub.c
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
# libfdt.a
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE:= libfdt
|
||||
LOCAL_C_INCLUDES := $(LIBFDT)
|
||||
LOCAL_SRC_FILES := \
|
||||
dtc/libfdt/fdt.c \
|
||||
dtc/libfdt/fdt_addresses.c \
|
||||
dtc/libfdt/fdt_empty_tree.c \
|
||||
dtc/libfdt/fdt_overlay.c \
|
||||
dtc/libfdt/fdt_ro.c \
|
||||
dtc/libfdt/fdt_rw.c \
|
||||
dtc/libfdt/fdt_strerror.c \
|
||||
dtc/libfdt/fdt_sw.c \
|
||||
dtc/libfdt/fdt_wip.c
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
# liblz4.a
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := liblz4
|
||||
LOCAL_C_INCLUDES += $(LIBLZ4)
|
||||
LOCAL_SRC_FILES := \
|
||||
lz4/lib/lz4.c \
|
||||
lz4/lib/lz4frame.c \
|
||||
lz4/lib/lz4hc.c \
|
||||
lz4/lib/xxhash.c
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
# libbz2.a
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := libbz2
|
||||
LOCAL_C_INCLUDES += $(LIBBZ2)
|
||||
LOCAL_SRC_FILES := \
|
||||
bzip2/blocksort.c \
|
||||
bzip2/huffman.c \
|
||||
bzip2/crctable.c \
|
||||
bzip2/randtable.c \
|
||||
bzip2/compress.c \
|
||||
bzip2/decompress.c \
|
||||
bzip2/bzlib.c
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
# liblzma.a
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := liblzma
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(EXT_PATH)/xz_config \
|
||||
$(EXT_PATH)/xz/src/common \
|
||||
$(EXT_PATH)/xz/src/liblzma/api \
|
||||
$(EXT_PATH)/xz/src/liblzma/check \
|
||||
$(EXT_PATH)/xz/src/liblzma/common \
|
||||
$(EXT_PATH)/xz/src/liblzma/delta \
|
||||
$(EXT_PATH)/xz/src/liblzma/lz \
|
||||
$(EXT_PATH)/xz/src/liblzma/lzma \
|
||||
$(EXT_PATH)/xz/src/liblzma/rangecoder \
|
||||
$(EXT_PATH)/xz/src/liblzma/simple \
|
||||
$(EXT_PATH)/xz/src/liblzma
|
||||
LOCAL_SRC_FILES := \
|
||||
xz/src/common/tuklib_cpucores.c \
|
||||
xz/src/common/tuklib_exit.c \
|
||||
xz/src/common/tuklib_mbstr_fw.c \
|
||||
xz/src/common/tuklib_mbstr_width.c \
|
||||
xz/src/common/tuklib_open_stdxxx.c \
|
||||
xz/src/common/tuklib_physmem.c \
|
||||
xz/src/common/tuklib_progname.c \
|
||||
xz/src/liblzma/check/check.c \
|
||||
xz/src/liblzma/check/crc32_fast.c \
|
||||
xz/src/liblzma/check/crc32_table.c \
|
||||
xz/src/liblzma/check/crc64_fast.c \
|
||||
xz/src/liblzma/check/crc64_table.c \
|
||||
xz/src/liblzma/check/sha256.c \
|
||||
xz/src/liblzma/common/alone_decoder.c \
|
||||
xz/src/liblzma/common/alone_encoder.c \
|
||||
xz/src/liblzma/common/auto_decoder.c \
|
||||
xz/src/liblzma/common/block_buffer_decoder.c \
|
||||
xz/src/liblzma/common/block_buffer_encoder.c \
|
||||
xz/src/liblzma/common/block_decoder.c \
|
||||
xz/src/liblzma/common/block_encoder.c \
|
||||
xz/src/liblzma/common/block_header_decoder.c \
|
||||
xz/src/liblzma/common/block_header_encoder.c \
|
||||
xz/src/liblzma/common/block_util.c \
|
||||
xz/src/liblzma/common/common.c \
|
||||
xz/src/liblzma/common/easy_buffer_encoder.c \
|
||||
xz/src/liblzma/common/easy_decoder_memusage.c \
|
||||
xz/src/liblzma/common/easy_encoder.c \
|
||||
xz/src/liblzma/common/easy_encoder_memusage.c \
|
||||
xz/src/liblzma/common/easy_preset.c \
|
||||
xz/src/liblzma/common/filter_buffer_decoder.c \
|
||||
xz/src/liblzma/common/filter_buffer_encoder.c \
|
||||
xz/src/liblzma/common/filter_common.c \
|
||||
xz/src/liblzma/common/filter_decoder.c \
|
||||
xz/src/liblzma/common/filter_encoder.c \
|
||||
xz/src/liblzma/common/filter_flags_decoder.c \
|
||||
xz/src/liblzma/common/filter_flags_encoder.c \
|
||||
xz/src/liblzma/common/hardware_cputhreads.c \
|
||||
xz/src/liblzma/common/hardware_physmem.c \
|
||||
xz/src/liblzma/common/index.c \
|
||||
xz/src/liblzma/common/index_decoder.c \
|
||||
xz/src/liblzma/common/index_encoder.c \
|
||||
xz/src/liblzma/common/index_hash.c \
|
||||
xz/src/liblzma/common/outqueue.c \
|
||||
xz/src/liblzma/common/stream_buffer_decoder.c \
|
||||
xz/src/liblzma/common/stream_buffer_encoder.c \
|
||||
xz/src/liblzma/common/stream_decoder.c \
|
||||
xz/src/liblzma/common/stream_encoder.c \
|
||||
xz/src/liblzma/common/stream_encoder_mt.c \
|
||||
xz/src/liblzma/common/stream_flags_common.c \
|
||||
xz/src/liblzma/common/stream_flags_decoder.c \
|
||||
xz/src/liblzma/common/stream_flags_encoder.c \
|
||||
xz/src/liblzma/common/vli_decoder.c \
|
||||
xz/src/liblzma/common/vli_encoder.c \
|
||||
xz/src/liblzma/common/vli_size.c \
|
||||
xz/src/liblzma/delta/delta_common.c \
|
||||
xz/src/liblzma/delta/delta_decoder.c \
|
||||
xz/src/liblzma/delta/delta_encoder.c \
|
||||
xz/src/liblzma/lz/lz_decoder.c \
|
||||
xz/src/liblzma/lz/lz_encoder.c \
|
||||
xz/src/liblzma/lz/lz_encoder_mf.c \
|
||||
xz/src/liblzma/lzma/fastpos_table.c \
|
||||
xz/src/liblzma/lzma/fastpos_tablegen.c \
|
||||
xz/src/liblzma/lzma/lzma2_decoder.c \
|
||||
xz/src/liblzma/lzma/lzma2_encoder.c \
|
||||
xz/src/liblzma/lzma/lzma_decoder.c \
|
||||
xz/src/liblzma/lzma/lzma_encoder.c \
|
||||
xz/src/liblzma/lzma/lzma_encoder_optimum_fast.c \
|
||||
xz/src/liblzma/lzma/lzma_encoder_optimum_normal.c \
|
||||
xz/src/liblzma/lzma/lzma_encoder_presets.c \
|
||||
xz/src/liblzma/rangecoder/price_table.c \
|
||||
xz/src/liblzma/rangecoder/price_tablegen.c \
|
||||
xz/src/liblzma/simple/arm.c \
|
||||
xz/src/liblzma/simple/armthumb.c \
|
||||
xz/src/liblzma/simple/ia64.c \
|
||||
xz/src/liblzma/simple/powerpc.c \
|
||||
xz/src/liblzma/simple/simple_coder.c \
|
||||
xz/src/liblzma/simple/simple_decoder.c \
|
||||
xz/src/liblzma/simple/simple_encoder.c \
|
||||
xz/src/liblzma/simple/sparc.c \
|
||||
xz/src/liblzma/simple/x86.c
|
||||
LOCAL_CFLAGS += -DHAVE_CONFIG_H -std=c99
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
# libsepol.a
|
||||
include $(SE_PATH)/libsepol/Android.mk
|
||||
|
||||