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
bb7a74e4
Commit
bb7a74e4
authored
Jan 18, 2022
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Zygisk API getFlags()
parent
76ddfeb9
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
173 additions
and
82 deletions
+173
-82
db.cpp
native/jni/core/db.cpp
+6
-18
db.hpp
native/jni/include/db.hpp
+0
-1
su_daemon.cpp
native/jni/su/su_daemon.cpp
+70
-3
api.hpp
native/jni/zygisk/api.hpp
+21
-8
cli.cpp
native/jni/zygisk/deny/cli.cpp
+1
-1
deny.hpp
native/jni/zygisk/deny/deny.hpp
+1
-1
utils.cpp
native/jni/zygisk/deny/utils.cpp
+9
-9
entry.cpp
native/jni/zygisk/entry.cpp
+19
-9
hook.cpp
native/jni/zygisk/hook.cpp
+30
-24
module.hpp
native/jni/zygisk/module.hpp
+15
-2
zygisk.hpp
native/jni/zygisk/zygisk.hpp
+1
-6
No files found.
native/jni/core/db.cpp
View file @
bb7a74e4
...
@@ -11,10 +11,13 @@
...
@@ -11,10 +11,13 @@
using
namespace
std
;
using
namespace
std
;
typedef
struct
sqlite3
sqlite3
;
struct
sqlite3
;
static
sqlite3
*
mDB
=
nullptr
;
static
sqlite3
*
mDB
=
nullptr
;
#define DBLOGV(...)
//#define DBLOGV(...) LOGD("magiskdb: " __VA_ARGS__)
// SQLite APIs
// SQLite APIs
#define SQLITE_OPEN_READWRITE 0x00000002
/* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_READWRITE 0x00000002
/* Ok for sqlite3_open_v2() */
...
@@ -294,7 +297,7 @@ int get_db_settings(db_settings &cfg, int key) {
...
@@ -294,7 +297,7 @@ int get_db_settings(db_settings &cfg, int key) {
char
*
err
;
char
*
err
;
auto
settings_cb
=
[
&
](
db_row
&
row
)
->
bool
{
auto
settings_cb
=
[
&
](
db_row
&
row
)
->
bool
{
cfg
[
row
[
"key"
]]
=
parse_int
(
row
[
"value"
]);
cfg
[
row
[
"key"
]]
=
parse_int
(
row
[
"value"
]);
LOGD
(
"magiskdb:
query %s=[%s]
\n
"
,
row
[
"key"
].
data
(),
row
[
"value"
].
data
());
DBLOGV
(
"
query %s=[%s]
\n
"
,
row
[
"key"
].
data
(),
row
[
"value"
].
data
());
return
true
;
return
true
;
};
};
if
(
key
>=
0
)
{
if
(
key
>=
0
)
{
...
@@ -312,7 +315,7 @@ int get_db_strings(db_strings &str, int key) {
...
@@ -312,7 +315,7 @@ int get_db_strings(db_strings &str, int key) {
char
*
err
;
char
*
err
;
auto
string_cb
=
[
&
](
db_row
&
row
)
->
bool
{
auto
string_cb
=
[
&
](
db_row
&
row
)
->
bool
{
str
[
row
[
"key"
]]
=
row
[
"value"
];
str
[
row
[
"key"
]]
=
row
[
"value"
];
LOGD
(
"magiskdb:
query %s=[%s]
\n
"
,
row
[
"key"
].
data
(),
row
[
"value"
].
data
());
DBLOGV
(
"
query %s=[%s]
\n
"
,
row
[
"key"
].
data
(),
row
[
"value"
].
data
());
return
true
;
return
true
;
};
};
if
(
key
>=
0
)
{
if
(
key
>=
0
)
{
...
@@ -326,21 +329,6 @@ int get_db_strings(db_strings &str, int key) {
...
@@ -326,21 +329,6 @@ int get_db_strings(db_strings &str, int key) {
return
0
;
return
0
;
}
}
int
get_uid_policy
(
su_access
&
su
,
int
uid
)
{
char
query
[
256
],
*
err
;
sprintf
(
query
,
"SELECT policy, logging, notification FROM policies "
"WHERE uid=%d AND (until=0 OR until>%li)"
,
uid
,
time
(
nullptr
));
err
=
db_exec
(
query
,
[
&
](
db_row
&
row
)
->
bool
{
su
.
policy
=
(
policy_t
)
parse_int
(
row
[
"policy"
]);
su
.
log
=
parse_int
(
row
[
"logging"
]);
su
.
notify
=
parse_int
(
row
[
"notification"
]);
LOGD
(
"magiskdb: query policy=[%d] log=[%d] notify=[%d]
\n
"
,
su
.
policy
,
su
.
log
,
su
.
notify
);
return
true
;
});
db_err_cmd
(
err
,
return
1
);
return
0
;
}
bool
get_manager
(
int
user_id
,
std
::
string
*
pkg
,
struct
stat
*
st
)
{
bool
get_manager
(
int
user_id
,
std
::
string
*
pkg
,
struct
stat
*
st
)
{
db_strings
str
;
db_strings
str
;
get_db_strings
(
str
,
SU_MANAGER
);
get_db_strings
(
str
,
SU_MANAGER
);
...
...
native/jni/include/db.hpp
View file @
bb7a74e4
...
@@ -125,7 +125,6 @@ using db_row_cb = std::function<bool(db_row&)>;
...
@@ -125,7 +125,6 @@ using db_row_cb = std::function<bool(db_row&)>;
int
get_db_settings
(
db_settings
&
cfg
,
int
key
=
-
1
);
int
get_db_settings
(
db_settings
&
cfg
,
int
key
=
-
1
);
int
get_db_strings
(
db_strings
&
str
,
int
key
=
-
1
);
int
get_db_strings
(
db_strings
&
str
,
int
key
=
-
1
);
int
get_uid_policy
(
su_access
&
su
,
int
uid
);
bool
get_manager
(
int
user_id
,
std
::
string
*
pkg
,
struct
stat
*
st
);
bool
get_manager
(
int
user_id
,
std
::
string
*
pkg
,
struct
stat
*
st
);
bool
get_manager
(
std
::
string
*
pkg
=
nullptr
);
bool
get_manager
(
std
::
string
*
pkg
=
nullptr
);
int
get_manager_app_id
();
int
get_manager_app_id
();
...
...
native/jni/su/su_daemon.cpp
View file @
bb7a74e4
...
@@ -64,14 +64,81 @@ static void database_check(const shared_ptr<su_info> &info) {
...
@@ -64,14 +64,81 @@ static void database_check(const shared_ptr<su_info> &info) {
break
;
break
;
}
}
if
(
uid
>
0
)
su_access
&
su
=
info
->
access
;
get_uid_policy
(
info
->
access
,
uid
);
if
(
uid
>
0
)
{
char
query
[
256
],
*
err
;
sprintf
(
query
,
"SELECT policy, logging, notification FROM policies "
"WHERE uid=%d AND (until=0 OR until>%li)"
,
uid
,
time
(
nullptr
));
err
=
db_exec
(
query
,
[
&
](
db_row
&
row
)
->
bool
{
su
.
policy
=
(
policy_t
)
parse_int
(
row
[
"policy"
]);
su
.
log
=
parse_int
(
row
[
"logging"
]);
su
.
notify
=
parse_int
(
row
[
"notification"
]);
LOGD
(
"magiskdb: query policy=[%d] log=[%d] notify=[%d]
\n
"
,
su
.
policy
,
su
.
log
,
su
.
notify
);
return
true
;
});
db_err_cmd
(
err
,
return
);
}
// We need to check our manager
// We need to check our manager
if
(
info
->
access
.
log
||
info
->
access
.
notify
)
if
(
su
.
log
||
su
.
notify
)
get_manager
(
to_user_id
(
uid
),
&
info
->
mgr_pkg
,
&
info
->
mgr_st
);
get_manager
(
to_user_id
(
uid
),
&
info
->
mgr_pkg
,
&
info
->
mgr_st
);
}
}
bool
uid_granted_root
(
int
uid
)
{
if
(
uid
==
UID_ROOT
)
return
true
;
db_settings
cfg
;
get_db_settings
(
cfg
);
// Check user root access settings
switch
(
cfg
[
ROOT_ACCESS
])
{
case
ROOT_ACCESS_DISABLED
:
return
false
;
case
ROOT_ACCESS_APPS_ONLY
:
if
(
uid
==
UID_SHELL
)
return
false
;
break
;
case
ROOT_ACCESS_ADB_ONLY
:
if
(
uid
!=
UID_SHELL
)
return
false
;
break
;
case
ROOT_ACCESS_APPS_AND_ADB
:
break
;
}
// Check multiuser settings
switch
(
cfg
[
SU_MULTIUSER_MODE
])
{
case
MULTIUSER_MODE_OWNER_ONLY
:
if
(
to_user_id
(
uid
)
!=
0
)
return
false
;
break
;
case
MULTIUSER_MODE_OWNER_MANAGED
:
uid
=
to_app_id
(
uid
);
break
;
case
MULTIUSER_MODE_USER
:
default
:
break
;
}
bool
granted
=
false
;
char
query
[
256
],
*
err
;
snprintf
(
query
,
sizeof
(
query
),
"SELECT policy FROM policies WHERE uid=%d AND (until=0 OR until>%li)"
,
uid
,
time
(
nullptr
));
err
=
db_exec
(
query
,
[
&
](
db_row
&
row
)
->
bool
{
granted
=
parse_int
(
row
[
"policy"
])
==
ALLOW
;
return
true
;
});
db_err_cmd
(
err
,
return
false
);
return
granted
;
}
static
shared_ptr
<
su_info
>
get_su_info
(
unsigned
uid
)
{
static
shared_ptr
<
su_info
>
get_su_info
(
unsigned
uid
)
{
LOGD
(
"su: request from uid=[%d]
\n
"
,
uid
);
LOGD
(
"su: request from uid=[%d]
\n
"
,
uid
);
...
...
native/jni/zygisk/api.hpp
View file @
bb7a74e4
...
@@ -138,20 +138,25 @@ enum Option : int {
...
@@ -138,20 +138,25 @@ enum Option : int {
// Setting this option only makes sense in preAppSpecialize.
// Setting this option only makes sense in preAppSpecialize.
// The actual unmounting happens during app process specialization.
// The actual unmounting happens during app process specialization.
//
//
// Processes added to Magisk's denylist will have all Magisk and its modules' files unmounted
// Set this option to force all Magisk and modules' files to be unmounted from the
// from its mount namespace. In addition, all Zygisk code will be unloaded from memory, which
// mount namespace of the process, regardless of the denylist enforcement status.
// also implies that no Zygisk modules (including yours) are loaded.
//
// However, if for any reason your module still wants the unmount part of the denylist
// operation to be enabled EVEN IF THE PROCESS IS NOT ON THE DENYLIST, set this option.
FORCE_DENYLIST_UNMOUNT
=
0
,
FORCE_DENYLIST_UNMOUNT
=
0
,
// When this option is set, your module's library will be dlclose-ed after post[XXX]Specialize.
// When this option is set, your module's library will be dlclose-ed after post[XXX]Specialize.
// Be aware that after dlclose-ing your module, all of your code will be unmapped.
// Be aware that after dlclose-ing your module, all of your code will be unmapped
from memory
.
// YOU
SHOULD NOT ENABLE THIS OPTION AFTER HOOKING ANY FUNCTION
IN THE PROCESS.
// YOU
MUST NOT ENABLE THIS OPTION AFTER HOOKING ANY FUNCTIONS
IN THE PROCESS.
DLCLOSE_MODULE_LIBRARY
=
1
,
DLCLOSE_MODULE_LIBRARY
=
1
,
};
};
// Bit masks of the return value of Api::getFlags()
enum
StateFlag
:
uint32_t
{
// The user has granted root access to the current process
PROCESS_GRANTED_ROOT
=
(
1u
<<
0
),
// The current process was added on the denylist
PROCESS_ON_DENYLIST
=
(
1u
<<
1
),
};
// All API functions will stop working after post[XXX]Specialize as Zygisk will be unloaded
// All API functions will stop working after post[XXX]Specialize as Zygisk will be unloaded
// from the specialized process afterwards.
// from the specialized process afterwards.
struct
Api
{
struct
Api
{
...
@@ -188,6 +193,10 @@ struct Api {
...
@@ -188,6 +193,10 @@ struct Api {
// Check zygisk::Option for the full list of options available.
// Check zygisk::Option for the full list of options available.
void
setOption
(
Option
opt
);
void
setOption
(
Option
opt
);
// Get information about the current process.
// Returns bitwise-or'd zygisk::StateFlag values.
uint32_t
getFlags
();
// Hook JNI native methods for a class
// Hook JNI native methods for a class
//
//
// Lookup all registered JNI native methods and replace it with your own functions.
// Lookup all registered JNI native methods and replace it with your own functions.
...
@@ -272,6 +281,7 @@ struct api_table {
...
@@ -272,6 +281,7 @@ struct api_table {
int
(
*
connectCompanion
)(
void
*
/* _this */
);
int
(
*
connectCompanion
)(
void
*
/* _this */
);
void
(
*
setOption
)(
void
*
/* _this */
,
Option
);
void
(
*
setOption
)(
void
*
/* _this */
,
Option
);
int
(
*
getModuleDir
)(
void
*
/* _this */
);
int
(
*
getModuleDir
)(
void
*
/* _this */
);
uint32_t
(
*
getFlags
)(
void
*
/* _this */
);
};
};
template
<
class
T
>
template
<
class
T
>
...
@@ -295,6 +305,9 @@ inline int Api::getModuleDir() {
...
@@ -295,6 +305,9 @@ inline int Api::getModuleDir() {
inline
void
Api
::
setOption
(
Option
opt
)
{
inline
void
Api
::
setOption
(
Option
opt
)
{
if
(
impl
->
setOption
)
impl
->
setOption
(
impl
->
_this
,
opt
);
if
(
impl
->
setOption
)
impl
->
setOption
(
impl
->
_this
,
opt
);
}
}
inline
uint32_t
Api
::
getFlags
()
{
return
impl
->
getFlags
?
impl
->
getFlags
(
impl
->
_this
)
:
0
;
}
inline
void
Api
::
hookJniNativeMethods
(
JNIEnv
*
env
,
const
char
*
className
,
JNINativeMethod
*
methods
,
int
numMethods
)
{
inline
void
Api
::
hookJniNativeMethods
(
JNIEnv
*
env
,
const
char
*
className
,
JNINativeMethod
*
methods
,
int
numMethods
)
{
if
(
impl
->
hookJniNativeMethods
)
impl
->
hookJniNativeMethods
(
env
,
className
,
methods
,
numMethods
);
if
(
impl
->
hookJniNativeMethods
)
impl
->
hookJniNativeMethods
(
env
,
className
,
methods
,
numMethods
);
}
}
...
...
native/jni/zygisk/deny/cli.cpp
View file @
bb7a74e4
...
@@ -51,7 +51,7 @@ void denylist_handler(int client, const sock_cred *cred) {
...
@@ -51,7 +51,7 @@ void denylist_handler(int client, const sock_cred *cred) {
ls_list
(
client
);
ls_list
(
client
);
return
;
return
;
case
DENY_STATUS
:
case
DENY_STATUS
:
res
=
(
zygisk_enabled
&&
denylist_en
abl
ed
)
?
DENY_IS_ENFORCED
:
DENY_NOT_ENFORCED
;
res
=
(
zygisk_enabled
&&
denylist_en
forc
ed
)
?
DENY_IS_ENFORCED
:
DENY_NOT_ENFORCED
;
break
;
break
;
}
}
...
...
native/jni/zygisk/deny/deny.hpp
View file @
bb7a74e4
...
@@ -22,7 +22,7 @@ bool is_deny_target(int uid, std::string_view process);
...
@@ -22,7 +22,7 @@ bool is_deny_target(int uid, std::string_view process);
void
revert_unmount
();
void
revert_unmount
();
extern
std
::
atomic
<
bool
>
denylist_en
abl
ed
;
extern
std
::
atomic
<
bool
>
denylist_en
forc
ed
;
extern
std
::
atomic
<
int
>
cached_manager_app_id
;
extern
std
::
atomic
<
int
>
cached_manager_app_id
;
enum
:
int
{
enum
:
int
{
...
...
native/jni/zygisk/deny/utils.cpp
View file @
bb7a74e4
...
@@ -21,9 +21,9 @@ static int inotify_fd = -1;
...
@@ -21,9 +21,9 @@ static int inotify_fd = -1;
// Locks the variables above
// Locks the variables above
static
pthread_mutex_t
data_lock
=
PTHREAD_MUTEX_INITIALIZER
;
static
pthread_mutex_t
data_lock
=
PTHREAD_MUTEX_INITIALIZER
;
atomic
<
bool
>
denylist_en
abl
ed
=
false
;
atomic
<
bool
>
denylist_en
forc
ed
=
false
;
#define do_kill (zygisk_enabled && denylist_en
abl
ed)
#define do_kill (zygisk_enabled && denylist_en
forc
ed)
static
void
rebuild_map
()
{
static
void
rebuild_map
()
{
app_id_proc_map
->
clear
();
app_id_proc_map
->
clear
();
...
@@ -317,13 +317,13 @@ static bool str_ends_safe(string_view s, string_view ss) {
...
@@ -317,13 +317,13 @@ static bool str_ends_safe(string_view s, string_view ss) {
static
void
update_deny_config
()
{
static
void
update_deny_config
()
{
char
sql
[
64
];
char
sql
[
64
];
sprintf
(
sql
,
"REPLACE INTO settings (key,value) VALUES('%s',%d)"
,
sprintf
(
sql
,
"REPLACE INTO settings (key,value) VALUES('%s',%d)"
,
DB_SETTING_KEYS
[
DENYLIST_CONFIG
],
denylist_enabl
ed
.
load
());
DB_SETTING_KEYS
[
DENYLIST_CONFIG
],
denylist_enforc
ed
.
load
());
char
*
err
=
db_exec
(
sql
);
char
*
err
=
db_exec
(
sql
);
db_err
(
err
);
db_err
(
err
);
}
}
int
enable_deny
()
{
int
enable_deny
()
{
if
(
denylist_en
abl
ed
)
{
if
(
denylist_en
forc
ed
)
{
return
DAEMON_SUCCESS
;
return
DAEMON_SUCCESS
;
}
else
{
}
else
{
mutex_guard
lock
(
data_lock
);
mutex_guard
lock
(
data_lock
);
...
@@ -338,10 +338,10 @@ int enable_deny() {
...
@@ -338,10 +338,10 @@ int enable_deny() {
LOGI
(
"* Enable DenyList
\n
"
);
LOGI
(
"* Enable DenyList
\n
"
);
denylist_en
abl
ed
=
true
;
denylist_en
forc
ed
=
true
;
if
(
!
ensure_data
())
{
if
(
!
ensure_data
())
{
denylist_en
abl
ed
=
false
;
denylist_en
forc
ed
=
false
;
return
DAEMON_ERROR
;
return
DAEMON_ERROR
;
}
}
...
@@ -358,8 +358,8 @@ int enable_deny() {
...
@@ -358,8 +358,8 @@ int enable_deny() {
}
}
int
disable_deny
()
{
int
disable_deny
()
{
if
(
denylist_en
abl
ed
)
{
if
(
denylist_en
forc
ed
)
{
denylist_en
abl
ed
=
false
;
denylist_en
forc
ed
=
false
;
LOGI
(
"* Disable DenyList
\n
"
);
LOGI
(
"* Disable DenyList
\n
"
);
mutex_guard
lock
(
data_lock
);
mutex_guard
lock
(
data_lock
);
...
@@ -370,7 +370,7 @@ int disable_deny() {
...
@@ -370,7 +370,7 @@ int disable_deny() {
}
}
void
initialize_denylist
()
{
void
initialize_denylist
()
{
if
(
!
denylist_en
abl
ed
)
{
if
(
!
denylist_en
forc
ed
)
{
db_settings
dbs
;
db_settings
dbs
;
get_db_settings
(
dbs
,
DENYLIST_CONFIG
);
get_db_settings
(
dbs
,
DENYLIST_CONFIG
);
if
(
dbs
[
DENYLIST_CONFIG
])
if
(
dbs
[
DENYLIST_CONFIG
])
...
...
native/jni/zygisk/entry.cpp
View file @
bb7a74e4
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
#include <db.hpp>
#include <db.hpp>
#include "zygisk.hpp"
#include "zygisk.hpp"
#include "module.hpp"
#include "deny/deny.hpp"
#include "deny/deny.hpp"
using
namespace
std
;
using
namespace
std
;
...
@@ -166,7 +167,7 @@ static int zygisk_log(int prio, const char *fmt, va_list ap) {
...
@@ -166,7 +167,7 @@ static int zygisk_log(int prio, const char *fmt, va_list ap) {
return
ret
;
return
ret
;
}
}
std
::
vector
<
int
>
remote_get_info
(
int
uid
,
const
char
*
process
,
AppInfo
*
info
)
{
std
::
vector
<
int
>
remote_get_info
(
int
uid
,
const
char
*
process
,
uint32_t
*
flags
)
{
vector
<
int
>
fds
;
vector
<
int
>
fds
;
if
(
int
fd
=
connect_daemon
();
fd
>=
0
)
{
if
(
int
fd
=
connect_daemon
();
fd
>=
0
)
{
write_int
(
fd
,
ZYGISK_REQUEST
);
write_int
(
fd
,
ZYGISK_REQUEST
);
...
@@ -174,8 +175,8 @@ std::vector<int> remote_get_info(int uid, const char *process, AppInfo *info) {
...
@@ -174,8 +175,8 @@ std::vector<int> remote_get_info(int uid, const char *process, AppInfo *info) {
write_int
(
fd
,
uid
);
write_int
(
fd
,
uid
);
write_string
(
fd
,
process
);
write_string
(
fd
,
process
);
xxread
(
fd
,
info
,
sizeof
(
*
info
));
xxread
(
fd
,
flags
,
sizeof
(
*
flags
));
if
(
!
info
->
on_denylist
)
{
if
(
(
*
flags
&
UNMOUNT_MASK
)
!=
UNMOUNT_MASK
)
{
fds
=
recv_fds
(
fd
);
fds
=
recv_fds
(
fd
);
}
}
close
(
fd
);
close
(
fd
);
...
@@ -314,11 +315,13 @@ static void magiskd_passthrough(int client) {
...
@@ -314,11 +315,13 @@ static void magiskd_passthrough(int client) {
atomic
<
int
>
cached_manager_app_id
=
-
1
;
atomic
<
int
>
cached_manager_app_id
=
-
1
;
extern
bool
uid_granted_root
(
int
uid
);
static
void
get_process_info
(
int
client
,
const
sock_cred
*
cred
)
{
static
void
get_process_info
(
int
client
,
const
sock_cred
*
cred
)
{
AppInfo
info
{};
int
uid
=
read_int
(
client
);
int
uid
=
read_int
(
client
);
string
process
=
read_string
(
client
);
string
process
=
read_string
(
client
);
uint32_t
flags
=
0
;
// This function is called on every single zygote process specialization,
// This function is called on every single zygote process specialization,
// so performance is critical. get_manager_app_id() is expensive as it goes
// so performance is critical. get_manager_app_id() is expensive as it goes
// through a SQLite query and potentially multiple filesystem stats, so we
// through a SQLite query and potentially multiple filesystem stats, so we
...
@@ -334,15 +337,22 @@ static void get_process_info(int client, const sock_cred *cred) {
...
@@ -334,15 +337,22 @@ static void get_process_info(int client, const sock_cred *cred) {
}
}
if
(
to_app_id
(
uid
)
==
manager_app_id
)
{
if
(
to_app_id
(
uid
)
==
manager_app_id
)
{
info
.
is_magisk_app
=
true
;
flags
|=
PROCESS_IS_MAGISK_APP
;
}
else
if
(
denylist_enabled
)
{
}
info
.
on_denylist
=
is_deny_target
(
uid
,
process
);
if
(
denylist_enforced
)
{
flags
|=
DENYLIST_ENFORCING
;
}
if
(
is_deny_target
(
uid
,
process
))
{
flags
|=
PROCESS_ON_DENYLIST
;
}
if
(
uid_granted_root
(
uid
))
{
flags
|=
PROCESS_GRANTED_ROOT
;
}
}
}
}
xwrite
(
client
,
&
info
,
sizeof
(
info
));
xwrite
(
client
,
&
flags
,
sizeof
(
flags
));
if
(
!
info
.
on_denylist
)
{
if
(
(
flags
&
UNMOUNT_MASK
)
!=
UNMOUNT_MASK
)
{
char
buf
[
256
];
char
buf
[
256
];
get_exe
(
cred
->
pid
,
buf
,
sizeof
(
buf
));
get_exe
(
cred
->
pid
,
buf
,
sizeof
(
buf
));
vector
<
int
>
fds
=
get_module_fds
(
str_ends
(
buf
,
"64"
));
vector
<
int
>
fds
=
get_module_fds
(
str_ends
(
buf
,
"64"
));
...
...
native/jni/zygisk/hook.cpp
View file @
bb7a74e4
...
@@ -26,7 +26,7 @@ static bool unhook_functions();
...
@@ -26,7 +26,7 @@ static bool unhook_functions();
namespace
{
namespace
{
enum
{
enum
{
UNMOUNT_FLAG
,
DO_UNMOUNT
,
FORK_AND_SPECIALIZE
,
FORK_AND_SPECIALIZE
,
APP_SPECIALIZE
,
APP_SPECIALIZE
,
SERVER_SPECIALIZE
,
SERVER_SPECIALIZE
,
...
@@ -46,12 +46,13 @@ struct HookContext {
...
@@ -46,12 +46,13 @@ struct HookContext {
void
*
raw_args
;
void
*
raw_args
;
};
};
const
char
*
process
;
const
char
*
process
;
int
pid
;
bitset
<
FLAG_MAX
>
flags
;
AppInfo
info
;
vector
<
ZygiskModule
>
modules
;
vector
<
ZygiskModule
>
modules
;
bitset
<
FLAG_MAX
>
state
;
int
pid
;
uint32_t
flags
;
HookContext
()
:
pid
(
-
1
),
info
{}
{}
HookContext
()
:
pid
(
-
1
),
flags
(
0
)
{}
static
void
close_fds
();
static
void
close_fds
();
void
unload_zygisk
();
void
unload_zygisk
();
...
@@ -154,7 +155,7 @@ DCL_HOOK_FUNC(int, fork) {
...
@@ -154,7 +155,7 @@ DCL_HOOK_FUNC(int, fork) {
DCL_HOOK_FUNC
(
int
,
unshare
,
int
flags
)
{
DCL_HOOK_FUNC
(
int
,
unshare
,
int
flags
)
{
int
res
=
old_unshare
(
flags
);
int
res
=
old_unshare
(
flags
);
if
(
g_ctx
&&
(
flags
&
CLONE_NEWNS
)
!=
0
&&
res
==
0
)
{
if
(
g_ctx
&&
(
flags
&
CLONE_NEWNS
)
!=
0
&&
res
==
0
)
{
if
(
g_ctx
->
flags
[
UNMOUNT_FLAG
])
{
if
(
g_ctx
->
state
[
DO_UNMOUNT
])
{
revert_unmount
();
revert_unmount
();
}
else
{
}
else
{
umount2
(
"/system/bin/app_process64"
,
MNT_DETACH
);
umount2
(
"/system/bin/app_process64"
,
MNT_DETACH
);
...
@@ -174,7 +175,7 @@ DCL_HOOK_FUNC(void, android_log_close) {
...
@@ -174,7 +175,7 @@ DCL_HOOK_FUNC(void, android_log_close) {
DCL_HOOK_FUNC
(
int
,
selinux_android_setcontext
,
DCL_HOOK_FUNC
(
int
,
selinux_android_setcontext
,
uid_t
uid
,
int
isSystemServer
,
const
char
*
seinfo
,
const
char
*
pkgname
)
{
uid_t
uid
,
int
isSystemServer
,
const
char
*
seinfo
,
const
char
*
pkgname
)
{
if
(
g_ctx
)
{
if
(
g_ctx
)
{
g_ctx
->
flags
[
CAN_DLCLOSE
]
=
unhook_functions
();
g_ctx
->
state
[
CAN_DLCLOSE
]
=
unhook_functions
();
}
}
return
old_selinux_android_setcontext
(
uid
,
isSystemServer
,
seinfo
,
pkgname
);
return
old_selinux_android_setcontext
(
uid
,
isSystemServer
,
seinfo
,
pkgname
);
}
}
...
@@ -297,6 +298,7 @@ bool ZygiskModule::RegisterModule(ApiTable *table, long *module) {
...
@@ -297,6 +298,7 @@ bool ZygiskModule::RegisterModule(ApiTable *table, long *module) {
switch
(
ver
)
{
switch
(
ver
)
{
case
2
:
case
2
:
table
->
v2
.
getModuleDir
=
[](
ZygiskModule
*
m
)
{
return
m
->
getModuleDir
();
};
table
->
v2
.
getModuleDir
=
[](
ZygiskModule
*
m
)
{
return
m
->
getModuleDir
();
};
table
->
v2
.
getFlags
=
[](
auto
)
{
return
ZygiskModule
::
getFlags
();
};
[[
fallthrough
]];
[[
fallthrough
]];
case
1
:
case
1
:
table
->
v1
.
hookJniNativeMethods
=
&
hookJniNativeMethods
;
table
->
v1
.
hookJniNativeMethods
=
&
hookJniNativeMethods
;
...
@@ -345,7 +347,7 @@ void ZygiskModule::setOption(zygisk::Option opt) {
...
@@ -345,7 +347,7 @@ void ZygiskModule::setOption(zygisk::Option opt) {
return
;
return
;
switch
(
opt
)
{
switch
(
opt
)
{
case
zygisk
:
:
FORCE_DENYLIST_UNMOUNT
:
case
zygisk
:
:
FORCE_DENYLIST_UNMOUNT
:
g_ctx
->
flags
[
UNMOUNT_FLAG
]
=
true
;
g_ctx
->
state
[
DO_UNMOUNT
]
=
true
;
break
;
break
;
case
zygisk
:
:
DLCLOSE_MODULE_LIBRARY
:
case
zygisk
:
:
DLCLOSE_MODULE_LIBRARY
:
unload
=
true
;
unload
=
true
;
...
@@ -353,6 +355,10 @@ void ZygiskModule::setOption(zygisk::Option opt) {
...
@@ -353,6 +355,10 @@ void ZygiskModule::setOption(zygisk::Option opt) {
}
}
}
}
uint32_t
ZygiskModule
::
getFlags
()
{
return
g_ctx
?
(
g_ctx
->
flags
&
~
PRIVATE_MASK
)
:
0
;
}
void
HookContext
::
run_modules_pre
(
const
vector
<
int
>
&
fds
)
{
void
HookContext
::
run_modules_pre
(
const
vector
<
int
>
&
fds
)
{
char
buf
[
256
];
char
buf
[
256
];
...
@@ -384,9 +390,9 @@ void HookContext::run_modules_pre(const vector<int> &fds) {
...
@@ -384,9 +390,9 @@ void HookContext::run_modules_pre(const vector<int> &fds) {
for
(
auto
&
m
:
modules
)
{
for
(
auto
&
m
:
modules
)
{
m
.
entry
(
&
m
.
api
,
env
);
m
.
entry
(
&
m
.
api
,
env
);
if
(
flags
[
APP_SPECIALIZE
])
{
if
(
state
[
APP_SPECIALIZE
])
{
m
.
preAppSpecialize
(
args
);
m
.
preAppSpecialize
(
args
);
}
else
if
(
flags
[
SERVER_SPECIALIZE
])
{
}
else
if
(
state
[
SERVER_SPECIALIZE
])
{
m
.
preServerSpecialize
(
server_args
);
m
.
preServerSpecialize
(
server_args
);
}
}
}
}
...
@@ -403,9 +409,9 @@ void HookContext::run_modules_pre(const vector<int> &fds) {
...
@@ -403,9 +409,9 @@ void HookContext::run_modules_pre(const vector<int> &fds) {
void
HookContext
::
run_modules_post
()
{
void
HookContext
::
run_modules_post
()
{
for
(
const
auto
&
m
:
modules
)
{
for
(
const
auto
&
m
:
modules
)
{
if
(
flags
[
APP_SPECIALIZE
])
{
if
(
state
[
APP_SPECIALIZE
])
{
m
.
postAppSpecialize
(
args
);
m
.
postAppSpecialize
(
args
);
}
else
if
(
flags
[
SERVER_SPECIALIZE
])
{
}
else
if
(
state
[
SERVER_SPECIALIZE
])
{
m
.
postServerSpecialize
(
server_args
);
m
.
postServerSpecialize
(
server_args
);
}
}
m
.
doUnload
();
m
.
doUnload
();
...
@@ -417,7 +423,7 @@ void HookContext::close_fds() {
...
@@ -417,7 +423,7 @@ void HookContext::close_fds() {
}
}
void
HookContext
::
unload_zygisk
()
{
void
HookContext
::
unload_zygisk
()
{
if
(
flags
[
CAN_DLCLOSE
])
{
if
(
state
[
CAN_DLCLOSE
])
{
// Do NOT call the destructor
// Do NOT call the destructor
operator
delete
(
jni_method_map
);
operator
delete
(
jni_method_map
);
// Directly unmap the whole memory block
// Directly unmap the whole memory block
...
@@ -436,19 +442,19 @@ void HookContext::unload_zygisk() {
...
@@ -436,19 +442,19 @@ void HookContext::unload_zygisk() {
void
HookContext
::
nativeSpecializeAppProcess_pre
()
{
void
HookContext
::
nativeSpecializeAppProcess_pre
()
{
g_ctx
=
this
;
g_ctx
=
this
;
flags
[
APP_SPECIALIZE
]
=
true
;
state
[
APP_SPECIALIZE
]
=
true
;
process
=
env
->
GetStringUTFChars
(
args
->
nice_name
,
nullptr
);
process
=
env
->
GetStringUTFChars
(
args
->
nice_name
,
nullptr
);
if
(
flags
[
FORK_AND_SPECIALIZE
])
{
if
(
state
[
FORK_AND_SPECIALIZE
])
{
ZLOGV
(
"pre forkAndSpecialize [%s]
\n
"
,
process
);
ZLOGV
(
"pre forkAndSpecialize [%s]
\n
"
,
process
);
}
else
{
}
else
{
ZLOGV
(
"pre specialize [%s]
\n
"
,
process
);
ZLOGV
(
"pre specialize [%s]
\n
"
,
process
);
}
}
auto
module_fds
=
remote_get_info
(
args
->
uid
,
process
,
&
info
);
auto
module_fds
=
remote_get_info
(
args
->
uid
,
process
,
&
flags
);
if
(
info
.
on_denylist
)
{
if
(
(
flags
&
UNMOUNT_MASK
)
==
UNMOUNT_MASK
)
{
// TODO: Handle MOUNT_EXTERNAL_NONE on older platforms
// TODO: Handle MOUNT_EXTERNAL_NONE on older platforms
ZLOGI
(
"[%s] is on the denylist
\n
"
,
process
);
ZLOGI
(
"[%s] is on the denylist
\n
"
,
process
);
flags
[
UNMOUNT_FLAG
]
=
true
;
state
[
DO_UNMOUNT
]
=
true
;
}
else
{
}
else
{
run_modules_pre
(
module_fds
);
run_modules_pre
(
module_fds
);
}
}
...
@@ -458,7 +464,7 @@ void HookContext::nativeSpecializeAppProcess_pre() {
...
@@ -458,7 +464,7 @@ void HookContext::nativeSpecializeAppProcess_pre() {
}
}
void
HookContext
::
nativeSpecializeAppProcess_post
()
{
void
HookContext
::
nativeSpecializeAppProcess_post
()
{
if
(
flags
[
FORK_AND_SPECIALIZE
])
{
if
(
state
[
FORK_AND_SPECIALIZE
])
{
ZLOGV
(
"post forkAndSpecialize [%s]
\n
"
,
process
);
ZLOGV
(
"post forkAndSpecialize [%s]
\n
"
,
process
);
}
else
{
}
else
{
ZLOGV
(
"post specialize [%s]
\n
"
,
process
);
ZLOGV
(
"post specialize [%s]
\n
"
,
process
);
...
@@ -466,21 +472,21 @@ void HookContext::nativeSpecializeAppProcess_post() {
...
@@ -466,21 +472,21 @@ void HookContext::nativeSpecializeAppProcess_post() {
env
->
ReleaseStringUTFChars
(
args
->
nice_name
,
process
);
env
->
ReleaseStringUTFChars
(
args
->
nice_name
,
process
);
run_modules_post
();
run_modules_post
();
if
(
info
.
is_magisk_app
)
{
if
(
flags
&
PROCESS_IS_MAGISK_APP
)
{
setenv
(
"ZYGISK_ENABLED"
,
"1"
,
1
);
setenv
(
"ZYGISK_ENABLED"
,
"1"
,
1
);
}
}
g_ctx
=
nullptr
;
g_ctx
=
nullptr
;
if
(
!
flags
[
FORK_AND_SPECIALIZE
])
{
if
(
!
state
[
FORK_AND_SPECIALIZE
])
{
unload_zygisk
();
unload_zygisk
();
}
}
}
}
void
HookContext
::
nativeForkSystemServer_pre
()
{
void
HookContext
::
nativeForkSystemServer_pre
()
{
fork_pre
();
fork_pre
();
flags
[
SERVER_SPECIALIZE
]
=
true
;
state
[
SERVER_SPECIALIZE
]
=
true
;
if
(
pid
==
0
)
{
if
(
pid
==
0
)
{
ZLOGV
(
"pre forkSystemServer
\n
"
);
ZLOGV
(
"pre forkSystemServer
\n
"
);
run_modules_pre
(
remote_get_info
(
1000
,
"system_server"
,
&
info
));
run_modules_pre
(
remote_get_info
(
1000
,
"system_server"
,
&
flags
));
close_fds
();
close_fds
();
android_logging
();
android_logging
();
}
}
...
@@ -496,7 +502,7 @@ void HookContext::nativeForkSystemServer_post() {
...
@@ -496,7 +502,7 @@ void HookContext::nativeForkSystemServer_post() {
void
HookContext
::
nativeForkAndSpecialize_pre
()
{
void
HookContext
::
nativeForkAndSpecialize_pre
()
{
fork_pre
();
fork_pre
();
flags
[
FORK_AND_SPECIALIZE
]
=
true
;
state
[
FORK_AND_SPECIALIZE
]
=
true
;
if
(
pid
==
0
)
{
if
(
pid
==
0
)
{
nativeSpecializeAppProcess_pre
();
nativeSpecializeAppProcess_pre
();
}
}
...
...
native/jni/zygisk/module.hpp
View file @
bb7a74e4
...
@@ -52,6 +52,17 @@ struct ServerSpecializeArgsImpl {
...
@@ -52,6 +52,17 @@ struct ServerSpecializeArgsImpl {
effective_capabilities
(
effective_capabilities
)
{}
effective_capabilities
(
effective_capabilities
)
{}
};
};
enum
:
uint32_t
{
PROCESS_GRANTED_ROOT
=
zygisk
::
StateFlag
::
PROCESS_GRANTED_ROOT
,
PROCESS_ON_DENYLIST
=
zygisk
::
StateFlag
::
PROCESS_ON_DENYLIST
,
DENYLIST_ENFORCING
=
(
1u
<<
30
),
PROCESS_IS_MAGISK_APP
=
(
1u
<<
31
),
UNMOUNT_MASK
=
(
PROCESS_ON_DENYLIST
|
DENYLIST_ENFORCING
),
PRIVATE_MASK
=
(
0x3u
<<
30
)
};
template
<
typename
T
>
template
<
typename
T
>
struct
force_cast_wrapper
{
struct
force_cast_wrapper
{
template
<
typename
U
>
template
<
typename
U
>
...
@@ -80,10 +91,11 @@ struct ApiTable {
...
@@ -80,10 +91,11 @@ struct ApiTable {
int
(
*
connectCompanion
)(
ZygiskModule
*
);
int
(
*
connectCompanion
)(
ZygiskModule
*
);
void
(
*
setOption
)(
ZygiskModule
*
,
zygisk
::
Option
);
void
(
*
setOption
)(
ZygiskModule
*
,
zygisk
::
Option
);
}
v1
;
}
v1
{}
;
struct
{
struct
{
int
(
*
getModuleDir
)(
ZygiskModule
*
);
int
(
*
getModuleDir
)(
ZygiskModule
*
);
}
v2
;
uint32_t
(
*
getFlags
)(
ZygiskModule
*
);
}
v2
{};
ApiTable
(
ZygiskModule
*
m
);
ApiTable
(
ZygiskModule
*
m
);
};
};
...
@@ -105,6 +117,7 @@ struct ZygiskModule {
...
@@ -105,6 +117,7 @@ struct ZygiskModule {
int
connectCompanion
()
const
;
int
connectCompanion
()
const
;
int
getModuleDir
()
const
;
int
getModuleDir
()
const
;
void
setOption
(
zygisk
::
Option
opt
);
void
setOption
(
zygisk
::
Option
opt
);
static
uint32_t
getFlags
();
void
doUnload
()
const
{
if
(
unload
)
dlclose
(
handle
);
}
void
doUnload
()
const
{
if
(
unload
)
dlclose
(
handle
);
}
ZygiskModule
(
int
id
,
void
*
handle
,
void
*
entry
);
ZygiskModule
(
int
id
,
void
*
handle
,
void
*
entry
);
...
...
native/jni/zygisk/zygisk.hpp
View file @
bb7a74e4
...
@@ -37,14 +37,9 @@ uintptr_t get_function_off(int pid, uintptr_t addr, char *lib);
...
@@ -37,14 +37,9 @@ uintptr_t get_function_off(int pid, uintptr_t addr, char *lib);
// Get function address, given library name + offset
// Get function address, given library name + offset
uintptr_t
get_function_addr
(
int
pid
,
const
char
*
lib
,
uintptr_t
off
);
uintptr_t
get_function_addr
(
int
pid
,
const
char
*
lib
,
uintptr_t
off
);
struct
AppInfo
{
bool
is_magisk_app
;
bool
on_denylist
;
};
extern
void
*
self_handle
;
extern
void
*
self_handle
;
void
unload_first_stage
();
void
unload_first_stage
();
void
hook_functions
();
void
hook_functions
();
std
::
vector
<
int
>
remote_get_info
(
int
uid
,
const
char
*
process
,
AppInfo
*
info
);
std
::
vector
<
int
>
remote_get_info
(
int
uid
,
const
char
*
process
,
uint32_t
*
flags
);
int
remote_request_unmount
();
int
remote_request_unmount
();
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