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
3ea10b7c
Commit
3ea10b7c
authored
Aug 12, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reorganize injection code
parent
1ec33863
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
113 additions
and
107 deletions
+113
-107
api.hpp
native/jni/inject/api.hpp
+47
-0
gen_jni_hooks.py
native/jni/inject/gen_jni_hooks.py
+2
-4
hook.cpp
native/jni/inject/hook.cpp
+46
-79
jni_hooks.hpp
native/jni/inject/jni_hooks.hpp
+18
-24
No files found.
native/jni/inject/api.hpp
0 → 100644
View file @
3ea10b7c
#pragma once
#include <jni.h>
struct
SpecializeAppProcessArgs
{
jint
&
uid
;
jint
&
gid
;
jintArray
&
gids
;
jint
&
runtime_flags
;
jint
&
mount_external
;
jstring
&
se_info
;
jstring
&
nice_name
;
jstring
&
instruction_set
;
jstring
&
app_data_dir
;
/* Optional */
jboolean
*
is_child_zygote
=
nullptr
;
jboolean
*
is_top_app
=
nullptr
;
jobjectArray
*
pkg_data_info_list
=
nullptr
;
jobjectArray
*
whitelisted_data_info_list
=
nullptr
;
jboolean
*
mount_data_dirs
=
nullptr
;
jboolean
*
mount_storage_dirs
=
nullptr
;
SpecializeAppProcessArgs
(
jint
&
uid
,
jint
&
gid
,
jintArray
&
gids
,
jint
&
runtime_flags
,
jint
&
mount_external
,
jstring
&
se_info
,
jstring
&
nice_name
,
jstring
&
instruction_set
,
jstring
&
app_data_dir
)
:
uid
(
uid
),
gid
(
gid
),
gids
(
gids
),
runtime_flags
(
runtime_flags
),
mount_external
(
mount_external
),
se_info
(
se_info
),
nice_name
(
nice_name
),
instruction_set
(
instruction_set
),
app_data_dir
(
app_data_dir
)
{}
};
struct
ForkSystemServerArgs
{
jint
&
uid
;
jint
&
gid
;
jintArray
&
gids
;
jint
&
runtime_flags
;
jlong
&
permitted_capabilities
;
jlong
&
effective_capabilities
;
ForkSystemServerArgs
(
jint
&
uid
,
jint
&
gid
,
jintArray
&
gids
,
jint
&
runtime_flags
,
jlong
&
permitted_capabilities
,
jlong
&
effective_capabilities
)
:
uid
(
uid
),
gid
(
gid
),
gids
(
gids
),
runtime_flags
(
runtime_flags
),
permitted_capabilities
(
permitted_capabilities
),
effective_capabilities
(
effective_capabilities
)
{}
};
native/jni/inject/gen_jni_hooks.py
View file @
3ea10b7c
...
@@ -150,7 +150,7 @@ def gen_definitions(methods, base_name):
...
@@ -150,7 +150,7 @@ def gen_definitions(methods, base_name):
jni_ret
=
'V'
jni_ret
=
'V'
for
m
in
methods
:
for
m
in
methods
:
func_name
=
f
'{base_name}_{m.name}'
func_name
=
f
'{base_name}_{m.name}'
decl
+=
ind
(
0
)
+
f
'
static
{cpp_ret} {func_name}(JNIEnv *env, jclass clazz, {m.cpp()}) {{'
decl
+=
ind
(
0
)
+
f
'{cpp_ret} {func_name}(JNIEnv *env, jclass clazz, {m.cpp()}) {{'
decl
+=
ind
(
1
)
+
'HookContext ctx{};'
decl
+=
ind
(
1
)
+
'HookContext ctx{};'
if
base_name
==
'nativeForkSystemServer'
:
if
base_name
==
'nativeForkSystemServer'
:
decl
+=
ind
(
1
)
+
'ForkSystemServerArgs args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities);'
decl
+=
ind
(
1
)
+
'ForkSystemServerArgs args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities);'
...
@@ -168,7 +168,6 @@ def gen_definitions(methods, base_name):
...
@@ -168,7 +168,6 @@ def gen_definitions(methods, base_name):
decl
+=
ret_stat
decl
+=
ret_stat
decl
+=
ind
(
0
)
+
'}'
decl
+=
ind
(
0
)
+
'}'
decl
+=
ind
(
0
)
+
'namespace {'
decl
+=
ind
(
0
)
+
f
'const JNINativeMethod {base_name}_methods[] = {{'
decl
+=
ind
(
0
)
+
f
'const JNINativeMethod {base_name}_methods[] = {{'
for
m
in
methods
:
for
m
in
methods
:
decl
+=
ind
(
1
)
+
'{'
decl
+=
ind
(
1
)
+
'{'
...
@@ -177,8 +176,7 @@ def gen_definitions(methods, base_name):
...
@@ -177,8 +176,7 @@ def gen_definitions(methods, base_name):
decl
+=
ind
(
2
)
+
f
'(void *) &{base_name}_{m.name}'
decl
+=
ind
(
2
)
+
f
'(void *) &{base_name}_{m.name}'
decl
+=
ind
(
1
)
+
'},'
decl
+=
ind
(
1
)
+
'},'
decl
+=
ind
(
0
)
+
'};'
decl
+=
ind
(
0
)
+
'};'
decl
+=
ind
(
0
)
+
f
'const int {base_name}_methods_num = std::size({base_name}_methods);'
decl
+=
ind
(
0
)
+
f
'constexpr int {base_name}_methods_num = std::size({base_name}_methods);'
decl
+=
ind
(
0
)
+
'} // namespace'
decl
+=
ind
(
0
)
decl
+=
ind
(
0
)
return
decl
return
decl
...
...
native/jni/inject/hook.cpp
View file @
3ea10b7c
...
@@ -6,55 +6,14 @@
...
@@ -6,55 +6,14 @@
#include "inject.hpp"
#include "inject.hpp"
#include "memory.hpp"
#include "memory.hpp"
#include "api.hpp"
using
namespace
std
;
using
namespace
std
;
using
jni_hook
::
hash_map
;
using
jni_hook
::
hash_map
;
using
jni_hook
::
tree_map
;
using
jni_hook
::
tree_map
;
using
xstring
=
jni_hook
::
string
;
using
xstring
=
jni_hook
::
string
;
struct
SpecializeAppProcessArgs
{
namespace
{
jint
&
uid
;
jint
&
gid
;
jintArray
&
gids
;
jint
&
runtime_flags
;
jint
&
mount_external
;
jstring
&
se_info
;
jstring
&
nice_name
;
jstring
&
instruction_set
;
jstring
&
app_data_dir
;
/* Optional */
jboolean
*
is_child_zygote
=
nullptr
;
jboolean
*
is_top_app
=
nullptr
;
jobjectArray
*
pkg_data_info_list
=
nullptr
;
jobjectArray
*
whitelisted_data_info_list
=
nullptr
;
jboolean
*
mount_data_dirs
=
nullptr
;
jboolean
*
mount_storage_dirs
=
nullptr
;
SpecializeAppProcessArgs
(
jint
&
uid
,
jint
&
gid
,
jintArray
&
gids
,
jint
&
runtime_flags
,
jint
&
mount_external
,
jstring
&
se_info
,
jstring
&
nice_name
,
jstring
&
instruction_set
,
jstring
&
app_data_dir
)
:
uid
(
uid
),
gid
(
gid
),
gids
(
gids
),
runtime_flags
(
runtime_flags
),
mount_external
(
mount_external
),
se_info
(
se_info
),
nice_name
(
nice_name
),
instruction_set
(
instruction_set
),
app_data_dir
(
app_data_dir
)
{}
};
struct
ForkSystemServerArgs
{
jint
&
uid
;
jint
&
gid
;
jintArray
&
gids
;
jint
&
runtime_flags
;
jlong
&
permitted_capabilities
;
jlong
&
effective_capabilities
;
ForkSystemServerArgs
(
jint
&
uid
,
jint
&
gid
,
jintArray
&
gids
,
jint
&
runtime_flags
,
jlong
&
permitted_capabilities
,
jlong
&
effective_capabilities
)
:
uid
(
uid
),
gid
(
gid
),
gids
(
gids
),
runtime_flags
(
runtime_flags
),
permitted_capabilities
(
permitted_capabilities
),
effective_capabilities
(
effective_capabilities
)
{}
};
struct
HookContext
{
struct
HookContext
{
int
pid
;
int
pid
;
...
@@ -65,33 +24,32 @@ struct HookContext {
...
@@ -65,33 +24,32 @@ struct HookContext {
void
*
raw_args
;
void
*
raw_args
;
};
};
};
};
struct
vtable_t
;
static
vector
<
tuple
<
const
char
*
,
const
char
*
,
void
**>>
*
xhook_list
;
static
vector
<
JNINativeMethod
>
*
jni_hook_list
;
static
hash_map
<
xstring
,
tree_map
<
xstring
,
tree_map
<
xstring
,
void
*>>>
*
jni_method_map
;
static
HookContext
*
current_ctx
;
// Global variables
static
JavaVM
*
g_jvm
;
vector
<
tuple
<
const
char
*
,
const
char
*
,
void
**>>
*
xhook_list
;
static
vtable_t
*
gAppRuntimeVTable
;
vector
<
JNINativeMethod
>
*
jni_hook_list
;
static
const
JNINativeInterface
*
old_functions
;
hash_map
<
xstring
,
tree_map
<
xstring
,
tree_map
<
xstring
,
void
*>>>
*
jni_method_map
;
static
JNINativeInterface
*
new_functions
;
#define DCL_HOOK_FUNC(ret, func, ...) \
HookContext
*
current_ctx
;
static ret (*old_##func)(__VA_ARGS__); \
JavaVM
*
g_jvm
;
static ret new_##func(__VA_ARGS__)
const
JNINativeInterface
*
old_functions
;
JNINativeInterface
*
new_functions
;
#define DCL_JNI_FUNC(name) \
#define DCL_JNI_FUNC(name) \
static void *name##_orig;
\
void *name##_orig;
\
extern const JNINativeMethod name##_methods[];
\
void name##_pre(HookContext *ctx, JNIEnv *env, jclass clazz);
\
extern const int name##_methods_num
;
void name##_post(HookContext *ctx, JNIEnv *env, jclass clazz)
;
namespace
{
// JNI method declarations
// JNI method declarations
DCL_JNI_FUNC
(
nativeForkAndSpecialize
)
DCL_JNI_FUNC
(
nativeForkAndSpecialize
)
DCL_JNI_FUNC
(
nativeSpecializeAppProcess
)
DCL_JNI_FUNC
(
nativeSpecializeAppProcess
)
DCL_JNI_FUNC
(
nativeForkSystemServer
)
DCL_JNI_FUNC
(
nativeForkSystemServer
)
}
#undef DCL_JNI_FUNC
// JNI method definitions
// Includes all method signatures of all supported Android versions
#include "jni_hooks.hpp"
#define HOOK_JNI(method) \
#define HOOK_JNI(method) \
if (methods[i].name == #method##sv) { \
if (methods[i].name == #method##sv) { \
...
@@ -108,7 +66,7 @@ if (methods[i].name == #method##sv) { \
...
@@ -108,7 +66,7 @@ if (methods[i].name == #method##sv) { \
continue; \
continue; \
}
}
static
unique_ptr
<
JNINativeMethod
[]
>
hookAndSaveJNIMethods
(
unique_ptr
<
JNINativeMethod
[]
>
hookAndSaveJNIMethods
(
JNIEnv
*
env
,
const
char
*
className
,
const
JNINativeMethod
*
methods
,
int
numMethods
)
{
JNIEnv
*
env
,
const
char
*
className
,
const
JNINativeMethod
*
methods
,
int
numMethods
)
{
if
(
g_jvm
==
nullptr
)
{
if
(
g_jvm
==
nullptr
)
{
// Save for later unhooking
// Save for later unhooking
...
@@ -135,9 +93,11 @@ static unique_ptr<JNINativeMethod[]> hookAndSaveJNIMethods(
...
@@ -135,9 +93,11 @@ static unique_ptr<JNINativeMethod[]> hookAndSaveJNIMethods(
return
newMethods
;
return
newMethods
;
}
}
static
jclass
gClassRef
;
#undef HOOK_JNI
static
jmethodID
class_getName
;
static
string
get_class_name
(
JNIEnv
*
env
,
jclass
clazz
)
{
jclass
gClassRef
;
jmethodID
class_getName
;
string
get_class_name
(
JNIEnv
*
env
,
jclass
clazz
)
{
if
(
!
gClassRef
)
{
if
(
!
gClassRef
)
{
jclass
cls
=
env
->
FindClass
(
"java/lang/Class"
);
jclass
cls
=
env
->
FindClass
(
"java/lang/Class"
);
gClassRef
=
(
jclass
)
env
->
NewGlobalRef
(
cls
);
gClassRef
=
(
jclass
)
env
->
NewGlobalRef
(
cls
);
...
@@ -154,7 +114,11 @@ static string get_class_name(JNIEnv *env, jclass clazz) {
...
@@ -154,7 +114,11 @@ static string get_class_name(JNIEnv *env, jclass clazz) {
// -----------------------------------------------------------------
// -----------------------------------------------------------------
static
jint
new_env_RegisterNatives
(
#define DCL_HOOK_FUNC(ret, func, ...) \
ret (*old_##func)(__VA_ARGS__); \
ret new_##func(__VA_ARGS__)
jint
new_env_RegisterNatives
(
JNIEnv
*
env
,
jclass
clazz
,
const
JNINativeMethod
*
methods
,
jint
numMethods
)
{
JNIEnv
*
env
,
jclass
clazz
,
const
JNINativeMethod
*
methods
,
jint
numMethods
)
{
auto
className
=
get_class_name
(
env
,
clazz
);
auto
className
=
get_class_name
(
env
,
clazz
);
LOGD
(
"hook: JNIEnv->RegisterNatives %s
\n
"
,
className
.
data
());
LOGD
(
"hook: JNIEnv->RegisterNatives %s
\n
"
,
className
.
data
());
...
@@ -196,6 +160,8 @@ struct vtable_t {
...
@@ -196,6 +160,8 @@ struct vtable_t {
void
(
*
onExit
)(
void
*
self
,
int
code
);
void
(
*
onExit
)(
void
*
self
,
int
code
);
};
};
vtable_t
*
gAppRuntimeVTable
;
// This method is a trampoline for hooking JNIEnv->RegisterNatives
// This method is a trampoline for hooking JNIEnv->RegisterNatives
DCL_HOOK_FUNC
(
void
,
onVmCreated
,
void
*
self
,
JNIEnv
*
env
)
{
DCL_HOOK_FUNC
(
void
,
onVmCreated
,
void
*
self
,
JNIEnv
*
env
)
{
LOGD
(
"hook: AppRuntime::onVmCreated
\n
"
);
LOGD
(
"hook: AppRuntime::onVmCreated
\n
"
);
...
@@ -215,7 +181,7 @@ DCL_HOOK_FUNC(void, onVmCreated, void *self, JNIEnv *env) {
...
@@ -215,7 +181,7 @@ DCL_HOOK_FUNC(void, onVmCreated, void *self, JNIEnv *env) {
}
}
// This method is a trampoline for swizzling android::AppRuntime vtable
// This method is a trampoline for swizzling android::AppRuntime vtable
static
bool
swizzled
=
false
;
bool
swizzled
=
false
;
DCL_HOOK_FUNC
(
void
,
setArgv0
,
void
*
self
,
const
char
*
argv0
,
bool
setProcName
)
{
DCL_HOOK_FUNC
(
void
,
setArgv0
,
void
*
self
,
const
char
*
argv0
,
bool
setProcName
)
{
if
(
swizzled
)
{
if
(
swizzled
)
{
old_setArgv0
(
self
,
argv0
,
setProcName
);
old_setArgv0
(
self
,
argv0
,
setProcName
);
...
@@ -236,9 +202,11 @@ DCL_HOOK_FUNC(void, setArgv0, void *self, const char *argv0, bool setProcName) {
...
@@ -236,9 +202,11 @@ DCL_HOOK_FUNC(void, setArgv0, void *self, const char *argv0, bool setProcName) {
old_setArgv0
(
self
,
argv0
,
setProcName
);
old_setArgv0
(
self
,
argv0
,
setProcName
);
}
}
#undef DCL_HOOK_FUNC
// -----------------------------------------------------------------
// -----------------------------------------------------------------
static
void
nativeSpecializeAppProcess_pre
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
void
nativeSpecializeAppProcess_pre
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
current_ctx
=
ctx
;
current_ctx
=
ctx
;
const
char
*
process
=
env
->
GetStringUTFChars
(
ctx
->
args
->
nice_name
,
nullptr
);
const
char
*
process
=
env
->
GetStringUTFChars
(
ctx
->
args
->
nice_name
,
nullptr
);
LOGD
(
"hook: %s %s
\n
"
,
__FUNCTION__
,
process
);
LOGD
(
"hook: %s %s
\n
"
,
__FUNCTION__
,
process
);
...
@@ -252,7 +220,7 @@ static void nativeSpecializeAppProcess_pre(HookContext *ctx, JNIEnv *env, jclass
...
@@ -252,7 +220,7 @@ static void nativeSpecializeAppProcess_pre(HookContext *ctx, JNIEnv *env, jclass
env
->
ReleaseStringUTFChars
(
ctx
->
args
->
nice_name
,
process
);
env
->
ReleaseStringUTFChars
(
ctx
->
args
->
nice_name
,
process
);
}
}
static
void
nativeSpecializeAppProcess_post
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
void
nativeSpecializeAppProcess_post
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
current_ctx
=
nullptr
;
current_ctx
=
nullptr
;
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
...
@@ -262,7 +230,7 @@ static void nativeSpecializeAppProcess_post(HookContext *ctx, JNIEnv *env, jclas
...
@@ -262,7 +230,7 @@ static void nativeSpecializeAppProcess_post(HookContext *ctx, JNIEnv *env, jclas
// -----------------------------------------------------------------
// -----------------------------------------------------------------
static
int
sigmask
(
int
how
,
int
signum
)
{
int
sigmask
(
int
how
,
int
signum
)
{
sigset_t
set
;
sigset_t
set
;
sigemptyset
(
&
set
);
sigemptyset
(
&
set
);
sigaddset
(
&
set
,
signum
);
sigaddset
(
&
set
,
signum
);
...
@@ -285,19 +253,19 @@ static int sigmask(int how, int signum) {
...
@@ -285,19 +253,19 @@ static int sigmask(int how, int signum) {
if (ctx->pid != 0)\
if (ctx->pid != 0)\
return;
return;
static
void
nativeForkAndSpecialize_pre
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
void
nativeForkAndSpecialize_pre
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
PRE_FORK
();
PRE_FORK
();
nativeSpecializeAppProcess_pre
(
ctx
,
env
,
clazz
);
nativeSpecializeAppProcess_pre
(
ctx
,
env
,
clazz
);
}
}
static
void
nativeForkAndSpecialize_post
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
void
nativeForkAndSpecialize_post
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
POST_FORK
();
POST_FORK
();
nativeSpecializeAppProcess_post
(
ctx
,
env
,
clazz
);
nativeSpecializeAppProcess_post
(
ctx
,
env
,
clazz
);
}
}
// -----------------------------------------------------------------
// -----------------------------------------------------------------
static
void
nativeForkSystemServer_pre
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
void
nativeForkSystemServer_pre
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
if
(
env
->
functions
==
new_functions
)
{
if
(
env
->
functions
==
new_functions
)
{
// Restore JNIEnv
// Restore JNIEnv
env
->
functions
=
old_functions
;
env
->
functions
=
old_functions
;
...
@@ -312,7 +280,7 @@ static void nativeForkSystemServer_pre(HookContext *ctx, JNIEnv *env, jclass cla
...
@@ -312,7 +280,7 @@ static void nativeForkSystemServer_pre(HookContext *ctx, JNIEnv *env, jclass cla
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
}
}
static
void
nativeForkSystemServer_post
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
void
nativeForkSystemServer_post
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
POST_FORK
();
POST_FORK
();
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
}
}
...
@@ -322,7 +290,7 @@ static void nativeForkSystemServer_post(HookContext *ctx, JNIEnv *env, jclass cl
...
@@ -322,7 +290,7 @@ static void nativeForkSystemServer_post(HookContext *ctx, JNIEnv *env, jclass cl
// -----------------------------------------------------------------
// -----------------------------------------------------------------
static
bool
hook_refresh
()
{
bool
hook_refresh
()
{
if
(
xhook_refresh
(
0
)
==
0
)
{
if
(
xhook_refresh
(
0
)
==
0
)
{
xhook_clear
();
xhook_clear
();
LOGI
(
"hook: xhook success
\n
"
);
LOGI
(
"hook: xhook success
\n
"
);
...
@@ -333,7 +301,7 @@ static bool hook_refresh() {
...
@@ -333,7 +301,7 @@ static bool hook_refresh() {
}
}
}
}
static
int
hook_register
(
const
char
*
path
,
const
char
*
symbol
,
void
*
new_func
,
void
**
old_func
)
{
int
hook_register
(
const
char
*
path
,
const
char
*
symbol
,
void
*
new_func
,
void
**
old_func
)
{
int
ret
=
xhook_register
(
path
,
symbol
,
new_func
,
old_func
);
int
ret
=
xhook_register
(
path
,
symbol
,
new_func
,
old_func
);
if
(
ret
!=
0
)
{
if
(
ret
!=
0
)
{
LOGE
(
"hook: Failed to register hook
\"
%s
\"\n
"
,
symbol
);
LOGE
(
"hook: Failed to register hook
\"
%s
\"\n
"
,
symbol
);
...
@@ -343,6 +311,8 @@ static int hook_register(const char *path, const char *symbol, void *new_func, v
...
@@ -343,6 +311,8 @@ static int hook_register(const char *path, const char *symbol, void *new_func, v
return
0
;
return
0
;
}
}
}
// namespace
template
<
class
T
>
template
<
class
T
>
static
inline
void
default_new
(
T
*&
p
)
{
p
=
new
T
();
}
static
inline
void
default_new
(
T
*&
p
)
{
p
=
new
T
();
}
...
@@ -418,6 +388,3 @@ bool unhook_functions() {
...
@@ -418,6 +388,3 @@ bool unhook_functions() {
delete
xhook_list
;
delete
xhook_list
;
return
hook_refresh
();
return
hook_refresh
();
}
}
// JNI method definitions, include all method signatures of past Android versions
#include "jni_hooks.hpp"
native/jni/inject/jni_hooks.hpp
View file @
3ea10b7c
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