mirror of
https://github.com/topjohnwu/Magisk
synced 2025-10-26 02:22:14 +01:00
Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8a44646b8 | ||
|
|
ae97d011ae | ||
|
|
1b7657a374 | ||
|
|
5665e04014 | ||
|
|
bb70385a42 | ||
|
|
9855877b03 | ||
|
|
76c9188fae | ||
|
|
e4e5269836 | ||
|
|
9e737df534 | ||
|
|
0b3192c4d5 | ||
|
|
968e6237bd | ||
|
|
d780b5a0e4 | ||
|
|
3e48427eaf | ||
|
|
31360c34ed | ||
|
|
e9624e2304 | ||
|
|
9c6e64f47d | ||
|
|
0afa601551 | ||
|
|
a94fa81195 | ||
|
|
6119c24720 | ||
|
|
7da205f4c8 | ||
|
|
754fafcfe9 | ||
|
|
bd7766b17e | ||
|
|
70b7d73453 | ||
|
|
5ad4702a5b | ||
|
|
40b6fe03c2 | ||
|
|
49ecba2476 | ||
|
|
ebd509d92d | ||
|
|
7193374a7e | ||
|
|
6728445542 | ||
|
|
10ed299c78 | ||
|
|
32b124913e | ||
|
|
599ae95251 | ||
|
|
d1be34c34a | ||
|
|
bc2cac90fe | ||
|
|
28350e3ad9 | ||
|
|
f48e6c93b8 | ||
|
|
7cfc24d68f | ||
|
|
a58d3ea04d | ||
|
|
dfee9954e0 | ||
|
|
eed86c760f | ||
|
|
c471bb6f67 | ||
|
|
518c2b0f95 | ||
|
|
328fc44194 | ||
|
|
b6f735a8f6 | ||
|
|
deae08fc4b | ||
|
|
c61135ee7b | ||
|
|
97cf15007f | ||
|
|
e8302dfbe2 | ||
|
|
558f95cf7e | ||
|
|
18f6ead891 | ||
|
|
10bd25be52 | ||
|
|
65511845d2 | ||
|
|
1c743839ea | ||
|
|
bcae9dec41 | ||
|
|
482c9af41f | ||
|
|
2bf2e7461f | ||
|
|
7d1082b1cb | ||
|
|
0dbae83aec | ||
|
|
f927c1b997 | ||
|
|
89ec7dad2b | ||
|
|
4fd61345af | ||
|
|
66cca24453 | ||
|
|
e733484fab | ||
|
|
e5c3183025 | ||
|
|
930c82316a | ||
|
|
3dc22db265 | ||
|
|
d8c51cb286 | ||
|
|
2f79d0c3b3 | ||
|
|
d8bb3af06b | ||
|
|
e139e8777b |
32
.gitmodules
vendored
32
.gitmodules
vendored
@@ -1,27 +1,27 @@
|
||||
[submodule "jni/selinux"]
|
||||
path = core/jni/external/selinux
|
||||
[submodule "selinux"]
|
||||
path = native/jni/external/selinux
|
||||
url = https://github.com/topjohnwu/selinux.git
|
||||
[submodule "jni/su"]
|
||||
path = core/jni/su
|
||||
[submodule "su"]
|
||||
path = native/jni/su
|
||||
url = https://github.com/topjohnwu/MagiskSU.git
|
||||
[submodule "jni/magiskpolicy"]
|
||||
path = core/jni/magiskpolicy
|
||||
[submodule "magiskpolicy"]
|
||||
path = native/jni/magiskpolicy
|
||||
url = https://github.com/topjohnwu/magiskpolicy.git
|
||||
[submodule "MagiskManager"]
|
||||
path = app
|
||||
url = https://github.com/topjohnwu/MagiskManager.git
|
||||
[submodule "jni/busybox"]
|
||||
path = core/jni/external/busybox
|
||||
[submodule "busybox"]
|
||||
path = native/jni/external/busybox
|
||||
url = https://github.com/topjohnwu/ndk-busybox.git
|
||||
[submodule "jni/external/dtc"]
|
||||
path = core/jni/external/dtc
|
||||
[submodule "dtc"]
|
||||
path = native/jni/external/dtc
|
||||
url = https://github.com/dgibson/dtc
|
||||
[submodule "jni/external/lz4"]
|
||||
path = core/jni/external/lz4
|
||||
[submodule "lz4"]
|
||||
path = native/jni/external/lz4
|
||||
url = https://github.com/lz4/lz4.git
|
||||
[submodule "jni/external/bzip2"]
|
||||
path = core/jni/external/bzip2
|
||||
[submodule "bzip2"]
|
||||
path = native/jni/external/bzip2
|
||||
url = https://github.com/nemequ/bzip2.git
|
||||
[submodule "jni/external/xz"]
|
||||
path = core/jni/external/xz
|
||||
[submodule "xz"]
|
||||
path = native/jni/external/xz
|
||||
url = https://github.com/xz-mirror/xz.git
|
||||
|
||||
36
README.MD
36
README.MD
@@ -6,17 +6,15 @@
|
||||
|
||||
### Environment Requirements
|
||||
|
||||
1. A 64-bit machine: `cmake` for Android is only available in 64-bit
|
||||
2. Python 3.5+: run `build.py` script
|
||||
3. Java Development Kit (JDK) 8: Compile Magisk Manager and sign zips
|
||||
4. Latest Android SDK: `ANDROID_HOME` environment variable should point to the Android SDK folder
|
||||
5. Android NDK: Install NDK along with SDK (`$ANDROID_HOME/ndk-bundle`), or specify custom path `ANDROID_NDK`
|
||||
6. (Windows Only) Python package Colorama: Install with `pip install colorama`, used for ANSI color codes
|
||||
7. (Unix only) C compiler: Build `zipadjust`. Windows users can use the pre-built `zipadjust.exe`
|
||||
1. Python 3.5+: run `build.py` script
|
||||
2. Java Development Kit (JDK) 8: Compile Magisk Manager and sign zips
|
||||
3. Latest Android SDK: `ANDROID_HOME` environment variable should point to the Android SDK folder
|
||||
4. Android NDK: Install NDK along with SDK (`$ANDROID_HOME/ndk-bundle`), or specify custom path `ANDROID_NDK`
|
||||
5. (Windows Only) Python package Colorama: Install with `pip install colorama`, used for ANSI color codes
|
||||
|
||||
### Instructions and Notes
|
||||
1. Magisk can be built with the latest NDK (r16 as of writing), however binaries released officially will be built with NDK r10e due to ELF incompatibilities with the binaries built from the newer NDKs.
|
||||
2. The easiest way to setup the environment is by importing this folder as an Android Studio project. The IDE will download required components and construct the environment for you. You still have to set the `ANDROID_HOME` environment variable to point to the SDK path.
|
||||
2. The easiest way to setup the environment is by importing the folder as an Android Studio project. The IDE will download required components and construct the environment for you. You still have to set the `ANDROID_HOME` environment variable to point to the SDK path.
|
||||
3. Run `build.py` with argument `-h` to see the built-in help message. The `-h` option also works for each supported actions, e.g. `./build.py binary -h`
|
||||
4. Build everything with `build.py`, don't directly call `gradlew` or `ndk-build`, since most requires special setup / dependencies.
|
||||
5. By default, `build.py` will build binaries and Magisk Manager in debug mode. If you want to build Magisk Manager in release mode (through the flag `--release`), you will need to place a Java Keystore file at `release_signature.jks` to sign Magisk Manager's APK. For more information, check out [Google's Official Documentation](https://developer.android.com/studio/publish/app-signing.html#signing-manually).
|
||||
@@ -43,34 +41,34 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
**MagiskManager** (`app`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2016-2018, John Wu (@topjohnwu)
|
||||
* All contributors and translators on Github
|
||||
|
||||
**MagiskSU** (`core/jni/su`)
|
||||
**MagiskSU** (`native/jni/su`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2016-2018, John Wu (@topjohnwu)
|
||||
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
|
||||
* Copyright 2013, Koushik Dutta (@koush)
|
||||
* Copyright 2010, Adam Shanks (@ChainsDD)
|
||||
* Copyright 2008, Zinx Verituse (@zinxv)
|
||||
|
||||
**MagiskPolicy** (`core/jni/magiskpolicy`)
|
||||
**MagiskPolicy** (`native/jni/magiskpolicy`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2016-2018, John Wu (@topjohnwu)
|
||||
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
|
||||
* Copyright 2015, Joshua Brindle (@joshua_brindle)
|
||||
|
||||
**MagiskHide** (`core/jni/magiskhide`)
|
||||
**MagiskHide** (`native/jni/magiskhide`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2016-2018, John Wu (@topjohnwu)
|
||||
* Copyright 2016, Pierre-Hugues Husson (phh@phh.me)
|
||||
|
||||
**resetprop** (`core/jni/resetprop`)
|
||||
**resetprop** (`native/jni/resetprop`)
|
||||
|
||||
* Copyright 2016-2017 John Wu (@topjohnwu)
|
||||
* Copyright 2016-2018 John Wu (@topjohnwu)
|
||||
* Copyright 2016 nkk71 (nkk71x@gmail.com)
|
||||
|
||||
**External Dependencies** (`core/jni/external`)
|
||||
**External Dependencies** (`native/jni/external`)
|
||||
|
||||
* Makefile for busybox, generated by [ndk-busybox-kitchen](https://github.com/topjohnwu/ndk-busybox-kitchen)
|
||||
* Each dependencies has its own license/copyright information in each subdirectory.
|
||||
@@ -78,4 +76,4 @@ All of them are either GPL or GPL compatible.
|
||||
|
||||
**Others Not Mentioned**
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2016-2018, John Wu (@topjohnwu)
|
||||
|
||||
2
app
2
app
Submodule app updated: de2285d5e9...0c782edf21
70
build.py
70
build.py
@@ -26,13 +26,6 @@ try:
|
||||
except FileNotFoundError:
|
||||
error('Please install Java and make sure \'java\' is available in PATH')
|
||||
|
||||
# If not Windows, we need gcc to compile
|
||||
if os.name != 'nt':
|
||||
try:
|
||||
subprocess.run(['gcc', '-v'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
except FileNotFoundError:
|
||||
error('Please install C compiler and make sure \'gcc\' is available in PATH')
|
||||
|
||||
import argparse
|
||||
import multiprocessing
|
||||
import zipfile
|
||||
@@ -89,13 +82,13 @@ def build_binary(args):
|
||||
header('* Building Magisk binaries')
|
||||
|
||||
# Force update logging.h timestamp to trigger recompilation
|
||||
os.utime(os.path.join('core', 'jni', 'include', 'logging.h'))
|
||||
os.utime(os.path.join('native', 'jni', 'include', 'logging.h'))
|
||||
|
||||
debug_flag = '' if args.release else '-DMAGISK_DEBUG'
|
||||
cflag = 'MAGISK_FLAGS=\"-DMAGISK_VERSION=\\\"{}\\\" -DMAGISK_VER_CODE={} {}\"'.format(args.versionString, args.versionCode, debug_flag)
|
||||
|
||||
# Prebuild
|
||||
proc = subprocess.run('{} -C core PRECOMPILE=true {} -j{}'.format(ndk_build, cflag, multiprocessing.cpu_count()), shell=True)
|
||||
proc = subprocess.run('{} -C native PRECOMPILE=true {} -j{}'.format(ndk_build, cflag, multiprocessing.cpu_count()), shell=True)
|
||||
if proc.returncode != 0:
|
||||
error('Build Magisk binary failed!')
|
||||
|
||||
@@ -104,7 +97,7 @@ def build_binary(args):
|
||||
mkdir_p(os.path.join('out', arch))
|
||||
with open(os.path.join('out', arch, 'dump.h'), 'w') as dump:
|
||||
dump.write('#include "stdlib.h"\n')
|
||||
mv(os.path.join('core', 'libs', arch, 'magisk'), os.path.join('out', arch, 'magisk'))
|
||||
mv(os.path.join('native', 'libs', arch, 'magisk'), os.path.join('out', arch, 'magisk'))
|
||||
with open(os.path.join('out', arch, 'magisk'), 'rb') as bin:
|
||||
dump.write('const uint8_t magisk_dump[] = "')
|
||||
dump.write(''.join("\\x{:02X}".format(c) for c in lzma.compress(bin.read(), preset=9)))
|
||||
@@ -112,7 +105,7 @@ def build_binary(args):
|
||||
|
||||
print('')
|
||||
|
||||
proc = subprocess.run('{} -C core {} -j{}'.format(ndk_build, cflag, multiprocessing.cpu_count()), shell=True)
|
||||
proc = subprocess.run('{} -C native {} -j{}'.format(ndk_build, cflag, multiprocessing.cpu_count()), shell=True)
|
||||
if proc.returncode != 0:
|
||||
error('Build Magisk binary failed!')
|
||||
|
||||
@@ -120,18 +113,14 @@ def build_binary(args):
|
||||
for arch in ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']:
|
||||
for binary in ['magiskinit', 'magiskboot', 'b64xz', 'busybox']:
|
||||
try:
|
||||
mv(os.path.join('core', 'libs', arch, binary), os.path.join('out', arch, binary))
|
||||
mv(os.path.join('native', 'libs', arch, binary), os.path.join('out', arch, binary))
|
||||
except:
|
||||
pass
|
||||
|
||||
def build_apk(args):
|
||||
header('* Building Magisk Manager')
|
||||
|
||||
for key in ['public.certificate.x509.pem', 'private.key.pk8']:
|
||||
source = os.path.join('ziptools', key)
|
||||
target = os.path.join('app', 'src', 'main', 'assets', key)
|
||||
cp(source, target)
|
||||
|
||||
mkdir(os.path.join('app', 'src', 'main', 'assets'))
|
||||
for script in ['magisk_uninstaller.sh', 'util_functions.sh']:
|
||||
source = os.path.join('scripts', script)
|
||||
target = os.path.join('app', 'src', 'main', 'assets', script)
|
||||
@@ -331,51 +320,22 @@ def zip_uninstaller(args):
|
||||
sign_adjust_zip(unsigned, output)
|
||||
|
||||
def sign_adjust_zip(unsigned, output):
|
||||
signer_name = 'zipsigner-1.1.jar'
|
||||
jarsigner = os.path.join('crypto', 'build', 'libs', signer_name)
|
||||
signer_name = 'zipsigner-2.1.jar'
|
||||
jarsigner = os.path.join('utils', 'build', 'libs', signer_name)
|
||||
|
||||
if os.name != 'nt' and not os.path.exists(os.path.join('ziptools', 'zipadjust')):
|
||||
header('* Building zipadjust')
|
||||
# Compile zipadjust
|
||||
proc = subprocess.run('gcc -o ziptools/zipadjust ziptools/zipadjust_src/*.c -lz', shell=True)
|
||||
if proc.returncode != 0:
|
||||
error('Build zipadjust failed!')
|
||||
if not os.path.exists(jarsigner):
|
||||
header('* Building ' + signer_name)
|
||||
proc = subprocess.run('{} crypto:shadowJar'.format(os.path.join('.', 'gradlew')), shell=True)
|
||||
proc = subprocess.run('{} utils:shadowJar'.format(os.path.join('.', 'gradlew')), shell=True)
|
||||
if proc.returncode != 0:
|
||||
error('Build {} failed!'.format(signer_name))
|
||||
|
||||
header('* Signing / Adjusting Zip')
|
||||
|
||||
publicKey = os.path.join('ziptools', 'public.certificate.x509.pem')
|
||||
privateKey = os.path.join('ziptools', 'private.key.pk8')
|
||||
header('* Signing Zip')
|
||||
|
||||
signed = tempfile.mkstemp()[1]
|
||||
|
||||
# Unsigned->signed
|
||||
proc = subprocess.run(['java', '-jar', jarsigner,
|
||||
publicKey, privateKey, unsigned, signed])
|
||||
proc = subprocess.run(['java', '-jar', jarsigner, unsigned, output])
|
||||
if proc.returncode != 0:
|
||||
error('First sign flashable zip failed!')
|
||||
|
||||
adjusted = tempfile.mkstemp()[1]
|
||||
|
||||
# Adjust zip
|
||||
proc = subprocess.run([os.path.join('ziptools', 'zipadjust'), signed, adjusted])
|
||||
if proc.returncode != 0:
|
||||
error('Adjust flashable zip failed!')
|
||||
|
||||
# Adjusted -> output
|
||||
proc = subprocess.run(['java', '-jar', jarsigner,
|
||||
"-m", publicKey, privateKey, adjusted, output])
|
||||
if proc.returncode != 0:
|
||||
error('Second sign flashable zip failed!')
|
||||
|
||||
# Cleanup
|
||||
rm(unsigned)
|
||||
rm(signed)
|
||||
rm(adjusted)
|
||||
error('Signing zip failed!')
|
||||
|
||||
def cleanup(args):
|
||||
if len(args.target) == 0:
|
||||
@@ -383,14 +343,14 @@ def cleanup(args):
|
||||
|
||||
if 'binary' in args.target:
|
||||
header('* Cleaning binaries')
|
||||
subprocess.run(ndk_build + ' -C core PRECOMPILE=true clean', shell=True)
|
||||
subprocess.run(ndk_build + ' -C core clean', shell=True)
|
||||
subprocess.run(ndk_build + ' -C native PRECOMPILE=true clean', shell=True)
|
||||
subprocess.run(ndk_build + ' -C native clean', shell=True)
|
||||
for arch in ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']:
|
||||
shutil.rmtree(os.path.join('out', arch), ignore_errors=True)
|
||||
|
||||
if 'java' in args.target:
|
||||
header('* Cleaning java')
|
||||
subprocess.run('{} app:clean snet:clean crypto:clean'.format(os.path.join('.', 'gradlew')), shell=True)
|
||||
subprocess.run('{} app:clean snet:clean utils:clean'.format(os.path.join('.', 'gradlew')), shell=True)
|
||||
for f in os.listdir('out'):
|
||||
if '.apk' in f:
|
||||
rm(os.path.join('out', f))
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
/* socket.c - All socket related operations
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "daemon.h"
|
||||
#include "logging.h"
|
||||
#include "utils.h"
|
||||
#include "magisk.h"
|
||||
|
||||
/* Setup the address and return socket fd */
|
||||
int setup_socket(struct sockaddr_un *sun) {
|
||||
int fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
memset(sun, 0, sizeof(*sun));
|
||||
sun->sun_family = AF_LOCAL;
|
||||
memcpy(sun->sun_path, REQUESTOR_DAEMON_PATH, sizeof(REQUESTOR_DAEMON_PATH) - 1);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Receive a file descriptor from a Unix socket.
|
||||
* Contributed by @mkasick
|
||||
*
|
||||
* Returns the file descriptor on success, or -1 if a file
|
||||
* descriptor was not actually included in the message
|
||||
*
|
||||
* On error the function terminates by calling exit(-1)
|
||||
*/
|
||||
int recv_fd(int sockfd) {
|
||||
// Need to receive data from the message, otherwise don't care about it.
|
||||
char iovbuf;
|
||||
|
||||
struct iovec iov = {
|
||||
.iov_base = &iovbuf,
|
||||
.iov_len = 1,
|
||||
};
|
||||
|
||||
char cmsgbuf[CMSG_SPACE(sizeof(int))];
|
||||
|
||||
struct msghdr msg = {
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
.msg_control = cmsgbuf,
|
||||
.msg_controllen = sizeof(cmsgbuf),
|
||||
};
|
||||
|
||||
xrecvmsg(sockfd, &msg, MSG_WAITALL);
|
||||
|
||||
// Was a control message actually sent?
|
||||
switch (msg.msg_controllen) {
|
||||
case 0:
|
||||
// No, so the file descriptor was closed and won't be used.
|
||||
return -1;
|
||||
case sizeof(cmsgbuf):
|
||||
// Yes, grab the file descriptor from it.
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
||||
|
||||
if (cmsg == NULL ||
|
||||
cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
|
||||
cmsg->cmsg_level != SOL_SOCKET ||
|
||||
cmsg->cmsg_type != SCM_RIGHTS) {
|
||||
error:
|
||||
LOGE("unable to read fd");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
return *(int *)CMSG_DATA(cmsg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a file descriptor through a Unix socket.
|
||||
* Contributed by @mkasick
|
||||
*
|
||||
* On error the function terminates by calling exit(-1)
|
||||
*
|
||||
* fd may be -1, in which case the dummy data is sent,
|
||||
* but no control message with the FD is sent.
|
||||
*/
|
||||
void send_fd(int sockfd, int fd) {
|
||||
// Need to send some data in the message, this will do.
|
||||
struct iovec iov = {
|
||||
.iov_base = "",
|
||||
.iov_len = 1,
|
||||
};
|
||||
|
||||
struct msghdr msg = {
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
};
|
||||
|
||||
char cmsgbuf[CMSG_SPACE(sizeof(int))];
|
||||
|
||||
if (fd != -1) {
|
||||
// Is the file descriptor actually open?
|
||||
if (fcntl(fd, F_GETFD) == -1) {
|
||||
if (errno != EBADF) {
|
||||
PLOGE("unable to send fd");
|
||||
}
|
||||
// It's closed, don't send a control message or sendmsg will EBADF.
|
||||
} else {
|
||||
// It's open, send the file descriptor in a control message.
|
||||
msg.msg_control = cmsgbuf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf);
|
||||
|
||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
||||
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
|
||||
*(int *)CMSG_DATA(cmsg) = fd;
|
||||
}
|
||||
}
|
||||
|
||||
xsendmsg(sockfd, &msg, 0);
|
||||
}
|
||||
|
||||
int read_int(int fd) {
|
||||
int val;
|
||||
xxread(fd, &val, sizeof(int));
|
||||
return val;
|
||||
}
|
||||
|
||||
void write_int(int fd, int val) {
|
||||
if (fd < 0) return;
|
||||
xwrite(fd, &val, sizeof(int));
|
||||
}
|
||||
|
||||
char* read_string(int fd) {
|
||||
int len = read_int(fd);
|
||||
if (len > PATH_MAX || len < 0) {
|
||||
LOGE("invalid string length %d", len);
|
||||
exit(1);
|
||||
}
|
||||
char* val = xmalloc(sizeof(char) * (len + 1));
|
||||
xxread(fd, val, len);
|
||||
val[len] = '\0';
|
||||
return val;
|
||||
}
|
||||
|
||||
void write_string(int fd, const char* val) {
|
||||
if (fd < 0) return;
|
||||
int len = strlen(val);
|
||||
write_int(fd, len);
|
||||
xwrite(fd, val, len);
|
||||
}
|
||||
1
core/jni/external/busybox
vendored
1
core/jni/external/busybox
vendored
Submodule core/jni/external/busybox deleted from e3a1a4d91f
1
core/jni/external/dtc
vendored
1
core/jni/external/dtc
vendored
Submodule core/jni/external/dtc deleted from 22a65c5331
1
core/jni/external/lz4
vendored
1
core/jni/external/lz4
vendored
Submodule core/jni/external/lz4 deleted from c10863b98e
295
core/jni/external/sha1/sha1.c
vendored
295
core/jni/external/sha1/sha1.c
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,127 +0,0 @@
|
||||
/* tools/mkbootimg/bootimg.h
|
||||
**
|
||||
** Copyright 2007, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "types.h"
|
||||
|
||||
#ifndef _BOOT_IMAGE_H_
|
||||
#define _BOOT_IMAGE_H_
|
||||
|
||||
typedef struct boot_img_hdr boot_img_hdr;
|
||||
|
||||
#define BOOT_MAGIC "ANDROID!"
|
||||
#define BOOT_MAGIC_SIZE 8
|
||||
#define BOOT_NAME_SIZE 16
|
||||
#define BOOT_ARGS_SIZE 512
|
||||
#define BOOT_EXTRA_ARGS_SIZE 1024
|
||||
|
||||
struct boot_img_hdr
|
||||
{
|
||||
uint8_t magic[BOOT_MAGIC_SIZE];
|
||||
|
||||
uint32_t kernel_size; /* size in bytes */
|
||||
uint32_t kernel_addr; /* physical load addr */
|
||||
|
||||
uint32_t ramdisk_size; /* size in bytes */
|
||||
uint32_t ramdisk_addr; /* physical load addr */
|
||||
|
||||
uint32_t second_size; /* size in bytes */
|
||||
uint32_t second_addr; /* physical load addr */
|
||||
|
||||
uint32_t tags_addr; /* physical addr for kernel tags */
|
||||
uint32_t page_size; /* flash page size we assume */
|
||||
uint32_t extra_size; /* extra blob size in bytes */
|
||||
|
||||
/* operating system version and security patch level; for
|
||||
* version "A.B.C" and patch level "Y-M-D":
|
||||
* ver = A << 14 | B << 7 | C (7 bits for each of A, B, C)
|
||||
* lvl = ((Y - 2000) & 127) << 4 | M (7 bits for Y, 4 bits for M)
|
||||
* os_version = ver << 11 | lvl */
|
||||
uint32_t os_version;
|
||||
|
||||
uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */
|
||||
|
||||
uint8_t cmdline[BOOT_ARGS_SIZE];
|
||||
|
||||
uint32_t id[8]; /* timestamp / checksum / sha1 / etc */
|
||||
|
||||
/* Supplemental command line data; kept here to maintain
|
||||
* binary compatibility with older versions of mkbootimg */
|
||||
uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
** +-----------------+
|
||||
** | boot header | 1 page
|
||||
** +-----------------+
|
||||
** | kernel | n pages
|
||||
** +-----------------+
|
||||
** | ramdisk | m pages
|
||||
** +-----------------+
|
||||
** | second stage | o pages
|
||||
** +-----------------+
|
||||
** | extra blobs | p pages
|
||||
** +-----------------+
|
||||
**
|
||||
** n = (kernel_size + page_size - 1) / page_size
|
||||
** m = (ramdisk_size + page_size - 1) / page_size
|
||||
** o = (second_size + page_size - 1) / page_size
|
||||
** p = (extra_size + page_size - 1) / page_size
|
||||
**
|
||||
** 0. all entities are page_size aligned in flash
|
||||
** 1. kernel and ramdisk are required (size != 0)
|
||||
** 2. second is optional (second_size == 0 -> no second)
|
||||
** 3. load each element (kernel, ramdisk, second) at
|
||||
** the specified physical address (kernel_addr, etc)
|
||||
** 4. prepare tags at tag_addr. kernel_args[] is
|
||||
** appended to the kernel commandline in the tags.
|
||||
** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
|
||||
** 6. if second_size != 0: jump to second_addr
|
||||
** else: jump to kernel_addr
|
||||
*/
|
||||
|
||||
typedef struct mtk_hdr {
|
||||
uint8_t magic[4]; /* MTK magic */
|
||||
uint32_t size; /* Size of the content */
|
||||
uint8_t name[32]; /* The type of the header */
|
||||
} mtk_hdr;
|
||||
|
||||
// Flags
|
||||
#define MTK_KERNEL 0x1
|
||||
#define MTK_RAMDISK 0x2
|
||||
#define CHROMEOS_FLAG 0x4
|
||||
|
||||
typedef struct boot_img {
|
||||
size_t map_size;
|
||||
uint32_t dt_size;
|
||||
size_t tail_size;
|
||||
uint8_t flags;
|
||||
file_t kernel_type, ramdisk_type;
|
||||
|
||||
boot_img_hdr hdr;
|
||||
mtk_hdr mtk_kernel_hdr, mtk_ramdisk_hdr;
|
||||
|
||||
void *map_addr;
|
||||
void *kernel;
|
||||
void *dtb;
|
||||
void *ramdisk;
|
||||
void *second;
|
||||
void *extra;
|
||||
void *tail;
|
||||
} boot_img;
|
||||
|
||||
#endif
|
||||
Submodule core/jni/magiskpolicy deleted from edab891427
@@ -1,42 +0,0 @@
|
||||
package com.topjohnwu.crypto;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.security.Security;
|
||||
|
||||
public class ZipSigner {
|
||||
public static void main(String[] args) {
|
||||
boolean minSign = false;
|
||||
int argStart = 0;
|
||||
|
||||
if (args.length < 4) {
|
||||
System.err.println("Usage: zipsigner [-m] publickey.x509[.pem] privatekey.pk8 input.jar output.jar");
|
||||
System.exit(2);
|
||||
}
|
||||
|
||||
if (args[0].equals("-m")) {
|
||||
minSign = true;
|
||||
argStart = 1;
|
||||
}
|
||||
|
||||
SignAPK.sBouncyCastleProvider = new BouncyCastleProvider();
|
||||
Security.insertProviderAt(SignAPK.sBouncyCastleProvider, 1);
|
||||
|
||||
File pubKey = new File(args[argStart]);
|
||||
File privKey = new File(args[argStart + 1]);
|
||||
File input = new File(args[argStart + 2]);
|
||||
File output = new File(args[argStart + 3]);
|
||||
|
||||
try (InputStream pub = new FileInputStream(pubKey);
|
||||
InputStream priv = new FileInputStream(privKey);
|
||||
JarMap jar = new JarMap(input, false)) {
|
||||
SignAPK.signZip(pub, priv, jar, output, minSign);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
166
docs/applets.md
166
docs/applets.md
File diff suppressed because one or more lines are too long
@@ -4,3 +4,5 @@
|
||||
- 2017.9.28
|
||||
- Update applets info to Magisk v14.1
|
||||
- Add OTA tips
|
||||
- 2017.1.8
|
||||
- Update to Magisk v15.2
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 258 KiB |
BIN
docs/images/restore_img.png
Normal file
BIN
docs/images/restore_img.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 244 KiB |
@@ -1,76 +0,0 @@
|
||||
# Magisk Modules and Online Repo
|
||||
## Magisk Module Format
|
||||
The Magisk module is a folder under `magisk`, which has a structure as described below:
|
||||
|
||||
```
|
||||
magisk
|
||||
├── .
|
||||
├── .
|
||||
├── a_module <--- The ID of the module, should match with module.prop
|
||||
│ ├── auto_mount <--- If this file exists, auto mount is enabled
|
||||
│ ├── disable <--- If this file exists, the module is disabled
|
||||
│ ├── module.prop <--- This files stores the indentity and properties of the module
|
||||
│ ├── post-fs-data.sh <--- This script will be executed in post-fs-data
|
||||
│ ├── remove <--- If this file exists, the module will be removed next reboot
|
||||
│ ├── service.sh <--- This script will be executed in late_start service
|
||||
│ ├── system.prop <--- This file will be loaded as system props
|
||||
│ ├── system <--- If auto mount is enabled, Magisk will "Magic Mount" this folder
|
||||
│ │ ├── app
|
||||
│ │ ├── .
|
||||
│ │ └── .
|
||||
│ ├── vendor <--- Auto generated. A symlink to $MODID/system/vendor
|
||||
│ ├── . <--- Any other files/folders are allowed
|
||||
│ └── .
|
||||
├── another_module
|
||||
│ ├── .
|
||||
│ └── .
|
||||
├── .
|
||||
├── .
|
||||
```
|
||||
|
||||
## Magisk Module Template
|
||||
The **Magisk Module Template** is hosted **[here](https://github.com/topjohnwu/magisk-module-template)**.
|
||||
|
||||
It is a template to create a flashable zip to install Magisk Modules. It is created to be simple to use so that anyone can create their own modules easily. The template itself contains minimal scripting for installation; most of the functions are located externally in [util_functions.sh](https://github.com/topjohnwu/Magisk/blob/master/scripts/util_functions.sh), which will be installed along with Magisk, and can be upgraded through a Magisk upgrade without the need of a template update.
|
||||
|
||||
The template should meet most modules' needs. Add files into `system`, which will be cloned into `/system` by Magisk after installing the module, and in addition to module files, `system.prop`, `post-fs-data.sh`, `service.sh` are also installable through this template.
|
||||
|
||||
Here are some files you would want to know:
|
||||
|
||||
- `config.sh`: A simple script used as a configuration file for the actual installation file to correctly install your module. It is the place you can select which features your module needs/disables.
|
||||
- `module.prop`: This file contains your module's indentity and properties, including name and versions etc.. This file will be used to identify your module on an actual device and in the [Magisk Modules Repo](https://github.com/Magisk-Modules-Repo)
|
||||
- `common/*`: These files will be installed to the module with the correspond role
|
||||
- `META-INF/com/google/android/update-binary`: The actual installation script. Modify this file for advanced custom behavior
|
||||
|
||||
## Create a Magisk Module With The Template
|
||||
1. Clone / download [this repo](https://github.com/topjohnwu/magisk-module-template)
|
||||
1. Open `config.sh` and carefully read the fully documented file. Follow the instructions within the script
|
||||
1. You should at least have `config.sh` and `module.prop` modified
|
||||
1. Directly zip all files; the result zip file is a flashable zip that can be used in both Magisk Manager and custom recoveries
|
||||
1. Please check [**Notes**](#notes) for several precautions
|
||||
|
||||
## Submit Your Module to Magisk Modules Repo
|
||||
If you want to share your module with others, you can submit your modules to [Magisk Modules Repo](https://github.com/Magisk-Modules-Repo). You would need some basic `git` knowledge here.
|
||||
|
||||
1. Create a module as stated above, and test if it works properly
|
||||
1. Fork [this repo](https://github.com/topjohnwu/magisk-module-template) to your account
|
||||
1. Commit and push your changes to your forked repo
|
||||
1. Open an issue in [topjohnwu/Magisk_Repo_Central](https://github.com/topjohnwu/Magisk_Repo_Central/issues/new) with your repo link
|
||||
1. I will review your module, and once accepted, your repo should be cloned into [Magisk-Modules-Repo](https://github.com/Magisk-Modules-Repo)
|
||||
1. You should receive an email to become the collaborator so you can edit the repo in the future.
|
||||
|
||||
#### Once your module is live on the Modules Repo, the description of your repo should be the ID of your module. Please do NOT change the description, repeat, do NOT change the description.
|
||||
|
||||

|
||||
|
||||
## Notes
|
||||
- The Module Template depends on external scripts, be aware of the minimal required Magisk version of the template.
|
||||
- **Windows users please check here!!** The line endings of all text files should be in the **Unix format**. Please use advanced text editors like Sublime, Atom, Notepad++ etc. to edit **ALL** text files, **NEVER** use Windows Notepad.
|
||||
- In `module.prop`, `version` can be an arbitrary string, so any fancy version name (e.g. ultra-beta-v1.1.1.1) is allowed. However, `versionCode` **MUST** be an integer. The value is used for version comparison.
|
||||
- Make sure your module ID **does not contain any spaces**.
|
||||
|
||||
## Notes For Repo Developers
|
||||
|
||||
- Magisk Manager monitors all repo's `master` branch. Any changes to the branch `master` will be reflected to all users immediately. If you are working on an update for a module, please work on another branch, make sure it works, then finally merge the changes back to `master`.
|
||||
- Once you finished upgrading your repo, increase at least the `versionCode` in `module.prop`. Magisk Manager uses this value to compare with the local installed module to determine whether an update is availible.
|
||||
- The description of your repo should be the same as your module ID. If you changed your description, Magisk Manager will fail to identify your repo, and cannot relate installed module to the online repo together.
|
||||
49
docs/modules.md
Normal file
49
docs/modules.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Magisk Modules
|
||||
## Magisk Module Format
|
||||
A Magisk module is a folder placed in the root folder in `magisk.img`, which has a structure as described below:
|
||||
|
||||
```
|
||||
$MOUNTPOINT
|
||||
├── .
|
||||
├── .
|
||||
├── $MODID <--- The ID of the module, should match with module.prop
|
||||
│ ├── auto_mount <--- If this file exists, auto mount is enabled
|
||||
│ ├── disable <--- If this file exists, the module is disabled
|
||||
│ ├── module.prop <--- This files stores the identity and properties of the module
|
||||
│ ├── post-fs-data.sh <--- This script will be executed in post-fs-data
|
||||
│ ├── remove <--- If this file exists, the module will be removed next reboot
|
||||
│ ├── service.sh <--- This script will be executed in late_start service
|
||||
│ ├── system.prop <--- This file will be loaded as system props
|
||||
│ ├── system <--- If auto mount is enabled, Magisk will "Magic Mount" this folder
|
||||
│ │ ├── .
|
||||
│ │ ├── .
|
||||
│ │ └── .
|
||||
│ ├── vendor <--- Auto generated. A symlink to $MODID/system/vendor
|
||||
│ ├── . <--- Any other files/folders are allowed
|
||||
│ └── .
|
||||
├── another_module
|
||||
│ ├── .
|
||||
│ └── .
|
||||
├── .
|
||||
├── .
|
||||
```
|
||||
You are not required to use my Magisk Module Template to create a module. As long as you place files with the structure above, it will be recognized as a module.
|
||||
|
||||
## Magisk Module Template
|
||||
The **Magisk Module Template** is hosted **[here](https://github.com/topjohnwu/magisk-module-template)**.
|
||||
|
||||
It is a template to create a flashable zip to install Magisk Modules. It is designed to be simple to use so that anyone can create their own modules easily. The template itself contains minimal scripting for installation; most of the functions are located externally in [util_functions.sh](https://github.com/topjohnwu/Magisk/blob/master/scripts/util_functions.sh), which will be installed along with Magisk, and can be upgraded through a Magisk upgrade without the need of a template update.
|
||||
|
||||
Here are some files you would want to know:
|
||||
|
||||
- `config.sh`: A simple script used as a configuration file. It is the place to configure which features your module needs/disables. A detailed instructions on how to use the template is also written in this file.
|
||||
- `module.prop`: This file contains your module's indentity and properties, including name and versions etc.. This file will be used to identify your module on an actual device and in the [Magisk Modules Repo](https://github.com/Magisk-Modules-Repo)
|
||||
- `common/*`: Boot stage scripts and `system.prop`
|
||||
- `META-INF/com/google/android/update-binary`: The actual installation script. Modify this file for advanced custom behavior
|
||||
|
||||
And here are some notes to be aware of:
|
||||
|
||||
- The template depends on external Magisk scripts, please specify the correct `minMagisk` value in `module.prop` with the template version your module is based on, or the minimum Magisk version your module is tested on.
|
||||
- **Windows users please check here!!** The line endings of all text files should be in the **Unix format**. Please use advanced text editors like Sublime, Atom, Notepad++ etc. to edit **ALL** text files, **NEVER** use Windows Notepad.
|
||||
- In `module.prop`, `version` can be an arbitrary string, so any fancy version name (e.g. `ultra-beta-v1.1.1.1`) is allowed. However, `versionCode` **MUST** be an integer. The value is used for version comparison.
|
||||
- Make sure your module ID **does not contain any spaces**.
|
||||
File diff suppressed because one or more lines are too long
12
docs/tips.md
12
docs/tips.md
File diff suppressed because one or more lines are too long
287
docs/tools.md
Normal file
287
docs/tools.md
Normal file
File diff suppressed because one or more lines are too long
0
core/.gitignore → native/.gitignore
vendored
0
core/.gitignore → native/.gitignore
vendored
@@ -31,7 +31,7 @@ LOCAL_SHARED_LIBRARIES := libsqlite libselinux
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
jni/include \
|
||||
jni/external/include \
|
||||
$(EXT_PATH)/include \
|
||||
$(LIBSELINUX)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
@@ -87,22 +87,21 @@ include $(BUILD_EXECUTABLE)
|
||||
# magiskboot
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := magiskboot
|
||||
LOCAL_STATIC_LIBRARIES := liblzma liblz4 libbz2 libfdt
|
||||
LOCAL_STATIC_LIBRARIES := libmincrypt liblzma liblz4 libbz2 libfdt
|
||||
LOCAL_C_INCLUDES := \
|
||||
jni/include \
|
||||
jni/external/include \
|
||||
$(EXT_PATH)/include \
|
||||
$(LIBLZMA) \
|
||||
$(LIBLZ4) \
|
||||
$(LIBBZ2) \
|
||||
$(LIBFDT)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
external/sha1/sha1.c \
|
||||
magiskboot/main.c \
|
||||
magiskboot/bootimg.c \
|
||||
magiskboot/hexpatch.c \
|
||||
magiskboot/compress.c \
|
||||
magiskboot/types.c \
|
||||
magiskboot/format.c \
|
||||
magiskboot/dtb.c \
|
||||
magiskboot/ramdisk.c \
|
||||
$(UTIL_SRC)
|
||||
@@ -2,3 +2,4 @@ APP_ABI := x86 x86_64 armeabi-v7a arm64-v8a
|
||||
APP_PLATFORM := android-21
|
||||
APP_CFLAGS := $(MAGISK_FLAGS) -std=gnu99
|
||||
APP_CPPFLAGS := -std=c++11
|
||||
APP_SHORT_COMMANDS := true
|
||||
@@ -51,7 +51,7 @@ struct node_entry {
|
||||
static void concat_path(struct node_entry *node) {
|
||||
if (node->parent)
|
||||
concat_path(node->parent);
|
||||
int len = strlen(buf);
|
||||
size_t len = strlen(buf);
|
||||
buf[len] = '/';
|
||||
strcpy(buf + len + 1, node->name);
|
||||
}
|
||||
@@ -140,14 +140,14 @@ static void pm_setenv(struct vector *v) {
|
||||
static void exec_common_script(const char* stage) {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
snprintf(buf, PATH_MAX, "%s/%s.d", COREDIR, stage);
|
||||
snprintf(buf2, PATH_MAX, "%s/%s.d", COREDIR, stage);
|
||||
|
||||
if (!(dir = xopendir(buf)))
|
||||
if (!(dir = xopendir(buf2)))
|
||||
return;
|
||||
|
||||
while ((entry = xreaddir(dir))) {
|
||||
if (entry->d_type == DT_REG) {
|
||||
snprintf(buf2, PATH_MAX, "%s/%s", buf, entry->d_name);
|
||||
snprintf(buf2, PATH_MAX, "%s/%s.d/%s", COREDIR, stage, entry->d_name);
|
||||
if (access(buf2, X_OK) == -1)
|
||||
continue;
|
||||
LOGI("%s.d: exec [%s]\n", stage, entry->d_name);
|
||||
@@ -274,7 +274,7 @@ static void clone_skeleton(struct node_entry *node) {
|
||||
char *con;
|
||||
xstat(full_path, &s);
|
||||
getfilecon(full_path, &con);
|
||||
LOGI("tmpfs: %s\n", full_path);
|
||||
LOGI("mnt_tmpfs : %s\n", full_path);
|
||||
xmount("tmpfs", full_path, "tmpfs", 0, NULL);
|
||||
chmod(full_path, s.st_mode & 0777);
|
||||
chown(full_path, s.st_uid, s.st_gid);
|
||||
@@ -295,7 +295,7 @@ static void clone_skeleton(struct node_entry *node) {
|
||||
if (child->parent->parent == NULL && strcmp(child->name, "vendor") == 0) {
|
||||
if (IS_LNK(child)) {
|
||||
cp_afc(MIRRDIR "/system/vendor", "/system/vendor");
|
||||
LOGI("cplink: %s -> %s\n", MIRRDIR "/system/vendor", "/system/vendor");
|
||||
LOGI("creat_link: %s <- %s\n", "/system/vendor", MIRRDIR "/system/vendor");
|
||||
}
|
||||
// Skip
|
||||
continue;
|
||||
@@ -315,9 +315,9 @@ static void clone_skeleton(struct node_entry *node) {
|
||||
// Copy symlinks directly
|
||||
cp_afc(buf2, buf);
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("cplink: %s -> %s\n",buf2, buf);
|
||||
LOGI("creat_link: %s <- %s\n",buf, buf2);
|
||||
#else
|
||||
LOGI("cplink: %s\n", buf);
|
||||
LOGI("creat_link: %s\n", buf);
|
||||
#endif
|
||||
} else {
|
||||
snprintf(buf, PATH_MAX, "%s/%s", full_path, child->name);
|
||||
@@ -647,23 +647,30 @@ void late_start(int client) {
|
||||
core_only:
|
||||
// Install Magisk Manager if exists
|
||||
if (access(MANAGERAPK, F_OK) == 0) {
|
||||
rename(MANAGERAPK, "/data/magisk.apk");
|
||||
setfilecon("/data/magisk.apk", "u:object_r:su_file:s0");
|
||||
while (1) {
|
||||
sleep(5);
|
||||
int apk_res = -1, pid;
|
||||
pid = exec_command(1, &apk_res, pm_setenv,
|
||||
"app_process",
|
||||
"/system/bin", "com.android.commands.pm.Pm",
|
||||
"install", "-r", MANAGERAPK, NULL);
|
||||
"install", "-r", "/data/magisk.apk", NULL);
|
||||
if (pid != -1) {
|
||||
int err = 0;
|
||||
while (fdgets(buf, PATH_MAX, apk_res) > 0) {
|
||||
LOGD("apk_install: %s", buf);
|
||||
err |= strstr(buf, "Error:") != NULL;
|
||||
}
|
||||
waitpid(pid, NULL, 0);
|
||||
fdgets(buf, PATH_MAX, apk_res);
|
||||
close(apk_res);
|
||||
// Keep trying until pm is started
|
||||
if (strstr(buf, "Error:") == NULL)
|
||||
break;
|
||||
if (err)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
unlink(MANAGERAPK);
|
||||
unlink("/data/magisk.apk");
|
||||
}
|
||||
|
||||
// All boot stage done, cleanup everything
|
||||
@@ -25,7 +25,7 @@ int is_daemon_init = 0, seperate_vendor = 0;
|
||||
static void *request_handler(void *args) {
|
||||
int client = *((int *) args);
|
||||
free(args);
|
||||
client_request req = read_int(client);
|
||||
int req = read_int(client);
|
||||
|
||||
struct ucred credential;
|
||||
get_client_cred(client, &credential);
|
||||
@@ -129,16 +129,12 @@ void daemon_init() {
|
||||
unlink("/data/magisk_debug.log");
|
||||
chmod("/data/adb", 0700);
|
||||
|
||||
// Use shell glob to match files
|
||||
exec_command_sync("sh", "-c",
|
||||
"mv -f /data/adb/magisk/stock_*.img.gz /data;"
|
||||
"rm -f /data/user*/*/magisk.db;", NULL);
|
||||
|
||||
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);
|
||||
@@ -146,13 +142,8 @@ void daemon_init() {
|
||||
chmod("/root", 0755);
|
||||
root = xopen("/root", O_RDONLY | O_CLOEXEC);
|
||||
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
|
||||
dir = xfdopendir(sbin);
|
||||
while((entry = xreaddir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
|
||||
linkat(sbin, entry->d_name, root, entry->d_name, 0);
|
||||
if (strcmp(entry->d_name, "magisk") == 0)
|
||||
unlinkat(sbin, entry->d_name, 0);
|
||||
}
|
||||
link_dir(sbin, root);
|
||||
unlink("/sbin/magisk");
|
||||
close(sbin);
|
||||
|
||||
xmount("tmpfs", "/sbin", "tmpfs", 0, NULL);
|
||||
@@ -165,14 +156,26 @@ void daemon_init() {
|
||||
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("/root/magisk", buf2);
|
||||
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("/root/magiskinit", buf2);
|
||||
xsymlink(buf, buf2);
|
||||
}
|
||||
|
||||
close(root);
|
||||
|
||||
// Backward compatibility
|
||||
@@ -191,7 +194,7 @@ void daemon_init() {
|
||||
// Check whether skip_initramfs device
|
||||
vec_for_each(&mounts, line) {
|
||||
if (strstr(line, " /system_root ")) {
|
||||
xmkdir_p(MIRRDIR "/system", 0755);
|
||||
xmkdirs(MIRRDIR "/system", 0755);
|
||||
bind_mount("/system_root/system", MIRRDIR "/system");
|
||||
skip_initramfs = 1;
|
||||
break;
|
||||
@@ -200,20 +203,20 @@ void daemon_init() {
|
||||
vec_for_each(&mounts, line) {
|
||||
if (!skip_initramfs && strstr(line, " /system ")) {
|
||||
sscanf(line, "%s", buf);
|
||||
xmkdir_p(MIRRDIR "/system", 0755);
|
||||
xmkdirs(MIRRDIR "/system", 0755);
|
||||
xmount(buf, MIRRDIR "/system", "ext4", MS_RDONLY, NULL);
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("mount: %s -> %s\n", buf, MIRRDIR "/system");
|
||||
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);
|
||||
xmkdir_p(MIRRDIR "/vendor", 0755);
|
||||
xmkdirs(MIRRDIR "/vendor", 0755);
|
||||
xmount(buf, MIRRDIR "/vendor", "ext4", MS_RDONLY, NULL);
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("mount: %s -> %s\n", buf, MIRRDIR "/vendor");
|
||||
LOGI("mount: %s <- %s\n", MIRRDIR "/vendor", buf);
|
||||
#else
|
||||
LOGI("mount: %s\n", MIRRDIR "/vendor");
|
||||
#endif
|
||||
@@ -224,16 +227,16 @@ void daemon_init() {
|
||||
if (!seperate_vendor) {
|
||||
xsymlink(MIRRDIR "/system/vendor", MIRRDIR "/vendor");
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("link: %s -> %s\n", MIRRDIR "/system/vendor", MIRRDIR "/vendor");
|
||||
LOGI("link: %s <- %s\n", MIRRDIR "/vendor", MIRRDIR "/system/vendor");
|
||||
#else
|
||||
LOGI("link: %s\n", MIRRDIR "/vendor");
|
||||
#endif
|
||||
}
|
||||
xmkdir_p(MIRRDIR "/bin", 0755);
|
||||
xmkdirs(MIRRDIR "/bin", 0755);
|
||||
bind_mount(DATABIN, MIRRDIR "/bin");
|
||||
|
||||
LOGI("* Setting up internal busybox");
|
||||
xmkdir_p(BBPATH, 0755);
|
||||
xmkdirs(BBPATH, 0755);
|
||||
exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL);
|
||||
xsymlink(MIRRDIR "/bin/busybox", BBPATH "/busybox");
|
||||
}
|
||||
@@ -262,6 +265,9 @@ void start_daemon() {
|
||||
exit(1);
|
||||
xlisten(fd, 10);
|
||||
|
||||
// Start the log monitor
|
||||
monitor_logs();
|
||||
|
||||
if ((is_daemon_init = (access(MAGISKTMP, F_OK) == 0))) {
|
||||
// Restart stuffs if the daemon is restarted
|
||||
exec_command_sync("logcat", "-b", "all", "-c", NULL);
|
||||
@@ -271,9 +277,6 @@ void start_daemon() {
|
||||
daemon_init();
|
||||
}
|
||||
|
||||
// Start the log monitor
|
||||
monitor_logs();
|
||||
|
||||
LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") daemon started\n");
|
||||
|
||||
// Change process name
|
||||
@@ -12,8 +12,10 @@
|
||||
|
||||
#include "magisk.h"
|
||||
#include "utils.h"
|
||||
#include "resetprop.h"
|
||||
|
||||
extern int is_daemon_init;
|
||||
int logd = 0;
|
||||
|
||||
static int am_proc_start_filter(const char *log) {
|
||||
return strstr(log, "am_proc_start") != NULL;
|
||||
@@ -44,9 +46,20 @@ struct log_listener log_events[] = {
|
||||
};
|
||||
|
||||
#ifdef MAGISK_DEBUG
|
||||
static int debug_log_pid, debug_log_fd;
|
||||
static int debug_log_pid = -1, debug_log_fd = -1;
|
||||
#endif
|
||||
|
||||
static void check_logd() {
|
||||
char *prop = getprop("init.svc.logd");
|
||||
if (prop != NULL) {
|
||||
free(prop);
|
||||
logd = 1;
|
||||
} else {
|
||||
LOGD("log_monitor: logd not started, disable logging");
|
||||
logd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void *logger_thread(void *args) {
|
||||
int log_fd = -1, log_pid;
|
||||
char line[4096];
|
||||
@@ -54,8 +67,17 @@ static void *logger_thread(void *args) {
|
||||
LOGD("log_monitor: logger start");
|
||||
|
||||
while (1) {
|
||||
if (!logd) {
|
||||
// Disable all services
|
||||
for (int i = 0; i < (sizeof(log_events) / sizeof(struct log_listener)); ++i) {
|
||||
close(log_events[i].fd);
|
||||
log_events[i].fd = -1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Start logcat
|
||||
log_pid = exec_command(0, &log_fd, NULL, "logcat", "-b", "all" , "-v", "threadtime", "-s", "am_proc_start", "Magisk", NULL);
|
||||
log_pid = exec_command(0, &log_fd, NULL, "logcat", "-b", "events", "-b", "main", "-v", "threadtime", "-s", "am_proc_start", "-s", "Magisk", NULL);
|
||||
while (fdgets(line, sizeof(line), log_fd)) {
|
||||
for (int i = 0; i < (sizeof(log_events) / sizeof(struct log_listener)); ++i) {
|
||||
if (log_events[i].fd > 0 && log_events[i].filter(line)) {
|
||||
@@ -74,7 +96,9 @@ static void *logger_thread(void *args) {
|
||||
waitpid(log_pid, NULL, 0);
|
||||
|
||||
// Clear buffer before restart
|
||||
exec_command_sync("logcat", "-b", "all", "-c", NULL);
|
||||
exec_command_sync("logcat", "-b", "events", "-b", "main", "-c", NULL);
|
||||
|
||||
check_logd();
|
||||
}
|
||||
|
||||
// Should never be here, but well...
|
||||
@@ -139,40 +163,49 @@ static void *debug_magisk_log_thread(void *args) {
|
||||
void monitor_logs() {
|
||||
pthread_t thread;
|
||||
|
||||
// Start log file dumper before monitor
|
||||
xpthread_create(&thread, NULL, magisk_log_thread, NULL);
|
||||
pthread_detach(thread);
|
||||
check_logd();
|
||||
|
||||
// Start logcat monitor
|
||||
xpthread_create(&thread, NULL, logger_thread, NULL);
|
||||
pthread_detach(thread);
|
||||
if (logd) {
|
||||
// Start log file dumper before monitor
|
||||
xpthread_create(&thread, NULL, magisk_log_thread, NULL);
|
||||
pthread_detach(thread);
|
||||
|
||||
// Start logcat monitor
|
||||
xpthread_create(&thread, NULL, logger_thread, NULL);
|
||||
pthread_detach(thread);
|
||||
}
|
||||
}
|
||||
|
||||
void start_debug_full_log() {
|
||||
#ifdef MAGISK_DEBUG
|
||||
// Log everything initially
|
||||
debug_log_fd = xopen(DEBUG_LOG, O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, 0644);
|
||||
debug_log_pid = exec_command(0, &debug_log_fd, NULL, "logcat", "-v", "threadtime", NULL);
|
||||
close(debug_log_fd);
|
||||
if (logd) {
|
||||
// Log everything initially
|
||||
debug_log_fd = xopen(DEBUG_LOG, O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, 0644);
|
||||
debug_log_pid = exec_command(0, &debug_log_fd, NULL, "logcat", "-v", "threadtime", NULL);
|
||||
close(debug_log_fd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void stop_debug_full_log() {
|
||||
#ifdef MAGISK_DEBUG
|
||||
// Stop recording the boot logcat after every boot task is done
|
||||
kill(debug_log_pid, SIGTERM);
|
||||
waitpid(debug_log_pid, NULL, 0);
|
||||
// Start debug thread
|
||||
start_debug_log();
|
||||
if (debug_log_pid > 0) {
|
||||
kill(debug_log_pid, SIGTERM);
|
||||
waitpid(debug_log_pid, NULL, 0);
|
||||
// Start debug thread
|
||||
start_debug_log();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void start_debug_log() {
|
||||
#ifdef MAGISK_DEBUG
|
||||
pthread_t thread;
|
||||
// Start debug thread
|
||||
xpthread_create(&thread, NULL, debug_magisk_log_thread, NULL);
|
||||
pthread_detach(thread);
|
||||
if (logd) {
|
||||
pthread_t thread;
|
||||
// Start debug thread
|
||||
xpthread_create(&thread, NULL, debug_magisk_log_thread, NULL);
|
||||
pthread_detach(thread);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user