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
8186f253
Commit
8186f253
authored
Jun 01, 2022
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix zygisk code unloading
parent
d4fe8632
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
54 additions
and
51 deletions
+54
-51
module.cpp
native/jni/core/module.cpp
+7
-1
entry.cpp
native/jni/zygisk/entry.cpp
+40
-46
main.cpp
native/jni/zygisk/main.cpp
+2
-3
zygisk.hpp
native/jni/zygisk/zygisk.hpp
+5
-1
No files found.
native/jni/core/module.cpp
View file @
8186f253
...
@@ -563,13 +563,19 @@ int app_process_64 = -1;
...
@@ -563,13 +563,19 @@ int app_process_64 = -1;
if (access("/system/bin/app_process" #bit, F_OK) == 0) { \
if (access("/system/bin/app_process" #bit, F_OK) == 0) { \
app_process_##bit = xopen("/system/bin/app_process" #bit, O_RDONLY | O_CLOEXEC); \
app_process_##bit = xopen("/system/bin/app_process" #bit, O_RDONLY | O_CLOEXEC); \
string zbin = zygisk_bin + "/app_process" #bit; \
string zbin = zygisk_bin + "/app_process" #bit; \
string dbin = zygisk_bin + "/magisk" #bit; \
string mbin = MAGISKTMP + "/magisk" #bit; \
string mbin = MAGISKTMP + "/magisk" #bit; \
int src = xopen(mbin.data(), O_RDONLY | O_CLOEXEC); \
int src = xopen(mbin.data(), O_RDONLY | O_CLOEXEC); \
int out = xopen(zbin.data(), O_CREAT | O_WRONLY | O_CLOEXEC, 0); \
int out = xopen(zbin.data(), O_CREAT | O_WRONLY | O_CLOEXEC, 0); \
xsendfile(out, src, nullptr, INT_MAX); \
xsendfile(out, src, nullptr, INT_MAX); \
close(src); \
close(out); \
close(out); \
out = xopen(dbin.data(), O_CREAT | O_WRONLY | O_CLOEXEC, 0); \
lseek(src, 0, SEEK_SET); \
xsendfile(out, src, nullptr, INT_MAX); \
close(out); \
close(src); \
clone_attr("/system/bin/app_process" #bit, zbin.data()); \
clone_attr("/system/bin/app_process" #bit, zbin.data()); \
clone_attr("/system/bin/app_process" #bit, dbin.data()); \
bind_mount(zbin.data(), "/system/bin/app_process" #bit); \
bind_mount(zbin.data(), "/system/bin/app_process" #bit); \
}
}
...
...
native/jni/zygisk/entry.cpp
View file @
8186f253
#include <libgen.h>
#include <libgen.h>
#include <dlfcn.h>
#include <dlfcn.h>
#include <sys/prctl.h>
#include <sys/prctl.h>
#include <sys/mount.h>
#include <android/log.h>
#include <android/log.h>
#include <android/dlext.h>
#include <android/dlext.h>
...
@@ -52,78 +53,56 @@ static void zygisk_cleanup_wait() {
...
@@ -52,78 +53,56 @@ static void zygisk_cleanup_wait() {
}
}
}
}
static
void
*
unload_first_stage
(
void
*
)
{
// Wait 10us to make sure 1st stage is done
timespec
ts
=
{
.
tv_sec
=
0
,
.
tv_nsec
=
10000L
};
nanosleep
(
&
ts
,
nullptr
);
unmap_all
(
HIJACK_BIN
);
xumount2
(
HIJACK_BIN
,
MNT_DETACH
);
return
nullptr
;
}
static
void
second_stage_entry
()
{
static
void
second_stage_entry
()
{
zygisk_logging
();
zygisk_logging
();
ZLOGD
(
"inject 2nd stage
\n
"
);
ZLOGD
(
"inject 2nd stage
\n
"
);
char
path
[
PATH_MAX
];
MAGISKTMP
=
getenv
(
MAGISKTMP_ENV
);
MAGISKTMP
=
getenv
(
MAGISKTMP_ENV
);
int
fd
=
parse_int
(
getenv
(
MAGISKFD_ENV
));
#if defined(__LP64__)
self_handle
=
dlopen
(
"/system/bin/app_process"
,
RTLD_NOLOAD
);
snprintf
(
path
,
sizeof
(
path
),
"/proc/self/fd/%d"
,
fd
);
#else
xreadlink
(
path
,
path
,
PATH_MAX
);
self_handle
=
dlopen
(
"/system/bin/app_process32"
,
RTLD_NOLOAD
);
android_dlextinfo
info
{
#endif
.
flags
=
ANDROID_DLEXT_USE_LIBRARY_FD
,
.
library_fd
=
fd
,
};
self_handle
=
android_dlopen_ext
(
path
,
RTLD_LAZY
,
&
info
);
dlclose
(
self_handle
);
dlclose
(
self_handle
);
close
(
fd
);
unsetenv
(
MAGISKTMP_ENV
);
unsetenv
(
MAGISKTMP_ENV
);
unsetenv
(
MAGISKFD_ENV
);
sanitize_environ
();
sanitize_environ
();
hook_functions
();
hook_functions
();
new_daemon_thread
(
&
unload_first_stage
,
nullptr
);
}
}
static
void
first_stage_entry
()
{
static
void
first_stage_entry
()
{
android_logging
();
ZLOGD
(
"inject 1st stage
\n
"
);
ZLOGD
(
"inject 1st stage
\n
"
);
char
path
[
PATH_MAX
];
char
buf
[
256
];
char
*
ld
=
getenv
(
"LD_PRELOAD"
);
char
*
ld
=
getenv
(
"LD_PRELOAD"
);
if
(
char
*
c
=
strrchr
(
ld
,
':'
))
{
if
(
char
*
c
=
strrchr
(
ld
,
':'
))
{
*
c
=
'\0'
;
*
c
=
'\0'
;
strlcpy
(
path
,
c
+
1
,
sizeof
(
path
));
setenv
(
"LD_PRELOAD"
,
ld
,
1
);
// Restore original LD_PRELOAD
setenv
(
"LD_PRELOAD"
,
ld
,
1
);
// Restore original LD_PRELOAD
}
else
{
}
else
{
unsetenv
(
"LD_PRELOAD"
);
unsetenv
(
"LD_PRELOAD"
);
strlcpy
(
path
,
ld
,
sizeof
(
path
));
}
// Force the linker to load the library on top of ourselves, so we do not
// need to unmap the 1st stage library that was loaded with LD_PRELOAD.
int
fd
=
xopen
(
path
,
O_RDONLY
|
O_CLOEXEC
);
// Use fd here instead of path to make sure inode is the same as 2nd stage
snprintf
(
buf
,
sizeof
(
buf
),
"%d"
,
fd
);
setenv
(
MAGISKFD_ENV
,
buf
,
1
);
struct
stat
s
{};
xfstat
(
fd
,
&
s
);
android_dlextinfo
info
{
.
flags
=
ANDROID_DLEXT_FORCE_LOAD
|
ANDROID_DLEXT_USE_LIBRARY_FD
,
.
library_fd
=
fd
,
};
auto
[
addr
,
size
]
=
find_map_range
(
path
,
s
.
st_ino
);
if
(
addr
&&
size
)
{
info
.
flags
|=
ANDROID_DLEXT_RESERVED_ADDRESS
;
info
.
reserved_addr
=
addr
;
// The existing address is guaranteed to fit, as 1st stage and 2nd stage
// are exactly the same ELF (same inode). However, the linker could over
// estimate the required size and refuse to dlopen. The estimated size
// is not accurate so size the size to unlimited.
info
.
reserved_size
=
-
1
;
}
}
// Load second stage
setenv
(
INJECT_ENV_2
,
"1"
,
1
);
setenv
(
INJECT_ENV_2
,
"1"
,
1
);
// Force dlopen ourselves to make ourselves dlclose-able.
#if defined(__LP64__)
// After this call, all global variables will be reset.
dlopen
(
"/system/bin/app_process"
,
RTLD_LAZY
);
android_dlopen_ext
(
path
,
RTLD_LAZY
,
&
info
);
#else
dlopen
(
"/system/bin/app_process32"
,
RTLD_LAZY
);
#endif
}
}
[[
gnu
::
constructor
]]
[[
maybe_unused
]]
[[
gnu
::
constructor
]]
[[
maybe_unused
]]
static
void
zygisk_init
()
{
static
void
zygisk_init
()
{
android_logging
();
if
(
getenv
(
INJECT_ENV_1
))
{
if
(
getenv
(
INJECT_ENV_1
))
{
unsetenv
(
INJECT_ENV_1
);
unsetenv
(
INJECT_ENV_1
);
first_stage_entry
();
first_stage_entry
();
...
@@ -301,8 +280,23 @@ static void setup_files(int client, const sock_cred *cred) {
...
@@ -301,8 +280,23 @@ static void setup_files(int client, const sock_cred *cred) {
}
}
}
}
// Hijack some binary in /system/bin to host 1st stage
const
char
*
hbin
;
string
mbin
;
int
app_fd
;
if
(
is_64_bit
)
{
hbin
=
HIJACK_BIN64
;
mbin
=
MAGISKTMP
+
"/"
ZYGISKBIN
"/magisk64"
;
app_fd
=
app_process_64
;
}
else
{
hbin
=
HIJACK_BIN32
;
mbin
=
MAGISKTMP
+
"/"
ZYGISKBIN
"/magisk32"
;
app_fd
=
app_process_32
;
}
xmount
(
mbin
.
data
(),
hbin
,
nullptr
,
MS_BIND
,
nullptr
);
write_int
(
client
,
0
);
write_int
(
client
,
0
);
send_fd
(
client
,
is_64_bit
?
app_process_64
:
app_process_32
);
send_fd
(
client
,
app_fd
);
write_string
(
client
,
MAGISKTMP
);
write_string
(
client
,
MAGISKTMP
);
}
}
...
...
native/jni/zygisk/main.cpp
View file @
8186f253
...
@@ -78,14 +78,13 @@ int app_process_main(int argc, char *argv[]) {
...
@@ -78,14 +78,13 @@ int app_process_main(int argc, char *argv[]) {
break
;
break
;
string
tmp
=
read_string
(
socket
);
string
tmp
=
read_string
(
socket
);
xreadlink
(
"/proc/self/exe"
,
buf
,
sizeof
(
buf
));
if
(
char
*
ld
=
getenv
(
"LD_PRELOAD"
))
{
if
(
char
*
ld
=
getenv
(
"LD_PRELOAD"
))
{
string
env
=
ld
;
string
env
=
ld
;
env
+=
':'
;
env
+=
':'
;
env
+=
buf
;
env
+=
HIJACK_BIN
;
setenv
(
"LD_PRELOAD"
,
env
.
data
(),
1
);
setenv
(
"LD_PRELOAD"
,
env
.
data
(),
1
);
}
else
{
}
else
{
setenv
(
"LD_PRELOAD"
,
buf
,
1
);
setenv
(
"LD_PRELOAD"
,
HIJACK_BIN
,
1
);
}
}
setenv
(
INJECT_ENV_1
,
"1"
,
1
);
setenv
(
INJECT_ENV_1
,
"1"
,
1
);
setenv
(
MAGISKTMP_ENV
,
tmp
.
data
(),
1
);
setenv
(
MAGISKTMP_ENV
,
tmp
.
data
(),
1
);
...
...
native/jni/zygisk/zygisk.hpp
View file @
8186f253
...
@@ -7,9 +7,11 @@
...
@@ -7,9 +7,11 @@
#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"
#define MAGISKFD_ENV "MAGISKFD"
#define MAGISKTMP_ENV "MAGISKTMP"
#define MAGISKTMP_ENV "MAGISKTMP"
#define HIJACK_BIN64 "/system/bin/bootanimation"
#define HIJACK_BIN32 "/system/bin/screencap"
namespace
ZygiskRequest
{
namespace
ZygiskRequest
{
enum
:
int
{
enum
:
int
{
SETUP
,
SETUP
,
...
@@ -26,10 +28,12 @@ enum : int {
...
@@ -26,10 +28,12 @@ enum : int {
#define ZLOGD(...) LOGD("zygisk64: " __VA_ARGS__)
#define ZLOGD(...) LOGD("zygisk64: " __VA_ARGS__)
#define ZLOGE(...) LOGE("zygisk64: " __VA_ARGS__)
#define ZLOGE(...) LOGE("zygisk64: " __VA_ARGS__)
#define ZLOGI(...) LOGI("zygisk64: " __VA_ARGS__)
#define ZLOGI(...) LOGI("zygisk64: " __VA_ARGS__)
#define HIJACK_BIN HIJACK_BIN64
#else
#else
#define ZLOGD(...) LOGD("zygisk32: " __VA_ARGS__)
#define ZLOGD(...) LOGD("zygisk32: " __VA_ARGS__)
#define ZLOGE(...) LOGE("zygisk32: " __VA_ARGS__)
#define ZLOGE(...) LOGE("zygisk32: " __VA_ARGS__)
#define ZLOGI(...) LOGI("zygisk32: " __VA_ARGS__)
#define ZLOGI(...) LOGI("zygisk32: " __VA_ARGS__)
#define HIJACK_BIN HIJACK_BIN32
#endif
#endif
// Find the memory address + size of the pages matching name + inode
// Find the memory address + size of the pages matching name + inode
...
...
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