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
e050f771
Commit
e050f771
authored
Jan 10, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Don't hook SystemProperties#set
Doesn't seem necessary
parent
540b4b7e
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
72 additions
and
134 deletions
+72
-134
hook.cpp
native/jni/inject/hook.cpp
+43
-72
jni_hooks.hpp
native/jni/inject/jni_hooks.hpp
+29
-62
No files found.
native/jni/inject/hook.cpp
View file @
e050f771
...
@@ -8,57 +8,42 @@
...
@@ -8,57 +8,42 @@
using
namespace
std
;
using
namespace
std
;
static
JavaVM
*
g_jvm
;
#define DCL_HOOK_FUNC(ret, func, ...) \
static ret (*old_##func)(__VA_ARGS__); \
static ret new_##func(__VA_ARGS__)
#define DCL_JNI_FUNC(name) \
static const JNINativeMethod *name##_orig = nullptr; \
extern const JNINativeMethod name##_methods[]; \
extern const int name##_methods_num;
// For some reason static vector won't work, use a pointer instead
// For some reason static vector won't work, use a pointer instead
static
vector
<
tuple
<
const
char
*
,
const
char
*
,
void
**>>
*
hook_list
;
static
vector
<
tuple
<
const
char
*
,
const
char
*
,
void
**>>
*
hook_list
;
static
JavaVM
*
g_jvm
;
namespace
{
namespace
{
struct
HookContext
{
struct
HookContext
{
int
pid
;
int
pid
;
};
};
}
// JNI method declarations
// JNI method declarations
DCL_JNI_FUNC
(
nativeForkAndSpecialize
)
DCL_JNI_FUNC
(
nativeSpecializeAppProcess
)
DCL_JNI_FUNC
(
nativeForkSystemServer
)
namespace
JNI
{
namespace
Zygote
{
const
JNINativeMethod
*
nativeForkAndSpecialize_orig
=
nullptr
;
const
JNINativeMethod
*
nativeSpecializeAppProcess_orig
=
nullptr
;
const
JNINativeMethod
*
nativeForkSystemServer_orig
=
nullptr
;
extern
const
JNINativeMethod
nativeForkAndSpecialize_methods
[];
extern
const
int
nativeForkAndSpecialize_methods_num
;
extern
const
JNINativeMethod
nativeSpecializeAppProcess_methods
[];
extern
const
int
nativeSpecializeAppProcess_methods_num
;
extern
const
JNINativeMethod
nativeForkSystemServer_methods
[];
extern
const
int
nativeForkSystemServer_methods_num
;
}
namespace
SystemProperties
{
const
JNINativeMethod
*
native_set_orig
=
nullptr
;
extern
const
JNINativeMethod
native_set_methods
[];
constexpr
int
native_set_methods_num
=
1
;
}
}
}
#define DEF_HOOK_FUNC(ret, func, ...) \
#define HOOK_JNI(method) \
static ret (*old_##func)(__VA_ARGS__); \
static ret new_##func(__VA_ARGS__)
#define HOOK_JNI(clazz, method) \
if (newMethods[i].name == #method##sv) { \
if (newMethods[i].name == #method##sv) { \
auto orig = new JNINativeMethod(); \
auto orig = new JNINativeMethod(); \
memcpy(orig, &newMethods[i], sizeof(JNINativeMethod)); \
memcpy(orig, &newMethods[i], sizeof(JNINativeMethod)); \
JNI::clazz::
method##_orig = orig; \
method##_orig = orig; \
for (int j = 0; j <
JNI::clazz::
method##_methods_num; ++j) { \
for (int j = 0; j < method##_methods_num; ++j) { \
if (strcmp(newMethods[i].signature,
JNI::clazz::
method##_methods[j].signature) == 0) { \
if (strcmp(newMethods[i].signature, method##_methods[j].signature) == 0) { \
newMethods[i] =
JNI::clazz::
method##_methods[j]; \
newMethods[i] = method##_methods[j]; \
LOGI("hook: replaced
" #clazz "
#" #method "\n"); \
LOGI("hook: replaced #" #method "\n"); \
++hooked; \
++hooked; \
break; \
break; \
} \
} \
...
@@ -66,11 +51,7 @@ if (newMethods[i].name == #method##sv) { \
...
@@ -66,11 +51,7 @@ if (newMethods[i].name == #method##sv) { \
continue; \
continue; \
}
}
#define clone_methods() \
DCL_HOOK_FUNC
(
int
,
jniRegisterNativeMethods
,
newMethods = make_unique<JNINativeMethod[]>(numMethods); \
memcpy(newMethods.get(), methods, sizeof(JNINativeMethod) * numMethods)
DEF_HOOK_FUNC
(
int
,
jniRegisterNativeMethods
,
JNIEnv
*
env
,
const
char
*
className
,
const
JNINativeMethod
*
methods
,
int
numMethods
)
{
JNIEnv
*
env
,
const
char
*
className
,
const
JNINativeMethod
*
methods
,
int
numMethods
)
{
LOGD
(
"hook: jniRegisterNativeMethods %s"
,
className
);
LOGD
(
"hook: jniRegisterNativeMethods %s"
,
className
);
...
@@ -83,16 +64,12 @@ DEF_HOOK_FUNC(int, jniRegisterNativeMethods,
...
@@ -83,16 +64,12 @@ DEF_HOOK_FUNC(int, jniRegisterNativeMethods,
}
}
if
(
className
==
"com/android/internal/os/Zygote"
sv
)
{
if
(
className
==
"com/android/internal/os/Zygote"
sv
)
{
clone_methods
();
newMethods
=
make_unique
<
JNINativeMethod
[]
>
(
numMethods
);
memcpy
(
newMethods
.
get
(),
methods
,
sizeof
(
JNINativeMethod
)
*
numMethods
);
for
(
int
i
=
0
;
i
<
numMethods
&&
hooked
<
3
;
++
i
)
{
for
(
int
i
=
0
;
i
<
numMethods
&&
hooked
<
3
;
++
i
)
{
HOOK_JNI
(
Zygote
,
nativeForkAndSpecialize
);
HOOK_JNI
(
nativeForkAndSpecialize
);
HOOK_JNI
(
Zygote
,
nativeSpecializeAppProcess
);
HOOK_JNI
(
nativeSpecializeAppProcess
);
HOOK_JNI
(
Zygote
,
nativeForkSystemServer
);
HOOK_JNI
(
nativeForkSystemServer
);
}
}
else
if
(
className
==
"android/os/SystemProperties"
sv
)
{
clone_methods
();
for
(
int
i
=
0
;
i
<
numMethods
&&
hooked
<
1
;
++
i
)
{
HOOK_JNI
(
SystemProperties
,
native_set
);
}
}
}
}
...
@@ -102,9 +79,11 @@ DEF_HOOK_FUNC(int, jniRegisterNativeMethods,
...
@@ -102,9 +79,11 @@ DEF_HOOK_FUNC(int, jniRegisterNativeMethods,
static
void
nativeForkAndSpecialize_pre
(
HookContext
*
ctx
,
static
void
nativeForkAndSpecialize_pre
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
,
jint
&
uid
,
jint
&
gid
,
jintArray
&
gids
,
jint
&
runtime_flags
,
JNIEnv
*
env
,
jclass
clazz
,
jint
&
uid
,
jint
&
gid
,
jintArray
&
gids
,
jint
&
runtime_flags
,
jobjectArray
&
rlimits
,
jint
&
mount_external
,
jstring
&
se_info
,
jstring
&
nice_name
,
jobjectArray
&
rlimits
,
jint
&
mount_external
,
jstring
&
se_info
,
jstring
&
nice_name
,
jintArray
&
fds_to_close
,
jintArray
&
fds_to_ignore
,
jboolean
&
is_child_zygote
,
jintArray
&
fds_to_close
,
jintArray
&
fds_to_ignore
,
/* These 2 arguments are unique to fork */
jstring
&
instruction_set
,
jstring
&
app_data_dir
,
jboolean
&
is_top_app
,
jobjectArray
&
pkg_data_info_list
,
jboolean
&
is_child_zygote
,
jstring
&
instruction_set
,
jstring
&
app_data_dir
,
jobjectArray
&
whitelisted_data_info_list
,
jboolean
&
mount_data_dirs
,
jboolean
&
mount_storage_dirs
)
{
jboolean
&
is_top_app
,
jobjectArray
&
pkg_data_info_list
,
jobjectArray
&
whitelisted_data_info_list
,
jboolean
&
mount_data_dirs
,
jboolean
&
mount_storage_dirs
)
{
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
}
}
...
@@ -118,11 +97,12 @@ static void nativeForkAndSpecialize_post(HookContext *ctx, JNIEnv *env, jclass c
...
@@ -118,11 +97,12 @@ static void nativeForkAndSpecialize_post(HookContext *ctx, JNIEnv *env, jclass c
// -----------------------------------------------------------------
// -----------------------------------------------------------------
static
void
nativeSpecializeAppProcess_pre
(
HookContext
*
ctx
,
static
void
nativeSpecializeAppProcess_pre
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
JNIEnv
*
env
,
jclass
clazz
,
jint
&
uid
,
jint
&
gid
,
jintArray
&
gids
,
jint
&
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jstring
nice_name
,
jobjectArray
&
rlimits
,
jint
&
mount_external
,
jstring
&
se_info
,
jstring
&
nice_name
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
,
jboolean
&
is_child_zygote
,
jstring
&
instruction_set
,
jstring
&
app_data_dir
,
jboolean
&
is_top_app
,
jobjectArray
&
pkg_data_info_list
,
jobjectArray
&
whitelisted_data_info_list
,
jboolean
&
is_top_app
,
jobjectArray
&
pkg_data_info_list
,
jboolean
&
mount_data_dirs
,
jboolean
&
mount_storage_dirs
)
{
jobjectArray
&
whitelisted_data_info_list
,
jboolean
&
mount_data_dirs
,
jboolean
&
mount_storage_dirs
)
{
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
}
}
...
@@ -142,6 +122,8 @@ static void nativeForkSystemServer_post(HookContext *ctx, JNIEnv *env, jclass cl
...
@@ -142,6 +122,8 @@ static void nativeForkSystemServer_post(HookContext *ctx, JNIEnv *env, jclass cl
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
}
}
// -----------------------------------------------------------------
static
bool
hook_refresh
()
{
static
bool
hook_refresh
()
{
if
(
xhook_refresh
(
0
)
==
0
)
{
if
(
xhook_refresh
(
0
)
==
0
)
{
xhook_clear
();
xhook_clear
();
...
@@ -176,8 +158,8 @@ void hook_functions() {
...
@@ -176,8 +158,8 @@ void hook_functions() {
hook_refresh
();
hook_refresh
();
}
}
#define push_method(
clazz,
method) \
#define push_method(method) \
if (
JNI::clazz::method##_orig) methods.emplace_back(*JNI::clazz::
method##_orig)
if (
method##_orig) methods.emplace_back(*
method##_orig)
bool
unhook_functions
()
{
bool
unhook_functions
()
{
JNIEnv
*
env
;
JNIEnv
*
env
;
...
@@ -186,10 +168,9 @@ bool unhook_functions() {
...
@@ -186,10 +168,9 @@ bool unhook_functions() {
// Unhook JNI methods
// Unhook JNI methods
vector
<
JNINativeMethod
>
methods
;
vector
<
JNINativeMethod
>
methods
;
push_method
(
nativeForkAndSpecialize
);
push_method
(
Zygote
,
nativeForkAndSpecialize
);
push_method
(
nativeSpecializeAppProcess
);
push_method
(
Zygote
,
nativeSpecializeAppProcess
);
push_method
(
nativeForkSystemServer
);
push_method
(
Zygote
,
nativeForkSystemServer
);
if
(
!
methods
.
empty
()
&&
old_jniRegisterNativeMethods
(
env
,
if
(
!
methods
.
empty
()
&&
old_jniRegisterNativeMethods
(
env
,
"com/android/internal/os/Zygote"
,
"com/android/internal/os/Zygote"
,
...
@@ -198,16 +179,6 @@ bool unhook_functions() {
...
@@ -198,16 +179,6 @@ bool unhook_functions() {
return
false
;
return
false
;
}
}
methods
.
clear
();
push_method
(
SystemProperties
,
native_set
);
if
(
!
methods
.
empty
()
&&
old_jniRegisterNativeMethods
(
env
,
"android/os/SystemProperties"
,
methods
.
data
(),
methods
.
size
())
!=
0
)
{
LOGE
(
"hook: Failed to register JNI hook for SystemProperties
\n
"
);
return
false
;
}
// Unhook xhook
// Unhook xhook
for
(
auto
&
[
path
,
sym
,
old_func
]
:
*
hook_list
)
{
for
(
auto
&
[
path
,
sym
,
old_func
]
:
*
hook_list
)
{
if
(
xhook_register
(
path
,
sym
,
*
old_func
,
nullptr
)
!=
0
)
{
if
(
xhook_register
(
path
,
sym
,
*
old_func
,
nullptr
)
!=
0
)
{
...
...
native/jni/inject/jni_hooks.hpp
View file @
e050f771
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Copyright (c) 2021, John 'topjohnwu' Wu
* Copyright (c) 2021, John 'topjohnwu' Wu
*/
*/
#define ENABLE_LEGACY_DP
1
// Nobody should use outdated developer preview...
#define ENABLE_LEGACY_DP
0
// Nobody should use outdated developer preview...
// All possible missing arguments
// All possible missing arguments
static
union
{
static
union
{
...
@@ -38,7 +38,7 @@ static ret name(__VA_ARGS__)
...
@@ -38,7 +38,7 @@ static ret name(__VA_ARGS__)
#define orig_fork(ver, ...) \
#define orig_fork(ver, ...) \
ctx.pid = reinterpret_cast<decltype(&nativeForkAndSpecialize_##ver)> \
ctx.pid = reinterpret_cast<decltype(&nativeForkAndSpecialize_##ver)> \
(
JNI::Zygote::
nativeForkAndSpecialize_orig->fnPtr)(__VA_ARGS__)
(nativeForkAndSpecialize_orig->fnPtr)(__VA_ARGS__)
#define post_fork() \
#define post_fork() \
nativeForkAndSpecialize_post(&ctx, env, clazz); \
nativeForkAndSpecialize_post(&ctx, env, clazz); \
...
@@ -184,7 +184,7 @@ DCL_FORK_AND_SPECIALIZE(samsung_p,
...
@@ -184,7 +184,7 @@ DCL_FORK_AND_SPECIALIZE(samsung_p,
post_fork
();
post_fork
();
}
}
#define D
CL
_FORK(ver) { \
#define D
EF
_FORK(ver) { \
"nativeForkAndSpecialize", \
"nativeForkAndSpecialize", \
nativeForkAndSpecialize_##ver##_sig, \
nativeForkAndSpecialize_##ver##_sig, \
(void *) &nativeForkAndSpecialize_##ver \
(void *) &nativeForkAndSpecialize_##ver \
...
@@ -202,7 +202,7 @@ DCL_FORK_AND_SPECIALIZE(samsung_p,
...
@@ -202,7 +202,7 @@ DCL_FORK_AND_SPECIALIZE(samsung_p,
#define orig_spec(ver, ...) \
#define orig_spec(ver, ...) \
reinterpret_cast<decltype(&nativeSpecializeAppProcess_##ver)> \
reinterpret_cast<decltype(&nativeSpecializeAppProcess_##ver)> \
(
JNI::Zygote::
nativeSpecializeAppProcess_orig->fnPtr)(__VA_ARGS__)
(nativeSpecializeAppProcess_orig->fnPtr)(__VA_ARGS__)
#define post_spec() \
#define post_spec() \
nativeSpecializeAppProcess_post(&ctx, env, clazz)
nativeSpecializeAppProcess_post(&ctx, env, clazz)
...
@@ -285,7 +285,7 @@ DCL_SPECIALIZE_APP(samsung_q,
...
@@ -285,7 +285,7 @@ DCL_SPECIALIZE_APP(samsung_q,
post_spec
();
post_spec
();
}
}
#define D
CL
_SPEC(ver) { \
#define D
EF
_SPEC(ver) { \
"nativeSpecializeAppProcess", \
"nativeSpecializeAppProcess", \
nativeSpecializeAppProcess_##ver##_sig, \
nativeSpecializeAppProcess_##ver##_sig, \
(void *) &nativeSpecializeAppProcess_##ver \
(void *) &nativeSpecializeAppProcess_##ver \
...
@@ -301,7 +301,7 @@ DCL_SPECIALIZE_APP(samsung_q,
...
@@ -301,7 +301,7 @@ DCL_SPECIALIZE_APP(samsung_q,
#define orig_server(ver, ...) \
#define orig_server(ver, ...) \
ctx.pid = reinterpret_cast<decltype(&nativeForkSystemServer_##ver)> \
ctx.pid = reinterpret_cast<decltype(&nativeForkSystemServer_##ver)> \
(
JNI::Zygote::
nativeForkSystemServer_orig->fnPtr)(__VA_ARGS__)
(nativeForkSystemServer_orig->fnPtr)(__VA_ARGS__)
#define post_server() \
#define post_server() \
nativeForkSystemServer_post(&ctx, env, clazz); \
nativeForkSystemServer_post(&ctx, env, clazz); \
...
@@ -329,71 +329,38 @@ DCL_FORK_SERVER(samsung_q, "(II[IIII[[IJJ)I",
...
@@ -329,71 +329,38 @@ DCL_FORK_SERVER(samsung_q, "(II[IIII[[IJJ)I",
post_server
();
post_server
();
}
}
#define D
CL
_SERVER(ver) { \
#define D
EF
_SERVER(ver) { \
"nativeForkSystemServer", \
"nativeForkSystemServer", \
nativeForkSystemServer_##ver##_sig, \
nativeForkSystemServer_##ver##_sig, \
(void *) &nativeForkSystemServer_##ver \
(void *) &nativeForkSystemServer_##ver \
}
}
/*
namespace
{
* On Android 9+, in very rare cases, SystemProperties.set("sys.user." + userId + ".ce_available", "true")
* will throw an exception (no idea if this is caused by hooking) and user data will be wiped.
* Hook it and clear the exception to prevent this problem from happening.
*
* https://cs.android.com/android/platform/superproject/+/android-9.0.0_r34:frameworks/base/services/core/java/com/android/server/pm/UserDataPreparer.java;l=107;bpv=0;bpt=0
*/
static
void
SystemProperties_set
(
JNIEnv
*
env
,
jobject
clazz
,
jstring
keyJ
,
jstring
valJ
)
{
const
char
*
key
=
env
->
GetStringUTFChars
(
keyJ
,
JNI_FALSE
);
char
user
[
16
];
bool
no_throw
=
sscanf
(
key
,
"sys.user.%[^.].ce_available"
,
user
)
==
1
;
env
->
ReleaseStringUTFChars
(
keyJ
,
key
);
reinterpret_cast
<
decltype
(
&
SystemProperties_set
)
>
(
JNI
::
SystemProperties
::
native_set_orig
->
fnPtr
)(
env
,
clazz
,
keyJ
,
valJ
);
jthrowable
exception
=
env
->
ExceptionOccurred
();
if
(
exception
&&
no_throw
)
{
LOGW
(
"prevented data destroy"
);
env
->
ExceptionDescribe
();
env
->
ExceptionClear
();
}
}
namespace
JNI
{
namespace
Zygote
{
const
JNINativeMethod
nativeForkAndSpecialize_methods
[]
=
{
const
JNINativeMethod
nativeForkAndSpecialize_methods
[]
=
{
DEF_FORK
(
m
),
DEF_FORK
(
o
),
DEF_FORK
(
p
),
DCL_FORK
(
m
),
DCL_FORK
(
o
),
DCL_FORK
(
p
),
DEF_FORK
(
q_alt
),
DEF_FORK
(
r
),
DCL_FORK
(
q_alt
),
DCL_FORK
(
r
),
DEF_FORK
(
samsung_m
),
DEF_FORK
(
samsung_n
),
DCL_FORK
(
samsung_m
),
DCL_FORK
(
samsung_n
),
DEF_FORK
(
samsung_o
),
DEF_FORK
(
samsung_p
),
DCL_FORK
(
samsung_o
),
DCL_FORK
(
samsung_p
),
#if ENABLE_LEGACY_DP
#if ENABLE_LEGACY_DP
DCL_FORK
(
r_dp2
),
DCL
_FORK
(
r_dp3
)
DEF_FORK
(
r_dp2
),
DEF
_FORK
(
r_dp3
)
#endif
#endif
};
};
const
int
nativeForkAndSpecialize_methods_num
=
std
::
size
(
nativeForkAndSpecialize_methods
);
const
int
nativeForkAndSpecialize_methods_num
=
std
::
size
(
nativeForkAndSpecialize_methods
);
const
JNINativeMethod
nativeSpecializeAppProcess_methods
[]
=
{
const
JNINativeMethod
nativeSpecializeAppProcess_methods
[]
=
{
DCL_SPEC
(
q
),
DCL
_SPEC
(
q_alt
),
DEF_SPEC
(
q
),
DEF
_SPEC
(
q_alt
),
DCL_SPEC
(
r
),
DCL
_SPEC
(
samsung_q
),
DEF_SPEC
(
r
),
DEF
_SPEC
(
samsung_q
),
#if ENABLE_LEGACY_DP
#if ENABLE_LEGACY_DP
DCL_SPEC
(
r_dp2
),
DCL
_SPEC
(
r_dp3
)
DEF_SPEC
(
r_dp2
),
DEF
_SPEC
(
r_dp3
)
#endif
#endif
};
};
const
int
nativeSpecializeAppProcess_methods_num
=
std
::
size
(
nativeSpecializeAppProcess_methods
);
const
int
nativeSpecializeAppProcess_methods_num
=
std
::
size
(
nativeSpecializeAppProcess_methods
);
const
JNINativeMethod
nativeForkSystemServer_methods
[]
=
{
DCL_SERVER
(
m
),
DCL_SERVER
(
samsung_q
)
const
JNINativeMethod
nativeForkSystemServer_methods
[]
=
{
};
DEF_SERVER
(
m
),
DEF_SERVER
(
samsung_q
)
const
int
nativeForkSystemServer_methods_num
=
std
::
size
(
nativeForkSystemServer_methods
);
};
}
const
int
nativeForkSystemServer_methods_num
=
std
::
size
(
nativeForkSystemServer_methods
);
namespace
SystemProperties
{
const
JNINativeMethod
native_set_methods
[]
=
{{
"native_set"
,
"(Ljava/lang/String;Ljava/lang/String;)V"
,
(
void
*
)
&
SystemProperties_set
}};
}
}
}
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