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
Hide 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) {
...
@@ -68,6 +68,9 @@ static void handle_request_async(int client, int code, ucred cred) {
close
(
client
);
close
(
client
);
reboot
();
reboot
();
break
;
break
;
case
ZYGISK_REQUEST
:
zygisk_handler
(
client
,
&
cred
);
break
;
default:
default:
close
(
client
);
close
(
client
);
break
;
break
;
...
@@ -116,6 +119,7 @@ static void handle_request(int client) {
...
@@ -116,6 +119,7 @@ static void handle_request(int client) {
case
BOOT_COMPLETE
:
case
BOOT_COMPLETE
:
case
SQLITE_CMD
:
case
SQLITE_CMD
:
case
GET_PATH
:
case
GET_PATH
:
case
MAGISKHIDE
:
if
(
!
is_root
)
{
if
(
!
is_root
)
{
write_int
(
client
,
ROOT_REQUIRED
);
write_int
(
client
,
ROOT_REQUIRED
);
goto
done
;
goto
done
;
...
@@ -127,9 +131,9 @@ static void handle_request(int client) {
...
@@ -127,9 +131,9 @@ static void handle_request(int client) {
goto
done
;
goto
done
;
}
}
break
;
break
;
case
MAGISKHIDE
:
// accept hide request from zygote
case
ZYGISK_REQUEST
:
if
(
!
is_
root
&&
!
is_
zygote
)
{
if
(
!
is_zygote
)
{
write_int
(
client
,
ROOT_REQUIRED
);
write_int
(
client
,
DAEMON_ERROR
);
goto
done
;
goto
done
;
}
}
break
;
break
;
...
@@ -260,7 +264,7 @@ int connect_daemon(bool create) {
...
@@ -260,7 +264,7 @@ int connect_daemon(bool create) {
if
(
connect
(
fd
,
(
sockaddr
*
)
&
sun
,
len
))
{
if
(
connect
(
fd
,
(
sockaddr
*
)
&
sun
,
len
))
{
if
(
!
create
||
getuid
()
!=
UID_ROOT
)
{
if
(
!
create
||
getuid
()
!=
UID_ROOT
)
{
LOGE
(
"No daemon is currently running!
\n
"
);
LOGE
(
"No daemon is currently running!
\n
"
);
exit
(
1
)
;
return
1
;
}
}
if
(
fork_dont_care
()
==
0
)
{
if
(
fork_dont_care
()
==
0
)
{
...
...
native/jni/core/logging.cpp
View file @
9b3efffb
...
@@ -158,6 +158,16 @@ void magisk_logging() {
...
@@ -158,6 +158,16 @@ void magisk_logging() {
log_cb
.
ex
=
nop_ex
;
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
()
{
void
start_log_daemon
()
{
int
fds
[
2
];
int
fds
[
2
];
if
(
pipe2
(
fds
,
O_CLOEXEC
)
==
0
)
{
if
(
pipe2
(
fds
,
O_CLOEXEC
)
==
0
)
{
...
...
native/jni/include/daemon.hpp
View file @
9b3efffb
...
@@ -25,6 +25,7 @@ enum : int {
...
@@ -25,6 +25,7 @@ enum : int {
MAGISKHIDE
,
MAGISKHIDE
,
SQLITE_CMD
,
SQLITE_CMD
,
REMOVE_MODULES
,
REMOVE_MODULES
,
ZYGISK_REQUEST
,
DAEMON_CODE_END
,
DAEMON_CODE_END
,
};
};
...
@@ -47,12 +48,15 @@ enum : int {
...
@@ -47,12 +48,15 @@ enum : int {
int
connect_daemon
(
bool
create
=
false
);
int
connect_daemon
(
bool
create
=
false
);
void
android_logging
();
// Daemon handlers
// Daemon handlers
void
post_fs_data
(
int
client
);
void
post_fs_data
(
int
client
);
void
late_start
(
int
client
);
void
late_start
(
int
client
);
void
boot_complete
(
int
client
);
void
boot_complete
(
int
client
);
void
magiskhide_handler
(
int
client
,
ucred
*
cred
);
void
magiskhide_handler
(
int
client
,
ucred
*
cred
);
void
su_daemon_handler
(
int
client
,
ucred
*
credential
);
void
su_daemon_handler
(
int
client
,
ucred
*
credential
);
void
zygisk_handler
(
int
client
,
ucred
*
cred
);
// MagiskHide
// MagiskHide
void
check_enable_hide
();
void
check_enable_hide
();
...
...
native/jni/zygisk/entry.cpp
View file @
9b3efffb
...
@@ -3,9 +3,10 @@
...
@@ -3,9 +3,10 @@
#include <sys/mount.h>
#include <sys/mount.h>
#include <sys/sendfile.h>
#include <sys/sendfile.h>
#include <sys/prctl.h>
#include <sys/prctl.h>
#include <android/log.h>
#include <utils.hpp>
#include <utils.hpp>
#include <daemon.hpp>
#include <magisk.hpp>
#include "inject.hpp"
#include "inject.hpp"
...
@@ -14,16 +15,6 @@ using namespace std;
...
@@ -14,16 +15,6 @@ using namespace std;
static
void
*
self_handle
=
nullptr
;
static
void
*
self_handle
=
nullptr
;
static
atomic
<
int
>
active_threads
=
-
1
;
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
()
{
void
self_unload
()
{
LOGD
(
"hook: Request to self unload
\n
"
);
LOGD
(
"hook: Request to self unload
\n
"
);
// If unhook failed, do not unload or else it will cause SIGSEGV
// If unhook failed, do not unload or else it will cause SIGSEGV
...
@@ -33,7 +24,7 @@ void self_unload() {
...
@@ -33,7 +24,7 @@ void self_unload() {
active_threads
--
;
active_threads
--
;
}
}
static
void
*
unload_first_stage
(
void
*
)
{
static
void
*
unload_first_stage
(
void
*
v
)
{
// Setup 1ms
// Setup 1ms
timespec
ts
=
{
.
tv_sec
=
0
,
.
tv_nsec
=
1000000L
};
timespec
ts
=
{
.
tv_sec
=
0
,
.
tv_nsec
=
1000000L
};
...
@@ -43,7 +34,8 @@ static void *unload_first_stage(void *) {
...
@@ -43,7 +34,8 @@ static void *unload_first_stage(void *) {
// Wait another 1ms to make sure all threads left our code
// Wait another 1ms to make sure all threads left our code
nanosleep
(
&
ts
,
nullptr
);
nanosleep
(
&
ts
,
nullptr
);
unmap_all
(
INJECT_LIB_1
);
char
*
path
=
static_cast
<
char
*>
(
v
);
unmap_all
(
path
);
active_threads
--
;
active_threads
--
;
return
nullptr
;
return
nullptr
;
}
}
...
@@ -87,66 +79,108 @@ static void inject_cleanup_wait() {
...
@@ -87,66 +79,108 @@ static void inject_cleanup_wait() {
__attribute__
((
constructor
))
__attribute__
((
constructor
))
static
void
inject_init
()
{
static
void
inject_init
()
{
if
(
getenv
(
INJECT_ENV_2
))
{
if
(
char
*
env
=
getenv
(
INJECT_ENV_2
))
{
inject
_logging
();
android
_logging
();
LOGD
(
"zygote: inject 2nd stage
\n
"
);
LOGD
(
"zygote: inject 2nd stage
\n
"
);
active_threads
=
1
;
active_threads
=
1
;
unsetenv
(
INJECT_ENV_2
);
unsetenv
(
INJECT_ENV_2
);
// Get our own handle
// Get our own handle
self_handle
=
dlopen
(
INJECT_LIB_2
,
RTLD_LAZY
);
self_handle
=
dlopen
(
env
,
RTLD_LAZY
);
dlclose
(
self_handle
);
dlclose
(
self_handle
);
unlink
(
INJECT_LIB_2
);
hook_functions
();
hook_functions
();
// Update path to 1st stage lib
*
(
strrchr
(
env
,
'.'
)
-
1
)
=
'1'
;
// Some cleanup
// Some cleanup
sanitize_environ
();
sanitize_environ
();
active_threads
++
;
active_threads
++
;
new_daemon_thread
(
&
unload_first_stage
);
new_daemon_thread
(
&
unload_first_stage
,
env
);
}
else
if
(
char
*
env
=
getenv
(
INJECT_ENV_1
))
{
}
else
if
(
getenv
(
INJECT_ENV_1
))
{
inject
_logging
();
android
_logging
();
LOGD
(
"zygote: inject 1st stage
\n
"
);
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"
);
unsetenv
(
"LD_PRELOAD"
);
else
path
=
ld
;
setenv
(
"LD_PRELOAD"
,
env
,
1
);
// Restore original LD_PRELOAD
}
// Update path to 2nd stage lib
*
(
strrchr
(
path
,
'.'
)
-
1
)
=
'2'
;
// Setup second stage
// Setup second stage
setenv
(
INJECT_ENV_2
,
"1"
,
1
);
setenv
(
INJECT_ENV_2
,
path
,
1
);
cp_afc
(
INJECT_LIB_1
,
INJECT_LIB_2
);
dlopen
(
path
,
RTLD_LAZY
);
dlopen
(
INJECT_LIB_2
,
RTLD_LAZY
);
unlink
(
INJECT_LIB_1
);
unsetenv
(
INJECT_ENV_1
);
unsetenv
(
INJECT_ENV_1
);
}
}
}
}
int
app_process_main
(
int
argc
,
char
*
argv
[])
{
int
app_process_main
(
int
argc
,
char
*
argv
[])
{
inject
_logging
();
android
_logging
();
char
buf
[
4096
];
if
(
realpath
(
"/proc/self/exe"
,
buf
)
==
nullptr
)
if
(
int
fd
=
connect_daemon
();
fd
>=
0
)
{
return
1
;
write_int
(
fd
,
ZYGISK_REQUEST
)
;
write_int
(
fd
,
ZYGISK_SETUP
);
int
in
=
xopen
(
buf
,
O_RDONLY
);
int
out
=
xopen
(
INJECT_LIB_1
,
O_WRONLY
|
O_CREAT
,
0644
);
if
(
read_int
(
fd
)
==
0
)
{
sendfile
(
out
,
in
,
nullptr
,
INT_MAX
);
string
path
=
read_string
(
fd
);
close
(
in
)
;
string
lib
=
path
+
".1.so"
;
close
(
out
);
if
(
char
*
ld
=
getenv
(
"LD_PRELOAD"
))
{
char
env
[
256
];
if
(
char
*
ld
=
getenv
(
"LD_PRELOAD"
))
{
sprintf
(
env
,
"%s:%s"
,
ld
,
lib
.
data
());
char
env
[
128
]
;
setenv
(
"LD_PRELOAD"
,
env
,
1
)
;
sprintf
(
env
,
"%s:"
INJECT_LIB_1
,
ld
);
}
else
{
setenv
(
"LD_PRELOAD"
,
env
,
1
);
setenv
(
"LD_PRELOAD"
,
lib
.
data
()
,
1
);
setenv
(
INJECT_ENV_1
,
ld
,
1
);
// Backup original LD_PRELOAD
}
}
else
{
setenv
(
INJECT_ENV_1
,
"1"
,
1
);
setenv
(
"LD_PRELOAD"
,
INJECT_LIB_1
,
1
);
}
setenv
(
INJECT_ENV_1
,
"1"
,
1
);
close
(
fd
);
}
}
// Execute real app_process
// 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
);
execve
(
buf
,
argv
,
environ
);
return
1
;
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 @@
...
@@ -3,11 +3,13 @@
#include <stdint.h>
#include <stdint.h>
#include <jni.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_1 "MAGISK_INJ_1"
#define INJECT_ENV_2 "MAGISK_INJ_2"
#define INJECT_ENV_2 "MAGISK_INJ_2"
enum
:
int
{
ZYGISK_SETUP
,
};
// Unmap all pages matching the name
// Unmap all pages matching the name
void
unmap_all
(
const
char
*
name
);
void
unmap_all
(
const
char
*
name
);
...
...
scripts/emulator.sh
View file @
9b3efffb
...
@@ -23,7 +23,7 @@ abort() {
...
@@ -23,7 +23,7 @@ abort() {
mount_sbin
()
{
mount_sbin
()
{
mount
-t
tmpfs
-o
'mode=0755'
tmpfs /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
if
[
!
-f
/system/build.prop
]
;
then
...
@@ -56,14 +56,14 @@ fi
...
@@ -56,14 +56,14 @@ fi
pgrep magiskd
>
/dev/null
&&
pkill
-9
magiskd
pgrep magiskd
>
/dev/null
&&
pkill
-9
magiskd
[
-f
/sbin/magisk
]
&&
umount
-l
/sbin
[
-f
/sbin/magisk
]
&&
umount
-l
/sbin
[
-f
/system/bin/magisk
]
&&
umount
-l
/system/bin
[
-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 stuffs
SELINUX
=
false
ln
-sf
./magiskinit magiskpolicy
[
-e
/sys/fs/selinux
]
&&
SELINUX
=
true
./magiskpolicy
--live
--magisk
if
$SELINUX
;
then
ln
-sf
./magiskinit magiskpolicy
./magiskpolicy
--live
--magisk
fi
BINDIR
=
/sbin
BINDIR
=
/sbin
...
@@ -99,12 +99,14 @@ elif [ -e /sbin ]; then
...
@@ -99,12 +99,14 @@ elif [ -e /sbin ]; then
done
done
else
else
# Android Q+ without sbin, use overlayfs
# Android Q+ without sbin, use overlayfs
BINDIR
=
/system/bin
BINDIR
=
/dev/magisk/upper
rm
-rf
/dev/magisk
mkdir
/dev/magisk
mkdir
-p
/dev/magisk/upper
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
mkdir
/dev/magisk/work
./magisk
--clone-attr
/system/bin /dev/magisk/upper
./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
fi
# Magisk stuffs
# 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