mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-08-14 16:17:27 +00:00
Compare commits
25 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 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -25,3 +25,6 @@
|
|||||||
[submodule "xz"]
|
[submodule "xz"]
|
||||||
path = native/jni/external/xz
|
path = native/jni/external/xz
|
||||||
url = https://github.com/xz-mirror/xz.git
|
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: 0c782edf21...15ed3e52f2
@@ -7,7 +7,7 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
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
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
@@ -19,9 +19,16 @@ allprojects {
|
|||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
|
maven { url "https://jitpack.io" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ext {
|
||||||
|
compileSdkVersion = 27
|
||||||
|
buildToolsVersion = "28.0.0-rc1"
|
||||||
|
supportLibVersion = "27.1.1"
|
||||||
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
10
build.py
10
build.py
@@ -93,7 +93,7 @@ def build_binary(args):
|
|||||||
error('Build Magisk binary failed!')
|
error('Build Magisk binary failed!')
|
||||||
|
|
||||||
print('')
|
print('')
|
||||||
for arch in ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']:
|
for arch in ['armeabi-v7a', 'x86']:
|
||||||
mkdir_p(os.path.join('out', arch))
|
mkdir_p(os.path.join('out', arch))
|
||||||
with open(os.path.join('out', arch, 'dump.h'), 'w') as dump:
|
with open(os.path.join('out', arch, 'dump.h'), 'w') as dump:
|
||||||
dump.write('#include "stdlib.h"\n')
|
dump.write('#include "stdlib.h"\n')
|
||||||
@@ -110,7 +110,7 @@ def build_binary(args):
|
|||||||
error('Build Magisk binary failed!')
|
error('Build Magisk binary failed!')
|
||||||
|
|
||||||
print('')
|
print('')
|
||||||
for arch in ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']:
|
for arch in ['armeabi-v7a', 'x86']:
|
||||||
for binary in ['magiskinit', 'magiskboot', 'b64xz', 'busybox']:
|
for binary in ['magiskinit', 'magiskboot', 'b64xz', 'busybox']:
|
||||||
try:
|
try:
|
||||||
mv(os.path.join('native', 'libs', arch, binary), os.path.join('out', arch, binary))
|
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)
|
zip_with_msg(zipf, source, target)
|
||||||
|
|
||||||
# Binaries
|
# 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']:
|
for binary in ['magiskinit', 'magiskboot']:
|
||||||
source = os.path.join('out', lib_dir, binary)
|
source = os.path.join('out', lib_dir, binary)
|
||||||
target = os.path.join(zip_dir, binary)
|
target = os.path.join(zip_dir, binary)
|
||||||
@@ -261,7 +261,7 @@ def zip_main(args):
|
|||||||
zipf.writestr(target, util_func)
|
zipf.writestr(target, util_func)
|
||||||
# addon.d.sh
|
# addon.d.sh
|
||||||
source = os.path.join('scripts', '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)
|
zip_with_msg(zipf, source, target)
|
||||||
|
|
||||||
# Prebuilts
|
# Prebuilts
|
||||||
@@ -291,7 +291,7 @@ def zip_uninstaller(args):
|
|||||||
zip_with_msg(zipf, source, target)
|
zip_with_msg(zipf, source, target)
|
||||||
|
|
||||||
# Binaries
|
# 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')
|
source = os.path.join('out', lib_dir, 'magiskboot')
|
||||||
target = os.path.join(zip_dir, 'magiskboot')
|
target = os.path.join(zip_dir, 'magiskboot')
|
||||||
zip_with_msg(zipf, source, target)
|
zip_with_msg(zipf, source, target)
|
||||||
|
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
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
|
|
||||||
|
68
gradlew
vendored
68
gradlew
vendored
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
##
|
||||||
@@ -6,12 +6,30 @@
|
|||||||
##
|
##
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Attempt to set APP_HOME
|
||||||
DEFAULT_JVM_OPTS=""
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
APP_NAME="Gradle"
|
||||||
APP_BASE_NAME=`basename "$0"`
|
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.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD="maximum"
|
||||||
|
|
||||||
@@ -30,6 +48,7 @@ die ( ) {
|
|||||||
cygwin=false
|
cygwin=false
|
||||||
msys=false
|
msys=false
|
||||||
darwin=false
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
case "`uname`" in
|
case "`uname`" in
|
||||||
CYGWIN* )
|
CYGWIN* )
|
||||||
cygwin=true
|
cygwin=true
|
||||||
@@ -40,26 +59,11 @@ case "`uname`" in
|
|||||||
MINGW* )
|
MINGW* )
|
||||||
msys=true
|
msys=true
|
||||||
;;
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
|
||||||
# Resolve links: $0 may be a link
|
|
||||||
PRG="$0"
|
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
|
||||||
ls=`ls -ld "$PRG"`
|
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
|
||||||
PRG="$link"
|
|
||||||
else
|
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java command to use to start the JVM.
|
||||||
@@ -85,7 +89,7 @@ location of your Java installation."
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# 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`
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
if [ $? -eq 0 ] ; then
|
if [ $? -eq 0 ] ; then
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
@@ -150,11 +154,19 @@ if $cygwin ; then
|
|||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
# Escape application args
|
||||||
function splitJvmOpts() {
|
save () {
|
||||||
JVM_OPTS=("$@")
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
}
|
}
|
||||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
APP_ARGS=$(save "$@")
|
||||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
|
||||||
|
|
||||||
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
|
@rem Set local scope for the variables with windows NT shell
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
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
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
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
|
@rem Find java.exe
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
@@ -46,10 +46,9 @@ echo location of your Java installation.
|
|||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
:init
|
: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 not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
|
||||||
|
|
||||||
:win9xME_args
|
:win9xME_args
|
||||||
@rem Slurp the command line arguments.
|
@rem Slurp the command line arguments.
|
||||||
@@ -60,11 +59,6 @@ set _SKIP=2
|
|||||||
if "x%~1" == "x" goto execute
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
set CMD_LINE_ARGS=%*
|
set CMD_LINE_ARGS=%*
|
||||||
goto execute
|
|
||||||
|
|
||||||
:4NT_args
|
|
||||||
@rem Get arguments from the 4NT Shell from JP Software
|
|
||||||
set CMD_LINE_ARGS=%$
|
|
||||||
|
|
||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the command line
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 27
|
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||||
|
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||||
|
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
ndkBuild {
|
ndkBuild {
|
||||||
|
@@ -9,6 +9,7 @@ LIBLZMA := $(EXT_PATH)/xz/src/liblzma/api
|
|||||||
LIBLZ4 := $(EXT_PATH)/lz4/lib
|
LIBLZ4 := $(EXT_PATH)/lz4/lib
|
||||||
LIBBZ2 := $(EXT_PATH)/bzip2
|
LIBBZ2 := $(EXT_PATH)/bzip2
|
||||||
LIBFDT := $(EXT_PATH)/dtc/libfdt
|
LIBFDT := $(EXT_PATH)/dtc/libfdt
|
||||||
|
LIBNANOPB := $(EXT_PATH)/nanopb
|
||||||
UTIL_SRC := utils/cpio.c \
|
UTIL_SRC := utils/cpio.c \
|
||||||
utils/file.c \
|
utils/file.c \
|
||||||
utils/img.c \
|
utils/img.c \
|
||||||
@@ -28,11 +29,13 @@ ifneq "$(or $(PRECOMPILE), $(GRADLE))" ""
|
|||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := magisk
|
LOCAL_MODULE := magisk
|
||||||
LOCAL_SHARED_LIBRARIES := libsqlite libselinux
|
LOCAL_SHARED_LIBRARIES := libsqlite libselinux
|
||||||
|
LOCAL_STATIC_LIBRARIES := libnanopb
|
||||||
LOCAL_C_INCLUDES := \
|
LOCAL_C_INCLUDES := \
|
||||||
jni/include \
|
jni/include \
|
||||||
|
jni/magiskpolicy \
|
||||||
$(EXT_PATH)/include \
|
$(EXT_PATH)/include \
|
||||||
$(LIBSELINUX)
|
$(LIBSELINUX) \
|
||||||
|
$(LIBNANOPB)
|
||||||
|
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
core/magisk.c \
|
core/magisk.c \
|
||||||
@@ -43,7 +46,8 @@ LOCAL_SRC_FILES := \
|
|||||||
magiskhide/magiskhide.c \
|
magiskhide/magiskhide.c \
|
||||||
magiskhide/proc_monitor.c \
|
magiskhide/proc_monitor.c \
|
||||||
magiskhide/hide_utils.c \
|
magiskhide/hide_utils.c \
|
||||||
resetprop/resetprop.cpp \
|
resetprop/persist_props.c \
|
||||||
|
resetprop/resetprop.c \
|
||||||
resetprop/system_properties.cpp \
|
resetprop/system_properties.cpp \
|
||||||
su/su.c \
|
su/su.c \
|
||||||
su/activity.c \
|
su/activity.c \
|
||||||
@@ -74,7 +78,6 @@ LOCAL_C_INCLUDES := \
|
|||||||
|
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
core/magiskinit.c \
|
core/magiskinit.c \
|
||||||
core/socket.c \
|
|
||||||
magiskpolicy/api.c \
|
magiskpolicy/api.c \
|
||||||
magiskpolicy/magiskpolicy.c \
|
magiskpolicy/magiskpolicy.c \
|
||||||
magiskpolicy/rules.c \
|
magiskpolicy/rules.c \
|
||||||
@@ -110,10 +113,8 @@ LOCAL_CFLAGS := -DXWRAP_EXIT
|
|||||||
LOCAL_LDLIBS := -lz
|
LOCAL_LDLIBS := -lz
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
# 32-bit static binaries
|
# static binaries
|
||||||
ifndef GRADLE # Do not run gradle sync on these binaries
|
ifndef GRADLE # Do not run gradle sync on these binaries
|
||||||
ifneq ($(TARGET_ARCH_ABI), x86_64)
|
|
||||||
ifneq ($(TARGET_ARCH_ABI), arm64-v8a)
|
|
||||||
# b64xz
|
# b64xz
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := b64xz
|
LOCAL_MODULE := b64xz
|
||||||
@@ -125,8 +126,6 @@ include $(BUILD_EXECUTABLE)
|
|||||||
# Busybox
|
# Busybox
|
||||||
include jni/external/busybox/Android.mk
|
include jni/external/busybox/Android.mk
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Precompile
|
# Precompile
|
||||||
endif
|
endif
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
APP_ABI := x86 x86_64 armeabi-v7a arm64-v8a
|
APP_ABI := x86 armeabi-v7a
|
||||||
APP_PLATFORM := android-21
|
APP_PLATFORM := android-21
|
||||||
APP_CFLAGS := $(MAGISK_FLAGS) -std=gnu99
|
APP_CFLAGS := $(MAGISK_FLAGS) -std=gnu99
|
||||||
APP_CPPFLAGS := -std=c++11
|
APP_CPPFLAGS := -std=c++11
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
#include "resetprop.h"
|
#include "resetprop.h"
|
||||||
|
#include "magiskpolicy.h"
|
||||||
|
|
||||||
static char *buf, *buf2;
|
static char *buf, *buf2;
|
||||||
static struct vector module_list;
|
static struct vector module_list;
|
||||||
@@ -124,15 +125,6 @@ static void bb_setenv(struct vector *v) {
|
|||||||
vec_push_back(v, NULL);
|
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 *
|
* Scripts *
|
||||||
***********/
|
***********/
|
||||||
@@ -359,7 +351,7 @@ static void simple_mount(const char *path) {
|
|||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
|
|
||||||
snprintf(buf, PATH_MAX, "%s%s", CACHEMOUNT, path);
|
snprintf(buf, PATH_MAX, "%s%s", SIMPLEMOUNT, path);
|
||||||
if (!(dir = opendir(buf)))
|
if (!(dir = opendir(buf)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -377,7 +369,7 @@ static void simple_mount(const char *path) {
|
|||||||
free(new_path);
|
free(new_path);
|
||||||
} else if (entry->d_type == DT_REG) {
|
} else if (entry->d_type == DT_REG) {
|
||||||
// Actual file path
|
// Actual file path
|
||||||
snprintf(buf, PATH_MAX, "%s%s", CACHEMOUNT, buf2);
|
snprintf(buf, PATH_MAX, "%s%s", SIMPLEMOUNT, buf2);
|
||||||
// Clone all attributes
|
// Clone all attributes
|
||||||
clone_attr(buf2, buf);
|
clone_attr(buf2, buf);
|
||||||
// Finally, mount the file
|
// Finally, mount the file
|
||||||
@@ -460,7 +452,7 @@ static int prepare_img() {
|
|||||||
|
|
||||||
void fix_filecon() {
|
void fix_filecon() {
|
||||||
int dirfd = xopen(MOUNTPOINT, O_RDONLY | O_CLOEXEC);
|
int dirfd = xopen(MOUNTPOINT, O_RDONLY | O_CLOEXEC);
|
||||||
restorecon(dirfd, 0);
|
restorecon(dirfd);
|
||||||
close(dirfd);
|
close(dirfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,15 +465,13 @@ static void unblock_boot_process() {
|
|||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void post_fs(int client) {
|
void startup() {
|
||||||
LOGI("** post-fs mode running\n");
|
if (!check_data())
|
||||||
// ack
|
return;
|
||||||
write_int(client, 0);
|
|
||||||
close(client);
|
|
||||||
|
|
||||||
// Uninstall or core only mode
|
// uninstaller or core-only mode
|
||||||
if (access(UNINSTALLER, F_OK) == 0 || access(DISABLEFILE, F_OK) == 0)
|
if (access(UNINSTALLER, F_OK) == 0 || access(DISABLEFILE, F_OK) == 0)
|
||||||
goto unblock;
|
goto initialize;
|
||||||
|
|
||||||
// Allocate buffer
|
// Allocate buffer
|
||||||
buf = xmalloc(PATH_MAX);
|
buf = xmalloc(PATH_MAX);
|
||||||
@@ -490,32 +480,152 @@ void post_fs(int client) {
|
|||||||
simple_mount("/system");
|
simple_mount("/system");
|
||||||
simple_mount("/vendor");
|
simple_mount("/vendor");
|
||||||
|
|
||||||
unblock:
|
initialize:
|
||||||
unblock_boot_process();
|
LOGI("** Initializing Magisk\n");
|
||||||
|
|
||||||
|
// Unlock all blocks for rw
|
||||||
|
unlock_blocks();
|
||||||
|
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void post_fs_data(int client) {
|
// Migration
|
||||||
// ack
|
rm_rf("/data/magisk");
|
||||||
write_int(client, 0);
|
unlink("/data/magisk.img");
|
||||||
close(client);
|
unlink("/data/magisk_debug.log");
|
||||||
if (!is_daemon_init && !check_data())
|
xmkdir("/data/adb", 0700);
|
||||||
goto unblock;
|
chmod("/data/adb", 0700);
|
||||||
|
|
||||||
// Start the debug log
|
LOGI("* Creating /sbin overlay");
|
||||||
start_debug_full_log();
|
DIR *dir;
|
||||||
|
struct dirent *entry;
|
||||||
|
int root, sbin, fd;
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
void *magisk, *init;
|
||||||
|
size_t magisk_size, init_size;
|
||||||
|
|
||||||
LOGI("** post-fs-data mode running\n");
|
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
|
||||||
|
|
||||||
// Allocate buffer
|
// Remove some traits of Magisk
|
||||||
if (buf == NULL) buf = xmalloc(PATH_MAX);
|
unlink("/init.magisk.rc");
|
||||||
if (buf2 == NULL) buf2 = xmalloc(PATH_MAX);
|
|
||||||
vec_init(&module_list);
|
|
||||||
|
|
||||||
// Initialize
|
// Create hardlink mirror of /sbin to /root
|
||||||
if (!is_daemon_init)
|
mkdir("/root", 0750);
|
||||||
daemon_init();
|
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);
|
||||||
|
|
||||||
// uninstaller
|
// 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) {
|
if (access(UNINSTALLER, F_OK) == 0) {
|
||||||
close(open(UNBLOCKFILE, O_RDONLY | O_CREAT));
|
close(open(UNBLOCKFILE, O_RDONLY | O_CREAT));
|
||||||
setenv("BOOTMODE", "true", 1);
|
setenv("BOOTMODE", "true", 1);
|
||||||
@@ -523,6 +633,28 @@ void post_fs_data(int client) {
|
|||||||
return;
|
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
|
// Merge, trim, mount magisk.img, which will also travel through the modules
|
||||||
// After this, it will create the module list
|
// After this, it will create the module list
|
||||||
if (prepare_img())
|
if (prepare_img())
|
||||||
@@ -614,8 +746,6 @@ core_only:
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto_start_magiskhide();
|
auto_start_magiskhide();
|
||||||
|
|
||||||
unblock:
|
|
||||||
unblock_boot_process();
|
unblock_boot_process();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,8 +760,7 @@ void late_start(int client) {
|
|||||||
if (buf2 == NULL) buf2 = xmalloc(PATH_MAX);
|
if (buf2 == NULL) buf2 = xmalloc(PATH_MAX);
|
||||||
|
|
||||||
// Wait till the full patch is done
|
// Wait till the full patch is done
|
||||||
wait_till_exists(PATCHDONE);
|
waitpid(full_patch_pid, NULL, 0);
|
||||||
unlink(PATCHDONE);
|
|
||||||
|
|
||||||
// Run scripts after full patch, most reliable way to run scripts
|
// Run scripts after full patch, most reliable way to run scripts
|
||||||
LOGI("* Running service.d scripts\n");
|
LOGI("* Running service.d scripts\n");
|
||||||
@@ -648,14 +777,13 @@ core_only:
|
|||||||
// Install Magisk Manager if exists
|
// Install Magisk Manager if exists
|
||||||
if (access(MANAGERAPK, F_OK) == 0) {
|
if (access(MANAGERAPK, F_OK) == 0) {
|
||||||
rename(MANAGERAPK, "/data/magisk.apk");
|
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) {
|
while (1) {
|
||||||
sleep(5);
|
sleep(5);
|
||||||
|
LOGD("apk_install: attempting to install APK");
|
||||||
int apk_res = -1, pid;
|
int apk_res = -1, pid;
|
||||||
pid = exec_command(1, &apk_res, pm_setenv,
|
pid = exec_command(1, &apk_res, NULL,
|
||||||
"app_process",
|
"/system/bin/pm", "install", "-r", "/data/magisk.apk", NULL);
|
||||||
"/system/bin", "com.android.commands.pm.Pm",
|
|
||||||
"install", "-r", "/data/magisk.apk", NULL);
|
|
||||||
if (pid != -1) {
|
if (pid != -1) {
|
||||||
int err = 0;
|
int err = 0;
|
||||||
while (fdgets(buf, PATH_MAX, apk_res) > 0) {
|
while (fdgets(buf, PATH_MAX, apk_res) > 0) {
|
||||||
|
@@ -19,8 +19,10 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
#include "resetprop.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) {
|
static void *request_handler(void *args) {
|
||||||
int client = *((int *) args);
|
int client = *((int *) args);
|
||||||
@@ -36,7 +38,6 @@ static void *request_handler(void *args) {
|
|||||||
case ADD_HIDELIST:
|
case ADD_HIDELIST:
|
||||||
case RM_HIDELIST:
|
case RM_HIDELIST:
|
||||||
case LS_HIDELIST:
|
case LS_HIDELIST:
|
||||||
case POST_FS:
|
|
||||||
case POST_FS_DATA:
|
case POST_FS_DATA:
|
||||||
case LATE_START:
|
case LATE_START:
|
||||||
if (credential.uid != 0) {
|
if (credential.uid != 0) {
|
||||||
@@ -75,9 +76,6 @@ static void *request_handler(void *args) {
|
|||||||
write_int(client, MAGISK_VER_CODE);
|
write_int(client, MAGISK_VER_CODE);
|
||||||
close(client);
|
close(client);
|
||||||
break;
|
break;
|
||||||
case POST_FS:
|
|
||||||
post_fs(client);
|
|
||||||
break;
|
|
||||||
case POST_FS_DATA:
|
case POST_FS_DATA:
|
||||||
post_fs_data(client);
|
post_fs_data(client);
|
||||||
break;
|
break;
|
||||||
@@ -96,6 +94,30 @@ static void *start_magisk_hide(void *args) {
|
|||||||
return NULL;
|
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() {
|
void auto_start_magiskhide() {
|
||||||
char *hide_prop = getprop2(MAGISKHIDE_PROP, 1);
|
char *hide_prop = getprop2(MAGISKHIDE_PROP, 1);
|
||||||
if (hide_prop == NULL || strcmp(hide_prop, "0") != 0) {
|
if (hide_prop == NULL || strcmp(hide_prop, "0") != 0) {
|
||||||
@@ -106,151 +128,18 @@ void auto_start_magiskhide() {
|
|||||||
free(hide_prop);
|
free(hide_prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void daemon_init() {
|
void start_daemon(int post_fs_data) {
|
||||||
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() {
|
|
||||||
setsid();
|
setsid();
|
||||||
setcon("u:r:su:s0");
|
setcon("u:r:"SEPOL_PROC_DOMAIN":s0");
|
||||||
umask(0);
|
|
||||||
int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC);
|
int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
xdup2(fd, STDIN_FILENO);
|
xdup2(fd, STDIN_FILENO);
|
||||||
xdup2(fd, STDOUT_FILENO);
|
xdup2(fd, STDOUT_FILENO);
|
||||||
xdup2(fd, STDERR_FILENO);
|
xdup2(fd, STDERR_FILENO);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
if (post_fs_data && fork_dont_care() == 0)
|
||||||
|
daemon_saver();
|
||||||
|
|
||||||
// Block user signals
|
// Block user signals
|
||||||
sigset_t block_set;
|
sigset_t block_set;
|
||||||
sigemptyset(&block_set);
|
sigemptyset(&block_set);
|
||||||
@@ -268,22 +157,17 @@ void start_daemon() {
|
|||||||
// Start the log monitor
|
// Start the log monitor
|
||||||
monitor_logs();
|
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
|
// Restart stuffs if the daemon is restarted
|
||||||
exec_command_sync("logcat", "-b", "all", "-c", NULL);
|
exec_command_sync("logcat", "-b", "all", "-c", NULL);
|
||||||
auto_start_magiskhide();
|
auto_start_magiskhide();
|
||||||
start_debug_log();
|
start_debug_log();
|
||||||
} else if (check_data()) {
|
|
||||||
daemon_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") daemon started\n");
|
LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") daemon started\n");
|
||||||
|
|
||||||
// Change process name
|
// Change process name
|
||||||
strcpy(argv0, "magisk_daemon");
|
strcpy(argv0, "magiskd");
|
||||||
|
|
||||||
// Unlock all blocks for rw
|
|
||||||
unlock_blocks();
|
|
||||||
|
|
||||||
// Loop forever to listen for requests
|
// Loop forever to listen for requests
|
||||||
while(1) {
|
while(1) {
|
||||||
@@ -297,7 +181,7 @@ void start_daemon() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Connect the daemon, and return a socketfd */
|
/* Connect the daemon, and return a socketfd */
|
||||||
int connect_daemon() {
|
int connect_daemon(int post_fs_data) {
|
||||||
struct sockaddr_un sun;
|
struct sockaddr_un sun;
|
||||||
int fd = setup_socket(&sun);
|
int fd = setup_socket(&sun);
|
||||||
if (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) {
|
if (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) {
|
||||||
@@ -308,10 +192,10 @@ int connect_daemon() {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xfork() == 0) {
|
if (fork_dont_care() == 0) {
|
||||||
LOGD("client: connect fail, try launching new daemon process\n");
|
LOGD("client: connect fail, try launching new daemon process\n");
|
||||||
close(fd);
|
close(fd);
|
||||||
start_daemon();
|
start_daemon(post_fs_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)))
|
while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)))
|
||||||
|
@@ -14,8 +14,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "resetprop.h"
|
#include "resetprop.h"
|
||||||
|
|
||||||
extern int is_daemon_init;
|
int loggable = 1;
|
||||||
int logd = 0;
|
|
||||||
|
|
||||||
static int am_proc_start_filter(const char *log) {
|
static int am_proc_start_filter(const char *log) {
|
||||||
return strstr(log, "am_proc_start") != NULL;
|
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;
|
static int debug_log_pid = -1, debug_log_fd = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void check_logd() {
|
static void test_logcat() {
|
||||||
char *prop = getprop("init.svc.logd");
|
int log_fd = -1, log_pid;
|
||||||
if (prop != NULL) {
|
char buf[1];
|
||||||
free(prop);
|
log_pid = exec_command(0, &log_fd, NULL, "logcat", NULL);
|
||||||
logd = 1;
|
if (read(log_fd, buf, sizeof(buf)) != sizeof(buf)) {
|
||||||
} else {
|
loggable = 0;
|
||||||
LOGD("log_monitor: logd not started, disable logging");
|
LOGD("log_monitor: cannot read from logcat, disable logging");
|
||||||
logd = 0;
|
|
||||||
}
|
}
|
||||||
|
kill(log_pid, SIGTERM);
|
||||||
|
waitpid(log_pid, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *logger_thread(void *args) {
|
static void *logger_thread(void *args) {
|
||||||
@@ -67,7 +67,7 @@ static void *logger_thread(void *args) {
|
|||||||
LOGD("log_monitor: logger start");
|
LOGD("log_monitor: logger start");
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!logd) {
|
if (!loggable) {
|
||||||
// Disable all services
|
// Disable all services
|
||||||
for (int i = 0; i < (sizeof(log_events) / sizeof(struct log_listener)); ++i) {
|
for (int i = 0; i < (sizeof(log_events) / sizeof(struct log_listener)); ++i) {
|
||||||
close(log_events[i].fd);
|
close(log_events[i].fd);
|
||||||
@@ -98,7 +98,7 @@ static void *logger_thread(void *args) {
|
|||||||
// Clear buffer before restart
|
// Clear buffer before restart
|
||||||
exec_command_sync("logcat", "-b", "events", "-b", "main", "-c", NULL);
|
exec_command_sync("logcat", "-b", "events", "-b", "main", "-c", NULL);
|
||||||
|
|
||||||
check_logd();
|
test_logcat();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should never be here, but well...
|
// Should never be here, but well...
|
||||||
@@ -106,38 +106,20 @@ static void *logger_thread(void *args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void *magisk_log_thread(void *args) {
|
static void *magisk_log_thread(void *args) {
|
||||||
// Buffer logs before we have data access
|
FILE *log = xfopen(LOGFILE, "w");
|
||||||
struct vector logs;
|
setbuf(log, NULL);
|
||||||
vec_init(&logs);
|
|
||||||
|
|
||||||
int pipefd[2];
|
int pipefd[2];
|
||||||
if (xpipe2(pipefd, O_CLOEXEC) == -1)
|
if (xpipe2(pipefd, O_CLOEXEC) == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
LOGD("log_monitor: magisk log dumper start");
|
||||||
|
|
||||||
// Register our listener
|
// Register our listener
|
||||||
log_events[LOG_EVENT].fd = pipefd[1];
|
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))
|
||||||
|
|
||||||
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);
|
fprintf(log, "%s", line);
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,9 +145,9 @@ static void *debug_magisk_log_thread(void *args) {
|
|||||||
void monitor_logs() {
|
void monitor_logs() {
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
|
|
||||||
check_logd();
|
test_logcat();
|
||||||
|
|
||||||
if (logd) {
|
if (loggable) {
|
||||||
// Start log file dumper before monitor
|
// Start log file dumper before monitor
|
||||||
xpthread_create(&thread, NULL, magisk_log_thread, NULL);
|
xpthread_create(&thread, NULL, magisk_log_thread, NULL);
|
||||||
pthread_detach(thread);
|
pthread_detach(thread);
|
||||||
@@ -178,7 +160,7 @@ void monitor_logs() {
|
|||||||
|
|
||||||
void start_debug_full_log() {
|
void start_debug_full_log() {
|
||||||
#ifdef MAGISK_DEBUG
|
#ifdef MAGISK_DEBUG
|
||||||
if (logd) {
|
if (loggable) {
|
||||||
// Log everything initially
|
// Log everything initially
|
||||||
debug_log_fd = xopen(DEBUG_LOG, O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, 0644);
|
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);
|
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() {
|
void start_debug_log() {
|
||||||
#ifdef MAGISK_DEBUG
|
#ifdef MAGISK_DEBUG
|
||||||
if (logd) {
|
if (loggable) {
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
// Start debug thread
|
// Start debug thread
|
||||||
xpthread_create(&thread, NULL, debug_magisk_log_thread, NULL);
|
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"
|
" --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"
|
" --mountimg IMG PATH mount IMG to PATH and prints the loop device\n"
|
||||||
" --umountimg PATH LOOP unmount PATH and delete 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"
|
" --unlock-blocks set BLKROSET flag to OFF for all block devices\n"
|
||||||
" --restorecon fix selinux context on Magisk files and folders\n"
|
" --restorecon fix selinux context on Magisk files and folders\n"
|
||||||
" --clone-attr SRC DEST clone permission, owner, and selinux context\n"
|
" --clone-attr SRC DEST clone permission, owner, and selinux context\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Supported init services:\n"
|
"Supported init triggers:\n"
|
||||||
" daemon, post-fs, post-fs-data, service\n"
|
" startup, post-fs-data, service\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Supported applets:\n"
|
"Supported applets:\n"
|
||||||
, argv0, argv0);
|
, argv0, argv0);
|
||||||
@@ -65,6 +66,7 @@ static void usage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
umask(0);
|
||||||
argv0 = argv[0];
|
argv0 = argv[0];
|
||||||
if (strcmp(basename(argv[0]), "magisk") == 0) {
|
if (strcmp(basename(argv[0]), "magisk") == 0) {
|
||||||
if (argc < 2) usage();
|
if (argc < 2) usage();
|
||||||
@@ -72,14 +74,14 @@ int main(int argc, char *argv[]) {
|
|||||||
printf("%s (%d)\n", MAGISK_VER_STR, MAGISK_VER_CODE);
|
printf("%s (%d)\n", MAGISK_VER_STR, MAGISK_VER_CODE);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (strcmp(argv[1], "-v") == 0) {
|
} else if (strcmp(argv[1], "-v") == 0) {
|
||||||
int fd = connect_daemon();
|
int fd = connect_daemon(0);
|
||||||
write_int(fd, CHECK_VERSION);
|
write_int(fd, CHECK_VERSION);
|
||||||
char *v = read_string(fd);
|
char *v = read_string(fd);
|
||||||
printf("%s\n", v);
|
printf("%s\n", v);
|
||||||
free(v);
|
free(v);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (strcmp(argv[1], "-V") == 0) {
|
} else if (strcmp(argv[1], "-V") == 0) {
|
||||||
int fd = connect_daemon();
|
int fd = connect_daemon(0);
|
||||||
write_int(fd, CHECK_VERSION_CODE);
|
write_int(fd, CHECK_VERSION_CODE);
|
||||||
printf("%d\n", read_int(fd));
|
printf("%d\n", read_int(fd));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -144,19 +146,18 @@ int main(int argc, char *argv[]) {
|
|||||||
clone_attr(argv[2], argv[3]);
|
clone_attr(argv[2], argv[3]);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (strcmp(argv[1], "--daemon") == 0) {
|
} else if (strcmp(argv[1], "--daemon") == 0) {
|
||||||
if (xfork() == 0)
|
int fd = connect_daemon(0);
|
||||||
start_daemon();
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
} else if (strcmp(argv[1], "--startup") == 0) {
|
||||||
|
startup();
|
||||||
return 0;
|
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) {
|
} else if (strcmp(argv[1], "--post-fs-data") == 0) {
|
||||||
int fd = connect_daemon();
|
int fd = connect_daemon(1);
|
||||||
write_int(fd, POST_FS_DATA);
|
write_int(fd, POST_FS_DATA);
|
||||||
return read_int(fd);
|
return read_int(fd);
|
||||||
} else if (strcmp(argv[1], "--service") == 0) {
|
} else if (strcmp(argv[1], "--service") == 0) {
|
||||||
int fd = connect_daemon();
|
int fd = connect_daemon(0);
|
||||||
write_int(fd, LATE_START);
|
write_int(fd, LATE_START);
|
||||||
return read_int(fd);
|
return read_int(fd);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -339,7 +339,7 @@ static void patch_socket_name(const char *path) {
|
|||||||
mmap_rw(path, &buf, &size);
|
mmap_rw(path, &buf, &size);
|
||||||
if (SOCKET_OFF < 0) {
|
if (SOCKET_OFF < 0) {
|
||||||
for (int i = 0; i < size; ++i) {
|
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;
|
SOCKET_OFF = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -350,55 +350,6 @@ static void patch_socket_name(const char *path) {
|
|||||||
munmap(buf, size);
|
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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
umask(0);
|
umask(0);
|
||||||
|
|
||||||
@@ -424,14 +375,8 @@ int main(int argc, char *argv[]) {
|
|||||||
if (null > STDERR_FILENO)
|
if (null > STDERR_FILENO)
|
||||||
close(null);
|
close(null);
|
||||||
|
|
||||||
// Extract and link files
|
// Backup self
|
||||||
mkdir("/overlay", 0000);
|
link("/init", "/init.bak");
|
||||||
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");
|
|
||||||
|
|
||||||
struct cmdline cmd;
|
struct cmdline cmd;
|
||||||
parse_cmdline(&cmd);
|
parse_cmdline(&cmd);
|
||||||
@@ -444,7 +389,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
if (cmd.skip_initramfs) {
|
if (cmd.skip_initramfs) {
|
||||||
// Clear rootfs
|
// Clear rootfs
|
||||||
excl_list = (char *[]) { "overlay", ".backup", NULL };
|
excl_list = (char *[]) { "overlay", ".backup", "init.bak", NULL };
|
||||||
frm_rf(root);
|
frm_rf(root);
|
||||||
} else if (access("/ramdisk.cpio.xz", R_OK) == 0) {
|
} else if (access("/ramdisk.cpio.xz", R_OK) == 0) {
|
||||||
// High compression mode
|
// High compression mode
|
||||||
@@ -513,23 +458,24 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
// Only patch rootfs if not intended to run in recovery
|
// Only patch rootfs if not intended to run in recovery
|
||||||
if (access("/etc/recovery.fstab", F_OK) != 0) {
|
if (access("/etc/recovery.fstab", F_OK) != 0) {
|
||||||
int overlay = open("/overlay", O_RDONLY | O_CLOEXEC);
|
int fd;
|
||||||
mv_dir(overlay, root);
|
|
||||||
close(overlay);
|
// Handle ramdisk overlays
|
||||||
|
fd = open("/overlay", O_RDONLY | O_CLOEXEC);
|
||||||
|
if (fd >= 0) {
|
||||||
|
mv_dir(fd, root);
|
||||||
|
close(fd);
|
||||||
rmdir("/overlay");
|
rmdir("/overlay");
|
||||||
|
}
|
||||||
|
|
||||||
patch_ramdisk();
|
patch_ramdisk();
|
||||||
patch_sepolicy();
|
patch_sepolicy();
|
||||||
|
|
||||||
close(STDIN_FILENO);
|
// Dump binaries
|
||||||
close(STDOUT_FILENO);
|
dump_magiskrc("/init.magisk.rc", 0750);
|
||||||
close(STDERR_FILENO);
|
dump_magisk("/sbin/magisk", 0755);
|
||||||
|
patch_socket_name("/sbin/magisk");
|
||||||
if (fork_dont_care() == 0) {
|
rename("/init.bak", "/sbin/magiskinit");
|
||||||
strcpy(argv[0], "magiskinit");
|
|
||||||
close(root);
|
|
||||||
magisk_init_daemon();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "magisk.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 */
|
/* Setup the address and return socket fd */
|
||||||
int setup_socket(struct sockaddr_un *sun) {
|
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
|
mincrypt/sha256.c
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
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
|
# libfdt.a
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE:= libfdt
|
LOCAL_MODULE:= libfdt
|
||||||
|
2
native/jni/external/busybox
vendored
2
native/jni/external/busybox
vendored
Submodule native/jni/external/busybox updated: 183821743b...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/un.h>
|
||||||
#include <sys/socket.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
|
// Commands require connecting to daemon
|
||||||
enum {
|
enum {
|
||||||
@@ -16,7 +18,6 @@ enum {
|
|||||||
SUPERUSER,
|
SUPERUSER,
|
||||||
CHECK_VERSION,
|
CHECK_VERSION,
|
||||||
CHECK_VERSION_CODE,
|
CHECK_VERSION_CODE,
|
||||||
POST_FS,
|
|
||||||
POST_FS_DATA,
|
POST_FS_DATA,
|
||||||
LATE_START,
|
LATE_START,
|
||||||
LAUNCH_MAGISKHIDE,
|
LAUNCH_MAGISKHIDE,
|
||||||
@@ -31,7 +32,7 @@ enum {
|
|||||||
DAEMON_ERROR = -1,
|
DAEMON_ERROR = -1,
|
||||||
DAEMON_SUCCESS = 0,
|
DAEMON_SUCCESS = 0,
|
||||||
ROOT_REQUIRED,
|
ROOT_REQUIRED,
|
||||||
LOGD_DISABLED,
|
LOGCAT_DISABLED,
|
||||||
HIDE_IS_ENABLED,
|
HIDE_IS_ENABLED,
|
||||||
HIDE_NOT_ENABLED,
|
HIDE_NOT_ENABLED,
|
||||||
HIDE_ITEM_EXIST,
|
HIDE_ITEM_EXIST,
|
||||||
@@ -40,10 +41,9 @@ enum {
|
|||||||
|
|
||||||
// daemon.c
|
// daemon.c
|
||||||
|
|
||||||
void start_daemon();
|
void start_daemon(int post_fs_data);
|
||||||
int connect_daemon();
|
int connect_daemon(int post_fs_data);
|
||||||
void auto_start_magiskhide();
|
void auto_start_magiskhide();
|
||||||
void daemon_init();
|
|
||||||
|
|
||||||
// socket.c
|
// socket.c
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ void write_string(int fd, const char* val);
|
|||||||
* Boot Stages *
|
* Boot Stages *
|
||||||
***************/
|
***************/
|
||||||
|
|
||||||
void post_fs(int client);
|
void startup();
|
||||||
void post_fs_data(int client);
|
void post_fs_data(int client);
|
||||||
void late_start(int client);
|
void late_start(int client);
|
||||||
void fix_filecon();
|
void fix_filecon();
|
||||||
|
@@ -58,7 +58,7 @@ struct log_listener {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern struct log_listener log_events[];
|
extern struct log_listener log_events[];
|
||||||
extern int logd;
|
extern int loggable;
|
||||||
|
|
||||||
void monitor_logs();
|
void monitor_logs();
|
||||||
void start_debug_full_log();
|
void start_debug_full_log();
|
||||||
|
@@ -14,12 +14,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LOGFILE "/cache/magisk.log"
|
#define LOGFILE "/cache/magisk.log"
|
||||||
#define DEBUG_LOG "/data/adb/magisk_debug.log"
|
|
||||||
#define UNBLOCKFILE "/dev/.magisk.unblock"
|
#define UNBLOCKFILE "/dev/.magisk.unblock"
|
||||||
#define PATCHDONE "/dev/.magisk.patch.done"
|
|
||||||
#define DISABLEFILE "/cache/.disable_magisk"
|
#define DISABLEFILE "/cache/.disable_magisk"
|
||||||
#define UNINSTALLER "/cache/magisk_uninstaller.sh"
|
#define UNINSTALLER "/cache/magisk_uninstaller.sh"
|
||||||
#define CACHEMOUNT "/cache/magisk_mount"
|
|
||||||
#define MAGISKTMP "/sbin/.core"
|
#define MAGISKTMP "/sbin/.core"
|
||||||
#define MIRRDIR MAGISKTMP "/mirror"
|
#define MIRRDIR MAGISKTMP "/mirror"
|
||||||
#define BBPATH MAGISKTMP "/busybox"
|
#define BBPATH MAGISKTMP "/busybox"
|
||||||
@@ -27,8 +24,12 @@
|
|||||||
#define COREDIR MOUNTPOINT "/.core"
|
#define COREDIR MOUNTPOINT "/.core"
|
||||||
#define HOSTSFILE COREDIR "/hosts"
|
#define HOSTSFILE COREDIR "/hosts"
|
||||||
#define HIDELIST COREDIR "/hidelist"
|
#define HIDELIST COREDIR "/hidelist"
|
||||||
#define MAINIMG "/data/adb/magisk.img"
|
#define SECURE_DIR "/data/adb/"
|
||||||
#define DATABIN "/data/adb/magisk"
|
#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 MANAGERAPK DATABIN "/magisk.apk"
|
||||||
#define MAGISKRC "/init.magisk.rc"
|
#define MAGISKRC "/init.magisk.rc"
|
||||||
|
|
||||||
@@ -55,7 +56,6 @@ extern char *argv0; /* For changing process name */
|
|||||||
#define init_applet ((char *[]) { "magiskpolicy", "supolicy", NULL })
|
#define init_applet ((char *[]) { "magiskpolicy", "supolicy", NULL })
|
||||||
|
|
||||||
extern int (*applet_main[]) (int, char *[]), (*init_applet_main[]) (int, char *[]);
|
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);
|
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 magiskhide_main(int argc, char *argv[]);
|
||||||
int magiskpolicy_main(int argc, char *argv[]);
|
int magiskpolicy_main(int argc, char *argv[]);
|
||||||
int su_client_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[]);
|
int resetprop_main(int argc, char *argv[]);
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1,17 +1,17 @@
|
|||||||
|
#include "magiskpolicy.h"
|
||||||
|
|
||||||
const char magiskrc[] =
|
const char magiskrc[] =
|
||||||
|
|
||||||
// Triggers
|
// Triggers
|
||||||
|
|
||||||
"on post-fs\n"
|
"on post-fs\n"
|
||||||
" start logd\n"
|
" start logd\n"
|
||||||
" start magisk_pfs\n"
|
|
||||||
" wait /dev/.magisk.unblock 10\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
|
|
||||||
"on post-fs-data\n"
|
"on post-fs-data\n"
|
||||||
" load_persist_props\n"
|
" load_persist_props\n"
|
||||||
" rm /dev/.magisk.unblock\n"
|
" rm /dev/.magisk.unblock\n"
|
||||||
" start magisk_pfsd\n"
|
" start magisk_startup\n"
|
||||||
" wait /dev/.magisk.unblock 10\n"
|
" wait /dev/.magisk.unblock 10\n"
|
||||||
" rm /dev/.magisk.unblock\n"
|
" rm /dev/.magisk.unblock\n"
|
||||||
"\n"
|
"\n"
|
||||||
@@ -20,25 +20,19 @@ const char magiskrc[] =
|
|||||||
|
|
||||||
"service magisk_daemon /sbin/magisk --daemon\n"
|
"service magisk_daemon /sbin/magisk --daemon\n"
|
||||||
" user root\n"
|
" user root\n"
|
||||||
" seclabel u:r:su:s0\n"
|
" seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
|
||||||
" oneshot\n"
|
" oneshot\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
||||||
"service magisk_pfs /sbin/magisk --post-fs\n"
|
"service magisk_startup /sbin/magisk --startup\n"
|
||||||
" user root\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"
|
" oneshot\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
||||||
"service magisk_service /sbin/magisk --service\n"
|
"service magisk_service /sbin/magisk --service\n"
|
||||||
" class late_start\n"
|
" class late_start\n"
|
||||||
" user root\n"
|
" user root\n"
|
||||||
" seclabel u:r:su:s0\n"
|
" seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
|
||||||
" oneshot\n"
|
" oneshot\n"
|
||||||
;
|
;
|
||||||
|
@@ -4,10 +4,6 @@
|
|||||||
#ifndef _RESETPROP_H_
|
#ifndef _RESETPROP_H_
|
||||||
#define _RESETPROP_H_
|
#define _RESETPROP_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int prop_exist(const char *name);
|
int prop_exist(const char *name);
|
||||||
int setprop(const char *name, const char *value);
|
int setprop(const char *name, const char *value);
|
||||||
int setprop2(const char *name, const char *value, const int trigger);
|
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 deleteprop(const char *name);
|
||||||
int deleteprop2(const char *name, const int persist);
|
int deleteprop2(const char *name, const int persist);
|
||||||
int read_prop_file(const char* filename, const int trigger);
|
int read_prop_file(const char* filename, const int trigger);
|
||||||
void getprop_all(void (*callback)(const char*, const char*));
|
void getprop_all(void (*callback)(const char *, const char *, void *), void *cookie);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -122,7 +122,7 @@ int setattrat(int dirfd, const char *pathname, struct file_attr *a);
|
|||||||
int fsetattr(int fd, struct file_attr *a);
|
int fsetattr(int fd, struct file_attr *a);
|
||||||
void fclone_attr(const int sourcefd, const int targetfd);
|
void fclone_attr(const int sourcefd, const int targetfd);
|
||||||
void clone_attr(const char *source, const char *target);
|
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_ro(const char *filename, void **buf, size_t *size);
|
||||||
int mmap_rw(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);
|
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) {
|
if (pos < boot->map_size) {
|
||||||
boot->tail = head + pos;
|
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
|
// 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")) {
|
if (strstr(name, "magisk")) {
|
||||||
deleteprop2(name, 0);
|
deleteprop2(name, 0);
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ static void rm_magisk_prop(const char *name, const char *value) {
|
|||||||
|
|
||||||
void clean_magisk_props() {
|
void clean_magisk_props() {
|
||||||
LOGD("hide_utils: Cleaning magisk props\n");
|
LOGD("hide_utils: Cleaning magisk props\n");
|
||||||
getprop_all(rm_magisk_prop);
|
getprop_all(rm_magisk_prop, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_list(char *proc) {
|
int add_list(char *proc) {
|
||||||
|
@@ -49,9 +49,9 @@ void launch_magiskhide(int client) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!logd) {
|
if (!loggable) {
|
||||||
if (client > 0) {
|
if (client > 0) {
|
||||||
write_int(client, LOGD_DISABLED);
|
write_int(client, LOGCAT_DISABLED);
|
||||||
close(client);
|
close(client);
|
||||||
}
|
}
|
||||||
setprop(MAGISKHIDE_PROP, "0");
|
setprop(MAGISKHIDE_PROP, "0");
|
||||||
@@ -135,7 +135,7 @@ int magiskhide_main(int argc, char *argv[]) {
|
|||||||
} else {
|
} else {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
}
|
}
|
||||||
int fd = connect_daemon();
|
int fd = connect_daemon(0);
|
||||||
write_int(fd, req);
|
write_int(fd, req);
|
||||||
if (req == ADD_HIDELIST || req == RM_HIDELIST) {
|
if (req == ADD_HIDELIST || req == RM_HIDELIST) {
|
||||||
write_string(fd, argv[2]);
|
write_string(fd, argv[2]);
|
||||||
@@ -147,14 +147,14 @@ int magiskhide_main(int argc, char *argv[]) {
|
|||||||
case ROOT_REQUIRED:
|
case ROOT_REQUIRED:
|
||||||
fprintf(stderr, "Root is required for this operation\n");
|
fprintf(stderr, "Root is required for this operation\n");
|
||||||
return code;
|
return code;
|
||||||
case LOGD_DISABLED:
|
case LOGCAT_DISABLED:
|
||||||
fprintf(stderr, "Logd is not running, cannot run logcat\n");
|
fprintf(stderr, "Logcat is disabled, cannot start MagiskHide\n");
|
||||||
return (code);
|
return (code);
|
||||||
case HIDE_NOT_ENABLED:
|
case HIDE_NOT_ENABLED:
|
||||||
fprintf(stderr, "Magisk hide is not enabled yet\n");
|
fprintf(stderr, "MagiskHide is not enabled yet\n");
|
||||||
return code;
|
return code;
|
||||||
case HIDE_IS_ENABLED:
|
case HIDE_IS_ENABLED:
|
||||||
fprintf(stderr, "Magisk hide is already enabled\n");
|
fprintf(stderr, "MagiskHide is already enabled\n");
|
||||||
return code;
|
return code;
|
||||||
case HIDE_ITEM_EXIST:
|
case HIDE_ITEM_EXIST:
|
||||||
fprintf(stderr, "Process [%s] already exists in hide list\n", argv[2]);
|
fprintf(stderr, "Process [%s] already exists in hide list\n", argv[2]);
|
||||||
|
@@ -4,7 +4,6 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#define TERM_THREAD SIGUSR1
|
#define TERM_THREAD SIGUSR1
|
||||||
#define HIDE_DONE SIGUSR2
|
|
||||||
|
|
||||||
// Kill process
|
// Kill process
|
||||||
void kill_proc(int pid);
|
void kill_proc(int pid);
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
#include "magiskhide.h"
|
#include "magiskhide.h"
|
||||||
|
|
||||||
static char init_ns[32], zygote_ns[2][32], cache_block[256];
|
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
|
// Workaround for the lack of pthread_cancel
|
||||||
static void term_thread(int sig) {
|
static void term_thread(int sig) {
|
||||||
@@ -38,17 +38,6 @@ static void term_thread(int sig) {
|
|||||||
pthread_exit(NULL);
|
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) {
|
static int read_namespace(const int pid, char* target, const size_t size) {
|
||||||
char path[32];
|
char path[32];
|
||||||
snprintf(path, sizeof(path), "/proc/%d/ns/mnt", pid);
|
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);
|
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);
|
LOGD("hide_daemon: start unmount for pid=[%d]\n", pid);
|
||||||
strcpy(argv0, "hide_daemon");
|
strcpy(argv0, "hide_daemon");
|
||||||
|
|
||||||
@@ -140,9 +129,6 @@ exit:
|
|||||||
kill(pid, SIGCONT);
|
kill(pid, SIGCONT);
|
||||||
// Free up memory
|
// Free up memory
|
||||||
vec_destroy(&mount_list);
|
vec_destroy(&mount_list);
|
||||||
// Wait a while and link it back
|
|
||||||
sleep(10);
|
|
||||||
kill(ppid, HIDE_DONE);
|
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +137,6 @@ void proc_monitor() {
|
|||||||
sigset_t block_set;
|
sigset_t block_set;
|
||||||
sigemptyset(&block_set);
|
sigemptyset(&block_set);
|
||||||
sigaddset(&block_set, TERM_THREAD);
|
sigaddset(&block_set, TERM_THREAD);
|
||||||
sigaddset(&block_set, HIDE_DONE);
|
|
||||||
pthread_sigmask(SIG_UNBLOCK, &block_set, NULL);
|
pthread_sigmask(SIG_UNBLOCK, &block_set, NULL);
|
||||||
|
|
||||||
// Register the cancel signal
|
// Register the cancel signal
|
||||||
@@ -159,8 +144,6 @@ void proc_monitor() {
|
|||||||
memset(&act, 0, sizeof(act));
|
memset(&act, 0, sizeof(act));
|
||||||
act.sa_handler = term_thread;
|
act.sa_handler = term_thread;
|
||||||
sigaction(TERM_THREAD, &act, NULL);
|
sigaction(TERM_THREAD, &act, NULL);
|
||||||
act.sa_handler = hide_done;
|
|
||||||
sigaction(HIDE_DONE, &act, NULL);
|
|
||||||
|
|
||||||
cache_block[0] = '\0';
|
cache_block[0] = '\0';
|
||||||
|
|
||||||
@@ -219,6 +202,11 @@ void proc_monitor() {
|
|||||||
if(ret != 2)
|
if(ret != 2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Allow hiding sub-services of applications
|
||||||
|
char *colon = strchr(processName, ':');
|
||||||
|
if (colon)
|
||||||
|
*colon = '\0';
|
||||||
|
|
||||||
// Critical region
|
// Critical region
|
||||||
pthread_mutex_lock(&hide_lock);
|
pthread_mutex_lock(&hide_lock);
|
||||||
vec_for_each(hide_list, line) {
|
vec_for_each(hide_list, line) {
|
||||||
@@ -239,23 +227,17 @@ void proc_monitor() {
|
|||||||
// Send pause signal ASAP
|
// Send pause signal ASAP
|
||||||
if (kill(pid, SIGSTOP) == -1) continue;
|
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);
|
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
|
* The setns system call do not support multithread processes
|
||||||
* We have to fork a new process, setns, then do the unmounts
|
* We have to fork a new process, setns, then do the unmounts
|
||||||
*/
|
*/
|
||||||
int selfpid = getpid();
|
|
||||||
if (fork_dont_care() == 0)
|
if (fork_dont_care() == 0)
|
||||||
hide_daemon(pid, selfpid);
|
hide_daemon(pid);
|
||||||
|
|
||||||
break;
|
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 nkk71 <nkk71x@gmail.com>
|
||||||
* Copyright 2016 topjohnwu <topjohnwu@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>
|
#include <stdio.h>
|
||||||
@@ -65,15 +19,11 @@
|
|||||||
|
|
||||||
#include "magisk.h"
|
#include "magisk.h"
|
||||||
#include "resetprop.h"
|
#include "resetprop.h"
|
||||||
extern "C" {
|
#include "_resetprop.h"
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
}
|
#include "utils.h"
|
||||||
|
|
||||||
#define PRINT_D(...) { LOGD(__VA_ARGS__); if (verbose) fprintf(stderr, __VA_ARGS__); }
|
int prop_verbose = 0;
|
||||||
#define PRINT_E(...) { LOGE(__VA_ARGS__); fprintf(stderr, __VA_ARGS__); }
|
|
||||||
#define PERSISTENT_PROPERTY_DIR "/data/property"
|
|
||||||
|
|
||||||
static int verbose = 0;
|
|
||||||
|
|
||||||
static int check_legal_property_name(const char *name) {
|
static int check_legal_property_name(const char *name) {
|
||||||
int namelen = strlen(name);
|
int namelen = strlen(name);
|
||||||
@@ -129,6 +79,49 @@ static int usage(char* arg0) {
|
|||||||
return 1;
|
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() {
|
static int init_resetprop() {
|
||||||
if (__system_properties_init2()) {
|
if (__system_properties_init2()) {
|
||||||
PRINT_E("resetprop: Initialize error\n");
|
PRINT_E("resetprop: Initialize error\n");
|
||||||
@@ -137,16 +130,36 @@ static int init_resetprop() {
|
|||||||
return 0;
|
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) {
|
int prop_exist(const char *name) {
|
||||||
if (init_resetprop()) return 0;
|
if (init_resetprop()) return 0;
|
||||||
return __system_property_find2(name) != NULL;
|
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) {
|
char *getprop(const char *name) {
|
||||||
return getprop2(name, 0);
|
return getprop2(name, 0);
|
||||||
}
|
}
|
||||||
@@ -155,103 +168,35 @@ char *getprop(const char *name) {
|
|||||||
char *getprop2(const char *name, int persist) {
|
char *getprop2(const char *name, int persist) {
|
||||||
if (check_legal_property_name(name))
|
if (check_legal_property_name(name))
|
||||||
return NULL;
|
return NULL;
|
||||||
char value[PROP_VALUE_MAX];
|
|
||||||
if (init_resetprop()) return NULL;
|
if (init_resetprop()) return NULL;
|
||||||
const prop_info *pi = __system_property_find2(name);
|
const prop_info *pi = __system_property_find2(name);
|
||||||
if (pi == NULL) {
|
if (pi == NULL) {
|
||||||
if (persist && strncmp(name, "persist.", 8) == 0) {
|
if (persist && strncmp(name, "persist.", 8) == 0) {
|
||||||
// Try to read from file
|
char *value = persist_getprop(name);
|
||||||
char path[PATH_MAX];
|
if (value)
|
||||||
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
|
return value;
|
||||||
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:
|
|
||||||
PRINT_D("resetprop: prop [%s] does not exist\n", name);
|
PRINT_D("resetprop: prop [%s] does not exist\n", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
} else {
|
} 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);
|
PRINT_D("resetprop: getprop [%s]: [%s]\n", name, value);
|
||||||
return strdup(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) {
|
void getprop_all(void (*callback)(const char *, const char *, void *), 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*)) {
|
|
||||||
if (init_resetprop()) return;
|
if (init_resetprop()) return;
|
||||||
struct wrapper wrap = {
|
struct read_cb_t read_cb = {
|
||||||
.func = callback
|
.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) {
|
int setprop(const char *name, const char *value) {
|
||||||
@@ -294,7 +239,7 @@ int deleteprop(const char *name) {
|
|||||||
return deleteprop2(name, 1);
|
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))
|
if (check_legal_property_name(name))
|
||||||
return 1;
|
return 1;
|
||||||
if (init_resetprop()) return -1;
|
if (init_resetprop()) return -1;
|
||||||
@@ -302,8 +247,8 @@ int deleteprop2(const char *name, const int persist) {
|
|||||||
path[0] = '\0';
|
path[0] = '\0';
|
||||||
PRINT_D("resetprop: deleteprop [%s]\n", name);
|
PRINT_D("resetprop: deleteprop [%s]\n", name);
|
||||||
if (persist && strncmp(name, "persist.", 8) == 0)
|
if (persist && strncmp(name, "persist.", 8) == 0)
|
||||||
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
|
persist = persist_deleteprop(name);
|
||||||
return __system_property_del(name) && unlink(path);
|
return __system_property_del(name) && !(persist && strncmp(name, "persist.", 8) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_prop_file(const char* filename, const int trigger) {
|
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;
|
if (comment) continue;
|
||||||
pch = strchr(line, '=');
|
pch = strchr(line, '=');
|
||||||
// Ignore ivalid formats
|
// Ignore invalid formats
|
||||||
if ( ((pch == NULL) || (i >= (pch - line))) || (pch >= line + read - 1) ) continue;
|
if ( ((pch == NULL) || (i >= (pch - line))) || (pch >= line + read - 1) ) continue;
|
||||||
// Separate the string
|
// Separate the string
|
||||||
*pch = '\0';
|
*pch = '\0';
|
||||||
@@ -367,7 +312,7 @@ int resetprop_main(int argc, char *argv[]) {
|
|||||||
goto usage;
|
goto usage;
|
||||||
}
|
}
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose = 1;
|
prop_verbose = 1;
|
||||||
continue;
|
continue;
|
||||||
case 'p':
|
case 'p':
|
||||||
persist = 1;
|
persist = 1;
|
||||||
@@ -390,7 +335,7 @@ int resetprop_main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
switch (argc) {
|
switch (argc) {
|
||||||
case 0:
|
case 0:
|
||||||
print_all_props(persist);
|
print_props(persist);
|
||||||
return 0;
|
return 0;
|
||||||
case 1:
|
case 1:
|
||||||
prop = getprop2(argv[0], persist);
|
prop = getprop2(argv[0], persist);
|
@@ -153,7 +153,7 @@ class prop_area {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const prop_info* find(const char* name);
|
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 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);
|
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 prop_info* find_property(prop_bt* const trie, const char* name, uint32_t namelen,
|
||||||
const char* value, uint32_t valuelen, bool alloc_if_needed);
|
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),
|
bool foreach_property(prop_bt* const trie, void (*propfn)(const prop_info* pi, void* cookie),
|
||||||
void* cookie);
|
void* cookie);
|
||||||
@@ -283,7 +283,8 @@ static prop_area* map_prop_area_rw(const char* filename, const char* context,
|
|||||||
return pa;
|
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;
|
struct stat fd_stat;
|
||||||
if (fstat(fd, &fd_stat) < 0) {
|
if (fstat(fd, &fd_stat) < 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -298,7 +299,7 @@ static prop_area* map_fd_ro(const int fd) {
|
|||||||
pa_size = fd_stat.st_size;
|
pa_size = fd_stat.st_size;
|
||||||
pa_data_size = pa_size - sizeof(prop_area);
|
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) {
|
if (map_result == MAP_FAILED) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -313,10 +314,10 @@ static prop_area* map_fd_ro(const int fd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static prop_area* map_prop_area(const char* filename) {
|
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;
|
if (fd == -1) return nullptr;
|
||||||
|
|
||||||
prop_area* map_result = map_fd_ro(fd);
|
prop_area* map_result = map_fd_rw(fd);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
return map_result;
|
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);
|
uint_least32_t prop_offset = atomic_load_explicit(¤t->prop, memory_order_relaxed);
|
||||||
if (prop_offset != 0) {
|
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;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -1116,17 +1117,16 @@ static bool initialize_properties() {
|
|||||||
if (!initialize_properties_from_file("/system/etc/selinux/plat_property_contexts")) {
|
if (!initialize_properties_from_file("/system/etc/selinux/plat_property_contexts")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!initialize_properties_from_file("/vendor/etc/selinux/nonplat_property_contexts")
|
// Don't check for failure here, so we always have a sane list of properties.
|
||||||
&& !initialize_properties_from_file("/vendor/etc/selinux/vendor_property_contexts")) {
|
// E.g. In case of recovery, the vendor partition will not have mounted and we
|
||||||
return false;
|
// 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 {
|
} else {
|
||||||
if (!initialize_properties_from_file("/plat_property_contexts")) {
|
if (!initialize_properties_from_file("/plat_property_contexts")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!initialize_properties_from_file("/nonplat_property_contexts")) {
|
initialize_properties_from_file("/nonplat_property_contexts");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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 UNLABEL_CON "u:object_r:unlabeled:s0"
|
||||||
#define SYSTEM_CON "u:object_r:system_file:s0"
|
#define SYSTEM_CON "u:object_r:system_file:s0"
|
||||||
|
|
||||||
void restorecon(int dirfd, int force) {
|
void restorecon(int dirfd) {
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
int fd;
|
int fd;
|
||||||
@@ -352,7 +352,7 @@ void restorecon(int dirfd, int force) {
|
|||||||
|
|
||||||
fd_getpath(dirfd, path, sizeof(path));
|
fd_getpath(dirfd, path, sizeof(path));
|
||||||
lgetfilecon(path, &con);
|
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);
|
lsetfilecon(path, SYSTEM_CON);
|
||||||
freecon(con);
|
freecon(con);
|
||||||
|
|
||||||
@@ -362,12 +362,12 @@ void restorecon(int dirfd, int force) {
|
|||||||
continue;
|
continue;
|
||||||
if (entry->d_type == DT_DIR) {
|
if (entry->d_type == DT_DIR) {
|
||||||
fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
||||||
restorecon(fd, force);
|
restorecon(fd);
|
||||||
} else {
|
} else {
|
||||||
fd = xopenat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC);
|
fd = xopenat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC);
|
||||||
fd_getpath(fd, path, sizeof(path));
|
fd_getpath(fd, path, sizeof(path));
|
||||||
lgetfilecon(path, &con);
|
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);
|
lsetfilecon(path, SYSTEM_CON);
|
||||||
freecon(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) {
|
static int _mmap(int rw, const char *filename, void **buf, size_t *size) {
|
||||||
struct stat st;
|
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);
|
fstat(fd, &st);
|
||||||
if (S_ISBLK(st.st_mode))
|
if (S_ISBLK(st.st_mode))
|
||||||
ioctl(fd, BLKGETSIZE64, size);
|
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) {
|
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) {
|
if (fd < 0) {
|
||||||
*buf = NULL;
|
*buf = NULL;
|
||||||
*size = 0;
|
*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) {
|
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) {
|
if (fd < 0) {
|
||||||
*buf = NULL;
|
*buf = NULL;
|
||||||
*size = 0;
|
*size = 0;
|
||||||
|
@@ -84,7 +84,7 @@ chmod -R 755 .
|
|||||||
CHROMEOS=false
|
CHROMEOS=false
|
||||||
|
|
||||||
ui_print "- Unpacking boot image"
|
ui_print "- Unpacking boot image"
|
||||||
./magiskboot --unpack "$BOOTIMAGE"
|
eval $LIB32PFX ./magiskboot --unpack "$BOOTIMAGE"
|
||||||
|
|
||||||
case $? in
|
case $? in
|
||||||
1 )
|
1 )
|
||||||
@@ -113,14 +113,14 @@ esac
|
|||||||
# Test patch status and do restore, after this section, ramdisk.cpio.orig is guaranteed to exist
|
# Test patch status and do restore, after this section, ramdisk.cpio.orig is guaranteed to exist
|
||||||
ui_print "- Checking ramdisk status"
|
ui_print "- Checking ramdisk status"
|
||||||
MAGISK_PATCHED=false
|
MAGISK_PATCHED=false
|
||||||
./magiskboot --cpio ramdisk.cpio test
|
eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio test
|
||||||
case $? in
|
case $? in
|
||||||
0 ) # Stock boot
|
0 ) # Stock boot
|
||||||
ui_print "- Stock boot image detected"
|
ui_print "- Stock boot image detected"
|
||||||
ui_print "- Backing up stock boot image"
|
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
|
STOCKDUMP=stock_boot_${SHA1}.img.gz
|
||||||
./magiskboot --compress "$BOOTIMAGE" $STOCKDUMP
|
eval $LIB32PFX ./magiskboot --compress "$BOOTIMAGE" $STOCKDUMP
|
||||||
cp -af ramdisk.cpio ramdisk.cpio.orig
|
cp -af ramdisk.cpio ramdisk.cpio.orig
|
||||||
;;
|
;;
|
||||||
1 ) # Magisk patched
|
1 ) # Magisk patched
|
||||||
@@ -140,8 +140,8 @@ esac
|
|||||||
if $MAGISK_PATCHED; then
|
if $MAGISK_PATCHED; then
|
||||||
ui_print "- Magisk patched image detected"
|
ui_print "- Magisk patched image detected"
|
||||||
# Find SHA1 of stock boot image
|
# 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`
|
||||||
./magiskboot --cpio ramdisk.cpio restore
|
eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio restore
|
||||||
cp -af ramdisk.cpio ramdisk.cpio.orig
|
cp -af ramdisk.cpio ramdisk.cpio.orig
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -156,9 +156,9 @@ fi
|
|||||||
|
|
||||||
ui_print "- Patching ramdisk"
|
ui_print "- Patching ramdisk"
|
||||||
|
|
||||||
./magiskboot --cpio ramdisk.cpio \
|
eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio \
|
||||||
'add 750 init magiskinit' \
|
\"add 750 init magiskinit\" \
|
||||||
"magisk ramdisk.cpio.orig $HIGHCOMP $KEEPVERITY $KEEPFORCEENCRYPT $SHA1"
|
\"magisk ramdisk.cpio.orig $HIGHCOMP $KEEPVERITY $KEEPFORCEENCRYPT $SHA1\"
|
||||||
|
|
||||||
rm -f ramdisk.cpio.orig
|
rm -f ramdisk.cpio.orig
|
||||||
|
|
||||||
@@ -167,17 +167,17 @@ rm -f ramdisk.cpio.orig
|
|||||||
##########################################################################################
|
##########################################################################################
|
||||||
|
|
||||||
if ! $KEEPVERITY && [ -f dtb ]; then
|
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
|
fi
|
||||||
|
|
||||||
if [ -f kernel ]; then
|
if [ -f kernel ]; then
|
||||||
# Remove Samsung RKP in stock kernel
|
# Remove Samsung RKP in stock kernel
|
||||||
./magiskboot --hexpatch kernel \
|
eval $LIB32PFX ./magiskboot --hexpatch kernel \
|
||||||
49010054011440B93FA00F71E9000054010840B93FA00F7189000054001840B91FA00F7188010054 \
|
49010054011440B93FA00F71E9000054010840B93FA00F7189000054001840B91FA00F7188010054 \
|
||||||
A1020054011440B93FA00F7140020054010840B93FA00F71E0010054001840B91FA00F7181010054
|
A1020054011440B93FA00F7140020054010840B93FA00F71E0010054001840B91FA00F7181010054
|
||||||
|
|
||||||
# skip_initramfs -> want_initramfs
|
# skip_initramfs -> want_initramfs
|
||||||
./magiskboot --hexpatch kernel \
|
eval $LIB32PFX ./magiskboot --hexpatch kernel \
|
||||||
736B69705F696E697472616D6673 \
|
736B69705F696E697472616D6673 \
|
||||||
77616E745F696E697472616D6673
|
77616E745F696E697472616D6673
|
||||||
fi
|
fi
|
||||||
@@ -187,9 +187,9 @@ fi
|
|||||||
##########################################################################################
|
##########################################################################################
|
||||||
|
|
||||||
ui_print "- Repacking boot image"
|
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
|
# Sign chromeos boot
|
||||||
$CHROMEOS && sign_chromeos
|
$CHROMEOS && sign_chromeos
|
||||||
|
|
||||||
./magiskboot --cleanup
|
eval $LIB32PFX ./magiskboot --cleanup
|
||||||
|
@@ -69,7 +69,7 @@ api_level_arch_detect
|
|||||||
|
|
||||||
ui_print "- Device platform: $ARCH"
|
ui_print "- Device platform: $ARCH"
|
||||||
|
|
||||||
BINDIR=$INSTALLER/$ARCH
|
BINDIR=$INSTALLER/$ARCH32
|
||||||
chmod -R 755 $CHROMEDIR $BINDIR
|
chmod -R 755 $CHROMEDIR $BINDIR
|
||||||
|
|
||||||
# Check if system root is installed and remove
|
# Check if system root is installed and remove
|
||||||
@@ -105,7 +105,7 @@ chmod -R 755 $MAGISKBIN
|
|||||||
if [ -d /system/addon.d ]; then
|
if [ -d /system/addon.d ]; then
|
||||||
ui_print "- Adding addon.d survival script"
|
ui_print "- Adding addon.d survival script"
|
||||||
mount -o rw,remount /system
|
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
|
chmod 755 /system/addon.d/99-magisk.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@@ -45,7 +45,7 @@ cd $MAGISKBIN
|
|||||||
ui_print "- Found Boot Image: $BOOTIMAGE"
|
ui_print "- Found Boot Image: $BOOTIMAGE"
|
||||||
|
|
||||||
ui_print "- Unpacking boot image"
|
ui_print "- Unpacking boot image"
|
||||||
./magiskboot --unpack "$BOOTIMAGE"
|
eval $LIB32PFX ./magiskboot --unpack "$BOOTIMAGE"
|
||||||
CHROMEOS=false
|
CHROMEOS=false
|
||||||
|
|
||||||
case $? in
|
case $? in
|
||||||
@@ -67,7 +67,7 @@ esac
|
|||||||
|
|
||||||
# Detect boot image state
|
# Detect boot image state
|
||||||
ui_print "- Checking ramdisk status"
|
ui_print "- Checking ramdisk status"
|
||||||
./magiskboot --cpio ramdisk.cpio test
|
eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio test
|
||||||
case $? in
|
case $? in
|
||||||
0 ) # Stock boot
|
0 ) # Stock boot
|
||||||
ui_print "- Stock boot image detected"
|
ui_print "- Stock boot image detected"
|
||||||
@@ -76,14 +76,14 @@ case $? in
|
|||||||
1|2 ) # Magisk patched
|
1|2 ) # Magisk patched
|
||||||
ui_print "- Magisk patched image detected"
|
ui_print "- Magisk patched image detected"
|
||||||
# Find SHA1 of stock boot image
|
# 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
|
OK=false
|
||||||
[ ! -z $SHA1 ] && restore_imgs $SHA1 && OK=true
|
[ ! -z $SHA1 ] && restore_imgs $SHA1 && OK=true
|
||||||
if ! $OK; then
|
if ! $OK; then
|
||||||
ui_print "! Boot image backup unavailable"
|
ui_print "! Boot image backup unavailable"
|
||||||
ui_print "- Restoring ramdisk with internal backup"
|
ui_print "- Restoring ramdisk with internal backup"
|
||||||
./magiskboot --cpio ramdisk.cpio restore
|
eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio restore
|
||||||
./magiskboot --repack $BOOTIMAGE
|
eval $LIB32PFX ./magiskboot --repack $BOOTIMAGE
|
||||||
# Sign chromeos boot
|
# Sign chromeos boot
|
||||||
$CHROMEOS && sign_chromeos
|
$CHROMEOS && sign_chromeos
|
||||||
flash_boot_image new-boot.img "$BOOTIMAGE"
|
flash_boot_image new-boot.img "$BOOTIMAGE"
|
||||||
|
@@ -20,7 +20,7 @@ MAGISKBIN=/data/adb/magisk
|
|||||||
[ -z $MOUNTPATH ] && MOUNTPATH=/sbin/.core/img
|
[ -z $MOUNTPATH ] && MOUNTPATH=/sbin/.core/img
|
||||||
[ -z $IMG ] && IMG=/data/adb/magisk.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
|
BOOTSIGNED=false
|
||||||
|
|
||||||
get_outfd() {
|
get_outfd() {
|
||||||
@@ -128,15 +128,15 @@ find_boot_image() {
|
|||||||
run_migrations() {
|
run_migrations() {
|
||||||
# Update the broken boot backup
|
# Update the broken boot backup
|
||||||
if [ -f /data/stock_boot_.img.gz ]; then
|
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
|
fi
|
||||||
# Update our previous backup to new format if exists
|
# Update our previous backup to new format if exists
|
||||||
if [ -f /data/stock_boot.img ]; then
|
if [ -f /data/stock_boot.img ]; then
|
||||||
ui_print "- Migrating boot image backup"
|
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
|
STOCKDUMP=/data/stock_boot_${SHA1}.img
|
||||||
mv /data/stock_boot.img $STOCKDUMP
|
mv /data/stock_boot.img $STOCKDUMP
|
||||||
$MAGISKBIN/magiskboot --compress $STOCKDUMP
|
eval $LIB32PFX $MAGISKBIN/magiskboot --compress $STOCKDUMP
|
||||||
fi
|
fi
|
||||||
# Move the stock backups
|
# Move the stock backups
|
||||||
if [ -f /data/magisk/stock_boot* ]; then
|
if [ -f /data/magisk/stock_boot* ]; then
|
||||||
@@ -154,7 +154,7 @@ run_migrations() {
|
|||||||
|
|
||||||
flash_boot_image() {
|
flash_boot_image() {
|
||||||
# Make sure all blocks are writable
|
# 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
|
case "$1" in
|
||||||
*.gz) COMMAND="gzip -d < '$1'";;
|
*.gz) COMMAND="gzip -d < '$1'";;
|
||||||
*) COMMAND="cat '$1'";;
|
*) COMMAND="cat '$1'";;
|
||||||
@@ -184,11 +184,11 @@ find_dtbo_image() {
|
|||||||
|
|
||||||
patch_dtbo_image() {
|
patch_dtbo_image() {
|
||||||
if [ ! -z $DTBOIMAGE ]; then
|
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"
|
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"
|
ui_print "- Patching fstab in dtbo to remove avb-verity"
|
||||||
$MAGISKBIN/magiskboot --dtb-patch $DTBOIMAGE
|
eval $LIB32PFX $MAGISKBIN/magiskboot --dtb-patch $DTBOIMAGE
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -200,7 +200,7 @@ restore_imgs() {
|
|||||||
STOCKDTBO=/data/stock_dtbo.img.gz
|
STOCKDTBO=/data/stock_dtbo.img.gz
|
||||||
|
|
||||||
# Make sure all blocks are writable
|
# 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
|
find_dtbo_image
|
||||||
if [ ! -z "$DTBOIMAGE" -a -f "$STOCKDTBO" ]; then
|
if [ ! -z "$DTBOIMAGE" -a -f "$STOCKDTBO" ]; then
|
||||||
ui_print "- Restoring stock dtbo image"
|
ui_print "- Restoring stock dtbo image"
|
||||||
@@ -220,7 +220,7 @@ sign_chromeos() {
|
|||||||
ui_print "- Signing ChromeOS boot image"
|
ui_print "- Signing ChromeOS boot image"
|
||||||
|
|
||||||
echo > empty
|
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 \
|
--keyblock ./chromeos/kernel.keyblock --signprivate ./chromeos/kernel_data_key.vbprivk \
|
||||||
--version 1 --vmlinuz new-boot.img --config empty --arch arm --bootloader empty --flags 0x1
|
--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`
|
ABILONG=`grep_prop ro.product.cpu.abi`
|
||||||
|
|
||||||
ARCH=arm
|
ARCH=arm
|
||||||
|
ARCH32=arm
|
||||||
IS64BIT=false
|
IS64BIT=false
|
||||||
if [ "$ABI" = "x86" ]; then ARCH=x86; fi;
|
if [ "$ABI" = "x86" ]; then ARCH=x86; ARCH32=x86; fi;
|
||||||
if [ "$ABI2" = "x86" ]; then ARCH=x86; fi;
|
if [ "$ABI2" = "x86" ]; then ARCH=x86; ARCH32=x86; fi;
|
||||||
if [ "$ABILONG" = "arm64-v8a" ]; then ARCH=arm64; IS64BIT=true; fi;
|
if [ "$ABILONG" = "arm64-v8a" ]; then ARCH=arm64; ARCH32=arm; IS64BIT=true; fi;
|
||||||
if [ "$ABILONG" = "x86_64" ]; then ARCH=x64; IS64BIT=true; fi;
|
if [ "$ABILONG" = "x86_64" ]; then ARCH=x64; ARCH32=x86; IS64BIT=true; fi;
|
||||||
}
|
}
|
||||||
|
|
||||||
boot_actions() {
|
boot_actions() {
|
||||||
@@ -286,7 +287,6 @@ recovery_actions() {
|
|||||||
mount -o bind /dev/urandom /dev/random
|
mount -o bind /dev/urandom /dev/random
|
||||||
# Preserve environment varibles
|
# Preserve environment varibles
|
||||||
OLD_PATH=$PATH
|
OLD_PATH=$PATH
|
||||||
OLD_LD_PATH=$LD_LIBRARY_PATH
|
|
||||||
if [ ! -d $TMPDIR/bin ]; then
|
if [ ! -d $TMPDIR/bin ]; then
|
||||||
# Add busybox to PATH
|
# Add busybox to PATH
|
||||||
mkdir -p $TMPDIR/bin
|
mkdir -p $TMPDIR/bin
|
||||||
@@ -296,13 +296,13 @@ recovery_actions() {
|
|||||||
fi
|
fi
|
||||||
# Temporarily block out all custom recovery binaries/libs
|
# Temporarily block out all custom recovery binaries/libs
|
||||||
mv /sbin /sbin_tmp
|
mv /sbin /sbin_tmp
|
||||||
# Add all possible library paths
|
# Set library paths
|
||||||
$IS64BIT && export LD_LIBRARY_PATH=/system/lib64:/system/vendor/lib64 || export LD_LIBRARY_PATH=/system/lib:/system/vendor/lib
|
$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() {
|
recovery_cleanup() {
|
||||||
mv /sbin_tmp /sbin 2>/dev/null
|
mv /sbin_tmp /sbin 2>/dev/null
|
||||||
export LD_LIBRARY_PATH=$OLD_LD_PATH
|
|
||||||
[ -z $OLD_PATH ] || export PATH=$OLD_PATH
|
[ -z $OLD_PATH ] || export PATH=$OLD_PATH
|
||||||
ui_print "- Unmounting partitions"
|
ui_print "- Unmounting partitions"
|
||||||
umount -l /system_root 2>/dev/null
|
umount -l /system_root 2>/dev/null
|
||||||
@@ -348,7 +348,7 @@ request_zip_size_check() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
image_size_check() {
|
image_size_check() {
|
||||||
SIZE="`$MAGISKBIN/magisk --imgsize $IMG`"
|
SIZE="`eval $LIB32PFX $MAGISKBIN/magisk --imgsize $IMG`"
|
||||||
curUsedM=`echo "$SIZE" | cut -d" " -f1`
|
curUsedM=`echo "$SIZE" | cut -d" " -f1`
|
||||||
curSizeM=`echo "$SIZE" | cut -d" " -f2`
|
curSizeM=`echo "$SIZE" | cut -d" " -f2`
|
||||||
curFreeM=$((curSizeM - curUsedM))
|
curFreeM=$((curSizeM - curUsedM))
|
||||||
@@ -362,28 +362,28 @@ mount_magisk_img() {
|
|||||||
if [ "$reqSizeM" -gt "$curFreeM" ]; then
|
if [ "$reqSizeM" -gt "$curFreeM" ]; then
|
||||||
newSizeM=$(((reqSizeM + curUsedM) / 32 * 32 + 64))
|
newSizeM=$(((reqSizeM + curUsedM) / 32 * 32 + 64))
|
||||||
ui_print "- Resizing $IMG to ${newSizeM}M"
|
ui_print "- Resizing $IMG to ${newSizeM}M"
|
||||||
$MAGISKBIN/magisk --resizeimg $IMG $newSizeM >&2
|
eval $LIB32PFX $MAGISKBIN/magisk --resizeimg $IMG $newSizeM >&2
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
newSizeM=$((reqSizeM / 32 * 32 + 64));
|
newSizeM=$((reqSizeM / 32 * 32 + 64));
|
||||||
ui_print "- Creating $IMG with size ${newSizeM}M"
|
ui_print "- Creating $IMG with size ${newSizeM}M"
|
||||||
$MAGISKBIN/magisk --createimg $IMG $newSizeM >&2
|
eval $LIB32PFX $MAGISKBIN/magisk --createimg $IMG $newSizeM >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ui_print "- Mounting $IMG to $MOUNTPATH"
|
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..."
|
is_mounted $MOUNTPATH || abort "! $IMG mount failed..."
|
||||||
}
|
}
|
||||||
|
|
||||||
unmount_magisk_img() {
|
unmount_magisk_img() {
|
||||||
$MAGISKBIN/magisk --umountimg $MOUNTPATH $MAGISKLOOP
|
eval $LIB32PFX $MAGISKBIN/magisk --umountimg $MOUNTPATH $MAGISKLOOP
|
||||||
|
|
||||||
# Shrink the image if possible
|
# Shrink the image if possible
|
||||||
image_size_check $IMG
|
image_size_check $IMG
|
||||||
newSizeM=$((curUsedM / 32 * 32 + 64))
|
newSizeM=$((curUsedM / 32 * 32 + 64))
|
||||||
if [ $curSizeM -gt $newSizeM ]; then
|
if [ $curSizeM -gt $newSizeM ]; then
|
||||||
ui_print "- Shrinking $IMG to ${newSizeM}M"
|
ui_print "- Shrinking $IMG to ${newSizeM}M"
|
||||||
$MAGISKBIN/magisk --resizeimg $IMG $newSizeM
|
eval $LIB32PFX $MAGISKBIN/magisk --resizeimg $IMG $newSizeM
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 27
|
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||||
buildToolsVersion "27.0.3"
|
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.topjohnwu.snet"
|
applicationId "com.topjohnwu.snet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 27
|
targetSdkVersion rootProject.ext.compileSdkVersion
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
}
|
}
|
||||||
@@ -20,10 +20,6 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
implementation 'com.google.android.gms:play-services-safetynet:7.0.0' /* The oldest version */
|
implementation 'com.google.android.gms:play-services-safetynet:7.0.0' /* The oldest version */
|
||||||
|
Reference in New Issue
Block a user