mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-08-14 06:47:27 +00:00
Compare commits
29 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3a9a3ed184 | ||
![]() |
88fae36b8a | ||
![]() |
fc9d4034a9 | ||
![]() |
cecc0b932d | ||
![]() |
0faed7159c | ||
![]() |
fb491cfdcf | ||
![]() |
fc706dcb40 | ||
![]() |
a2c1b024f3 | ||
![]() |
3d865394d7 | ||
![]() |
76ef1d0d86 | ||
![]() |
9484ec0c17 | ||
![]() |
614c552e55 | ||
![]() |
7db3d84ba2 | ||
![]() |
87f6018468 | ||
![]() |
9194c50590 | ||
![]() |
7ff45974c6 | ||
![]() |
2533a4fc4a | ||
![]() |
42284c5efb | ||
![]() |
7d7686da33 | ||
![]() |
65e455ef0b | ||
![]() |
ac05e2f2e2 | ||
![]() |
787f7b3035 | ||
![]() |
31bd642b80 | ||
![]() |
f0bac6b154 | ||
![]() |
cc7e74ca11 | ||
![]() |
e8a44646b8 | ||
![]() |
ae97d011ae | ||
![]() |
1b7657a374 | ||
![]() |
5665e04014 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -25,3 +25,6 @@
|
||||
[submodule "xz"]
|
||||
path = native/jni/external/xz
|
||||
url = https://github.com/xz-mirror/xz.git
|
||||
[submodule "nanopb"]
|
||||
path = native/jni/external/nanopb
|
||||
url = https://github.com/nanopb/nanopb.git
|
||||
|
2
app
2
app
Submodule app updated: d5408d1f09...15ed3e52f2
@@ -7,7 +7,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
||||
classpath 'com.android.tools.build:gradle:3.1.2'
|
||||
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
@@ -19,9 +19,16 @@ allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
compileSdkVersion = 27
|
||||
buildToolsVersion = "28.0.0-rc1"
|
||||
supportLibVersion = "27.1.1"
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
10
build.py
10
build.py
@@ -93,7 +93,7 @@ def build_binary(args):
|
||||
error('Build Magisk binary failed!')
|
||||
|
||||
print('')
|
||||
for arch in ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']:
|
||||
for arch in ['armeabi-v7a', 'x86']:
|
||||
mkdir_p(os.path.join('out', arch))
|
||||
with open(os.path.join('out', arch, 'dump.h'), 'w') as dump:
|
||||
dump.write('#include "stdlib.h"\n')
|
||||
@@ -110,7 +110,7 @@ def build_binary(args):
|
||||
error('Build Magisk binary failed!')
|
||||
|
||||
print('')
|
||||
for arch in ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']:
|
||||
for arch in ['armeabi-v7a', 'x86']:
|
||||
for binary in ['magiskinit', 'magiskboot', 'b64xz', 'busybox']:
|
||||
try:
|
||||
mv(os.path.join('native', 'libs', arch, binary), os.path.join('out', arch, binary))
|
||||
@@ -234,7 +234,7 @@ def zip_main(args):
|
||||
zip_with_msg(zipf, source, target)
|
||||
|
||||
# Binaries
|
||||
for lib_dir, zip_dir in [('arm64-v8a', 'arm64'), ('armeabi-v7a', 'arm'), ('x86', 'x86'), ('x86_64', 'x64')]:
|
||||
for lib_dir, zip_dir in [('armeabi-v7a', 'arm'), ('x86', 'x86')]:
|
||||
for binary in ['magiskinit', 'magiskboot']:
|
||||
source = os.path.join('out', lib_dir, binary)
|
||||
target = os.path.join(zip_dir, binary)
|
||||
@@ -261,7 +261,7 @@ def zip_main(args):
|
||||
zipf.writestr(target, util_func)
|
||||
# addon.d.sh
|
||||
source = os.path.join('scripts', 'addon.d.sh')
|
||||
target = os.path.join('addon.d', '99-magisk.sh')
|
||||
target = os.path.join('common', '99-magisk.sh')
|
||||
zip_with_msg(zipf, source, target)
|
||||
|
||||
# Prebuilts
|
||||
@@ -291,7 +291,7 @@ def zip_uninstaller(args):
|
||||
zip_with_msg(zipf, source, target)
|
||||
|
||||
# Binaries
|
||||
for lib_dir, zip_dir in [('arm64-v8a', 'arm64'), ('armeabi-v7a', 'arm'), ('x86', 'x86'), ('x86_64', 'x64')]:
|
||||
for lib_dir, zip_dir in [('armeabi-v7a', 'arm'), ('x86', 'x86')]:
|
||||
source = os.path.join('out', lib_dir, 'magiskboot')
|
||||
target = os.path.join(zip_dir, 'magiskboot')
|
||||
zip_with_msg(zipf, source, target)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# Tips and Tricks
|
||||
|
||||
## OTA Installation Tips
|
||||
Magisk do modifications systemless-ly, which means applying official OTAs is much simpler. Here I provide a few tutorials for several different kind of devices to apply OTAs and preserve Magisk after the installation if possible.
|
||||
Magisk does modifications systemless-ly, which means applying official OTAs is much simpler. Here I provide a few tutorials for several different kind of devices to apply OTAs and preserve Magisk after the installation if possible.
|
||||
|
||||
**This tutorial is only for Magisk v14.1+**
|
||||
|
||||
@@ -50,4 +50,4 @@ If you decide to start by installing Magisk without touching your recovery parti
|
||||
How to remove a file systemless-ly? To actually make the file **disappear** is complicated (possible, not worth the effort). **Replacing it with a dummy file should be good enough**! Create an empty file with the same name and place it in the same path within a module, it shall replace your target file with a dummy file.
|
||||
|
||||
## Remove Folders
|
||||
Same as mentioned above, actually making the folder to **disappear** is not worth the effort. **Replacing it with an empty folder should be good enough**! A handy trick for module developers using [Magisk Module Template](https://github.com/topjohnwu/magisk-module-template) is to add the folder you want to remove into the `REPLACE` list within `config.sh`. If your module doesn't provide a correspond folder, it will create an empty folder, and automatically add `.replace` into the empty folder so the dummy folder will properly replace the one in `/system`.
|
||||
Same as mentioned above, actually making the folder to **disappear** is not worth the effort. **Replacing it with an empty folder should be good enough**! A handy trick for module developers using [Magisk Module Template](https://github.com/topjohnwu/magisk-module-template) is to add the folder you want to remove into the `REPLACE` list within `config.sh`. If your module doesn't provide a correspond folder, it will create an empty folder, and automatically add `.replace` into the empty folder so the dummy folder will properly replace the one in `/system`.
|
||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,5 @@
|
||||
#Mon Dec 04 11:24:34 CST 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
|
||||
|
100
gradlew
vendored
100
gradlew
vendored
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
@@ -6,42 +6,6 @@
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
@@ -60,6 +24,46 @@ cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -85,7 +89,7 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
@@ -150,11 +154,19 @@ if $cygwin ; then
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
14
gradlew.bat
vendored
14
gradlew.bat
vendored
@@ -8,14 +8,14 @@
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
@@ -46,10 +46,9 @@ echo location of your Java installation.
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
@@ -60,11 +59,6 @@ set _SKIP=2
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
@@ -1,7 +1,8 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
|
@@ -9,6 +9,7 @@ LIBLZMA := $(EXT_PATH)/xz/src/liblzma/api
|
||||
LIBLZ4 := $(EXT_PATH)/lz4/lib
|
||||
LIBBZ2 := $(EXT_PATH)/bzip2
|
||||
LIBFDT := $(EXT_PATH)/dtc/libfdt
|
||||
LIBNANOPB := $(EXT_PATH)/nanopb
|
||||
UTIL_SRC := utils/cpio.c \
|
||||
utils/file.c \
|
||||
utils/img.c \
|
||||
@@ -28,11 +29,13 @@ ifneq "$(or $(PRECOMPILE), $(GRADLE))" ""
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := magisk
|
||||
LOCAL_SHARED_LIBRARIES := libsqlite libselinux
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := libnanopb
|
||||
LOCAL_C_INCLUDES := \
|
||||
jni/include \
|
||||
jni/magiskpolicy \
|
||||
$(EXT_PATH)/include \
|
||||
$(LIBSELINUX)
|
||||
$(LIBSELINUX) \
|
||||
$(LIBNANOPB)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
core/magisk.c \
|
||||
@@ -43,7 +46,8 @@ LOCAL_SRC_FILES := \
|
||||
magiskhide/magiskhide.c \
|
||||
magiskhide/proc_monitor.c \
|
||||
magiskhide/hide_utils.c \
|
||||
resetprop/resetprop.cpp \
|
||||
resetprop/persist_props.c \
|
||||
resetprop/resetprop.c \
|
||||
resetprop/system_properties.cpp \
|
||||
su/su.c \
|
||||
su/activity.c \
|
||||
@@ -74,7 +78,6 @@ LOCAL_C_INCLUDES := \
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
core/magiskinit.c \
|
||||
core/socket.c \
|
||||
magiskpolicy/api.c \
|
||||
magiskpolicy/magiskpolicy.c \
|
||||
magiskpolicy/rules.c \
|
||||
@@ -110,10 +113,8 @@ LOCAL_CFLAGS := -DXWRAP_EXIT
|
||||
LOCAL_LDLIBS := -lz
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# 32-bit static binaries
|
||||
# static binaries
|
||||
ifndef GRADLE # Do not run gradle sync on these binaries
|
||||
ifneq ($(TARGET_ARCH_ABI), x86_64)
|
||||
ifneq ($(TARGET_ARCH_ABI), arm64-v8a)
|
||||
# b64xz
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := b64xz
|
||||
@@ -125,8 +126,6 @@ include $(BUILD_EXECUTABLE)
|
||||
# Busybox
|
||||
include jni/external/busybox/Android.mk
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# Precompile
|
||||
endif
|
||||
|
@@ -1,4 +1,4 @@
|
||||
APP_ABI := x86 x86_64 armeabi-v7a arm64-v8a
|
||||
APP_ABI := x86 armeabi-v7a
|
||||
APP_PLATFORM := android-21
|
||||
APP_CFLAGS := $(MAGISK_FLAGS) -std=gnu99
|
||||
APP_CPPFLAGS := -std=c++11
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include "utils.h"
|
||||
#include "daemon.h"
|
||||
#include "resetprop.h"
|
||||
#include "magiskpolicy.h"
|
||||
|
||||
static char *buf, *buf2;
|
||||
static struct vector module_list;
|
||||
@@ -124,15 +125,6 @@ static void bb_setenv(struct vector *v) {
|
||||
vec_push_back(v, NULL);
|
||||
}
|
||||
|
||||
static void pm_setenv(struct vector *v) {
|
||||
for (int i = 0; environ[i]; ++i) {
|
||||
if (strncmp(environ[i], "CLASSPATH=", 10) != 0)
|
||||
vec_push_back(v, strdup(environ[i]));
|
||||
}
|
||||
vec_push_back(v, strdup("CLASSPATH=/system/framework/pm.jar"));
|
||||
vec_push_back(v, NULL);
|
||||
}
|
||||
|
||||
/***********
|
||||
* Scripts *
|
||||
***********/
|
||||
@@ -359,7 +351,7 @@ static void simple_mount(const char *path) {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
|
||||
snprintf(buf, PATH_MAX, "%s%s", CACHEMOUNT, path);
|
||||
snprintf(buf, PATH_MAX, "%s%s", SIMPLEMOUNT, path);
|
||||
if (!(dir = opendir(buf)))
|
||||
return;
|
||||
|
||||
@@ -377,7 +369,7 @@ static void simple_mount(const char *path) {
|
||||
free(new_path);
|
||||
} else if (entry->d_type == DT_REG) {
|
||||
// Actual file path
|
||||
snprintf(buf, PATH_MAX, "%s%s", CACHEMOUNT, buf2);
|
||||
snprintf(buf, PATH_MAX, "%s%s", SIMPLEMOUNT, buf2);
|
||||
// Clone all attributes
|
||||
clone_attr(buf2, buf);
|
||||
// Finally, mount the file
|
||||
@@ -460,7 +452,7 @@ static int prepare_img() {
|
||||
|
||||
void fix_filecon() {
|
||||
int dirfd = xopen(MOUNTPOINT, O_RDONLY | O_CLOEXEC);
|
||||
restorecon(dirfd, 0);
|
||||
restorecon(dirfd);
|
||||
close(dirfd);
|
||||
}
|
||||
|
||||
@@ -473,15 +465,13 @@ static void unblock_boot_process() {
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
void post_fs(int client) {
|
||||
LOGI("** post-fs mode running\n");
|
||||
// ack
|
||||
write_int(client, 0);
|
||||
close(client);
|
||||
void startup() {
|
||||
if (!check_data())
|
||||
return;
|
||||
|
||||
// Uninstall or core only mode
|
||||
// uninstaller or core-only mode
|
||||
if (access(UNINSTALLER, F_OK) == 0 || access(DISABLEFILE, F_OK) == 0)
|
||||
goto unblock;
|
||||
goto initialize;
|
||||
|
||||
// Allocate buffer
|
||||
buf = xmalloc(PATH_MAX);
|
||||
@@ -490,32 +480,152 @@ void post_fs(int client) {
|
||||
simple_mount("/system");
|
||||
simple_mount("/vendor");
|
||||
|
||||
unblock:
|
||||
unblock_boot_process();
|
||||
}
|
||||
initialize:
|
||||
LOGI("** Initializing Magisk\n");
|
||||
|
||||
void post_fs_data(int client) {
|
||||
// ack
|
||||
write_int(client, 0);
|
||||
close(client);
|
||||
if (!is_daemon_init && !check_data())
|
||||
goto unblock;
|
||||
// Unlock all blocks for rw
|
||||
unlock_blocks();
|
||||
|
||||
// Start the debug log
|
||||
start_debug_full_log();
|
||||
// Magisk binaries
|
||||
char *bin_path = NULL;
|
||||
if (access("/cache/data_bin", F_OK) == 0)
|
||||
bin_path = "/cache/data_bin";
|
||||
else if (access("/data/data/com.topjohnwu.magisk/install", F_OK) == 0)
|
||||
bin_path = "/data/data/com.topjohnwu.magisk/install";
|
||||
else if (access("/data/user_de/0/com.topjohnwu.magisk/install", F_OK) == 0)
|
||||
bin_path = "/data/user_de/0/com.topjohnwu.magisk/install";
|
||||
if (bin_path) {
|
||||
rm_rf(DATABIN);
|
||||
cp_afc(bin_path, DATABIN);
|
||||
rm_rf(bin_path);
|
||||
}
|
||||
|
||||
LOGI("** post-fs-data mode running\n");
|
||||
// Migration
|
||||
rm_rf("/data/magisk");
|
||||
unlink("/data/magisk.img");
|
||||
unlink("/data/magisk_debug.log");
|
||||
xmkdir("/data/adb", 0700);
|
||||
chmod("/data/adb", 0700);
|
||||
|
||||
// Allocate buffer
|
||||
if (buf == NULL) buf = xmalloc(PATH_MAX);
|
||||
if (buf2 == NULL) buf2 = xmalloc(PATH_MAX);
|
||||
vec_init(&module_list);
|
||||
LOGI("* Creating /sbin overlay");
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
int root, sbin, fd;
|
||||
char buf[PATH_MAX];
|
||||
void *magisk, *init;
|
||||
size_t magisk_size, init_size;
|
||||
|
||||
// Initialize
|
||||
if (!is_daemon_init)
|
||||
daemon_init();
|
||||
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
|
||||
|
||||
// uninstaller
|
||||
// Remove some traits of Magisk
|
||||
unlink("/init.magisk.rc");
|
||||
|
||||
// Create hardlink mirror of /sbin to /root
|
||||
mkdir("/root", 0750);
|
||||
full_read("/sbin/magisk", &magisk, &magisk_size);
|
||||
unlink("/sbin/magisk");
|
||||
full_read("/sbin/magiskinit", &init, &init_size);
|
||||
unlink("/sbin/magiskinit");
|
||||
root = xopen("/root", O_RDONLY | O_CLOEXEC);
|
||||
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
|
||||
link_dir(sbin, root);
|
||||
close(sbin);
|
||||
|
||||
// Mount the /sbin tmpfs overlay
|
||||
xmount("tmpfs", "/sbin", "tmpfs", 0, NULL);
|
||||
chmod("/sbin", 0755);
|
||||
setfilecon("/sbin", "u:object_r:rootfs:s0");
|
||||
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
|
||||
|
||||
// Setup magisk symlinks
|
||||
fd = creat("/sbin/magisk", 0755);
|
||||
xwrite(fd, magisk, magisk_size);
|
||||
close(fd);
|
||||
free(magisk);
|
||||
setfilecon("/sbin/magisk", "u:object_r:"SEPOL_FILE_DOMAIN":s0");
|
||||
for (int i = 0; applet[i]; ++i) {
|
||||
snprintf(buf, PATH_MAX, "/sbin/%s", applet[i]);
|
||||
xsymlink("/sbin/magisk", buf);
|
||||
}
|
||||
|
||||
// Setup magiskinit symlinks
|
||||
fd = creat("/sbin/magiskinit", 0755);
|
||||
xwrite(fd, init, init_size);
|
||||
close(fd);
|
||||
free(init);
|
||||
setfilecon("/sbin/magiskinit", "u:object_r:"SEPOL_FILE_DOMAIN":s0");
|
||||
for (int i = 0; init_applet[i]; ++i) {
|
||||
snprintf(buf, PATH_MAX, "/sbin/%s", init_applet[i]);
|
||||
xsymlink("/sbin/magiskinit", buf);
|
||||
}
|
||||
|
||||
// Create symlinks pointing back to /root
|
||||
dir = xfdopendir(root);
|
||||
while((entry = xreaddir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
|
||||
snprintf(buf, PATH_MAX, "/root/%s", entry->d_name);
|
||||
symlinkat(buf, sbin, entry->d_name);
|
||||
}
|
||||
|
||||
close(sbin);
|
||||
close(root);
|
||||
|
||||
LOGI("* Mounting mirrors");
|
||||
struct vector mounts;
|
||||
vec_init(&mounts);
|
||||
file_to_vector("/proc/mounts", &mounts);
|
||||
char *line;
|
||||
int skip_initramfs = 0;
|
||||
// Check whether skip_initramfs device
|
||||
vec_for_each(&mounts, line) {
|
||||
if (strstr(line, " /system_root ")) {
|
||||
xmkdirs(MIRRDIR "/system", 0755);
|
||||
bind_mount("/system_root/system", MIRRDIR "/system");
|
||||
skip_initramfs = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
vec_for_each(&mounts, line) {
|
||||
if (!skip_initramfs && strstr(line, " /system ")) {
|
||||
sscanf(line, "%s", buf);
|
||||
xmkdirs(MIRRDIR "/system", 0755);
|
||||
xmount(buf, MIRRDIR "/system", "ext4", MS_RDONLY, NULL);
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("mount: %s <- %s\n", MIRRDIR "/system", buf);
|
||||
#else
|
||||
LOGI("mount: %s\n", MIRRDIR "/system");
|
||||
#endif
|
||||
} else if (strstr(line, " /vendor ")) {
|
||||
seperate_vendor = 1;
|
||||
sscanf(line, "%s", buf);
|
||||
xmkdirs(MIRRDIR "/vendor", 0755);
|
||||
xmount(buf, MIRRDIR "/vendor", "ext4", MS_RDONLY, NULL);
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("mount: %s <- %s\n", MIRRDIR "/vendor", buf);
|
||||
#else
|
||||
LOGI("mount: %s\n", MIRRDIR "/vendor");
|
||||
#endif
|
||||
}
|
||||
free(line);
|
||||
}
|
||||
vec_destroy(&mounts);
|
||||
if (!seperate_vendor) {
|
||||
xsymlink(MIRRDIR "/system/vendor", MIRRDIR "/vendor");
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("link: %s <- %s\n", MIRRDIR "/vendor", MIRRDIR "/system/vendor");
|
||||
#else
|
||||
LOGI("link: %s\n", MIRRDIR "/vendor");
|
||||
#endif
|
||||
}
|
||||
xmkdirs(MIRRDIR "/bin", 0755);
|
||||
bind_mount(DATABIN, MIRRDIR "/bin");
|
||||
|
||||
LOGI("* Setting up internal busybox");
|
||||
xmkdirs(BBPATH, 0755);
|
||||
exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL);
|
||||
xsymlink(MIRRDIR "/bin/busybox", BBPATH "/busybox");
|
||||
|
||||
// uninstall
|
||||
if (access(UNINSTALLER, F_OK) == 0) {
|
||||
close(open(UNBLOCKFILE, O_RDONLY | O_CREAT));
|
||||
setenv("BOOTMODE", "true", 1);
|
||||
@@ -523,6 +633,28 @@ void post_fs_data(int client) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start post-fs-data mode
|
||||
execv("/sbin/magisk", (char *[]) { "magisk", "--post-fs-data", NULL });
|
||||
}
|
||||
|
||||
void post_fs_data(int client) {
|
||||
// ack
|
||||
write_int(client, 0);
|
||||
close(client);
|
||||
|
||||
// Start the debug log
|
||||
start_debug_full_log();
|
||||
|
||||
LOGI("** post-fs-data mode running\n");
|
||||
|
||||
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
|
||||
full_patch_pid = exec_command(0, NULL, NULL, "/sbin/magiskpolicy", "--live", "allow "SEPOL_PROC_DOMAIN" * * *", NULL);
|
||||
|
||||
// Allocate buffer
|
||||
buf = xmalloc(PATH_MAX);
|
||||
buf2 = xmalloc(PATH_MAX);
|
||||
vec_init(&module_list);
|
||||
|
||||
// Merge, trim, mount magisk.img, which will also travel through the modules
|
||||
// After this, it will create the module list
|
||||
if (prepare_img())
|
||||
@@ -614,8 +746,6 @@ core_only:
|
||||
}
|
||||
|
||||
auto_start_magiskhide();
|
||||
|
||||
unblock:
|
||||
unblock_boot_process();
|
||||
}
|
||||
|
||||
@@ -630,8 +760,7 @@ void late_start(int client) {
|
||||
if (buf2 == NULL) buf2 = xmalloc(PATH_MAX);
|
||||
|
||||
// Wait till the full patch is done
|
||||
wait_till_exists(PATCHDONE);
|
||||
unlink(PATCHDONE);
|
||||
waitpid(full_patch_pid, NULL, 0);
|
||||
|
||||
// Run scripts after full patch, most reliable way to run scripts
|
||||
LOGI("* Running service.d scripts\n");
|
||||
@@ -648,14 +777,13 @@ core_only:
|
||||
// Install Magisk Manager if exists
|
||||
if (access(MANAGERAPK, F_OK) == 0) {
|
||||
rename(MANAGERAPK, "/data/magisk.apk");
|
||||
setfilecon("/data/magisk.apk", "u:object_r:su_file:s0");
|
||||
setfilecon("/data/magisk.apk", "u:object_r:"SEPOL_FILE_DOMAIN":s0");
|
||||
while (1) {
|
||||
sleep(5);
|
||||
LOGD("apk_install: attempting to install APK");
|
||||
int apk_res = -1, pid;
|
||||
pid = exec_command(1, &apk_res, pm_setenv,
|
||||
"app_process",
|
||||
"/system/bin", "com.android.commands.pm.Pm",
|
||||
"install", "-r", "/data/magisk.apk", NULL);
|
||||
pid = exec_command(1, &apk_res, NULL,
|
||||
"/system/bin/pm", "install", "-r", "/data/magisk.apk", NULL);
|
||||
if (pid != -1) {
|
||||
int err = 0;
|
||||
while (fdgets(buf, PATH_MAX, apk_res) > 0) {
|
||||
|
@@ -19,8 +19,10 @@
|
||||
#include "utils.h"
|
||||
#include "daemon.h"
|
||||
#include "resetprop.h"
|
||||
#include "magiskpolicy.h"
|
||||
|
||||
int is_daemon_init = 0, seperate_vendor = 0;
|
||||
int seperate_vendor = 0;
|
||||
int full_patch_pid;
|
||||
|
||||
static void *request_handler(void *args) {
|
||||
int client = *((int *) args);
|
||||
@@ -36,7 +38,6 @@ static void *request_handler(void *args) {
|
||||
case ADD_HIDELIST:
|
||||
case RM_HIDELIST:
|
||||
case LS_HIDELIST:
|
||||
case POST_FS:
|
||||
case POST_FS_DATA:
|
||||
case LATE_START:
|
||||
if (credential.uid != 0) {
|
||||
@@ -75,9 +76,6 @@ static void *request_handler(void *args) {
|
||||
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;
|
||||
@@ -96,6 +94,30 @@ static void *start_magisk_hide(void *args) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void daemon_saver() {
|
||||
int fd, val;
|
||||
struct sockaddr_un sun;
|
||||
|
||||
// Change process name
|
||||
strcpy(argv0, "magisk_saver");
|
||||
|
||||
while (1) {
|
||||
fd = setup_socket(&sun);
|
||||
while(connect(fd, (struct sockaddr*) &sun, sizeof(sun)))
|
||||
usleep(10000);
|
||||
|
||||
write_int(fd, DO_NOTHING);
|
||||
|
||||
// Should hold forever unless the other side is closed
|
||||
read(fd, &val, sizeof(int));
|
||||
|
||||
// If it came here, the daemon is terminated
|
||||
close(fd);
|
||||
if (fork_dont_care() == 0)
|
||||
start_daemon(0);
|
||||
}
|
||||
}
|
||||
|
||||
void auto_start_magiskhide() {
|
||||
char *hide_prop = getprop2(MAGISKHIDE_PROP, 1);
|
||||
if (hide_prop == NULL || strcmp(hide_prop, "0") != 0) {
|
||||
@@ -106,151 +128,18 @@ void auto_start_magiskhide() {
|
||||
free(hide_prop);
|
||||
}
|
||||
|
||||
void daemon_init() {
|
||||
is_daemon_init = 1;
|
||||
|
||||
// Magisk binaries
|
||||
char *bin_path = NULL;
|
||||
if (access("/cache/data_bin", F_OK) == 0)
|
||||
bin_path = "/cache/data_bin";
|
||||
else if (access("/data/data/com.topjohnwu.magisk/install", F_OK) == 0)
|
||||
bin_path = "/data/data/com.topjohnwu.magisk/install";
|
||||
else if (access("/data/user_de/0/com.topjohnwu.magisk/install", F_OK) == 0)
|
||||
bin_path = "/data/user_de/0/com.topjohnwu.magisk/install";
|
||||
if (bin_path) {
|
||||
rm_rf(DATABIN);
|
||||
cp_afc(bin_path, DATABIN);
|
||||
rm_rf(bin_path);
|
||||
}
|
||||
|
||||
// Migration
|
||||
rm_rf("/data/magisk");
|
||||
unlink("/data/magisk.img");
|
||||
unlink("/data/magisk_debug.log");
|
||||
chmod("/data/adb", 0700);
|
||||
|
||||
LOGI("* Creating /sbin overlay");
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
int root, sbin;
|
||||
char buf[PATH_MAX], buf2[PATH_MAX];
|
||||
char magisk_name[10], init_name[10];
|
||||
|
||||
// Setup links under /sbin
|
||||
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
|
||||
xmkdir("/root", 0755);
|
||||
chmod("/root", 0755);
|
||||
root = xopen("/root", O_RDONLY | O_CLOEXEC);
|
||||
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
|
||||
link_dir(sbin, root);
|
||||
unlink("/sbin/magisk");
|
||||
close(sbin);
|
||||
|
||||
xmount("tmpfs", "/sbin", "tmpfs", 0, NULL);
|
||||
chmod("/sbin", 0755);
|
||||
setfilecon("/sbin", "u:object_r:rootfs:s0");
|
||||
dir = xfdopendir(root);
|
||||
while((entry = xreaddir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
|
||||
snprintf(buf, PATH_MAX, "/root/%s", entry->d_name);
|
||||
snprintf(buf2, PATH_MAX, "/sbin/%s", entry->d_name);
|
||||
xsymlink(buf, buf2);
|
||||
}
|
||||
|
||||
gen_rand_str(magisk_name, sizeof(magisk_name));
|
||||
snprintf(buf, PATH_MAX, "/root/%s", magisk_name);
|
||||
unlink("/sbin/magisk");
|
||||
rename("/root/magisk", buf);
|
||||
xsymlink(buf, "/sbin/magisk");
|
||||
for (int i = 0; applet[i]; ++i) {
|
||||
snprintf(buf2, PATH_MAX, "/sbin/%s", applet[i]);
|
||||
xsymlink(buf, buf2);
|
||||
}
|
||||
|
||||
gen_rand_str(init_name, sizeof(init_name));
|
||||
snprintf(buf, PATH_MAX, "/root/%s", init_name);
|
||||
unlink("/sbin/magiskinit");
|
||||
rename("/root/magiskinit", buf);
|
||||
for (int i = 0; init_applet[i]; ++i) {
|
||||
snprintf(buf2, PATH_MAX, "/sbin/%s", init_applet[i]);
|
||||
xsymlink(buf, buf2);
|
||||
}
|
||||
|
||||
close(root);
|
||||
|
||||
// Backward compatibility
|
||||
xsymlink(DATABIN, "/data/magisk");
|
||||
xsymlink(MAINIMG, "/data/magisk.img");
|
||||
xsymlink(MOUNTPOINT, "/magisk");
|
||||
|
||||
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
|
||||
|
||||
LOGI("* Mounting mirrors");
|
||||
struct vector mounts;
|
||||
vec_init(&mounts);
|
||||
file_to_vector("/proc/mounts", &mounts);
|
||||
char *line;
|
||||
int skip_initramfs = 0;
|
||||
// Check whether skip_initramfs device
|
||||
vec_for_each(&mounts, line) {
|
||||
if (strstr(line, " /system_root ")) {
|
||||
xmkdirs(MIRRDIR "/system", 0755);
|
||||
bind_mount("/system_root/system", MIRRDIR "/system");
|
||||
skip_initramfs = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
vec_for_each(&mounts, line) {
|
||||
if (!skip_initramfs && strstr(line, " /system ")) {
|
||||
sscanf(line, "%s", buf);
|
||||
xmkdirs(MIRRDIR "/system", 0755);
|
||||
xmount(buf, MIRRDIR "/system", "ext4", MS_RDONLY, NULL);
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("mount: %s <- %s\n", MIRRDIR "/system", buf);
|
||||
#else
|
||||
LOGI("mount: %s\n", MIRRDIR "/system");
|
||||
#endif
|
||||
} else if (strstr(line, " /vendor ")) {
|
||||
seperate_vendor = 1;
|
||||
sscanf(line, "%s", buf);
|
||||
xmkdirs(MIRRDIR "/vendor", 0755);
|
||||
xmount(buf, MIRRDIR "/vendor", "ext4", MS_RDONLY, NULL);
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("mount: %s <- %s\n", MIRRDIR "/vendor", buf);
|
||||
#else
|
||||
LOGI("mount: %s\n", MIRRDIR "/vendor");
|
||||
#endif
|
||||
}
|
||||
free(line);
|
||||
}
|
||||
vec_destroy(&mounts);
|
||||
if (!seperate_vendor) {
|
||||
xsymlink(MIRRDIR "/system/vendor", MIRRDIR "/vendor");
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("link: %s <- %s\n", MIRRDIR "/vendor", MIRRDIR "/system/vendor");
|
||||
#else
|
||||
LOGI("link: %s\n", MIRRDIR "/vendor");
|
||||
#endif
|
||||
}
|
||||
xmkdirs(MIRRDIR "/bin", 0755);
|
||||
bind_mount(DATABIN, MIRRDIR "/bin");
|
||||
|
||||
LOGI("* Setting up internal busybox");
|
||||
xmkdirs(BBPATH, 0755);
|
||||
exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL);
|
||||
xsymlink(MIRRDIR "/bin/busybox", BBPATH "/busybox");
|
||||
}
|
||||
|
||||
void start_daemon() {
|
||||
void start_daemon(int post_fs_data) {
|
||||
setsid();
|
||||
setcon("u:r:su:s0");
|
||||
umask(0);
|
||||
setcon("u:r:"SEPOL_PROC_DOMAIN":s0");
|
||||
int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
xdup2(fd, STDIN_FILENO);
|
||||
xdup2(fd, STDOUT_FILENO);
|
||||
xdup2(fd, STDERR_FILENO);
|
||||
close(fd);
|
||||
|
||||
if (post_fs_data && fork_dont_care() == 0)
|
||||
daemon_saver();
|
||||
|
||||
// Block user signals
|
||||
sigset_t block_set;
|
||||
sigemptyset(&block_set);
|
||||
@@ -268,22 +157,17 @@ void start_daemon() {
|
||||
// Start the log monitor
|
||||
monitor_logs();
|
||||
|
||||
if ((is_daemon_init = (access(MAGISKTMP, F_OK) == 0))) {
|
||||
if (!post_fs_data && (access(MAGISKTMP, F_OK) == 0)) {
|
||||
// Restart stuffs if the daemon is restarted
|
||||
exec_command_sync("logcat", "-b", "all", "-c", NULL);
|
||||
auto_start_magiskhide();
|
||||
start_debug_log();
|
||||
} else if (check_data()) {
|
||||
daemon_init();
|
||||
}
|
||||
|
||||
LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") daemon started\n");
|
||||
|
||||
// Change process name
|
||||
strcpy(argv0, "magisk_daemon");
|
||||
|
||||
// Unlock all blocks for rw
|
||||
unlock_blocks();
|
||||
strcpy(argv0, "magiskd");
|
||||
|
||||
// Loop forever to listen for requests
|
||||
while(1) {
|
||||
@@ -297,7 +181,7 @@ void start_daemon() {
|
||||
}
|
||||
|
||||
/* Connect the daemon, and return a socketfd */
|
||||
int connect_daemon() {
|
||||
int connect_daemon(int post_fs_data) {
|
||||
struct sockaddr_un sun;
|
||||
int fd = setup_socket(&sun);
|
||||
if (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) {
|
||||
@@ -308,10 +192,10 @@ int connect_daemon() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (xfork() == 0) {
|
||||
if (fork_dont_care() == 0) {
|
||||
LOGD("client: connect fail, try launching new daemon process\n");
|
||||
close(fd);
|
||||
start_daemon();
|
||||
start_daemon(post_fs_data);
|
||||
}
|
||||
|
||||
while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)))
|
||||
|
@@ -14,8 +14,7 @@
|
||||
#include "utils.h"
|
||||
#include "resetprop.h"
|
||||
|
||||
extern int is_daemon_init;
|
||||
int logd = 0;
|
||||
int loggable = 1;
|
||||
|
||||
static int am_proc_start_filter(const char *log) {
|
||||
return strstr(log, "am_proc_start") != NULL;
|
||||
@@ -49,15 +48,16 @@ struct log_listener log_events[] = {
|
||||
static int debug_log_pid = -1, debug_log_fd = -1;
|
||||
#endif
|
||||
|
||||
static void check_logd() {
|
||||
char *prop = getprop("init.svc.logd");
|
||||
if (prop != NULL) {
|
||||
free(prop);
|
||||
logd = 1;
|
||||
} else {
|
||||
LOGD("log_monitor: logd not started, disable logging");
|
||||
logd = 0;
|
||||
static void test_logcat() {
|
||||
int log_fd = -1, log_pid;
|
||||
char buf[1];
|
||||
log_pid = exec_command(0, &log_fd, NULL, "logcat", NULL);
|
||||
if (read(log_fd, buf, sizeof(buf)) != sizeof(buf)) {
|
||||
loggable = 0;
|
||||
LOGD("log_monitor: cannot read from logcat, disable logging");
|
||||
}
|
||||
kill(log_pid, SIGTERM);
|
||||
waitpid(log_pid, NULL, 0);
|
||||
}
|
||||
|
||||
static void *logger_thread(void *args) {
|
||||
@@ -67,7 +67,7 @@ static void *logger_thread(void *args) {
|
||||
LOGD("log_monitor: logger start");
|
||||
|
||||
while (1) {
|
||||
if (!logd) {
|
||||
if (!loggable) {
|
||||
// Disable all services
|
||||
for (int i = 0; i < (sizeof(log_events) / sizeof(struct log_listener)); ++i) {
|
||||
close(log_events[i].fd);
|
||||
@@ -98,7 +98,7 @@ static void *logger_thread(void *args) {
|
||||
// Clear buffer before restart
|
||||
exec_command_sync("logcat", "-b", "events", "-b", "main", "-c", NULL);
|
||||
|
||||
check_logd();
|
||||
test_logcat();
|
||||
}
|
||||
|
||||
// Should never be here, but well...
|
||||
@@ -106,38 +106,20 @@ static void *logger_thread(void *args) {
|
||||
}
|
||||
|
||||
static void *magisk_log_thread(void *args) {
|
||||
// Buffer logs before we have data access
|
||||
struct vector logs;
|
||||
vec_init(&logs);
|
||||
|
||||
FILE *log = xfopen(LOGFILE, "w");
|
||||
setbuf(log, NULL);
|
||||
int pipefd[2];
|
||||
if (xpipe2(pipefd, O_CLOEXEC) == -1)
|
||||
return NULL;
|
||||
|
||||
LOGD("log_monitor: magisk log dumper start");
|
||||
|
||||
// Register our listener
|
||||
log_events[LOG_EVENT].fd = pipefd[1];
|
||||
|
||||
LOGD("log_monitor: magisk log dumper start");
|
||||
for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line))
|
||||
fprintf(log, "%s", line);
|
||||
|
||||
FILE *log = NULL;
|
||||
for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) {
|
||||
if (!is_daemon_init) {
|
||||
vec_push_back(&logs, strdup(line));
|
||||
} else {
|
||||
if (log == NULL) {
|
||||
// Dump buffered logs to file
|
||||
log = xfopen(LOGFILE, "w");
|
||||
setbuf(log, NULL);
|
||||
char *tmp;
|
||||
vec_for_each(&logs, tmp) {
|
||||
fprintf(log, "%s", tmp);
|
||||
free(tmp);
|
||||
}
|
||||
vec_destroy(&logs);
|
||||
}
|
||||
fprintf(log, "%s", line);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -163,9 +145,9 @@ static void *debug_magisk_log_thread(void *args) {
|
||||
void monitor_logs() {
|
||||
pthread_t thread;
|
||||
|
||||
check_logd();
|
||||
test_logcat();
|
||||
|
||||
if (logd) {
|
||||
if (loggable) {
|
||||
// Start log file dumper before monitor
|
||||
xpthread_create(&thread, NULL, magisk_log_thread, NULL);
|
||||
pthread_detach(thread);
|
||||
@@ -178,7 +160,7 @@ void monitor_logs() {
|
||||
|
||||
void start_debug_full_log() {
|
||||
#ifdef MAGISK_DEBUG
|
||||
if (logd) {
|
||||
if (loggable) {
|
||||
// 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);
|
||||
@@ -201,7 +183,7 @@ void stop_debug_full_log() {
|
||||
|
||||
void start_debug_log() {
|
||||
#ifdef MAGISK_DEBUG
|
||||
if (logd) {
|
||||
if (loggable) {
|
||||
pthread_t thread;
|
||||
// Start debug thread
|
||||
xpthread_create(&thread, NULL, debug_magisk_log_thread, NULL);
|
||||
|
@@ -47,13 +47,14 @@ static void usage() {
|
||||
" --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"
|
||||
" --daemon manually start magisk daemon\n"
|
||||
" --[init trigger] start service for init trigger\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"
|
||||
"Supported init triggers:\n"
|
||||
" startup, post-fs-data, service\n"
|
||||
"\n"
|
||||
"Supported applets:\n"
|
||||
, argv0, argv0);
|
||||
@@ -65,6 +66,7 @@ static void usage() {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
umask(0);
|
||||
argv0 = argv[0];
|
||||
if (strcmp(basename(argv[0]), "magisk") == 0) {
|
||||
if (argc < 2) usage();
|
||||
@@ -72,14 +74,14 @@ int main(int argc, char *argv[]) {
|
||||
printf("%s (%d)\n", MAGISK_VER_STR, MAGISK_VER_CODE);
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "-v") == 0) {
|
||||
int fd = connect_daemon();
|
||||
int fd = connect_daemon(0);
|
||||
write_int(fd, CHECK_VERSION);
|
||||
char *v = read_string(fd);
|
||||
printf("%s\n", v);
|
||||
free(v);
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "-V") == 0) {
|
||||
int fd = connect_daemon();
|
||||
int fd = connect_daemon(0);
|
||||
write_int(fd, CHECK_VERSION_CODE);
|
||||
printf("%d\n", read_int(fd));
|
||||
return 0;
|
||||
@@ -144,19 +146,18 @@ int main(int argc, char *argv[]) {
|
||||
clone_attr(argv[2], argv[3]);
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "--daemon") == 0) {
|
||||
if (xfork() == 0)
|
||||
start_daemon();
|
||||
int fd = connect_daemon(0);
|
||||
close(fd);
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "--startup") == 0) {
|
||||
startup();
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "--post-fs") == 0) {
|
||||
int fd = connect_daemon();
|
||||
write_int(fd, POST_FS);
|
||||
return read_int(fd);
|
||||
} else if (strcmp(argv[1], "--post-fs-data") == 0) {
|
||||
int fd = connect_daemon();
|
||||
int fd = connect_daemon(1);
|
||||
write_int(fd, POST_FS_DATA);
|
||||
return read_int(fd);
|
||||
} else if (strcmp(argv[1], "--service") == 0) {
|
||||
int fd = connect_daemon();
|
||||
int fd = connect_daemon(0);
|
||||
write_int(fd, LATE_START);
|
||||
return read_int(fd);
|
||||
} else {
|
||||
|
@@ -339,7 +339,7 @@ static void patch_socket_name(const char *path) {
|
||||
mmap_rw(path, &buf, &size);
|
||||
if (SOCKET_OFF < 0) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (memcmp(buf + i, socket_name, sizeof(SOCKET_NAME)) == 0) {
|
||||
if (memcmp(buf + i, SOCKET_NAME, sizeof(SOCKET_NAME)) == 0) {
|
||||
SOCKET_OFF = i;
|
||||
break;
|
||||
}
|
||||
@@ -350,55 +350,6 @@ static void patch_socket_name(const char *path) {
|
||||
munmap(buf, size);
|
||||
}
|
||||
|
||||
static void magisk_init_daemon() {
|
||||
setsid();
|
||||
|
||||
// Full patch
|
||||
sepol_allow("su", ALL, ALL, ALL);
|
||||
|
||||
// Wait till init cold boot done
|
||||
while (access("/dev/.coldboot_done", F_OK))
|
||||
usleep(1);
|
||||
|
||||
int null = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
dup3(null, STDIN_FILENO, O_CLOEXEC);
|
||||
dup3(null, STDOUT_FILENO, O_CLOEXEC);
|
||||
dup3(null, STDERR_FILENO, O_CLOEXEC);
|
||||
if (null > STDERR_FILENO)
|
||||
close(null);
|
||||
|
||||
// Transit our context to su (mimic setcon)
|
||||
int fd, crap;
|
||||
fd = open("/proc/self/attr/current", O_WRONLY);
|
||||
write(fd, "u:r:su:s0", 9);
|
||||
close(fd);
|
||||
|
||||
// Dump full patch to kernel
|
||||
dump_policydb(SELINUX_LOAD);
|
||||
close(creat(PATCHDONE, 0));
|
||||
destroy_policydb();
|
||||
|
||||
// Keep Magisk daemon always alive
|
||||
while (1) {
|
||||
struct sockaddr_un sun;
|
||||
fd = setup_socket(&sun);
|
||||
memcpy(sun.sun_path + 1, RAND_SOCKET_NAME, sizeof(SOCKET_NAME));
|
||||
while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)))
|
||||
usleep(10000); /* Wait 10 ms after each try */
|
||||
|
||||
/* Should hold forever */
|
||||
read(fd, &crap, sizeof(crap));
|
||||
|
||||
/* If things went here, it means the other side of the socket is closed
|
||||
* We restart the daemon again */
|
||||
close(fd);
|
||||
if (fork_dont_care() == 0) {
|
||||
execv("/sbin/magisk", (char *[]) { "magisk", "--daemon", NULL } );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
umask(0);
|
||||
|
||||
@@ -424,14 +375,8 @@ int main(int argc, char *argv[]) {
|
||||
if (null > STDERR_FILENO)
|
||||
close(null);
|
||||
|
||||
// Extract and link files
|
||||
mkdir("/overlay", 0000);
|
||||
dump_magiskrc("/overlay/init.magisk.rc", 0750);
|
||||
mkdir("/overlay/sbin", 0755);
|
||||
dump_magisk("/overlay/sbin/magisk", 0755);
|
||||
patch_socket_name("/overlay/sbin/magisk");
|
||||
mkdir("/overlay/root", 0755);
|
||||
link("/init", "/overlay/root/magiskinit");
|
||||
// Backup self
|
||||
link("/init", "/init.bak");
|
||||
|
||||
struct cmdline cmd;
|
||||
parse_cmdline(&cmd);
|
||||
@@ -444,7 +389,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
if (cmd.skip_initramfs) {
|
||||
// Clear rootfs
|
||||
excl_list = (char *[]) { "overlay", ".backup", NULL };
|
||||
excl_list = (char *[]) { "overlay", ".backup", "init.bak", NULL };
|
||||
frm_rf(root);
|
||||
} else if (access("/ramdisk.cpio.xz", R_OK) == 0) {
|
||||
// High compression mode
|
||||
@@ -513,23 +458,24 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
// Only patch rootfs if not intended to run in recovery
|
||||
if (access("/etc/recovery.fstab", F_OK) != 0) {
|
||||
int overlay = open("/overlay", O_RDONLY | O_CLOEXEC);
|
||||
mv_dir(overlay, root);
|
||||
close(overlay);
|
||||
rmdir("/overlay");
|
||||
int fd;
|
||||
|
||||
// Handle ramdisk overlays
|
||||
fd = open("/overlay", O_RDONLY | O_CLOEXEC);
|
||||
if (fd >= 0) {
|
||||
mv_dir(fd, root);
|
||||
close(fd);
|
||||
rmdir("/overlay");
|
||||
}
|
||||
|
||||
patch_ramdisk();
|
||||
patch_sepolicy();
|
||||
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
|
||||
if (fork_dont_care() == 0) {
|
||||
strcpy(argv[0], "magiskinit");
|
||||
close(root);
|
||||
magisk_init_daemon();
|
||||
}
|
||||
// Dump binaries
|
||||
dump_magiskrc("/init.magisk.rc", 0750);
|
||||
dump_magisk("/sbin/magisk", 0755);
|
||||
patch_socket_name("/sbin/magisk");
|
||||
rename("/init.bak", "/sbin/magiskinit");
|
||||
}
|
||||
|
||||
// Clean up
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#include "utils.h"
|
||||
#include "magisk.h"
|
||||
|
||||
char socket_name[] = SOCKET_NAME;
|
||||
static char socket_name[] = SOCKET_NAME; /* Workaround compiler bug pre NDK r13 */
|
||||
|
||||
/* Setup the address and return socket fd */
|
||||
int setup_socket(struct sockaddr_un *sun) {
|
||||
|
10
native/jni/external/Android.mk
vendored
10
native/jni/external/Android.mk
vendored
@@ -28,6 +28,16 @@ LOCAL_SRC_FILES := \
|
||||
mincrypt/sha256.c
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
# libnanopb.a
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE:= libnanopb
|
||||
LOCAL_C_INCLUDES := $(LIBNANOPB)
|
||||
LOCAL_SRC_FILES := \
|
||||
nanopb/pb_common.c \
|
||||
nanopb/pb_decode.c \
|
||||
nanopb/pb_encode.c
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
# libfdt.a
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE:= libfdt
|
||||
|
2
native/jni/external/busybox
vendored
2
native/jni/external/busybox
vendored
Submodule native/jni/external/busybox updated: e1895e6c95...4f5bf4ad83
1
native/jni/external/nanopb
vendored
Submodule
1
native/jni/external/nanopb
vendored
Submodule
Submodule native/jni/external/nanopb added at 04cd1f94cc
2
native/jni/external/selinux
vendored
2
native/jni/external/selinux
vendored
Submodule native/jni/external/selinux updated: 8e849a5639...4d28de872c
@@ -8,7 +8,9 @@
|
||||
#include <sys/un.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
extern int is_daemon_init, seperate_vendor;
|
||||
extern int is_daemon_init;
|
||||
extern int seperate_vendor;
|
||||
extern int full_patch_pid;
|
||||
|
||||
// Commands require connecting to daemon
|
||||
enum {
|
||||
@@ -16,7 +18,6 @@ enum {
|
||||
SUPERUSER,
|
||||
CHECK_VERSION,
|
||||
CHECK_VERSION_CODE,
|
||||
POST_FS,
|
||||
POST_FS_DATA,
|
||||
LATE_START,
|
||||
LAUNCH_MAGISKHIDE,
|
||||
@@ -31,7 +32,7 @@ enum {
|
||||
DAEMON_ERROR = -1,
|
||||
DAEMON_SUCCESS = 0,
|
||||
ROOT_REQUIRED,
|
||||
LOGD_DISABLED,
|
||||
LOGCAT_DISABLED,
|
||||
HIDE_IS_ENABLED,
|
||||
HIDE_NOT_ENABLED,
|
||||
HIDE_ITEM_EXIST,
|
||||
@@ -40,10 +41,9 @@ enum {
|
||||
|
||||
// daemon.c
|
||||
|
||||
void start_daemon();
|
||||
int connect_daemon();
|
||||
void start_daemon(int post_fs_data);
|
||||
int connect_daemon(int post_fs_data);
|
||||
void auto_start_magiskhide();
|
||||
void daemon_init();
|
||||
|
||||
// socket.c
|
||||
|
||||
@@ -59,7 +59,7 @@ void write_string(int fd, const char* val);
|
||||
* Boot Stages *
|
||||
***************/
|
||||
|
||||
void post_fs(int client);
|
||||
void startup();
|
||||
void post_fs_data(int client);
|
||||
void late_start(int client);
|
||||
void fix_filecon();
|
||||
|
@@ -58,7 +58,7 @@ struct log_listener {
|
||||
};
|
||||
|
||||
extern struct log_listener log_events[];
|
||||
extern int logd;
|
||||
extern int loggable;
|
||||
|
||||
void monitor_logs();
|
||||
void start_debug_full_log();
|
||||
|
@@ -14,12 +14,9 @@
|
||||
#endif
|
||||
|
||||
#define LOGFILE "/cache/magisk.log"
|
||||
#define DEBUG_LOG "/data/adb/magisk_debug.log"
|
||||
#define UNBLOCKFILE "/dev/.magisk.unblock"
|
||||
#define PATCHDONE "/dev/.magisk.patch.done"
|
||||
#define DISABLEFILE "/cache/.disable_magisk"
|
||||
#define UNINSTALLER "/cache/magisk_uninstaller.sh"
|
||||
#define CACHEMOUNT "/cache/magisk_mount"
|
||||
#define MAGISKTMP "/sbin/.core"
|
||||
#define MIRRDIR MAGISKTMP "/mirror"
|
||||
#define BBPATH MAGISKTMP "/busybox"
|
||||
@@ -27,8 +24,12 @@
|
||||
#define COREDIR MOUNTPOINT "/.core"
|
||||
#define HOSTSFILE COREDIR "/hosts"
|
||||
#define HIDELIST COREDIR "/hidelist"
|
||||
#define MAINIMG "/data/adb/magisk.img"
|
||||
#define DATABIN "/data/adb/magisk"
|
||||
#define SECURE_DIR "/data/adb/"
|
||||
#define MAINIMG SECURE_DIR "magisk.img"
|
||||
#define DATABIN SECURE_DIR "magisk"
|
||||
#define MAGISKDB SECURE_DIR "magisk.db"
|
||||
#define SIMPLEMOUNT SECURE_DIR "magisk_simple"
|
||||
#define DEBUG_LOG SECURE_DIR "magisk_debug.log"
|
||||
#define MANAGERAPK DATABIN "/magisk.apk"
|
||||
#define MAGISKRC "/init.magisk.rc"
|
||||
|
||||
@@ -55,7 +56,6 @@ extern char *argv0; /* For changing process name */
|
||||
#define init_applet ((char *[]) { "magiskpolicy", "supolicy", NULL })
|
||||
|
||||
extern int (*applet_main[]) (int, char *[]), (*init_applet_main[]) (int, char *[]);
|
||||
extern char socket_name[]; /* Workaround compiler bug pre NDK r13 */
|
||||
|
||||
int create_links(const char *bin, const char *path);
|
||||
|
||||
@@ -63,13 +63,6 @@ int create_links(const char *bin, const char *path);
|
||||
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
|
||||
|
@@ -1,17 +1,17 @@
|
||||
#include "magiskpolicy.h"
|
||||
|
||||
const char magiskrc[] =
|
||||
|
||||
// Triggers
|
||||
|
||||
"on post-fs\n"
|
||||
" start logd\n"
|
||||
" start magisk_pfs\n"
|
||||
" wait /dev/.magisk.unblock 10\n"
|
||||
"\n"
|
||||
|
||||
"on post-fs-data\n"
|
||||
" load_persist_props\n"
|
||||
" rm /dev/.magisk.unblock\n"
|
||||
" start magisk_pfsd\n"
|
||||
" start magisk_startup\n"
|
||||
" wait /dev/.magisk.unblock 10\n"
|
||||
" rm /dev/.magisk.unblock\n"
|
||||
"\n"
|
||||
@@ -20,25 +20,19 @@ const char magiskrc[] =
|
||||
|
||||
"service magisk_daemon /sbin/magisk --daemon\n"
|
||||
" user root\n"
|
||||
" seclabel u:r:su:s0\n"
|
||||
" seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
|
||||
" oneshot\n"
|
||||
"\n"
|
||||
|
||||
"service magisk_pfs /sbin/magisk --post-fs\n"
|
||||
"service magisk_startup /sbin/magisk --startup\n"
|
||||
" user root\n"
|
||||
" seclabel u:r:su:s0\n"
|
||||
" seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
|
||||
" oneshot\n"
|
||||
"\n"
|
||||
|
||||
"service magisk_pfsd /sbin/magisk --post-fs-data\n"
|
||||
" user root\n"
|
||||
" seclabel u:r:su:s0\n"
|
||||
" oneshot\n"
|
||||
"\n"
|
||||
|
||||
"service magisk_service /sbin/magisk --service\n"
|
||||
"service magisk_service /sbin/magisk --service\n"
|
||||
" class late_start\n"
|
||||
" user root\n"
|
||||
" seclabel u:r:su:s0\n"
|
||||
" seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
|
||||
" oneshot\n"
|
||||
;
|
||||
|
@@ -4,10 +4,6 @@
|
||||
#ifndef _RESETPROP_H_
|
||||
#define _RESETPROP_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int prop_exist(const char *name);
|
||||
int setprop(const char *name, const char *value);
|
||||
int setprop2(const char *name, const char *value, const int trigger);
|
||||
@@ -16,10 +12,6 @@ char *getprop2(const char *name, int persist);
|
||||
int deleteprop(const char *name);
|
||||
int deleteprop2(const char *name, const int persist);
|
||||
int read_prop_file(const char* filename, const int trigger);
|
||||
void getprop_all(void (*callback)(const char*, const char*));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
void getprop_all(void (*callback)(const char *, const char *, void *), void *cookie);
|
||||
|
||||
#endif
|
||||
|
@@ -122,7 +122,7 @@ int setattrat(int dirfd, const char *pathname, struct file_attr *a);
|
||||
int fsetattr(int fd, struct file_attr *a);
|
||||
void fclone_attr(const int sourcefd, const int targetfd);
|
||||
void clone_attr(const char *source, const char *target);
|
||||
void restorecon(int dirfd, int force);
|
||||
void restorecon(int dirfd);
|
||||
int mmap_ro(const char *filename, void **buf, size_t *size);
|
||||
int mmap_rw(const char *filename, void **buf, size_t *size);
|
||||
void fd_full_read(int fd, void **buf, size_t *size);
|
||||
|
@@ -168,7 +168,7 @@ int parse_img(const char *image, boot_img *boot) {
|
||||
|
||||
if (pos < boot->map_size) {
|
||||
boot->tail = head + pos;
|
||||
boot->tail_size = boot->map_size - pos;
|
||||
boot->tail_size = boot->map_size - (boot->tail - boot->map_addr);
|
||||
}
|
||||
|
||||
// Check tail info, currently only for LG Bump and Samsung SEANDROIDENFORCE
|
||||
|
@@ -56,7 +56,7 @@ void hide_sensitive_props() {
|
||||
}
|
||||
}
|
||||
|
||||
static void rm_magisk_prop(const char *name, const char *value) {
|
||||
static void rm_magisk_prop(const char *name, const char *value, void *v) {
|
||||
if (strstr(name, "magisk")) {
|
||||
deleteprop2(name, 0);
|
||||
}
|
||||
@@ -64,7 +64,7 @@ static void rm_magisk_prop(const char *name, const char *value) {
|
||||
|
||||
void clean_magisk_props() {
|
||||
LOGD("hide_utils: Cleaning magisk props\n");
|
||||
getprop_all(rm_magisk_prop);
|
||||
getprop_all(rm_magisk_prop, NULL);
|
||||
}
|
||||
|
||||
int add_list(char *proc) {
|
||||
|
@@ -49,11 +49,14 @@ void launch_magiskhide(int client) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!logd) {
|
||||
if (!loggable) {
|
||||
if (client > 0) {
|
||||
write_int(client, LOGD_DISABLED);
|
||||
write_int(client, LOGCAT_DISABLED);
|
||||
close(client);
|
||||
}
|
||||
setprop(MAGISKHIDE_PROP, "0");
|
||||
// Remove without actually removing persist props
|
||||
deleteprop2(MAGISKHIDE_PROP, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,7 +135,7 @@ int magiskhide_main(int argc, char *argv[]) {
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
}
|
||||
int fd = connect_daemon();
|
||||
int fd = connect_daemon(0);
|
||||
write_int(fd, req);
|
||||
if (req == ADD_HIDELIST || req == RM_HIDELIST) {
|
||||
write_string(fd, argv[2]);
|
||||
@@ -144,14 +147,14 @@ int magiskhide_main(int argc, char *argv[]) {
|
||||
case ROOT_REQUIRED:
|
||||
fprintf(stderr, "Root is required for this operation\n");
|
||||
return code;
|
||||
case LOGD_DISABLED:
|
||||
fprintf(stderr, "Logd is not running, cannot run logcat\n");
|
||||
case LOGCAT_DISABLED:
|
||||
fprintf(stderr, "Logcat is disabled, cannot start MagiskHide\n");
|
||||
return (code);
|
||||
case HIDE_NOT_ENABLED:
|
||||
fprintf(stderr, "Magisk hide is not enabled yet\n");
|
||||
fprintf(stderr, "MagiskHide is not enabled yet\n");
|
||||
return code;
|
||||
case HIDE_IS_ENABLED:
|
||||
fprintf(stderr, "Magisk hide is already enabled\n");
|
||||
fprintf(stderr, "MagiskHide is already enabled\n");
|
||||
return code;
|
||||
case HIDE_ITEM_EXIST:
|
||||
fprintf(stderr, "Process [%s] already exists in hide list\n", argv[2]);
|
||||
|
@@ -4,7 +4,6 @@
|
||||
#include <pthread.h>
|
||||
|
||||
#define TERM_THREAD SIGUSR1
|
||||
#define HIDE_DONE SIGUSR2
|
||||
|
||||
// Kill process
|
||||
void kill_proc(int pid);
|
||||
|
@@ -20,7 +20,7 @@
|
||||
#include "magiskhide.h"
|
||||
|
||||
static char init_ns[32], zygote_ns[2][32], cache_block[256];
|
||||
static int hide_queue = 0, zygote_num, has_cache = 1, pipefd[2] = { -1, -1 };
|
||||
static int zygote_num, has_cache = 1, pipefd[2] = { -1, -1 };
|
||||
|
||||
// Workaround for the lack of pthread_cancel
|
||||
static void term_thread(int sig) {
|
||||
@@ -38,17 +38,6 @@ static void term_thread(int sig) {
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
static void hide_done(int sig) {
|
||||
--hide_queue;
|
||||
if (hide_queue == 0) {
|
||||
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
|
||||
xsymlink(DATABIN, "/data/magisk");
|
||||
xsymlink(MAINIMG, "/data/magisk.img");
|
||||
xsymlink(MOUNTPOINT, "/magisk");
|
||||
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int read_namespace(const int pid, char* target, const size_t size) {
|
||||
char path[32];
|
||||
snprintf(path, sizeof(path), "/proc/%d/ns/mnt", pid);
|
||||
@@ -72,7 +61,7 @@ static void lazy_unmount(const char* mountpoint) {
|
||||
LOGD("hide_daemon: Unmounted (%s)\n", mountpoint);
|
||||
}
|
||||
|
||||
static void hide_daemon(int pid, int ppid) {
|
||||
static void hide_daemon(int pid) {
|
||||
LOGD("hide_daemon: start unmount for pid=[%d]\n", pid);
|
||||
strcpy(argv0, "hide_daemon");
|
||||
|
||||
@@ -140,9 +129,6 @@ exit:
|
||||
kill(pid, SIGCONT);
|
||||
// Free up memory
|
||||
vec_destroy(&mount_list);
|
||||
// Wait a while and link it back
|
||||
sleep(10);
|
||||
kill(ppid, HIDE_DONE);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
@@ -151,7 +137,6 @@ void proc_monitor() {
|
||||
sigset_t block_set;
|
||||
sigemptyset(&block_set);
|
||||
sigaddset(&block_set, TERM_THREAD);
|
||||
sigaddset(&block_set, HIDE_DONE);
|
||||
pthread_sigmask(SIG_UNBLOCK, &block_set, NULL);
|
||||
|
||||
// Register the cancel signal
|
||||
@@ -159,8 +144,6 @@ void proc_monitor() {
|
||||
memset(&act, 0, sizeof(act));
|
||||
act.sa_handler = term_thread;
|
||||
sigaction(TERM_THREAD, &act, NULL);
|
||||
act.sa_handler = hide_done;
|
||||
sigaction(HIDE_DONE, &act, NULL);
|
||||
|
||||
cache_block[0] = '\0';
|
||||
|
||||
@@ -219,6 +202,11 @@ void proc_monitor() {
|
||||
if(ret != 2)
|
||||
continue;
|
||||
|
||||
// Allow hiding sub-services of applications
|
||||
char *colon = strchr(processName, ':');
|
||||
if (colon)
|
||||
*colon = '\0';
|
||||
|
||||
// Critical region
|
||||
pthread_mutex_lock(&hide_lock);
|
||||
vec_for_each(hide_list, line) {
|
||||
@@ -239,23 +227,17 @@ void proc_monitor() {
|
||||
// Send pause signal ASAP
|
||||
if (kill(pid, SIGSTOP) == -1) continue;
|
||||
|
||||
// Restore the colon so we can log the actual process name
|
||||
if (colon)
|
||||
*colon = ':';
|
||||
LOGI("proc_monitor: %s (PID=%d ns=%s)\n", processName, pid, ns);
|
||||
|
||||
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
|
||||
unlink("/magisk");
|
||||
unlink("/data/magisk");
|
||||
unlink("/data/magisk.img");
|
||||
unlink(MAGISKRC);
|
||||
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
|
||||
++hide_queue;
|
||||
|
||||
/*
|
||||
* The setns system call do not support multithread processes
|
||||
* We have to fork a new process, setns, then do the unmounts
|
||||
*/
|
||||
int selfpid = getpid();
|
||||
if (fork_dont_care() == 0)
|
||||
hide_daemon(pid, selfpid);
|
||||
hide_daemon(pid);
|
||||
|
||||
break;
|
||||
}
|
||||
|
Submodule native/jni/magiskpolicy updated: 21a557a184...c694776162
31
native/jni/resetprop/_resetprop.h
Normal file
31
native/jni/resetprop/_resetprop.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/* resetprop.h - Internal struct definitions
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MAGISK_PROPS_H
|
||||
#define MAGISK_PROPS_H
|
||||
|
||||
#include "system_properties.h"
|
||||
#include "logging.h"
|
||||
|
||||
extern int prop_verbose;
|
||||
|
||||
#define PRINT_D(...) { LOGD(__VA_ARGS__); if (prop_verbose) fprintf(stderr, __VA_ARGS__); }
|
||||
#define PRINT_E(...) { LOGE(__VA_ARGS__); fprintf(stderr, __VA_ARGS__); }
|
||||
|
||||
struct prop_t {
|
||||
char *name;
|
||||
char value[PROP_VALUE_MAX];
|
||||
};
|
||||
|
||||
struct read_cb_t {
|
||||
void (*func)(const char *name, const char *value, void *cookie);
|
||||
void *cookie;
|
||||
};
|
||||
|
||||
char *persist_getprop(const char *name);
|
||||
void persist_getprop_all(struct read_cb_t *read_cb);
|
||||
bool persist_deleteprop(const char *name);
|
||||
void collect_props(const char *name, const char *value, void *prop_list);
|
||||
|
||||
#endif //MAGISK_PROPS_H
|
252
native/jni/resetprop/persist_props.c
Normal file
252
native/jni/resetprop/persist_props.c
Normal file
@@ -0,0 +1,252 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <pb.h>
|
||||
#include <pb_decode.h>
|
||||
#include <pb_encode.h>
|
||||
|
||||
#include "_resetprop.h"
|
||||
#include "utils.h"
|
||||
#include "vector.h"
|
||||
|
||||
#define PERSISTENT_PROPERTY_DIR "/data/property"
|
||||
|
||||
/* ***********************************************************************
|
||||
* Auto generated header and constant definitions compiled from
|
||||
* android/platform/system/core/master/init/persistent_properties.proto
|
||||
* using Nanopb's protoc
|
||||
* Nanopb: https://github.com/nanopb/nanopb
|
||||
* ***********************************************************************/
|
||||
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.3.9.1 at Sun Apr 22 14:36:22 2018. */
|
||||
|
||||
/* @@protoc_insertion_point(includes) */
|
||||
#if PB_PROTO_HEADER_VERSION != 30
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _PersistentProperties {
|
||||
pb_callback_t properties;
|
||||
/* @@protoc_insertion_point(struct:PersistentProperties) */
|
||||
} PersistentProperties;
|
||||
|
||||
typedef struct _PersistentProperties_PersistentPropertyRecord {
|
||||
pb_callback_t name;
|
||||
bool has_value;
|
||||
char value[92];
|
||||
/* @@protoc_insertion_point(struct:PersistentProperties_PersistentPropertyRecord) */
|
||||
} PersistentProperties_PersistentPropertyRecord;
|
||||
|
||||
/* Default values for struct fields */
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define PersistentProperties_init_default {{{NULL}, NULL}}
|
||||
#define PersistentProperties_PersistentPropertyRecord_init_default {{{NULL}, NULL}, false, ""}
|
||||
#define PersistentProperties_init_zero {{{NULL}, NULL}}
|
||||
#define PersistentProperties_PersistentPropertyRecord_init_zero {{{NULL}, NULL}, false, ""}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define PersistentProperties_properties_tag 1
|
||||
#define PersistentProperties_PersistentPropertyRecord_name_tag 1
|
||||
#define PersistentProperties_PersistentPropertyRecord_value_tag 2
|
||||
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.3.9.1 at Sun Apr 22 14:36:22 2018. */
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
const pb_field_t PersistentProperties_PersistentPropertyRecord_fields[3] = {
|
||||
PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, PersistentProperties_PersistentPropertyRecord, name, name, 0),
|
||||
PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, PersistentProperties_PersistentPropertyRecord, value, name, 0),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t PersistentProperties_fields[2] = {
|
||||
PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, PersistentProperties, properties, properties, &PersistentProperties_PersistentPropertyRecord_fields),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
/* PersistentProperties_size depends on runtime parameters */
|
||||
/* PersistentProperties_PersistentPropertyRecord_size depends on runtime parameters */
|
||||
|
||||
/* Message IDs (where set with "msgid" option) */
|
||||
#ifdef PB_MSGID
|
||||
|
||||
#define PROPS_MESSAGES \
|
||||
|
||||
#endif
|
||||
/* @@protoc_insertion_point(eof) */
|
||||
|
||||
|
||||
/* ***************************
|
||||
* End of auto generated code
|
||||
* ***************************/
|
||||
|
||||
static bool name_decode(pb_istream_t *stream, const pb_field_t *field, void **arg) {
|
||||
uint8_t *name = xmalloc(stream->bytes_left + 1);
|
||||
name[stream->bytes_left] = '\0';
|
||||
if (!pb_read(stream, name, stream->bytes_left))
|
||||
return false;
|
||||
*arg = name;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool name_encode(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) {
|
||||
return pb_encode_tag_for_field(stream, field) && pb_encode_string(stream, *arg, strlen(*arg));
|
||||
}
|
||||
|
||||
static bool prop_decode(pb_istream_t *stream, const pb_field_t *field, void **arg) {
|
||||
PersistentProperties_PersistentPropertyRecord prop = {};
|
||||
prop.name.funcs.decode = name_decode;
|
||||
if (!pb_decode(stream, PersistentProperties_PersistentPropertyRecord_fields, &prop))
|
||||
return false;
|
||||
struct read_cb_t *read_cb = *arg;
|
||||
read_cb->func(prop.name.arg, prop.value, read_cb->cookie);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool prop_encode(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) {
|
||||
PersistentProperties_PersistentPropertyRecord prop = {};
|
||||
prop.name.funcs.encode = name_encode;
|
||||
prop.has_value = true;
|
||||
struct vector *v = *arg;
|
||||
struct prop_t *e;
|
||||
vec_for_each(v, e) {
|
||||
if (e == NULL)
|
||||
continue;
|
||||
if (!pb_encode_tag_for_field(stream, field))
|
||||
return false;
|
||||
prop.name.arg = e->name;
|
||||
strcpy(prop.value, e->value);
|
||||
if (!pb_encode_submessage(stream, PersistentProperties_PersistentPropertyRecord_fields, &prop))
|
||||
return false;
|
||||
free(e->name);
|
||||
free(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool write_callback(pb_ostream_t *stream, const uint8_t *buf, size_t count) {
|
||||
int fd = (intptr_t)stream->state;
|
||||
return xwrite(fd, buf, count) == count;
|
||||
}
|
||||
|
||||
static pb_ostream_t create_ostream(const char *filename) {
|
||||
int fd = creat(filename, 0644);
|
||||
pb_ostream_t o = {&write_callback, (void*)(intptr_t)fd, SIZE_MAX, 0};
|
||||
return o;
|
||||
}
|
||||
|
||||
static void pb_getprop_cb(const char *name, const char *value, void *v) {
|
||||
struct prop_t *prop = v;
|
||||
if (prop->name && strcmp(name, prop->name) == 0) {
|
||||
strcpy(prop->value, value);
|
||||
prop->name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void persist_getprop_all(struct read_cb_t *read_cb) {
|
||||
if (access(PERSISTENT_PROPERTY_DIR "/persistent_properties", R_OK) == 0) {
|
||||
PRINT_D("resetprop: decode with protobuf from [" PERSISTENT_PROPERTY_DIR "/persistent_properties]\n");
|
||||
PersistentProperties props = PersistentProperties_init_zero;
|
||||
props.properties.funcs.decode = prop_decode;
|
||||
props.properties.arg = read_cb;
|
||||
uint8_t *buf;
|
||||
size_t size;
|
||||
mmap_ro(PERSISTENT_PROPERTY_DIR "/persistent_properties", (void **) &buf, &size);
|
||||
pb_istream_t stream = pb_istream_from_buffer(buf, size);
|
||||
pb_decode(&stream, PersistentProperties_fields, &props);
|
||||
munmap(buf, size);
|
||||
} else {
|
||||
DIR *dir = opendir(PERSISTENT_PROPERTY_DIR);
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0 )
|
||||
continue;
|
||||
char *value = persist_getprop(entry->d_name);
|
||||
if (value) {
|
||||
read_cb->func(strdup(entry->d_name), value, read_cb->cookie);
|
||||
free(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *persist_getprop(const char *name) {
|
||||
struct prop_t prop;
|
||||
prop.name = (char *) name;
|
||||
if (access(PERSISTENT_PROPERTY_DIR "/persistent_properties", R_OK) == 0) {
|
||||
struct read_cb_t read_cb = {
|
||||
.func = pb_getprop_cb,
|
||||
.cookie = &prop
|
||||
};
|
||||
persist_getprop_all(&read_cb);
|
||||
if (prop.name)
|
||||
return NULL;
|
||||
} else {
|
||||
// Try to read from file
|
||||
char path[PATH_MAX];
|
||||
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
|
||||
int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
PRINT_D("resetprop: read prop from [%s]\n", path);
|
||||
prop.value[read(fd, prop.value, sizeof(PROP_VALUE_MAX))] = '\0'; // Null terminate the read value
|
||||
close(fd);
|
||||
}
|
||||
return strdup(prop.value);
|
||||
}
|
||||
|
||||
bool persist_deleteprop(const char *name) {
|
||||
if (access(PERSISTENT_PROPERTY_DIR "/persistent_properties", R_OK) == 0) {
|
||||
struct vector v;
|
||||
vec_init(&v);
|
||||
struct read_cb_t read_cb = {
|
||||
.func = collect_props,
|
||||
.cookie = &v
|
||||
};
|
||||
persist_getprop_all(&read_cb);
|
||||
struct prop_t *p;
|
||||
bool reencode = false;
|
||||
vec_for_each(&v, p) {
|
||||
if (strcmp(p->name, name) == 0) {
|
||||
// Remove the prop from the list
|
||||
free(p->name);
|
||||
free(p);
|
||||
vec_cur(&v) = NULL;
|
||||
reencode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (reencode) {
|
||||
// Dump the props back
|
||||
PersistentProperties props = PersistentProperties_init_zero;
|
||||
pb_ostream_t ostream = create_ostream(PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp");
|
||||
props.properties.funcs.encode = prop_encode;
|
||||
props.properties.arg = &v;
|
||||
PRINT_D("resetprop: encode with protobuf to [" PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp]\n");
|
||||
if (!pb_encode(&ostream, PersistentProperties_fields, &props))
|
||||
return false;
|
||||
clone_attr(PERSISTENT_PROPERTY_DIR "/persistent_properties", PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp");
|
||||
rename(PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp", PERSISTENT_PROPERTY_DIR "/persistent_properties");
|
||||
}
|
||||
|
||||
vec_destroy(&v);
|
||||
return reencode;
|
||||
} else {
|
||||
char path[PATH_MAX];
|
||||
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
|
||||
if (unlink(path) == 0) {
|
||||
PRINT_D("resetprop: unlink [%s]\n", path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
@@ -2,52 +2,6 @@
|
||||
*
|
||||
* Copyright 2016 nkk71 <nkk71x@gmail.com>
|
||||
* Copyright 2016 topjohnwu <topjohnwu@gmail.com>
|
||||
*
|
||||
* Info:
|
||||
*
|
||||
* all changes are in
|
||||
*
|
||||
* bionic/libc/bionic/system_properties.cpp
|
||||
*
|
||||
* Functions that need to be patched/added in system_properties.cpp
|
||||
*
|
||||
* int __system_properties_init2()
|
||||
* on android 7, first tear down the everything then let it initialize again:
|
||||
* if (initialized) {
|
||||
* //list_foreach(contexts, [](context_node* l) { l->reset_access(); });
|
||||
* //return 0;
|
||||
* free_and_unmap_contexts();
|
||||
* initialized = false;
|
||||
* }
|
||||
*
|
||||
*
|
||||
* static prop_area* map_prop_area(const char* filename, bool is_legacy)
|
||||
* we dont want this read only so change: 'O_RDONLY' to 'O_RDWR'
|
||||
*
|
||||
* static prop_area* map_fd_ro(const int fd)
|
||||
* we dont want this read only so change: 'PROT_READ' to 'PROT_READ | PROT_WRITE'
|
||||
*
|
||||
*
|
||||
* Copy the code of prop_info *prop_area::find_property, and modify to delete props
|
||||
* const prop_info *prop_area::find_property_and_del(prop_bt *const trie, const char *name)
|
||||
* {
|
||||
* ...
|
||||
* ... Do not alloc a new prop_bt here, remove all code involve alloc_if_needed
|
||||
* ...
|
||||
*
|
||||
* if (prop_offset != 0) {
|
||||
* atomic_store_explicit(¤t->prop, 0, memory_order_release); // Add this line to nullify the prop entry
|
||||
* return to_prop_info(¤t->prop);
|
||||
* } else {
|
||||
*
|
||||
* ....
|
||||
* }
|
||||
*
|
||||
*
|
||||
* by patching just those functions directly, all other functions should be ok
|
||||
* as is.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -65,15 +19,11 @@
|
||||
|
||||
#include "magisk.h"
|
||||
#include "resetprop.h"
|
||||
extern "C" {
|
||||
#include "_resetprop.h"
|
||||
#include "vector.h"
|
||||
}
|
||||
#include "utils.h"
|
||||
|
||||
#define PRINT_D(...) { LOGD(__VA_ARGS__); if (verbose) fprintf(stderr, __VA_ARGS__); }
|
||||
#define PRINT_E(...) { LOGE(__VA_ARGS__); fprintf(stderr, __VA_ARGS__); }
|
||||
#define PERSISTENT_PROPERTY_DIR "/data/property"
|
||||
|
||||
static int verbose = 0;
|
||||
int prop_verbose = 0;
|
||||
|
||||
static int check_legal_property_name(const char *name) {
|
||||
int namelen = strlen(name);
|
||||
@@ -129,6 +79,49 @@ static int usage(char* arg0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// The callback passes to __system_property_read_callback2, actually runs the callback in read_cb
|
||||
static void callback_wrapper(void *read_cb, const char *name, const char *value, uint32_t serial) {
|
||||
((struct read_cb_t *) read_cb)->func(name, value, ((struct read_cb_t *) read_cb)->cookie);
|
||||
}
|
||||
|
||||
/* **********************************
|
||||
* Callback functions for read_cb_t
|
||||
* **********************************/
|
||||
|
||||
void collect_props(const char *name, const char *value, void *prop_list) {
|
||||
struct prop_t *p = (struct prop_t *) xmalloc(sizeof(*p));
|
||||
p->name = strdup(name);
|
||||
strcpy(p->value, value);
|
||||
vec_push_back(prop_list, p);
|
||||
}
|
||||
|
||||
static void collect_unique_props(const char *name, const char *value, void *prop_list) {
|
||||
struct vector *v = prop_list;
|
||||
struct prop_t *p;
|
||||
bool uniq = true;
|
||||
vec_for_each(v, p) {
|
||||
if (strcmp(name, p->name) == 0) {
|
||||
uniq = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (uniq)
|
||||
collect_props(name, value, prop_list);
|
||||
}
|
||||
|
||||
static void store_prop_value(const char *name, const char *value, void *dst) {
|
||||
strcpy(dst, value);
|
||||
}
|
||||
|
||||
static void prop_foreach_cb(const prop_info* pi, void* read_cb) {
|
||||
__system_property_read_callback2(pi, callback_wrapper, read_cb);
|
||||
}
|
||||
|
||||
// Comparision function used to sort prop vectors
|
||||
static int prop_cmp(const void *p1, const void *p2) {
|
||||
return strcmp(((struct prop_t *) p1)->name, ((struct prop_t *) p2)->name);
|
||||
}
|
||||
|
||||
static int init_resetprop() {
|
||||
if (__system_properties_init2()) {
|
||||
PRINT_E("resetprop: Initialize error\n");
|
||||
@@ -137,16 +130,36 @@ static int init_resetprop() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_props(int persist) {
|
||||
struct prop_t *p;
|
||||
struct vector prop_list;
|
||||
vec_init(&prop_list);
|
||||
getprop_all(collect_props, &prop_list);
|
||||
if (persist) {
|
||||
struct read_cb_t read_cb = {
|
||||
.func = collect_unique_props,
|
||||
.cookie = &prop_list
|
||||
};
|
||||
persist_getprop_all(&read_cb);
|
||||
}
|
||||
vec_sort(&prop_list, prop_cmp);
|
||||
vec_for_each(&prop_list, p) {
|
||||
printf("[%s]: [%s]\n", p->name, p->value);
|
||||
free(p->name);
|
||||
free(p);
|
||||
}
|
||||
vec_destroy(&prop_list);
|
||||
}
|
||||
|
||||
/* **************************************************
|
||||
* Implementations of functions in resetprop.h (APIs)
|
||||
* **************************************************/
|
||||
|
||||
int prop_exist(const char *name) {
|
||||
if (init_resetprop()) return 0;
|
||||
return __system_property_find2(name) != NULL;
|
||||
}
|
||||
|
||||
static void read_prop_info(void* cookie, const char *name, const char *value, uint32_t serial) {
|
||||
strcpy((char *) cookie, value);
|
||||
}
|
||||
|
||||
|
||||
char *getprop(const char *name) {
|
||||
return getprop2(name, 0);
|
||||
}
|
||||
@@ -155,103 +168,35 @@ char *getprop(const char *name) {
|
||||
char *getprop2(const char *name, int persist) {
|
||||
if (check_legal_property_name(name))
|
||||
return NULL;
|
||||
char value[PROP_VALUE_MAX];
|
||||
if (init_resetprop()) return NULL;
|
||||
const prop_info *pi = __system_property_find2(name);
|
||||
if (pi == NULL) {
|
||||
if (persist && strncmp(name, "persist.", 8) == 0) {
|
||||
// Try to read from file
|
||||
char path[PATH_MAX];
|
||||
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
|
||||
int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) goto no_prop;
|
||||
PRINT_D("resetprop: read prop from [%s]\n", path);
|
||||
size_t len = read(fd, value, sizeof(value));
|
||||
value[len] = '\0'; // Null terminate the read value
|
||||
} else {
|
||||
no_prop:
|
||||
char *value = persist_getprop(name);
|
||||
if (value)
|
||||
return value;
|
||||
}
|
||||
PRINT_D("resetprop: prop [%s] does not exist\n", name);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
__system_property_read_callback2(pi, read_prop_info, value);
|
||||
char value[PROP_VALUE_MAX];
|
||||
struct read_cb_t read_cb = {
|
||||
.func = store_prop_value,
|
||||
.cookie = value
|
||||
};
|
||||
__system_property_read_callback2(pi, callback_wrapper, &read_cb);
|
||||
PRINT_D("resetprop: getprop [%s]: [%s]\n", name, value);
|
||||
return strdup(value);
|
||||
}
|
||||
PRINT_D("resetprop: getprop [%s]: [%s]\n", name, value);
|
||||
return strdup(value);
|
||||
}
|
||||
|
||||
struct wrapper {
|
||||
void (*func)(const char *, const char *);
|
||||
};
|
||||
|
||||
static void cb_wrapper(void* cookie, const char *name, const char *value, uint32_t serial) {
|
||||
((wrapper *) cookie)->func(name, value);
|
||||
}
|
||||
|
||||
static void prop_foreach_cb(const prop_info* pi, void* cookie) {
|
||||
__system_property_read_callback2(pi, cb_wrapper, cookie);
|
||||
}
|
||||
|
||||
class property {
|
||||
public:
|
||||
property(const char *n, const char *v) {
|
||||
name = strdup(n);
|
||||
value = strdup(v);
|
||||
}
|
||||
~property() {
|
||||
free((void *)name);
|
||||
free((void *)value);
|
||||
}
|
||||
const char *name;
|
||||
const char *value;
|
||||
};
|
||||
|
||||
vector prop_list;
|
||||
|
||||
static int prop_cmp(const void *p1, const void *p2) {
|
||||
return strcmp(((property *) p1)->name, ((property *) p2)->name);
|
||||
}
|
||||
|
||||
static void print_all_props_cb(const char *name, const char *value) {
|
||||
vec_push_back(&prop_list, new property(name, value));
|
||||
}
|
||||
|
||||
static void print_all_props(int persist) {
|
||||
void *p;
|
||||
vec_init(&prop_list);
|
||||
getprop_all(print_all_props_cb);
|
||||
if (persist) {
|
||||
// Check all persist props in data
|
||||
DIR *dir = opendir(PERSISTENT_PROPERTY_DIR);
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0 )
|
||||
continue;
|
||||
int found = 0;
|
||||
vec_for_each(&prop_list, p) {
|
||||
if (strcmp(((property *) p)->name, entry->d_name) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
vec_push_back(&prop_list, new property(entry->d_name, getprop2(entry->d_name, 1)));
|
||||
}
|
||||
}
|
||||
vec_sort(&prop_list, prop_cmp);
|
||||
vec_for_each(&prop_list, p) {
|
||||
printf("[%s]: [%s]\n", ((property *) p)->name, ((property *) p)->value);
|
||||
delete((property *) p);
|
||||
}
|
||||
vec_destroy(&prop_list);
|
||||
}
|
||||
|
||||
void getprop_all(void (*callback)(const char*, const char*)) {
|
||||
void getprop_all(void (*callback)(const char *, const char *, void *), void *cookie) {
|
||||
if (init_resetprop()) return;
|
||||
struct wrapper wrap = {
|
||||
.func = callback
|
||||
struct read_cb_t read_cb = {
|
||||
.func = callback,
|
||||
.cookie = cookie
|
||||
};
|
||||
__system_property_foreach2(prop_foreach_cb, &wrap);
|
||||
__system_property_foreach2(prop_foreach_cb, &read_cb);
|
||||
}
|
||||
|
||||
int setprop(const char *name, const char *value) {
|
||||
@@ -294,7 +239,7 @@ int deleteprop(const char *name) {
|
||||
return deleteprop2(name, 1);
|
||||
}
|
||||
|
||||
int deleteprop2(const char *name, const int persist) {
|
||||
int deleteprop2(const char *name, int persist) {
|
||||
if (check_legal_property_name(name))
|
||||
return 1;
|
||||
if (init_resetprop()) return -1;
|
||||
@@ -302,8 +247,8 @@ int deleteprop2(const char *name, const int persist) {
|
||||
path[0] = '\0';
|
||||
PRINT_D("resetprop: deleteprop [%s]\n", name);
|
||||
if (persist && strncmp(name, "persist.", 8) == 0)
|
||||
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
|
||||
return __system_property_del(name) && unlink(path);
|
||||
persist = persist_deleteprop(name);
|
||||
return __system_property_del(name) && !(persist && strncmp(name, "persist.", 8) == 0);
|
||||
}
|
||||
|
||||
int read_prop_file(const char* filename, const int trigger) {
|
||||
@@ -336,7 +281,7 @@ int read_prop_file(const char* filename, const int trigger) {
|
||||
}
|
||||
if (comment) continue;
|
||||
pch = strchr(line, '=');
|
||||
// Ignore ivalid formats
|
||||
// Ignore invalid formats
|
||||
if ( ((pch == NULL) || (i >= (pch - line))) || (pch >= line + read - 1) ) continue;
|
||||
// Separate the string
|
||||
*pch = '\0';
|
||||
@@ -367,7 +312,7 @@ int resetprop_main(int argc, char *argv[]) {
|
||||
goto usage;
|
||||
}
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
prop_verbose = 1;
|
||||
continue;
|
||||
case 'p':
|
||||
persist = 1;
|
||||
@@ -390,7 +335,7 @@ int resetprop_main(int argc, char *argv[]) {
|
||||
|
||||
switch (argc) {
|
||||
case 0:
|
||||
print_all_props(persist);
|
||||
print_props(persist);
|
||||
return 0;
|
||||
case 1:
|
||||
prop = getprop2(argv[0], persist);
|
@@ -153,7 +153,7 @@ class prop_area {
|
||||
}
|
||||
|
||||
const prop_info* find(const char* name);
|
||||
bool del(const char *name); // resetprop add
|
||||
bool del(const char *name); /* resetprop add */
|
||||
bool add(const char* name, unsigned int namelen, const char* value, unsigned int valuelen);
|
||||
|
||||
bool foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie);
|
||||
@@ -184,7 +184,7 @@ class prop_area {
|
||||
const prop_info* find_property(prop_bt* const trie, const char* name, uint32_t namelen,
|
||||
const char* value, uint32_t valuelen, bool alloc_if_needed);
|
||||
|
||||
bool find_property_and_del(prop_bt *const trie, const char *name); // resetprop add
|
||||
bool find_property_and_del(prop_bt *const trie, const char *name); /* resetprop add */
|
||||
|
||||
bool foreach_property(prop_bt* const trie, void (*propfn)(const prop_info* pi, void* cookie),
|
||||
void* cookie);
|
||||
@@ -283,7 +283,8 @@ static prop_area* map_prop_area_rw(const char* filename, const char* context,
|
||||
return pa;
|
||||
}
|
||||
|
||||
static prop_area* map_fd_ro(const int fd) {
|
||||
// resetprop: map the memory as rw
|
||||
static prop_area* map_fd_rw(const int fd) {
|
||||
struct stat fd_stat;
|
||||
if (fstat(fd, &fd_stat) < 0) {
|
||||
return nullptr;
|
||||
@@ -298,7 +299,7 @@ static prop_area* map_fd_ro(const int fd) {
|
||||
pa_size = fd_stat.st_size;
|
||||
pa_data_size = pa_size - sizeof(prop_area);
|
||||
|
||||
void* const map_result = mmap(nullptr, pa_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // resetprop: add PROT_WRITE
|
||||
void* const map_result = mmap(nullptr, pa_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); /* resetprop: add PROT_WRITE */
|
||||
if (map_result == MAP_FAILED) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -313,10 +314,10 @@ static prop_area* map_fd_ro(const int fd) {
|
||||
}
|
||||
|
||||
static prop_area* map_prop_area(const char* filename) {
|
||||
int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDWR); // resetprop: O_RDONLY -> O_RDWR
|
||||
int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDWR); /* resetprop: O_RDONLY -> O_RDWR */
|
||||
if (fd == -1) return nullptr;
|
||||
|
||||
prop_area* map_result = map_fd_ro(fd);
|
||||
prop_area* map_result = map_fd_rw(fd);
|
||||
close(fd);
|
||||
|
||||
return map_result;
|
||||
@@ -530,7 +531,7 @@ bool prop_area::find_property_and_del(prop_bt* const trie, const char* name) {
|
||||
|
||||
uint_least32_t prop_offset = atomic_load_explicit(¤t->prop, memory_order_relaxed);
|
||||
if (prop_offset != 0) {
|
||||
atomic_store_explicit(¤t->prop, 0, memory_order_release); // resetprop: nullify the offset to delete the prop
|
||||
atomic_store_explicit(¤t->prop, 0, memory_order_release);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -1116,17 +1117,16 @@ static bool initialize_properties() {
|
||||
if (!initialize_properties_from_file("/system/etc/selinux/plat_property_contexts")) {
|
||||
return false;
|
||||
}
|
||||
if (!initialize_properties_from_file("/vendor/etc/selinux/nonplat_property_contexts")
|
||||
&& !initialize_properties_from_file("/vendor/etc/selinux/vendor_property_contexts")) {
|
||||
return false;
|
||||
}
|
||||
// Don't check for failure here, so we always have a sane list of properties.
|
||||
// E.g. In case of recovery, the vendor partition will not have mounted and we
|
||||
// still need the system / platform properties to function.
|
||||
initialize_properties_from_file("/vendor/etc/selinux/nonplat_property_contexts") ||
|
||||
initialize_properties_from_file("/vendor/etc/selinux/vendor_property_contexts");
|
||||
} else {
|
||||
if (!initialize_properties_from_file("/plat_property_contexts")) {
|
||||
return false;
|
||||
}
|
||||
if (!initialize_properties_from_file("/nonplat_property_contexts")) {
|
||||
return false;
|
||||
}
|
||||
initialize_properties_from_file("/nonplat_property_contexts");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Submodule native/jni/su updated: ed5dd827e9...42eab87edc
@@ -344,7 +344,7 @@ void fclone_attr(const int sourcefd, const int targetfd) {
|
||||
#define UNLABEL_CON "u:object_r:unlabeled:s0"
|
||||
#define SYSTEM_CON "u:object_r:system_file:s0"
|
||||
|
||||
void restorecon(int dirfd, int force) {
|
||||
void restorecon(int dirfd) {
|
||||
struct dirent *entry;
|
||||
DIR *dir;
|
||||
int fd;
|
||||
@@ -352,7 +352,7 @@ void restorecon(int dirfd, int force) {
|
||||
|
||||
fd_getpath(dirfd, path, sizeof(path));
|
||||
lgetfilecon(path, &con);
|
||||
if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
|
||||
if (strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
|
||||
lsetfilecon(path, SYSTEM_CON);
|
||||
freecon(con);
|
||||
|
||||
@@ -362,12 +362,12 @@ void restorecon(int dirfd, int force) {
|
||||
continue;
|
||||
if (entry->d_type == DT_DIR) {
|
||||
fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
||||
restorecon(fd, force);
|
||||
restorecon(fd);
|
||||
} else {
|
||||
fd = xopenat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC);
|
||||
fd_getpath(fd, path, sizeof(path));
|
||||
lgetfilecon(path, &con);
|
||||
if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
|
||||
if (strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
|
||||
lsetfilecon(path, SYSTEM_CON);
|
||||
freecon(con);
|
||||
}
|
||||
@@ -379,7 +379,7 @@ void restorecon(int dirfd, int force) {
|
||||
|
||||
static int _mmap(int rw, const char *filename, void **buf, size_t *size) {
|
||||
struct stat st;
|
||||
int fd = xopen(filename, rw ? O_RDWR : O_RDONLY);
|
||||
int fd = xopen(filename, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC);
|
||||
fstat(fd, &st);
|
||||
if (S_ISBLK(st.st_mode))
|
||||
ioctl(fd, BLKGETSIZE64, size);
|
||||
@@ -407,7 +407,7 @@ void fd_full_read(int fd, void **buf, size_t *size) {
|
||||
}
|
||||
|
||||
void full_read(const char *filename, void **buf, size_t *size) {
|
||||
int fd = xopen(filename, O_RDONLY);
|
||||
int fd = xopen(filename, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
*buf = NULL;
|
||||
*size = 0;
|
||||
@@ -418,7 +418,7 @@ void full_read(const char *filename, void **buf, size_t *size) {
|
||||
}
|
||||
|
||||
void full_read_at(int dirfd, const char *filename, void **buf, size_t *size) {
|
||||
int fd = xopenat(dirfd, filename, O_RDONLY);
|
||||
int fd = xopenat(dirfd, filename, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
*buf = NULL;
|
||||
*size = 0;
|
||||
|
@@ -17,7 +17,7 @@ static int e2fsck(const char *img) {
|
||||
// Check and repair ext4 image
|
||||
char buffer[128];
|
||||
int pid, fd = -1;
|
||||
pid = exec_command(1, &fd, NULL, "e2fsck", "-yf", img, NULL);
|
||||
pid = exec_command(1, &fd, NULL, "/system/bin/e2fsck", "-yf", img, NULL);
|
||||
if (pid < 0)
|
||||
return 1;
|
||||
while (fdgets(buffer, sizeof(buffer), fd))
|
||||
@@ -60,10 +60,10 @@ int create_img(const char *img, int size) {
|
||||
|
||||
char size_str[16];
|
||||
snprintf(size_str, sizeof(size_str), "%dM", size);
|
||||
ret = exec_command_sync("make_ext4fs", "-b", "4096", "-l", size_str, img, NULL);
|
||||
ret = exec_command_sync("/system/bin/make_ext4fs", "-b", "4096", "-l", size_str, img, NULL);
|
||||
if (ret < 0) {
|
||||
// On Android P there is no make_ext4fs, use mke2fs
|
||||
ret = exec_command_sync("mke2fs", "-b", "4096", "-t", "ext4", img, size_str, NULL);
|
||||
ret = exec_command_sync("/system/bin/mke2fs", "-b", "4096", "-t", "ext4", img, size_str, NULL);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -73,7 +73,7 @@ int get_img_size(const char *img, int *used, int *total) {
|
||||
return 1;
|
||||
char buffer[PATH_MAX];
|
||||
int pid, fd = -1, status = 1;
|
||||
pid = exec_command(1, &fd, NULL, "e2fsck", "-n", img, NULL);
|
||||
pid = exec_command(1, &fd, NULL, "/system/bin/e2fsck", "-n", img, NULL);
|
||||
if (pid < 0)
|
||||
return 1;
|
||||
while (fdgets(buffer, sizeof(buffer), fd)) {
|
||||
@@ -105,7 +105,7 @@ int resize_img(const char *img, int size) {
|
||||
char buffer[128];
|
||||
int pid, fd = -1, used, total;
|
||||
snprintf(buffer, sizeof(buffer), "%dM", size);
|
||||
pid = exec_command(1, &fd, NULL, "resize2fs", img, buffer, NULL);
|
||||
pid = exec_command(1, &fd, NULL, "/system/bin/resize2fs", img, buffer, NULL);
|
||||
if (pid < 0)
|
||||
return 1;
|
||||
while (fdgets(buffer, sizeof(buffer), fd))
|
||||
|
@@ -84,7 +84,7 @@ chmod -R 755 .
|
||||
CHROMEOS=false
|
||||
|
||||
ui_print "- Unpacking boot image"
|
||||
./magiskboot --unpack "$BOOTIMAGE"
|
||||
eval $LIB32PFX ./magiskboot --unpack "$BOOTIMAGE"
|
||||
|
||||
case $? in
|
||||
1 )
|
||||
@@ -113,14 +113,14 @@ esac
|
||||
# Test patch status and do restore, after this section, ramdisk.cpio.orig is guaranteed to exist
|
||||
ui_print "- Checking ramdisk status"
|
||||
MAGISK_PATCHED=false
|
||||
./magiskboot --cpio ramdisk.cpio test
|
||||
eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio test
|
||||
case $? in
|
||||
0 ) # Stock boot
|
||||
ui_print "- Stock boot image detected"
|
||||
ui_print "- Backing up stock boot image"
|
||||
SHA1=`./magiskboot --sha1 "$BOOTIMAGE" 2>/dev/null`
|
||||
SHA1=`eval $LIB32PFX ./magiskboot --sha1 "$BOOTIMAGE" 2>/dev/null`
|
||||
STOCKDUMP=stock_boot_${SHA1}.img.gz
|
||||
./magiskboot --compress "$BOOTIMAGE" $STOCKDUMP
|
||||
eval $LIB32PFX ./magiskboot --compress "$BOOTIMAGE" $STOCKDUMP
|
||||
cp -af ramdisk.cpio ramdisk.cpio.orig
|
||||
;;
|
||||
1 ) # Magisk patched
|
||||
@@ -140,8 +140,8 @@ esac
|
||||
if $MAGISK_PATCHED; then
|
||||
ui_print "- Magisk patched image detected"
|
||||
# Find SHA1 of stock boot image
|
||||
[ -z $SHA1 ] && SHA1=`./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null`
|
||||
./magiskboot --cpio ramdisk.cpio restore
|
||||
[ -z $SHA1 ] && SHA1=`eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null`
|
||||
eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio restore
|
||||
cp -af ramdisk.cpio ramdisk.cpio.orig
|
||||
fi
|
||||
|
||||
@@ -156,9 +156,9 @@ fi
|
||||
|
||||
ui_print "- Patching ramdisk"
|
||||
|
||||
./magiskboot --cpio ramdisk.cpio \
|
||||
'add 750 init magiskinit' \
|
||||
"magisk ramdisk.cpio.orig $HIGHCOMP $KEEPVERITY $KEEPFORCEENCRYPT $SHA1"
|
||||
eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio \
|
||||
\"add 750 init magiskinit\" \
|
||||
\"magisk ramdisk.cpio.orig $HIGHCOMP $KEEPVERITY $KEEPFORCEENCRYPT $SHA1\"
|
||||
|
||||
rm -f ramdisk.cpio.orig
|
||||
|
||||
@@ -167,17 +167,17 @@ rm -f ramdisk.cpio.orig
|
||||
##########################################################################################
|
||||
|
||||
if ! $KEEPVERITY && [ -f dtb ]; then
|
||||
./magiskboot --dtb-patch dtb && ui_print "- Patching fstab in dtb to remove dm-verity"
|
||||
eval $LIB32PFX ./magiskboot --dtb-patch dtb && ui_print "- Patching fstab in dtb to remove dm-verity"
|
||||
fi
|
||||
|
||||
if [ -f kernel ]; then
|
||||
# Remove Samsung RKP in stock kernel
|
||||
./magiskboot --hexpatch kernel \
|
||||
eval $LIB32PFX ./magiskboot --hexpatch kernel \
|
||||
49010054011440B93FA00F71E9000054010840B93FA00F7189000054001840B91FA00F7188010054 \
|
||||
A1020054011440B93FA00F7140020054010840B93FA00F71E0010054001840B91FA00F7181010054
|
||||
|
||||
# skip_initramfs -> want_initramfs
|
||||
./magiskboot --hexpatch kernel \
|
||||
eval $LIB32PFX ./magiskboot --hexpatch kernel \
|
||||
736B69705F696E697472616D6673 \
|
||||
77616E745F696E697472616D6673
|
||||
fi
|
||||
@@ -187,9 +187,9 @@ fi
|
||||
##########################################################################################
|
||||
|
||||
ui_print "- Repacking boot image"
|
||||
./magiskboot --repack "$BOOTIMAGE" || abort "! Unable to repack boot image!"
|
||||
eval $LIB32PFX ./magiskboot --repack "$BOOTIMAGE" || abort "! Unable to repack boot image!"
|
||||
|
||||
# Sign chromeos boot
|
||||
$CHROMEOS && sign_chromeos
|
||||
|
||||
./magiskboot --cleanup
|
||||
eval $LIB32PFX ./magiskboot --cleanup
|
||||
|
@@ -69,7 +69,7 @@ api_level_arch_detect
|
||||
|
||||
ui_print "- Device platform: $ARCH"
|
||||
|
||||
BINDIR=$INSTALLER/$ARCH
|
||||
BINDIR=$INSTALLER/$ARCH32
|
||||
chmod -R 755 $CHROMEDIR $BINDIR
|
||||
|
||||
# Check if system root is installed and remove
|
||||
@@ -105,7 +105,7 @@ chmod -R 755 $MAGISKBIN
|
||||
if [ -d /system/addon.d ]; then
|
||||
ui_print "- Adding addon.d survival script"
|
||||
mount -o rw,remount /system
|
||||
cp -af $INSTALLER/addon.d/99-magisk.sh /system/addon.d/99-magisk.sh
|
||||
cp -af $INSTALLER/common/99-magisk.sh /system/addon.d/99-magisk.sh
|
||||
chmod 755 /system/addon.d/99-magisk.sh
|
||||
fi
|
||||
|
||||
|
@@ -45,7 +45,7 @@ cd $MAGISKBIN
|
||||
ui_print "- Found Boot Image: $BOOTIMAGE"
|
||||
|
||||
ui_print "- Unpacking boot image"
|
||||
./magiskboot --unpack "$BOOTIMAGE"
|
||||
eval $LIB32PFX ./magiskboot --unpack "$BOOTIMAGE"
|
||||
CHROMEOS=false
|
||||
|
||||
case $? in
|
||||
@@ -67,7 +67,7 @@ esac
|
||||
|
||||
# Detect boot image state
|
||||
ui_print "- Checking ramdisk status"
|
||||
./magiskboot --cpio ramdisk.cpio test
|
||||
eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio test
|
||||
case $? in
|
||||
0 ) # Stock boot
|
||||
ui_print "- Stock boot image detected"
|
||||
@@ -76,14 +76,14 @@ case $? in
|
||||
1|2 ) # Magisk patched
|
||||
ui_print "- Magisk patched image detected"
|
||||
# Find SHA1 of stock boot image
|
||||
[ -z $SHA1 ] && SHA1=`./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null`
|
||||
[ -z $SHA1 ] && SHA1=`eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null`
|
||||
OK=false
|
||||
[ ! -z $SHA1 ] && restore_imgs $SHA1 && OK=true
|
||||
if ! $OK; then
|
||||
ui_print "! Boot image backup unavailable"
|
||||
ui_print "- Restoring ramdisk with internal backup"
|
||||
./magiskboot --cpio ramdisk.cpio restore
|
||||
./magiskboot --repack $BOOTIMAGE
|
||||
eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio restore
|
||||
eval $LIB32PFX ./magiskboot --repack $BOOTIMAGE
|
||||
# Sign chromeos boot
|
||||
$CHROMEOS && sign_chromeos
|
||||
flash_boot_image new-boot.img "$BOOTIMAGE"
|
||||
|
@@ -20,7 +20,7 @@ MAGISKBIN=/data/adb/magisk
|
||||
[ -z $MOUNTPATH ] && MOUNTPATH=/sbin/.core/img
|
||||
[ -z $IMG ] && IMG=/data/adb/magisk.img
|
||||
|
||||
BOOTSIGNER="/system/bin/dalvikvm -Xnodex2oat -Xnoimage-dex2oat -cp \$APK com.topjohnwu.magisk.utils.BootSigner"
|
||||
BOOTSIGNER="eval \$LIBPFX /system/bin/dalvikvm -Xnodex2oat -Xnoimage-dex2oat -cp \$APK com.topjohnwu.magisk.utils.BootSigner"
|
||||
BOOTSIGNED=false
|
||||
|
||||
get_outfd() {
|
||||
@@ -128,15 +128,15 @@ find_boot_image() {
|
||||
run_migrations() {
|
||||
# Update the broken boot backup
|
||||
if [ -f /data/stock_boot_.img.gz ]; then
|
||||
$MAGISKBIN/magiskboot --decompress /data/stock_boot_.img.gz /data/stock_boot.img
|
||||
eval $LIB32PFX $MAGISKBIN/magiskboot --decompress /data/stock_boot_.img.gz /data/stock_boot.img
|
||||
fi
|
||||
# Update our previous backup to new format if exists
|
||||
if [ -f /data/stock_boot.img ]; then
|
||||
ui_print "- Migrating boot image backup"
|
||||
SHA1=`$MAGISKBIN/magiskboot --sha1 /data/stock_boot.img 2>/dev/null`
|
||||
SHA1=`eval $LIB32PFX $MAGISKBIN/magiskboot --sha1 /data/stock_boot.img 2>/dev/null`
|
||||
STOCKDUMP=/data/stock_boot_${SHA1}.img
|
||||
mv /data/stock_boot.img $STOCKDUMP
|
||||
$MAGISKBIN/magiskboot --compress $STOCKDUMP
|
||||
eval $LIB32PFX $MAGISKBIN/magiskboot --compress $STOCKDUMP
|
||||
fi
|
||||
# Move the stock backups
|
||||
if [ -f /data/magisk/stock_boot* ]; then
|
||||
@@ -154,7 +154,7 @@ run_migrations() {
|
||||
|
||||
flash_boot_image() {
|
||||
# Make sure all blocks are writable
|
||||
$MAGISKBIN/magisk --unlock-blocks 2>/dev/null
|
||||
eval $LIB32PFX $MAGISKBIN/magisk --unlock-blocks 2>/dev/null
|
||||
case "$1" in
|
||||
*.gz) COMMAND="gzip -d < '$1'";;
|
||||
*) COMMAND="cat '$1'";;
|
||||
@@ -184,11 +184,11 @@ find_dtbo_image() {
|
||||
|
||||
patch_dtbo_image() {
|
||||
if [ ! -z $DTBOIMAGE ]; then
|
||||
if $MAGISKBIN/magiskboot --dtb-test $DTBOIMAGE; then
|
||||
if eval $LIB32PFX $MAGISKBIN/magiskboot --dtb-test $DTBOIMAGE; then
|
||||
ui_print "- Backing up stock dtbo image"
|
||||
$MAGISKBIN/magiskboot --compress $DTBOIMAGE $MAGISKBIN/stock_dtbo.img.gz
|
||||
eval $LIB32PFX $MAGISKBIN/magiskboot --compress $DTBOIMAGE $MAGISKBIN/stock_dtbo.img.gz
|
||||
ui_print "- Patching fstab in dtbo to remove avb-verity"
|
||||
$MAGISKBIN/magiskboot --dtb-patch $DTBOIMAGE
|
||||
eval $LIB32PFX $MAGISKBIN/magiskboot --dtb-patch $DTBOIMAGE
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
@@ -200,7 +200,7 @@ restore_imgs() {
|
||||
STOCKDTBO=/data/stock_dtbo.img.gz
|
||||
|
||||
# Make sure all blocks are writable
|
||||
$MAGISKBIN/magisk --unlock-blocks 2>/dev/null
|
||||
eval $LIB32PFX $MAGISKBIN/magisk --unlock-blocks 2>/dev/null
|
||||
find_dtbo_image
|
||||
if [ ! -z "$DTBOIMAGE" -a -f "$STOCKDTBO" ]; then
|
||||
ui_print "- Restoring stock dtbo image"
|
||||
@@ -220,7 +220,7 @@ sign_chromeos() {
|
||||
ui_print "- Signing ChromeOS boot image"
|
||||
|
||||
echo > empty
|
||||
./chromeos/futility vbutil_kernel --pack new-boot.img.signed \
|
||||
eval $LIBPFX ./chromeos/futility vbutil_kernel --pack new-boot.img.signed \
|
||||
--keyblock ./chromeos/kernel.keyblock --signprivate ./chromeos/kernel_data_key.vbprivk \
|
||||
--version 1 --vmlinuz new-boot.img --config empty --arch arm --bootloader empty --flags 0x1
|
||||
|
||||
@@ -266,11 +266,12 @@ api_level_arch_detect() {
|
||||
ABILONG=`grep_prop ro.product.cpu.abi`
|
||||
|
||||
ARCH=arm
|
||||
ARCH32=arm
|
||||
IS64BIT=false
|
||||
if [ "$ABI" = "x86" ]; then ARCH=x86; fi;
|
||||
if [ "$ABI2" = "x86" ]; then ARCH=x86; fi;
|
||||
if [ "$ABILONG" = "arm64-v8a" ]; then ARCH=arm64; IS64BIT=true; fi;
|
||||
if [ "$ABILONG" = "x86_64" ]; then ARCH=x64; IS64BIT=true; fi;
|
||||
if [ "$ABI" = "x86" ]; then ARCH=x86; ARCH32=x86; fi;
|
||||
if [ "$ABI2" = "x86" ]; then ARCH=x86; ARCH32=x86; fi;
|
||||
if [ "$ABILONG" = "arm64-v8a" ]; then ARCH=arm64; ARCH32=arm; IS64BIT=true; fi;
|
||||
if [ "$ABILONG" = "x86_64" ]; then ARCH=x64; ARCH32=x86; IS64BIT=true; fi;
|
||||
}
|
||||
|
||||
boot_actions() {
|
||||
@@ -286,7 +287,6 @@ recovery_actions() {
|
||||
mount -o bind /dev/urandom /dev/random
|
||||
# Preserve environment varibles
|
||||
OLD_PATH=$PATH
|
||||
OLD_LD_PATH=$LD_LIBRARY_PATH
|
||||
if [ ! -d $TMPDIR/bin ]; then
|
||||
# Add busybox to PATH
|
||||
mkdir -p $TMPDIR/bin
|
||||
@@ -296,13 +296,13 @@ recovery_actions() {
|
||||
fi
|
||||
# Temporarily block out all custom recovery binaries/libs
|
||||
mv /sbin /sbin_tmp
|
||||
# Add all possible library paths
|
||||
$IS64BIT && export LD_LIBRARY_PATH=/system/lib64:/system/vendor/lib64 || export LD_LIBRARY_PATH=/system/lib:/system/vendor/lib
|
||||
# Set library paths
|
||||
$IS64BIT && LIBPFX="LD_LIBRARY_PATH=/system/lib64:/system/vendor/lib64" || LIBPFX="LD_LIBRARY_PATH=/system/lib:/system/vendor/lib"
|
||||
LIB32PFX="LD_LIBRARY_PATH=/system/lib:/system/vendor/lib"
|
||||
}
|
||||
|
||||
recovery_cleanup() {
|
||||
mv /sbin_tmp /sbin 2>/dev/null
|
||||
export LD_LIBRARY_PATH=$OLD_LD_PATH
|
||||
[ -z $OLD_PATH ] || export PATH=$OLD_PATH
|
||||
ui_print "- Unmounting partitions"
|
||||
umount -l /system_root 2>/dev/null
|
||||
@@ -348,7 +348,7 @@ request_zip_size_check() {
|
||||
}
|
||||
|
||||
image_size_check() {
|
||||
SIZE="`$MAGISKBIN/magisk --imgsize $IMG`"
|
||||
SIZE="`eval $LIB32PFX $MAGISKBIN/magisk --imgsize $IMG`"
|
||||
curUsedM=`echo "$SIZE" | cut -d" " -f1`
|
||||
curSizeM=`echo "$SIZE" | cut -d" " -f2`
|
||||
curFreeM=$((curSizeM - curUsedM))
|
||||
@@ -362,28 +362,28 @@ mount_magisk_img() {
|
||||
if [ "$reqSizeM" -gt "$curFreeM" ]; then
|
||||
newSizeM=$(((reqSizeM + curUsedM) / 32 * 32 + 64))
|
||||
ui_print "- Resizing $IMG to ${newSizeM}M"
|
||||
$MAGISKBIN/magisk --resizeimg $IMG $newSizeM >&2
|
||||
eval $LIB32PFX $MAGISKBIN/magisk --resizeimg $IMG $newSizeM >&2
|
||||
fi
|
||||
else
|
||||
newSizeM=$((reqSizeM / 32 * 32 + 64));
|
||||
ui_print "- Creating $IMG with size ${newSizeM}M"
|
||||
$MAGISKBIN/magisk --createimg $IMG $newSizeM >&2
|
||||
eval $LIB32PFX $MAGISKBIN/magisk --createimg $IMG $newSizeM >&2
|
||||
fi
|
||||
|
||||
ui_print "- Mounting $IMG to $MOUNTPATH"
|
||||
MAGISKLOOP=`$MAGISKBIN/magisk --mountimg $IMG $MOUNTPATH`
|
||||
MAGISKLOOP=`eval $LIB32PFX $MAGISKBIN/magisk --mountimg $IMG $MOUNTPATH`
|
||||
is_mounted $MOUNTPATH || abort "! $IMG mount failed..."
|
||||
}
|
||||
|
||||
unmount_magisk_img() {
|
||||
$MAGISKBIN/magisk --umountimg $MOUNTPATH $MAGISKLOOP
|
||||
eval $LIB32PFX $MAGISKBIN/magisk --umountimg $MOUNTPATH $MAGISKLOOP
|
||||
|
||||
# Shrink the image if possible
|
||||
image_size_check $IMG
|
||||
newSizeM=$((curUsedM / 32 * 32 + 64))
|
||||
if [ $curSizeM -gt $newSizeM ]; then
|
||||
ui_print "- Shrinking $IMG to ${newSizeM}M"
|
||||
$MAGISKBIN/magisk --resizeimg $IMG $newSizeM
|
||||
eval $LIB32PFX $MAGISKBIN/magisk --resizeimg $IMG $newSizeM
|
||||
fi
|
||||
}
|
||||
|
||||
|
@@ -1,13 +1,13 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
buildToolsVersion "27.0.3"
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.topjohnwu.snet"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 27
|
||||
targetSdkVersion rootProject.ext.compileSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
@@ -20,10 +20,6 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'com.google.android.gms:play-services-safetynet:7.0.0' /* The oldest version */
|
||||
|
Reference in New Issue
Block a user