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
9ed110c9
Commit
9ed110c9
authored
Jan 08, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add JNI hooks to critical methods
parent
a30d510e
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
700 additions
and
5 deletions
+700
-5
Android.mk
native/jni/Android.mk
+2
-1
entry.cpp
native/jni/inject/entry.cpp
+1
-0
hook.cpp
native/jni/inject/hook.cpp
+75
-4
inject.hpp
native/jni/inject/inject.hpp
+26
-0
jni_hooks.cpp
native/jni/inject/jni_hooks.cpp
+596
-0
No files found.
native/jni/Android.mk
View file @
9ed110c9
...
@@ -33,7 +33,8 @@ LOCAL_SRC_FILES := \
...
@@ -33,7 +33,8 @@ LOCAL_SRC_FILES := \
su/su_daemon.cpp \
su/su_daemon.cpp \
inject/entry.cpp \
inject/entry.cpp \
inject/utils.cpp \
inject/utils.cpp \
inject/hook.cpp
inject/hook.cpp \
inject/jni_hooks.cpp
LOCAL_LDLIBS := -llog
LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE)
include $(BUILD_EXECUTABLE)
...
...
native/jni/inject/entry.cpp
View file @
9ed110c9
...
@@ -42,6 +42,7 @@ static void inject_cleanup() {
...
@@ -42,6 +42,7 @@ static void inject_cleanup() {
}
}
void
self_unload
()
{
void
self_unload
()
{
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
if
(
!
unhook_functions
())
if
(
!
unhook_functions
())
return
;
return
;
...
...
native/jni/inject/hook.cpp
View file @
9ed110c9
...
@@ -8,20 +8,61 @@
...
@@ -8,20 +8,61 @@
using
namespace
std
;
using
namespace
std
;
// Static vector won't work, use a pointer instead
static
JavaVM
*
g_jvm
;
// 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
;
#define DEF_HOOK_FUNC(ret, func, ...) \
#define DEF_HOOK_FUNC(ret, func, ...) \
static ret (*old_##func)(__VA_ARGS__); \
static ret (*old_##func)(__VA_ARGS__); \
static ret new_##func(__VA_ARGS__)
static ret new_##func(__VA_ARGS__)
#define HOOK_JNI(clazz, method) \
if (newMethods[i].name == #method##sv) { \
JNI::clazz::method##_orig = new JNINativeMethod(); \
memcpy(JNI::clazz::method##_orig, &newMethods[i], sizeof(JNINativeMethod)); \
for (int j = 0; j < JNI::clazz::method##_methods_num; ++j) { \
if (strcmp(newMethods[i].signature, JNI::clazz::method##_methods[j].signature) == 0) { \
newMethods[i] = JNI::clazz::method##_methods[j]; \
LOGI("hook: replaced " #clazz "#" #method "\n"); \
++hooked; \
break; \
} \
} \
continue; \
}
#define clone_methods() \
newMethods = make_unique<JNINativeMethod[]>(numMethods); \
memcpy(newMethods.get(), methods, sizeof(JNINativeMethod) * numMethods)
DEF_HOOK_FUNC
(
int
,
jniRegisterNativeMethods
,
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
);
// TODO: actually do things like replacing JNI native methods
unique_ptr
<
JNINativeMethod
[]
>
newMethods
;
int
hooked
=
0
;
if
(
g_jvm
==
nullptr
)
{
// Save for later unhooking
env
->
GetJavaVM
(
&
g_jvm
);
}
return
old_jniRegisterNativeMethods
(
env
,
className
,
methods
,
numMethods
);
if
(
className
==
"com/android/internal/os/Zygote"
sv
)
{
clone_methods
();
for
(
int
i
=
0
;
i
<
numMethods
&&
hooked
<
3
;
++
i
)
{
HOOK_JNI
(
Zygote
,
nativeForkAndSpecialize
);
HOOK_JNI
(
Zygote
,
nativeSpecializeAppProcess
);
HOOK_JNI
(
Zygote
,
nativeForkSystemServer
);
}
}
else
if
(
className
==
"android/os/SystemProperties"
sv
)
{
clone_methods
();
for
(
int
i
=
0
;
i
<
numMethods
&&
hooked
<
1
;
++
i
)
{
HOOK_JNI
(
SystemProperties
,
native_set
);
}
}
return
old_jniRegisterNativeMethods
(
env
,
className
,
newMethods
.
get
()
?:
methods
,
numMethods
);
}
}
static
bool
hook_refresh
()
{
static
bool
hook_refresh
()
{
...
@@ -58,10 +99,40 @@ void hook_functions() {
...
@@ -58,10 +99,40 @@ void hook_functions() {
hook_refresh
();
hook_refresh
();
}
}
#define push_method(clazz, method) \
if (JNI::clazz::method##_orig) methods.emplace_back(*JNI::clazz::method##_orig)
bool
unhook_functions
()
{
bool
unhook_functions
()
{
JNIEnv
*
env
;
if
(
g_jvm
->
GetEnv
(
reinterpret_cast
<
void
**>
(
&
env
),
JNI_VERSION_1_6
)
!=
JNI_OK
)
return
false
;
vector
<
JNINativeMethod
>
methods
;
push_method
(
Zygote
,
nativeForkAndSpecialize
);
push_method
(
Zygote
,
nativeSpecializeAppProcess
);
push_method
(
Zygote
,
nativeForkSystemServer
);
if
(
!
methods
.
empty
()
&&
old_jniRegisterNativeMethods
(
env
,
"com/android/internal/os/Zygote"
,
methods
.
data
(),
methods
.
size
())
!=
0
)
{
LOGE
(
"hook: Failed to register JNI hook for Zygote
\n
"
);
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
;
}
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
)
{
LOGE
(
"hook: Failed to register hook
\"
%s
\"\n
"
,
sym
);
\
LOGE
(
"hook: Failed to register hook
\"
%s
\"\n
"
,
sym
);
return
false
;
return
false
;
}
}
}
}
...
...
native/jni/inject/inject.hpp
View file @
9ed110c9
#pragma once
#pragma once
#include <stdint.h>
#include <stdint.h>
#include <jni.h>
#define INJECT_LIB_1 "/dev/tmp/magisk.1.so"
#define INJECT_LIB_1 "/dev/tmp/magisk.1.so"
#define INJECT_LIB_2 "/dev/tmp/magisk.2.so"
#define INJECT_LIB_2 "/dev/tmp/magisk.2.so"
...
@@ -19,3 +20,28 @@ uintptr_t get_remote_lib(int pid, const char *lib);
...
@@ -19,3 +20,28 @@ uintptr_t get_remote_lib(int pid, const char *lib);
void
self_unload
();
void
self_unload
();
void
hook_functions
();
void
hook_functions
();
bool
unhook_functions
();
bool
unhook_functions
();
// JNI method declarations
namespace
JNI
{
namespace
Zygote
{
extern
JNINativeMethod
*
nativeForkAndSpecialize_orig
;
extern
JNINativeMethod
*
nativeSpecializeAppProcess_orig
;
extern
JNINativeMethod
*
nativeForkSystemServer_orig
;
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
{
extern
JNINativeMethod
*
native_set_orig
;
extern
const
JNINativeMethod
native_set_methods
[];
constexpr
int
native_set_methods_num
=
1
;
}
}
native/jni/inject/jni_hooks.cpp
0 → 100644
View file @
9ed110c9
This diff is collapsed.
Click to expand it.
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