Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
9b3efffb
Commit
9b3efffb
authored
Aug 18, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use magiskd to setup files
parent
003fea52
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
120 additions
and
64 deletions
+120
-64
daemon.cpp
native/jni/core/daemon.cpp
+8
-4
logging.cpp
native/jni/core/logging.cpp
+10
-0
daemon.hpp
native/jni/include/daemon.hpp
+4
-0
entry.cpp
native/jni/zygisk/entry.cpp
+81
-47
inject.hpp
native/jni/zygisk/inject.hpp
+4
-2
emulator.sh
scripts/emulator.sh
+13
-11
No files found.
native/jni/core/daemon.cpp
View file @
9b3efffb
...
...
@@ -68,6 +68,9 @@ static void handle_request_async(int client, int code, ucred cred) {
close
(
client
);
reboot
();
break
;
case
ZYGISK_REQUEST
:
zygisk_handler
(
client
,
&
cred
);
break
;
default:
close
(
client
);
break
;
...
...
@@ -116,6 +119,7 @@ static void handle_request(int client) {
case
BOOT_COMPLETE
:
case
SQLITE_CMD
:
case
GET_PATH
:
case
MAGISKHIDE
:
if
(
!
is_root
)
{
write_int
(
client
,
ROOT_REQUIRED
);
goto
done
;
...
...
@@ -127,9 +131,9 @@ static void handle_request(int client) {
goto
done
;
}
break
;
case
MAGISKHIDE
:
// accept hide request from zygote
if
(
!
is_
root
&&
!
is_
zygote
)
{
write_int
(
client
,
ROOT_REQUIRED
);
case
ZYGISK_REQUEST
:
if
(
!
is_zygote
)
{
write_int
(
client
,
DAEMON_ERROR
);
goto
done
;
}
break
;
...
...
@@ -260,7 +264,7 @@ int connect_daemon(bool create) {
if
(
connect
(
fd
,
(
sockaddr
*
)
&
sun
,
len
))
{
if
(
!
create
||
getuid
()
!=
UID_ROOT
)
{
LOGE
(
"No daemon is currently running!
\n
"
);
exit
(
1
)
;
return
1
;
}
if
(
fork_dont_care
()
==
0
)
{
...
...
native/jni/core/logging.cpp
View file @
9b3efffb
...
...
@@ -158,6 +158,16 @@ void magisk_logging() {
log_cb
.
ex
=
nop_ex
;
}
#define alog(prio) [](auto fmt, auto ap){ \
return __android_log_vprint(ANDROID_LOG_##prio, "Magisk", fmt, ap); }
void
android_logging
()
{
log_cb
.
d
=
alog
(
DEBUG
);
log_cb
.
i
=
alog
(
INFO
);
log_cb
.
w
=
alog
(
WARN
);
log_cb
.
e
=
alog
(
ERROR
);
log_cb
.
ex
=
nop_ex
;
}
void
start_log_daemon
()
{
int
fds
[
2
];
if
(
pipe2
(
fds
,
O_CLOEXEC
)
==
0
)
{
...
...
native/jni/include/daemon.hpp
View file @
9b3efffb
...
...
@@ -25,6 +25,7 @@ enum : int {
MAGISKHIDE
,
SQLITE_CMD
,
REMOVE_MODULES
,
ZYGISK_REQUEST
,
DAEMON_CODE_END
,
};
...
...
@@ -47,12 +48,15 @@ enum : int {
int
connect_daemon
(
bool
create
=
false
);
void
android_logging
();
// Daemon handlers
void
post_fs_data
(
int
client
);
void
late_start
(
int
client
);
void
boot_complete
(
int
client
);
void
magiskhide_handler
(
int
client
,
ucred
*
cred
);
void
su_daemon_handler
(
int
client
,
ucred
*
credential
);
void
zygisk_handler
(
int
client
,
ucred
*
cred
);
// MagiskHide
void
check_enable_hide
();
...
...
native/jni/zygisk/entry.cpp
View file @
9b3efffb
...
...
@@ -3,9 +3,10 @@
#include <sys/mount.h>
#include <sys/sendfile.h>
#include <sys/prctl.h>
#include <android/log.h>
#include <utils.hpp>
#include <daemon.hpp>
#include <magisk.hpp>
#include "inject.hpp"
...
...
@@ -14,16 +15,6 @@ using namespace std;
static
void
*
self_handle
=
nullptr
;
static
atomic
<
int
>
active_threads
=
-
1
;
#define alog(prio) [](auto fmt, auto ap){ \
return __android_log_vprint(ANDROID_LOG_##prio, "Magisk", fmt, ap); }
static
void
inject_logging
()
{
log_cb
.
d
=
alog
(
DEBUG
);
log_cb
.
i
=
alog
(
INFO
);
log_cb
.
w
=
alog
(
WARN
);
log_cb
.
e
=
alog
(
ERROR
);
log_cb
.
ex
=
nop_ex
;
}
void
self_unload
()
{
LOGD
(
"hook: Request to self unload
\n
"
);
// If unhook failed, do not unload or else it will cause SIGSEGV
...
...
@@ -33,7 +24,7 @@ void self_unload() {
active_threads
--
;
}
static
void
*
unload_first_stage
(
void
*
)
{
static
void
*
unload_first_stage
(
void
*
v
)
{
// Setup 1ms
timespec
ts
=
{
.
tv_sec
=
0
,
.
tv_nsec
=
1000000L
};
...
...
@@ -43,7 +34,8 @@ static void *unload_first_stage(void *) {
// Wait another 1ms to make sure all threads left our code
nanosleep
(
&
ts
,
nullptr
);
unmap_all
(
INJECT_LIB_1
);
char
*
path
=
static_cast
<
char
*>
(
v
);
unmap_all
(
path
);
active_threads
--
;
return
nullptr
;
}
...
...
@@ -87,66 +79,108 @@ static void inject_cleanup_wait() {
__attribute__
((
constructor
))
static
void
inject_init
()
{
if
(
getenv
(
INJECT_ENV_2
))
{
inject
_logging
();
if
(
char
*
env
=
getenv
(
INJECT_ENV_2
))
{
android
_logging
();
LOGD
(
"zygote: inject 2nd stage
\n
"
);
active_threads
=
1
;
unsetenv
(
INJECT_ENV_2
);
// Get our own handle
self_handle
=
dlopen
(
INJECT_LIB_2
,
RTLD_LAZY
);
self_handle
=
dlopen
(
env
,
RTLD_LAZY
);
dlclose
(
self_handle
);
unlink
(
INJECT_LIB_2
);
hook_functions
();
// Update path to 1st stage lib
*
(
strrchr
(
env
,
'.'
)
-
1
)
=
'1'
;
// Some cleanup
sanitize_environ
();
active_threads
++
;
new_daemon_thread
(
&
unload_first_stage
);
}
else
if
(
char
*
env
=
getenv
(
INJECT_ENV_1
))
{
inject
_logging
();
new_daemon_thread
(
&
unload_first_stage
,
env
);
}
else
if
(
getenv
(
INJECT_ENV_1
))
{
android
_logging
();
LOGD
(
"zygote: inject 1st stage
\n
"
);
if
(
env
[
0
]
==
'1'
)
char
*
ld
=
getenv
(
"LD_PRELOAD"
);
char
*
path
;
if
(
char
*
c
=
strrchr
(
ld
,
':'
))
{
*
c
=
'\0'
;
setenv
(
"LD_PRELOAD"
,
ld
,
1
);
// Restore original LD_PRELOAD
path
=
c
+
1
;
}
else
{
unsetenv
(
"LD_PRELOAD"
);
else
setenv
(
"LD_PRELOAD"
,
env
,
1
);
// Restore original LD_PRELOAD
path
=
ld
;
}
// Update path to 2nd stage lib
*
(
strrchr
(
path
,
'.'
)
-
1
)
=
'2'
;
// Setup second stage
setenv
(
INJECT_ENV_2
,
"1"
,
1
);
cp_afc
(
INJECT_LIB_1
,
INJECT_LIB_2
);
dlopen
(
INJECT_LIB_2
,
RTLD_LAZY
);
setenv
(
INJECT_ENV_2
,
path
,
1
);
dlopen
(
path
,
RTLD_LAZY
);
unlink
(
INJECT_LIB_1
);
unsetenv
(
INJECT_ENV_1
);
}
}
int
app_process_main
(
int
argc
,
char
*
argv
[])
{
inject_logging
();
char
buf
[
4096
];
if
(
realpath
(
"/proc/self/exe"
,
buf
)
==
nullptr
)
return
1
;
android_logging
();
int
in
=
xopen
(
buf
,
O_RDONLY
);
int
out
=
xopen
(
INJECT_LIB_1
,
O_WRONLY
|
O_CREAT
,
0644
);
sendfile
(
out
,
in
,
nullptr
,
INT_MAX
);
close
(
in
);
close
(
out
);
if
(
int
fd
=
connect_daemon
();
fd
>=
0
)
{
write_int
(
fd
,
ZYGISK_REQUEST
);
write_int
(
fd
,
ZYGISK_SETUP
);
if
(
read_int
(
fd
)
==
0
)
{
string
path
=
read_string
(
fd
);
string
lib
=
path
+
".1.so"
;
if
(
char
*
ld
=
getenv
(
"LD_PRELOAD"
))
{
char
env
[
128
];
sprintf
(
env
,
"%s:"
INJECT_LIB_1
,
ld
);
char
env
[
256
];
sprintf
(
env
,
"%s:%s"
,
ld
,
lib
.
data
()
);
setenv
(
"LD_PRELOAD"
,
env
,
1
);
setenv
(
INJECT_ENV_1
,
ld
,
1
);
// Backup original LD_PRELOAD
}
else
{
setenv
(
"LD_PRELOAD"
,
INJECT_LIB_1
,
1
);
setenv
(
"LD_PRELOAD"
,
lib
.
data
(),
1
);
}
setenv
(
INJECT_ENV_1
,
"1"
,
1
);
}
close
(
fd
);
}
// Execute real app_process
xumount2
(
buf
,
MNT_DETACH
);
char
buf
[
256
];
xreadlink
(
"/proc/self/exe"
,
buf
,
sizeof
(
buf
));
xumount2
(
"/proc/self/exe"
,
MNT_DETACH
);
execve
(
buf
,
argv
,
environ
);
return
1
;
}
// The following code runs in magiskd
static
void
setup_files
(
int
client
,
ucred
*
cred
)
{
LOGD
(
"zygisk: setup files
\n
"
);
char
buf
[
PATH_MAX
];
sprintf
(
buf
,
"/proc/%d/exe"
,
cred
->
pid
);
if
(
realpath
(
buf
,
buf
)
==
nullptr
)
{
write_int
(
client
,
1
);
return
;
}
write_int
(
client
,
0
);
string
path
=
MAGISKTMP
+
"/zygisk."
+
basename
(
buf
);
cp_afc
(
buf
,
(
path
+
".1.so"
).
data
());
cp_afc
(
buf
,
(
path
+
".2.so"
).
data
());
write_string
(
client
,
path
);
}
void
zygisk_handler
(
int
client
,
ucred
*
cred
)
{
int
code
=
read_int
(
client
);
switch
(
code
)
{
case
ZYGISK_SETUP
:
setup_files
(
client
,
cred
);
break
;
}
close
(
client
);
}
native/jni/zygisk/inject.hpp
View file @
9b3efffb
...
...
@@ -3,11 +3,13 @@
#include <stdint.h>
#include <jni.h>
#define INJECT_LIB_1 "/dev/tmp/magisk.1.so"
#define INJECT_LIB_2 "/dev/tmp/magisk.2.so"
#define INJECT_ENV_1 "MAGISK_INJ_1"
#define INJECT_ENV_2 "MAGISK_INJ_2"
enum
:
int
{
ZYGISK_SETUP
,
};
// Unmap all pages matching the name
void
unmap_all
(
const
char
*
name
);
...
...
scripts/emulator.sh
View file @
9b3efffb
...
...
@@ -23,7 +23,7 @@ abort() {
mount_sbin
()
{
mount
-t
tmpfs
-o
'mode=0755'
tmpfs /sbin
$SELINUX
&&
chcon
u:object_r:rootfs:s0 /sbin
chcon
u:object_r:rootfs:s0 /sbin
}
if
[
!
-f
/system/build.prop
]
;
then
...
...
@@ -56,14 +56,14 @@ fi
pgrep magiskd
>
/dev/null
&&
pkill
-9
magiskd
[
-f
/sbin/magisk
]
&&
umount
-l
/sbin
[
-f
/system/bin/magisk
]
&&
umount
-l
/system/bin
if
[
-d
/dev/magisk
]
;
then
umount
-l
/dev/magisk 2>/dev/null
rm
-rf
/dev/magisk
fi
# SELinux stuffs
SELINUX
=
false
[
-e
/sys/fs/selinux
]
&&
SELINUX
=
true
if
$SELINUX
;
then
ln
-sf
./magiskinit magiskpolicy
./magiskpolicy
--live
--magisk
fi
ln
-sf
./magiskinit magiskpolicy
./magiskpolicy
--live
--magisk
BINDIR
=
/sbin
...
...
@@ -99,12 +99,14 @@ elif [ -e /sbin ]; then
done
else
# Android Q+ without sbin, use overlayfs
BINDIR
=
/system/bin
rm
-rf
/dev/magisk
mkdir
-p
/dev/magisk/upper
BINDIR
=
/dev/magisk/upper
mkdir
/dev/magisk
mount
-t
tmpfs
-o
'mode=0755'
tmpfs /dev/magisk
chcon
u:object_r:system_file:s0 /dev/magisk
mkdir
/dev/magisk/upper
mkdir
/dev/magisk/work
./magisk
--clone-attr
/system/bin /dev/magisk/upper
mount
-t
overlay overlay
-olowerdir
=
/system/bin,upperdir
=
/dev/magisk/upper,workdir
=
/dev/magisk/work /system/bin
mount
-t
overlay overlay
-o
lowerdir
=
/system/bin,upperdir
=
/dev/magisk/upper,workdir
=
/dev/magisk/work /system/bin
fi
# Magisk stuffs
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment