mirror of
https://github.com/topjohnwu/Magisk
synced 2025-10-27 04:02:14 +01:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d58a8dc868 | ||
|
|
e94be0b70e | ||
|
|
f6ae7e1bf1 | ||
|
|
f7b4935677 | ||
|
|
a3c49de6a5 | ||
|
|
e8dd1b292f | ||
|
|
d21264d01b | ||
|
|
b0567eadfd | ||
|
|
5fc2058336 | ||
|
|
d0567d29d2 | ||
|
|
4db0ad32f0 | ||
|
|
d065040321 | ||
|
|
17f0fea3fc | ||
|
|
8ca1e43533 | ||
|
|
bd01c314dc | ||
|
|
e404476609 | ||
|
|
942c870981 | ||
|
|
baff9256c5 | ||
|
|
b4c0a255fc | ||
|
|
9f6a27c20d | ||
|
|
742dc137ed | ||
|
|
39a6bd33ce | ||
|
|
4672a5fad6 | ||
|
|
e649b0a2df | ||
|
|
fd8dbe3eff | ||
|
|
bb97cc594d | ||
|
|
70a322263e | ||
|
|
c6f144d482 | ||
|
|
3709489b3a | ||
|
|
145ef32e28 | ||
|
|
2212800a23 | ||
|
|
2e25431bb6 | ||
|
|
32c8e7522f | ||
|
|
a5e4f3cc6b | ||
|
|
a30777bd9f | ||
|
|
e989195a68 | ||
|
|
997d58932e | ||
|
|
b4015f877f | ||
|
|
d15fff95b9 |
13
.gitignore
vendored
13
.gitignore
vendored
@@ -1,9 +1,16 @@
|
||||
out/
|
||||
obj/
|
||||
libs/
|
||||
out
|
||||
*.zip
|
||||
*.jks
|
||||
*.apk
|
||||
|
||||
# Built binaries
|
||||
ziptools/zipadjust
|
||||
|
||||
# Android Studio / Gradle
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
|
||||
18
.gitmodules
vendored
18
.gitmodules
vendored
@@ -1,27 +1,27 @@
|
||||
[submodule "jni/selinux"]
|
||||
path = jni/external/selinux
|
||||
path = core/jni/external/selinux
|
||||
url = https://github.com/topjohnwu/selinux.git
|
||||
[submodule "jni/su"]
|
||||
path = jni/su
|
||||
path = core/jni/su
|
||||
url = https://github.com/topjohnwu/MagiskSU.git
|
||||
[submodule "jni/magiskpolicy"]
|
||||
path = jni/magiskpolicy
|
||||
path = core/jni/magiskpolicy
|
||||
url = https://github.com/topjohnwu/magiskpolicy.git
|
||||
[submodule "MagiskManager"]
|
||||
path = java
|
||||
path = app
|
||||
url = https://github.com/topjohnwu/MagiskManager.git
|
||||
[submodule "jni/busybox"]
|
||||
path = jni/external/busybox
|
||||
path = core/jni/external/busybox
|
||||
url = https://github.com/topjohnwu/ndk-busybox.git
|
||||
[submodule "jni/external/dtc"]
|
||||
path = jni/external/dtc
|
||||
path = core/jni/external/dtc
|
||||
url = https://github.com/dgibson/dtc
|
||||
[submodule "jni/external/lz4"]
|
||||
path = jni/external/lz4
|
||||
path = core/jni/external/lz4
|
||||
url = https://github.com/lz4/lz4.git
|
||||
[submodule "jni/external/bzip2"]
|
||||
path = jni/external/bzip2
|
||||
path = core/jni/external/bzip2
|
||||
url = https://github.com/nemequ/bzip2.git
|
||||
[submodule "jni/external/xz"]
|
||||
path = jni/external/xz
|
||||
path = core/jni/external/xz
|
||||
url = https://github.com/xz-mirror/xz.git
|
||||
|
||||
33
README.MD
33
README.MD
@@ -11,14 +11,15 @@
|
||||
3. Java Development Kit (JDK) 8: Compile Magisk Manager and sign zips
|
||||
4. Latest Android SDK: `ANDROID_HOME` environment variable should point to the Android SDK folder
|
||||
5. Android NDK: Install NDK along with SDK (`$ANDROID_HOME/ndk-bundle`), or specify custom path `ANDROID_NDK`
|
||||
6. (Windows Only) Colorama: Install Colorama with `pip install colorama`, used for ANSI color codes
|
||||
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`
|
||||
|
||||
### Instructions and Notes
|
||||
1. Magisk can be built with the latest NDK (r16 as of writing), however official released binaries will be built with NDK r10e due to ELF incompatibilities with the binaries built from newer NDKs.
|
||||
2. The easiest way to setup a working environment is to open Magisk Manager with Android Studio. The IDE will download required components and construct the environment for you. Don't forget to set `ANDROID_HOME` environment variable to the SDK path.
|
||||
3. Run the script with `-h` as an argument to see the built-in help message. The `-h` option also works for each supported actions, e.g. `./build.py binary -h`
|
||||
4. By default, the script will build binaries and Magisk Manager in debug mode. If you want to build Magisk Manager in release mode (through the flag `--release`), you will need to place your Java Keystore file at `release_signature.jks` to sign Magisk Manager's APK. For more information, check out [Google's Official Documentation](https://developer.android.com/studio/publish/app-signing.html#signing-manually).
|
||||
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.
|
||||
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).
|
||||
|
||||
|
||||
## License
|
||||
@@ -40,12 +41,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
## Credits
|
||||
|
||||
**MagiskManager** (`java`)
|
||||
**MagiskManager** (`app`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* All contributors and translators
|
||||
* All contributors and translators on Github
|
||||
|
||||
**MagiskSU** (`jni/su`)
|
||||
**MagiskSU** (`core/jni/su`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
|
||||
@@ -53,28 +54,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* Copyright 2010, Adam Shanks (@ChainsDD)
|
||||
* Copyright 2008, Zinx Verituse (@zinxv)
|
||||
|
||||
**MagiskPolicy** (`jni/magiskpolicy`)
|
||||
**MagiskPolicy** (`core/jni/magiskpolicy`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
|
||||
* Copyright 2015, Joshua Brindle (@joshua_brindle)
|
||||
|
||||
**MagiskHide** (`jni/magiskhide`)
|
||||
**MagiskHide** (`core/jni/magiskhide`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2016, Pierre-Hugues Husson (phh@phh.me)
|
||||
|
||||
**resetprop** (`jni/resetprop`)
|
||||
**resetprop** (`core/jni/resetprop`)
|
||||
|
||||
* Copyright 2016-2017 John Wu (@topjohnwu)
|
||||
* Copyright 2016 nkk71 (nkk71x@gmail.com)
|
||||
|
||||
**ndk-busybox** (`jni/external/busybox`)
|
||||
**External Dependencies** (`core/jni/external`)
|
||||
|
||||
* Makefile for NDK, generated by [ndk-busybox-kitchen](https://github.com/topjohnwu/ndk-busybox-kitchen): Copyright 2017, John Wu (@topjohnwu)
|
||||
* Patches for NDK: Many contributors along the way, all placed in [osm0sis/android-busybox-ndk](https://github.com/osm0sis/android-busybox-ndk)
|
||||
* The copyright message for busybox should be included in its own directory
|
||||
* 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.
|
||||
All of them are either GPL or GPL compatible.
|
||||
|
||||
**Others Not Mentioned** (exclude `jni/external`)
|
||||
**Others Not Mentioned**
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
|
||||
1
app
Submodule
1
app
Submodule
Submodule app added at 0d9527921a
27
build.gradle
Normal file
27
build.gradle
Normal file
@@ -0,0 +1,27 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
||||
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
76
build.py
76
build.py
@@ -43,6 +43,11 @@ import lzma
|
||||
import base64
|
||||
import tempfile
|
||||
|
||||
if 'ANDROID_NDK' in os.environ:
|
||||
ndk_build = os.path.join(os.environ['ANDROID_NDK'], 'ndk-build')
|
||||
else:
|
||||
ndk_build = os.path.join(os.environ['ANDROID_HOME'], 'ndk-bundle', 'ndk-build')
|
||||
|
||||
def mv(source, target):
|
||||
print('mv: {} -> {}'.format(source, target))
|
||||
shutil.move(source, target)
|
||||
@@ -53,7 +58,7 @@ def cp(source, target):
|
||||
|
||||
def rm(file):
|
||||
try:
|
||||
os.remove(file)
|
||||
os.remove(file)
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
@@ -83,19 +88,14 @@ def build_all(args):
|
||||
def build_binary(args):
|
||||
header('* Building Magisk binaries')
|
||||
|
||||
# Force update Android.mk timestamp to trigger recompilation
|
||||
os.utime(os.path.join('jni', 'Android.mk'))
|
||||
# Force update logging.h timestamp to trigger recompilation
|
||||
os.utime(os.path.join('core', '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)
|
||||
|
||||
if 'ANDROID_NDK' in os.environ:
|
||||
ndk_build = os.path.join(os.environ['ANDROID_NDK'], 'ndk-build')
|
||||
else:
|
||||
ndk_build = os.path.join(os.environ['ANDROID_HOME'], 'ndk-bundle', 'ndk-build')
|
||||
|
||||
# Prebuild
|
||||
proc = subprocess.run('{} PRECOMPILE=true {} -j{}'.format(ndk_build, cflag, multiprocessing.cpu_count()), shell=True)
|
||||
proc = subprocess.run('{} -C core PRECOMPILE=true {} -j{}'.format(ndk_build, cflag, multiprocessing.cpu_count()), shell=True)
|
||||
if proc.returncode != 0:
|
||||
error('Build Magisk binary failed!')
|
||||
|
||||
@@ -104,7 +104,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('libs', arch, 'magisk'), os.path.join('out', arch, 'magisk'))
|
||||
mv(os.path.join('core', '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 +112,7 @@ def build_binary(args):
|
||||
|
||||
print('')
|
||||
|
||||
proc = subprocess.run('{} {} -j{}'.format(ndk_build, cflag, multiprocessing.cpu_count()), shell=True)
|
||||
proc = subprocess.run('{} -C core {} -j{}'.format(ndk_build, cflag, multiprocessing.cpu_count()), shell=True)
|
||||
if proc.returncode != 0:
|
||||
error('Build Magisk binary failed!')
|
||||
|
||||
@@ -120,7 +120,7 @@ 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('libs', arch, binary), os.path.join('out', arch, binary))
|
||||
mv(os.path.join('core', 'libs', arch, binary), os.path.join('out', arch, binary))
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -129,18 +129,16 @@ def build_apk(args):
|
||||
|
||||
for key in ['public.certificate.x509.pem', 'private.key.pk8']:
|
||||
source = os.path.join('ziptools', key)
|
||||
target = os.path.join('java', 'app', 'src', 'main', 'assets', key)
|
||||
target = os.path.join('app', 'src', 'main', 'assets', key)
|
||||
cp(source, target)
|
||||
|
||||
for script in ['magisk_uninstaller.sh', 'util_functions.sh']:
|
||||
source = os.path.join('scripts', script)
|
||||
target = os.path.join('java', 'app', 'src', 'main', 'assets', script)
|
||||
target = os.path.join('app', 'src', 'main', 'assets', script)
|
||||
cp(source, target)
|
||||
|
||||
os.chdir('java')
|
||||
|
||||
if args.release:
|
||||
if not os.path.exists(os.path.join('..', 'release_signature.jks')):
|
||||
if not os.path.exists('release_signature.jks'):
|
||||
error('Please generate a java keystore and place it in \'release_signature.jks\'')
|
||||
|
||||
proc = subprocess.run('{} app:assembleRelease'.format(os.path.join('.', 'gradlew')), shell=True)
|
||||
@@ -173,17 +171,15 @@ def build_apk(args):
|
||||
error('Cannot find apksigner.jar in Android SDK build tools')
|
||||
|
||||
proc = subprocess.run('java -jar {} sign --ks {} --out {} {}'.format(
|
||||
apksigner,
|
||||
os.path.join('..', 'release_signature.jks'),
|
||||
release, aligned), shell=True)
|
||||
apksigner, 'release_signature.jks', release, aligned), shell=True)
|
||||
if proc.returncode != 0:
|
||||
error('Release sign Magisk Manager failed!')
|
||||
|
||||
rm(unsigned)
|
||||
rm(aligned)
|
||||
|
||||
mkdir(os.path.join('..', 'out'))
|
||||
target = os.path.join('..', 'out', 'app-release.apk')
|
||||
mkdir('out')
|
||||
target = os.path.join('out', 'app-release.apk')
|
||||
print('')
|
||||
mv(release, target)
|
||||
else:
|
||||
@@ -192,25 +188,20 @@ def build_apk(args):
|
||||
error('Build Magisk Manager failed!')
|
||||
|
||||
source = os.path.join('app', 'build', 'outputs', 'apk', 'debug', 'app-debug.apk')
|
||||
mkdir(os.path.join('..', 'out'))
|
||||
target = os.path.join('..', 'out', 'app-debug.apk')
|
||||
mkdir('out')
|
||||
target = os.path.join('out', 'app-debug.apk')
|
||||
print('')
|
||||
mv(source, target)
|
||||
|
||||
# Return to upper directory
|
||||
os.chdir('..')
|
||||
|
||||
def build_snet(args):
|
||||
os.chdir('java')
|
||||
proc = subprocess.run('{} snet:assembleRelease'.format(os.path.join('.', 'gradlew')), shell=True)
|
||||
if proc.returncode != 0:
|
||||
error('Build snet extention failed!')
|
||||
source = os.path.join('snet', 'build', 'outputs', 'apk', 'release', 'snet-release-unsigned.apk')
|
||||
mkdir(os.path.join('..', 'out'))
|
||||
target = os.path.join('..', 'out', 'snet.apk')
|
||||
mkdir('out')
|
||||
target = os.path.join('out', 'snet.apk')
|
||||
print('')
|
||||
mv(source, target)
|
||||
os.chdir('..')
|
||||
|
||||
def gen_update_binary():
|
||||
update_bin = []
|
||||
@@ -275,7 +266,7 @@ def zip_main(args):
|
||||
with open(source, 'r') as script:
|
||||
# Add version info util_functions.sh
|
||||
util_func = script.read().replace(
|
||||
'MAGISK_VERSION_STUB', 'MAGISK_VER="{}"\nMAGISK_VER_CODE={}'.format(args.versionString, args.versionCode))
|
||||
'#MAGISK_VERSION_STUB', 'MAGISK_VER="{}"\nMAGISK_VER_CODE={}'.format(args.versionString, args.versionCode))
|
||||
target = os.path.join('common', 'util_functions.sh')
|
||||
print('zip: ' + source + ' -> ' + target)
|
||||
zipf.writestr(target, util_func)
|
||||
@@ -325,11 +316,9 @@ def zip_uninstaller(args):
|
||||
source = os.path.join('scripts', 'util_functions.sh')
|
||||
with open(source, 'r') as script:
|
||||
# Remove the stub
|
||||
util_func = script.read().replace(
|
||||
'MAGISK_VERSION_STUB', '')
|
||||
target = os.path.join('util_functions.sh')
|
||||
print('zip: ' + source + ' -> ' + target)
|
||||
zipf.writestr(target, util_func)
|
||||
zipf.writestr(target, script.read())
|
||||
|
||||
# Prebuilts
|
||||
for chromeos in ['futility', 'kernel_data_key.vbprivk', 'kernel.keyblock']:
|
||||
@@ -342,8 +331,8 @@ def zip_uninstaller(args):
|
||||
sign_adjust_zip(unsigned, output)
|
||||
|
||||
def sign_adjust_zip(unsigned, output):
|
||||
signer_name = 'zipsigner-1.0.jar'
|
||||
jarsigner = os.path.join('java', 'crypto', 'build', 'libs', signer_name)
|
||||
signer_name = 'zipsigner-1.1.jar'
|
||||
jarsigner = os.path.join('crypto', 'build', 'libs', signer_name)
|
||||
|
||||
if os.name != 'nt' and not os.path.exists(os.path.join('ziptools', 'zipadjust')):
|
||||
header('* Building zipadjust')
|
||||
@@ -353,11 +342,9 @@ def sign_adjust_zip(unsigned, output):
|
||||
error('Build zipadjust failed!')
|
||||
if not os.path.exists(jarsigner):
|
||||
header('* Building ' + signer_name)
|
||||
os.chdir('java')
|
||||
proc = subprocess.run('{} crypto:shadowJar'.format(os.path.join('.', 'gradlew')), shell=True)
|
||||
if proc.returncode != 0:
|
||||
error('Build {} failed!'.format(signer_name))
|
||||
os.chdir('..')
|
||||
|
||||
header('* Signing / Adjusting Zip')
|
||||
|
||||
@@ -396,15 +383,14 @@ def cleanup(args):
|
||||
|
||||
if 'binary' in args.target:
|
||||
header('* Cleaning binaries')
|
||||
subprocess.run(os.path.join(os.environ['ANDROID_HOME'], 'ndk-bundle', 'ndk-build') + ' clean', shell=True)
|
||||
subprocess.run(ndk_build + ' -C core PRECOMPILE=true clean', shell=True)
|
||||
subprocess.run(ndk_build + ' -C core 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')
|
||||
os.chdir('java')
|
||||
subprocess.run('{} clean'.format(os.path.join('.', 'gradlew')), shell=True)
|
||||
os.chdir('..')
|
||||
subprocess.run('{} app:clean snet:clean crypto:clean'.format(os.path.join('.', 'gradlew')), shell=True)
|
||||
for f in os.listdir('out'):
|
||||
if '.apk' in f:
|
||||
rm(os.path.join('out', f))
|
||||
@@ -448,8 +434,8 @@ clean_parser.add_argument('target', nargs='*')
|
||||
clean_parser.set_defaults(func=cleanup)
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
3
core/.gitignore
vendored
Normal file
3
core/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/build
|
||||
obj
|
||||
libs
|
||||
20
core/build.gradle
Normal file
20
core/build.gradle
Normal file
@@ -0,0 +1,20 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
path 'jni/Android.mk'
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
// Passes an optional argument to ndk-build.
|
||||
arguments "GRADLE=true"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,20 @@ LIBLZMA := $(EXT_PATH)/xz/src/liblzma/api
|
||||
LIBLZ4 := $(EXT_PATH)/lz4/lib
|
||||
LIBBZ2 := $(EXT_PATH)/bzip2
|
||||
LIBFDT := $(EXT_PATH)/dtc/libfdt
|
||||
UTIL_SRC := utils/cpio.c \
|
||||
utils/file.c \
|
||||
utils/img.c \
|
||||
utils/list.c \
|
||||
utils/misc.c \
|
||||
utils/pattern.c \
|
||||
utils/vector.c \
|
||||
utils/xwrap.c
|
||||
|
||||
########################
|
||||
# Binaries
|
||||
########################
|
||||
|
||||
ifdef PRECOMPILE
|
||||
ifneq "$(or $(PRECOMPILE), $(GRADLE))" ""
|
||||
|
||||
# magisk main binary
|
||||
include $(CLEAR_VARS)
|
||||
@@ -23,7 +31,7 @@ LOCAL_SHARED_LIBRARIES := libsqlite libselinux
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
jni/include \
|
||||
jni/external \
|
||||
jni/external/include \
|
||||
$(LIBSELINUX)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
@@ -31,12 +39,7 @@ LOCAL_SRC_FILES := \
|
||||
core/daemon.c \
|
||||
core/log_monitor.c \
|
||||
core/bootstages.c \
|
||||
utils/misc.c \
|
||||
utils/vector.c \
|
||||
utils/xwrap.c \
|
||||
utils/list.c \
|
||||
utils/img.c \
|
||||
utils/file.c \
|
||||
core/socket.c \
|
||||
magiskhide/magiskhide.c \
|
||||
magiskhide/proc_monitor.c \
|
||||
magiskhide/hide_utils.c \
|
||||
@@ -47,14 +50,16 @@ LOCAL_SRC_FILES := \
|
||||
su/db.c \
|
||||
su/pts.c \
|
||||
su/su_daemon.c \
|
||||
su/su_socket.c
|
||||
su/su_socket.c \
|
||||
$(UTIL_SRC)
|
||||
|
||||
LOCAL_CFLAGS := -DIS_DAEMON
|
||||
LOCAL_CFLAGS := -DIS_DAEMON -DSELINUX
|
||||
LOCAL_LDLIBS := -llog
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# precompile
|
||||
else
|
||||
endif
|
||||
|
||||
ifndef PRECOMPILE
|
||||
|
||||
# magiskinit
|
||||
include $(CLEAR_VARS)
|
||||
@@ -62,21 +67,20 @@ LOCAL_MODULE := magiskinit
|
||||
LOCAL_STATIC_LIBRARIES := libsepol liblzma
|
||||
LOCAL_C_INCLUDES := \
|
||||
jni/include \
|
||||
out/$(TARGET_ARCH_ABI) \
|
||||
jni/magiskpolicy \
|
||||
../out/$(TARGET_ARCH_ABI) \
|
||||
$(LIBSEPOL) \
|
||||
$(LIBLZMA)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
core/magiskinit.c \
|
||||
utils/vector.c \
|
||||
utils/file.c \
|
||||
utils/xwrap.c \
|
||||
core/socket.c \
|
||||
magiskpolicy/api.c \
|
||||
magiskpolicy/magiskpolicy.c \
|
||||
magiskpolicy/rules.c \
|
||||
magiskpolicy/sepolicy.c
|
||||
magiskpolicy/sepolicy.c \
|
||||
$(UTIL_SRC)
|
||||
|
||||
LOCAL_CFLAGS := -DNO_SELINUX
|
||||
LOCAL_LDFLAGS := -static
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
@@ -86,29 +90,29 @@ LOCAL_MODULE := magiskboot
|
||||
LOCAL_STATIC_LIBRARIES := liblzma liblz4 libbz2 libfdt
|
||||
LOCAL_C_INCLUDES := \
|
||||
jni/include \
|
||||
jni/external/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/cpio.c \
|
||||
magiskboot/sha1.c \
|
||||
magiskboot/types.c \
|
||||
magiskboot/dtb.c \
|
||||
utils/xwrap.c \
|
||||
utils/file.c \
|
||||
utils/vector.c
|
||||
magiskboot/ramdisk.c \
|
||||
$(UTIL_SRC)
|
||||
|
||||
LOCAL_CFLAGS := -DNO_SELINUX
|
||||
LOCAL_CFLAGS := -DXWRAP_EXIT
|
||||
LOCAL_LDLIBS := -lz
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# 32-bit static binaries
|
||||
ifndef GRADLE # Do not run gradle sync on these binaries
|
||||
ifneq ($(TARGET_ARCH_ABI), x86_64)
|
||||
ifneq ($(TARGET_ARCH_ABI), arm64-v8a)
|
||||
# b64xz
|
||||
@@ -123,6 +127,7 @@ include $(BUILD_EXECUTABLE)
|
||||
include jni/external/busybox/Android.mk
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# Precompile
|
||||
endif
|
||||
@@ -11,8 +11,6 @@
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <linux/loop.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/wait.h>
|
||||
#include <selinux/selinux.h>
|
||||
@@ -24,7 +22,6 @@
|
||||
|
||||
static char *buf, *buf2;
|
||||
static struct vector module_list;
|
||||
static int seperate_vendor = 0;
|
||||
|
||||
extern char **environ;
|
||||
|
||||
@@ -395,102 +392,6 @@ static void simple_mount(const char *path) {
|
||||
* Miscellaneous *
|
||||
*****************/
|
||||
|
||||
// A one time setup
|
||||
static void daemon_init() {
|
||||
LOGI("* Creating /sbin overlay");
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
int root, sbin;
|
||||
// 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);
|
||||
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);
|
||||
}
|
||||
close(sbin);
|
||||
xmount("tmpfs", "/sbin", "tmpfs", 0, NULL);
|
||||
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
|
||||
fchmod(sbin, 0755);
|
||||
fsetfilecon(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);
|
||||
}
|
||||
for (int i = 0; applet[i]; ++i) {
|
||||
snprintf(buf2, PATH_MAX, "/sbin/%s", applet[i]);
|
||||
xsymlink("/root/magisk", buf2);
|
||||
}
|
||||
xsymlink(MOUNTPOINT, FAKEPOINT);
|
||||
close(root);
|
||||
close(sbin);
|
||||
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 ")) {
|
||||
xmkdir_p(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);
|
||||
xmkdir_p(MIRRDIR "/system", 0755);
|
||||
xmount(buf, MIRRDIR "/system", "ext4", MS_RDONLY, NULL);
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("mount: %s -> %s\n", buf, MIRRDIR "/system");
|
||||
#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);
|
||||
xmount(buf, MIRRDIR "/vendor", "ext4", MS_RDONLY, NULL);
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("mount: %s -> %s\n", buf, MIRRDIR "/vendor");
|
||||
#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 "/system/vendor", MIRRDIR "/vendor");
|
||||
#else
|
||||
LOGI("link: %s\n", MIRRDIR "/vendor");
|
||||
#endif
|
||||
}
|
||||
xmkdir_p(MIRRDIR "/bin", 0755);
|
||||
bind_mount(DATABIN, MIRRDIR "/bin");
|
||||
|
||||
LOGI("* Setting up internal busybox");
|
||||
xmkdir_p(BBPATH, 0755);
|
||||
exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL);
|
||||
xsymlink(MIRRDIR "/bin/busybox", BBPATH "/busybox");
|
||||
}
|
||||
|
||||
static int prepare_img() {
|
||||
// First merge images
|
||||
if (merge_img("/data/magisk_merge.img", MAINIMG)) {
|
||||
@@ -509,8 +410,6 @@ static int prepare_img() {
|
||||
if (magiskloop == NULL)
|
||||
return 1;
|
||||
|
||||
vec_init(&module_list);
|
||||
|
||||
xmkdir(COREDIR, 0755);
|
||||
xmkdir(COREDIR "/post-fs-data.d", 0755);
|
||||
xmkdir(COREDIR "/service.d", 0755);
|
||||
@@ -575,9 +474,6 @@ void post_fs(int client) {
|
||||
write_int(client, 0);
|
||||
close(client);
|
||||
|
||||
// Allow magiskinit to full patch
|
||||
close(creat(PATCHSTART, 0));
|
||||
|
||||
// Uninstall or core only mode
|
||||
if (access(UNINSTALLER, F_OK) == 0 || access(DISABLEFILE, F_OK) == 0)
|
||||
goto unblock;
|
||||
@@ -608,26 +504,11 @@ void post_fs_data(int client) {
|
||||
// Allocate buffer
|
||||
if (buf == NULL) buf = xmalloc(PATH_MAX);
|
||||
if (buf2 == NULL) buf2 = xmalloc(PATH_MAX);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Lazy.... use shell blob to match files
|
||||
exec_command_sync("sh", "-c", "mv -f /data/magisk/stock_*.img.gz /data", NULL);
|
||||
vec_init(&module_list);
|
||||
|
||||
// Initialize
|
||||
daemon_init();
|
||||
if (!is_daemon_init)
|
||||
daemon_init();
|
||||
|
||||
// uninstaller
|
||||
if (access(UNINSTALLER, F_OK) == 0) {
|
||||
@@ -744,8 +625,7 @@ void late_start(int client) {
|
||||
if (buf2 == NULL) buf2 = xmalloc(PATH_MAX);
|
||||
|
||||
// Wait till the full patch is done
|
||||
while (access(PATCHDONE, F_OK) == -1)
|
||||
usleep(500); /* Wait 0.5ms */
|
||||
wait_till_exists(PATCHDONE);
|
||||
unlink(PATCHDONE);
|
||||
|
||||
// Run scripts after full patch, most reliable way to run scripts
|
||||
318
core/jni/core/daemon.c
Normal file
318
core/jni/core/daemon.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
@@ -14,8 +13,35 @@
|
||||
#include "magisk.h"
|
||||
#include "utils.h"
|
||||
|
||||
int logcat_events[] = { -1, -1, -1 };
|
||||
extern int is_restart;
|
||||
extern int is_daemon_init;
|
||||
|
||||
static int am_proc_start_filter(const char *log) {
|
||||
return strstr(log, "am_proc_start") != NULL;
|
||||
}
|
||||
|
||||
static int magisk_log_filter(const char *log) {
|
||||
char *ss;
|
||||
return (ss = strstr(log, " Magisk")) && (ss[-1] != 'D') && (ss[-1] != 'V');
|
||||
}
|
||||
|
||||
static int magisk_debug_log_filter(const char *log) {
|
||||
return strstr(log, "Magisk") != NULL;
|
||||
}
|
||||
|
||||
struct log_listener log_events[] = {
|
||||
{ /* HIDE_EVENT */
|
||||
.fd = -1,
|
||||
.filter = am_proc_start_filter
|
||||
},
|
||||
{ /* LOG_EVENT */
|
||||
.fd = -1,
|
||||
.filter = magisk_log_filter
|
||||
},
|
||||
{ /* DEBUG_EVENT */
|
||||
.fd = -1,
|
||||
.filter = magisk_debug_log_filter
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef MAGISK_DEBUG
|
||||
static int debug_log_pid, debug_log_fd;
|
||||
@@ -31,16 +57,23 @@ static void *logger_thread(void *args) {
|
||||
// Start logcat
|
||||
log_pid = exec_command(0, &log_fd, NULL, "logcat", "-b", "all" , "-v", "threadtime", "-s", "am_proc_start", "Magisk", NULL);
|
||||
while (fdgets(line, sizeof(line), log_fd)) {
|
||||
for (int i = 0; i < (sizeof(logcat_events) / sizeof(int)); ++i) {
|
||||
if (logcat_events[i] > 0) {
|
||||
for (int i = 0; i < (sizeof(log_events) / sizeof(struct log_listener)); ++i) {
|
||||
if (log_events[i].fd > 0 && log_events[i].filter(line)) {
|
||||
char *s = strdup(line);
|
||||
xwrite(logcat_events[i], &s, sizeof(s));
|
||||
xwrite(log_events[i].fd, &s, sizeof(s));
|
||||
}
|
||||
}
|
||||
if (kill(log_pid, 0))
|
||||
break;
|
||||
}
|
||||
// Clear buffer if restart required
|
||||
|
||||
// Cleanup
|
||||
close(log_fd);
|
||||
log_fd = -1;
|
||||
kill(log_pid, SIGTERM);
|
||||
waitpid(log_pid, NULL, 0);
|
||||
|
||||
// Clear buffer before restart
|
||||
exec_command_sync("logcat", "-b", "all", "-c", NULL);
|
||||
}
|
||||
|
||||
@@ -51,43 +84,38 @@ static void *logger_thread(void *args) {
|
||||
static void *magisk_log_thread(void *args) {
|
||||
int have_data = 0;
|
||||
|
||||
// Temp buffer for logs before we have data access
|
||||
// Buffer logs before we have data access
|
||||
struct vector logs;
|
||||
vec_init(&logs);
|
||||
|
||||
FILE *log;
|
||||
int pipefd[2];
|
||||
if (xpipe2(pipefd, O_CLOEXEC) == -1)
|
||||
return NULL;
|
||||
|
||||
// Register our listener
|
||||
logcat_events[LOG_EVENT] = pipefd[1];
|
||||
log_events[LOG_EVENT].fd = pipefd[1];
|
||||
|
||||
LOGD("log_monitor: magisk log dumper start");
|
||||
|
||||
FILE *log;
|
||||
for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) {
|
||||
char *ss;
|
||||
if ((ss = strstr(line, " Magisk")) && (ss[-1] != 'D') && (ss[-1] != 'V')) {
|
||||
if (!have_data) {
|
||||
if ((have_data = check_data())) {
|
||||
// Dump buffered logs to file
|
||||
if (!is_restart)
|
||||
rename(LOGFILE, LASTLOG);
|
||||
log = xfopen(LOGFILE, "a");
|
||||
setbuf(log, NULL);
|
||||
char *tmp;
|
||||
vec_for_each(&logs, tmp) {
|
||||
fprintf(log, "%s", tmp);
|
||||
free(tmp);
|
||||
}
|
||||
vec_destroy(&logs);
|
||||
} else {
|
||||
vec_push_back(&logs, strdup(line));
|
||||
if (!have_data) {
|
||||
if ((have_data = check_data())) {
|
||||
// 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);
|
||||
} else {
|
||||
vec_push_back(&logs, strdup(line));
|
||||
}
|
||||
if (have_data)
|
||||
fprintf(log, "%s", line);
|
||||
}
|
||||
if (have_data)
|
||||
fprintf(log, "%s", line);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -102,13 +130,11 @@ static void *debug_magisk_log_thread(void *args) {
|
||||
LOGD("log_monitor: debug log dumper start");
|
||||
|
||||
// Register our listener
|
||||
logcat_events[DEBUG_EVENT] = pipefd[1];
|
||||
log_events[DEBUG_EVENT].fd = pipefd[1];
|
||||
|
||||
for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line))
|
||||
fprintf(log, "%s", line);
|
||||
|
||||
for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) {
|
||||
char *ss;
|
||||
if ((ss = strstr(line, "Magisk")))
|
||||
fprintf(log, "%s", line);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -12,11 +12,7 @@
|
||||
|
||||
char *argv0;
|
||||
|
||||
char *applet[] =
|
||||
{ "su", "resetprop", "magiskhide", NULL };
|
||||
|
||||
int (*applet_main[]) (int, char *[]) =
|
||||
{ su_client_main, resetprop_main, magiskhide_main, NULL };
|
||||
int (*applet_main[]) (int, char *[]) = { su_client_main, resetprop_main, magiskhide_main, NULL };
|
||||
|
||||
int create_links(const char *bin, const char *path) {
|
||||
char self[PATH_MAX], linkpath[PATH_MAX];
|
||||
@@ -44,7 +40,7 @@ static void usage() {
|
||||
" -c print current binary version\n"
|
||||
" -v print running daemon version\n"
|
||||
" -V print running daemon version code\n"
|
||||
" --list list all availible applets\n"
|
||||
" --list list all available applets\n"
|
||||
" --install [SOURCE] DIR symlink all applets to DIR. SOURCE is optional\n"
|
||||
" --createimg IMG SIZE create ext4 image. SIZE is interpreted in MB\n"
|
||||
" --imgsize IMG report ext4 image used/total size\n"
|
||||
@@ -73,7 +69,7 @@ int main(int argc, char *argv[]) {
|
||||
if (strcmp(basename(argv[0]), "magisk") == 0) {
|
||||
if (argc < 2) usage();
|
||||
if (strcmp(argv[1], "-c") == 0) {
|
||||
printf("%s\n", MAGISK_VER_STR);
|
||||
printf("%s (%d)\n", MAGISK_VER_STR, MAGISK_VER_CODE);
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "-v") == 0) {
|
||||
int fd = connect_daemon();
|
||||
@@ -148,8 +144,9 @@ int main(int argc, char *argv[]) {
|
||||
clone_attr(argv[2], argv[3]);
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "--daemon") == 0) {
|
||||
// Start daemon, this process won't return
|
||||
start_daemon();
|
||||
if (xfork() == 0)
|
||||
start_daemon();
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "--post-fs") == 0) {
|
||||
int fd = connect_daemon();
|
||||
write_int(fd, POST_FS);
|
||||
File diff suppressed because it is too large
Load Diff
152
core/jni/core/socket.c
Normal file
152
core/jni/core/socket.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/* 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);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ LOCAL_PATH:= $(call my-dir)
|
||||
# libsqlite.so (stub)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE:= libsqlite
|
||||
LOCAL_C_INCLUDES := jni/external/include
|
||||
LOCAL_SRC_FILES := stubs/sqlite3_stub.c
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
@@ -58,7 +59,7 @@ include $(BUILD_STATIC_LIBRARY)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := liblzma
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(EXT_PATH)/xz_config \
|
||||
$(EXT_PATH)/include/xz_config \
|
||||
$(EXT_PATH)/xz/src/common \
|
||||
$(EXT_PATH)/xz/src/liblzma/api \
|
||||
$(EXT_PATH)/xz/src/liblzma/check \
|
||||
0
jni/external/xz → core/jni/external/xz
vendored
0
jni/external/xz → core/jni/external/xz
vendored
60
core/jni/include/cpio.h
Normal file
60
core/jni/include/cpio.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef _CPIO_H_
|
||||
#define _CPIO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "vector.h"
|
||||
|
||||
typedef struct cpio_entry {
|
||||
// uint32_t ino;
|
||||
uint32_t mode;
|
||||
uint32_t uid;
|
||||
uint32_t gid;
|
||||
// uint32_t nlink;
|
||||
// uint32_t mtime;
|
||||
uint32_t filesize;
|
||||
// uint32_t devmajor;
|
||||
// uint32_t devminor;
|
||||
// uint32_t rdevmajor;
|
||||
// uint32_t rdevminor;
|
||||
// uint32_t namesize;
|
||||
// uint32_t check;
|
||||
char *filename;
|
||||
void *data;
|
||||
int remove;
|
||||
} cpio_entry;
|
||||
|
||||
typedef struct cpio_newc_header {
|
||||
char magic[6];
|
||||
char ino[8];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char nlink[8];
|
||||
char mtime[8];
|
||||
char filesize[8];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
char rdevmajor[8];
|
||||
char rdevminor[8];
|
||||
char namesize[8];
|
||||
char check[8];
|
||||
} cpio_newc_header;
|
||||
|
||||
// Basic cpio functions
|
||||
void cpio_free(cpio_entry *e);
|
||||
int cpio_find(struct vector *v, const char *entry);
|
||||
int cpio_cmp(const void *a, const void *b);
|
||||
void parse_cpio(struct vector *v, const char *filename);
|
||||
void dump_cpio(struct vector *v, const char *filename);
|
||||
void cpio_vec_insert(struct vector *v, cpio_entry *n);
|
||||
void cpio_vec_destroy(struct vector *v);
|
||||
void cpio_rm(struct vector *v, int recursive, const char *entry);
|
||||
void cpio_mkdir(struct vector *v, mode_t mode, const char *entry);
|
||||
void cpio_ln(struct vector *v, const char *target, const char *entry);
|
||||
void cpio_add(struct vector *v, mode_t mode, const char *entry, const char *filename);
|
||||
int cpio_mv(struct vector *v, const char *from, const char *to);
|
||||
int cpio_extract(struct vector *v, const char *entry, const char *filename);
|
||||
void cpio_extract_all(struct vector *v);
|
||||
|
||||
#endif
|
||||
@@ -5,9 +5,10 @@
|
||||
#define _DAEMON_H_
|
||||
|
||||
#include <pthread.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
extern pthread_t sepol_patch;
|
||||
extern int is_restart;
|
||||
extern int is_daemon_init, seperate_vendor;
|
||||
|
||||
// Commands require connecting to daemon
|
||||
typedef enum {
|
||||
@@ -42,6 +43,11 @@ typedef enum {
|
||||
void start_daemon();
|
||||
int connect_daemon();
|
||||
void auto_start_magiskhide();
|
||||
void daemon_init();
|
||||
|
||||
// socket.c
|
||||
|
||||
int setup_socket(struct sockaddr_un *sun);
|
||||
int recv_fd(int sockfd);
|
||||
void send_fd(int sockfd, int fd);
|
||||
int read_int(int fd);
|
||||
@@ -72,6 +78,6 @@ void ls_hide_list(int client);
|
||||
* Superuser *
|
||||
*************/
|
||||
|
||||
void su_daemon_receiver(int client);
|
||||
void su_daemon_receiver(int client, struct ucred *credential);
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user