mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-29 15:47:38 +00:00
25c557248c
Previously, we use either BroadcastReceivers or Activities to receive messages from our native daemon, but both have their own downsides. Some OEMs blocks broadcasts if the app is not running in the background, regardless of who the caller is. Activities on the other hand, despite working 100% of the time, will steal the focus of the current foreground app, even though we are just doing some logging and showing a toast. In addition, since stubs for hiding Magisk Manager is introduced, our only communication method is left with the broadcast option, as only broadcasting allows targeting a specific package name, not a component name (which will be obfuscated in the case of stubs). To make sure root requests will work on all devices, Magisk had to do some experiments every boot to test whether broadcast is deliverable or not. This makes the whole thing even more complicated then ever. So lets take a look at another kind of component in Android apps: ContentProviders. It is a vital part of Android's ecosystem, and as far as I know no OEMs will block requests to ContentProviders (or else tons of functionality will break catastrophically). Starting at API 11, the system supports calling a specific method in ContentProviders, optionally sending extra data along with the method call. This is perfect for the native daemon to start a communication with Magisk Manager. Another cool thing is that we no longer need to know the component name of the reciever, as ContentProviders identify themselves with an "authority" name, which in Magisk Manager's case is tied to the package name. We already have a mechanism to keep track of our current manager package name, so this works out of the box. So yay! No more flaky broadcast tests, no more stupid OEMs blocking broadcasts for some bizzare reasons. This method should in theory work on almost all devices and situations.
121 lines
3.2 KiB
Bash
Executable File
121 lines
3.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
################################################################
|
|
# AVD Magisk Setup
|
|
################################################################
|
|
#
|
|
# This script will setup an environment with minimal Magisk that
|
|
# Magisk Manager will be happy to run properly within the official
|
|
# emulator bundled with Android Studio (AVD).
|
|
#
|
|
# ONLY use this script for developing Magisk Manager or root apps
|
|
# in the emulator. The constructed Magisk environment is not a
|
|
# fully functional one as if it is running on an actual device.
|
|
#
|
|
# The script assumes you are using x86/x64 emulator images.
|
|
# Build binaries with `./build.py binary` before running this script.
|
|
#
|
|
################################################################
|
|
|
|
abort() {
|
|
echo "$@"
|
|
exit 1
|
|
}
|
|
|
|
mount_sbin() {
|
|
mount -t tmpfs -o 'mode=0755' tmpfs /sbin
|
|
$SELINUX && chcon u:object_r:rootfs:s0 /sbin
|
|
}
|
|
|
|
if [ ! -f /system/build.prop ]; then
|
|
# Running on PC
|
|
cd "`dirname "$0"`/.."
|
|
adb push native/out/x86/busybox scripts/emulator.sh /data/local/tmp
|
|
emu_arch=`adb shell uname -m`
|
|
if [ "$emu_arch" = "x86_64" ]; then
|
|
adb push native/out/x86/magiskinit64 /data/local/tmp/magiskinit
|
|
else
|
|
adb push native/out/x86/magiskinit /data/local/tmp
|
|
fi
|
|
adb shell sh /data/local/tmp/emulator.sh
|
|
exit 0
|
|
fi
|
|
|
|
cd /data/local/tmp
|
|
chmod 777 busybox
|
|
chmod 777 magiskinit
|
|
|
|
if [ `./busybox id -u` -ne 0 ]; then
|
|
# Re-run script with root
|
|
exec /system/xbin/su 0 sh $0
|
|
fi
|
|
|
|
# First setup a good env to work with
|
|
rm -rf bin
|
|
./busybox mkdir bin
|
|
./busybox --install -s bin
|
|
OLD_PATH="$PATH"
|
|
PATH="/data/local/tmp/bin:$PATH"
|
|
|
|
# Remove previous setup if exist
|
|
pgrep magiskd >/dev/null && pkill -9 magiskd
|
|
[ -f /sbin/magisk ] && umount -l /sbin
|
|
|
|
# SELinux stuffs
|
|
[ -e /sys/fs/selinux ] && SELINUX=true || SELINUX=false
|
|
if $SELINUX; then
|
|
ln -sf ./magiskinit magiskpolicy
|
|
./magiskpolicy --live --magisk 'allow magisk * * *'
|
|
fi
|
|
|
|
# Setup sbin overlay
|
|
if mount | grep -q rootfs; then
|
|
mount -o rw,remount /
|
|
rm -rf /root
|
|
mkdir /root
|
|
chmod 750 /root
|
|
ln /sbin/* /root
|
|
mount -o ro,remount /
|
|
mount_sbin
|
|
ln -s /root/* /sbin
|
|
else
|
|
mount_sbin
|
|
mkdir -p /sbin/.magisk/mirror/system_root
|
|
block=`mount | grep ' / ' | awk '{ print $1 }'`
|
|
[ $block = "/dev/root" ] && block=/dev/block/dm-0
|
|
mount -o ro $block /sbin/.magisk/mirror/system_root
|
|
for file in /sbin/.magisk/mirror/system_root/sbin/*; do
|
|
[ ! -e $file ] && break
|
|
if [ -L $file ]; then
|
|
cp -af $file /sbin
|
|
else
|
|
sfile=/sbin/`basename $file`
|
|
touch $sfile
|
|
mount -o bind $file $sfile
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Magisk stuffs
|
|
if [ -e /apex ]; then
|
|
./magiskinit -x magisk /sbin/magisk.bin
|
|
[ -e /system/lib64 ] && LIB=lib64 || LIB=lib
|
|
cat <<EOF > /sbin/magisk
|
|
#!/system/bin/sh
|
|
export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:/apex/com.android.runtime/$LIB"
|
|
exec /sbin/magisk.bin "\$0" "\$@"
|
|
EOF
|
|
else
|
|
./magiskinit -x magisk /sbin/magisk
|
|
fi
|
|
chmod 755 /sbin/magisk
|
|
ln -s ./magisk /sbin/su
|
|
ln -s ./magisk /sbin/resetprop
|
|
ln -s ./magisk /sbin/magiskhide
|
|
mkdir -p /sbin/.magisk/busybox
|
|
cp -af ./busybox /sbin/.magisk/busybox/busybox
|
|
/sbin/.magisk/busybox/busybox --install -s /sbin/.magisk/busybox
|
|
mkdir -p /data/adb/modules 2>/dev/null
|
|
mkdir /data/adb/post-fs-data.d 2>/dev/null
|
|
mkdir /data/adb/services.d 2>/dev/null
|
|
/sbin/magisk --daemon
|