Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
S
SandHook
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
SandHook
Commits
beabc0fb
Commit
beabc0fb
authored
Jan 21, 2019
by
swift_gan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
done inline hook
parent
04f28dc1
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
374 additions
and
21 deletions
+374
-21
CMakeLists.txt
app/CMakeLists.txt
+1
-0
build.gradle
app/build.gradle
+1
-1
arch.h
app/src/main/cpp/includes/arch.h
+17
-0
utils.h
app/src/main/cpp/includes/utils.h
+14
-0
native-lib.cpp
app/src/main/cpp/native-lib.cpp
+54
-17
arm64.S
app/src/main/cpp/trampoline/arch/arm64.S
+2
-2
trampoline.h
app/src/main/cpp/trampoline/trampoline.h
+4
-0
fake_dlfcn.cpp
app/src/main/cpp/utils/fake_dlfcn.cpp
+185
-0
fake_dlfcn.h
app/src/main/cpp/utils/fake_dlfcn.h
+34
-0
hide_api.h
app/src/main/cpp/utils/hide_api.h
+40
-0
MainActivity.java
app/src/main/java/com/swift/sandhook/MainActivity.java
+1
-1
SandHook.java
app/src/main/java/com/swift/sandhook/SandHook.java
+21
-0
No files found.
app/CMakeLists.txt
View file @
beabc0fb
...
...
@@ -20,6 +20,7 @@ add_library( # Sets the name of the library.
src/main/cpp/native-lib.cpp
src/main/cpp/trampoline/trampoline.cpp
src/main/cpp/trampoline/trampoline_manager.cpp
src/main/cpp/utils/fake_dlfcn.cpp
src/main/cpp/trampoline/arch/arm32.S
src/main/cpp/trampoline/arch/arm64.S
)
...
...
app/build.gradle
View file @
beabc0fb
...
...
@@ -11,7 +11,7 @@ android {
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild
{
cmake
{
arguments
'-DBUILD_TESTING=OFF'
arguments
'-DBUILD_TESTING=OFF'
,
'-DANDROID_TOOLCHAIN=gcc'
cppFlags
"-frtti -fexceptions"
abiFilters
'armeabi-v7a'
,
'arm64-v8a'
}
...
...
app/src/main/cpp/includes/arch.h
View file @
beabc0fb
...
...
@@ -22,6 +22,23 @@ namespace SandHook {
#else
#endif
#if defined(__arm__)
static
void
clearCacheArm32
(
char
*
begin
,
char
*
end
)
{
const
int
syscall
=
0xf0002
;
__asm
__volatile
(
"mov r0, %0
\n
"
"mov r1, %1
\n
"
"mov r3, %2
\n
"
"mov r2, #0x0
\n
"
"svc 0x00000000
\n
"
:
:
"r"
(
begin
),
"r"
(
end
),
"r"
(
syscall
)
:
"r0"
,
"r1"
,
"r3"
);
}
#endif
}
...
...
app/src/main/cpp/includes/utils.h
View file @
beabc0fb
...
...
@@ -75,6 +75,20 @@ Size getAddressFromJava(JNIEnv* env, char* className, char* fieldName) {
return
env
->
GetStaticLongField
(
clazz
,
id
);
}
Size
getAddressFromJavaByCallMethod
(
JNIEnv
*
env
,
char
*
className
,
char
*
methodName
)
{
jclass
clazz
=
env
->
FindClass
(
className
);
if
(
clazz
==
NULL
){
printf
(
"find class error !"
);
return
0
;
}
jmethodID
id
=
env
->
GetStaticMethodID
(
clazz
,
methodName
,
"()J"
);
if
(
id
==
NULL
){
printf
(
"find field error !"
);
return
0
;
}
return
env
->
CallStaticLongMethodA
(
clazz
,
id
,
nullptr
);
}
jint
getIntFromJava
(
JNIEnv
*
env
,
char
*
className
,
char
*
fieldName
)
{
jclass
clazz
=
env
->
FindClass
(
className
);
if
(
clazz
==
NULL
){
...
...
app/src/main/cpp/native-lib.cpp
View file @
beabc0fb
#include <jni.h>
#include "casts/cast_art_method.h"
#include "./trampoline/trampoline_manager.h"
#include "./utils/hide_api.h"
SandHook
::
TrampolineManager
trampolineManager
;
...
...
@@ -14,6 +15,7 @@ Java_com_swift_sandhook_SandHook_initNative(JNIEnv *env, jclass type, jint sdk)
SDK_INT
=
sdk
;
SandHook
::
CastArtMethod
::
init
(
env
,
sdk
);
trampolineManager
.
init
(
SandHook
::
CastArtMethod
::
entryPointQuickCompiled
->
getOffset
());
initHideApi
(
env
,
sdk
);
return
JNI_TRUE
;
}
...
...
@@ -30,6 +32,42 @@ void disableInterpreterForO(art::mirror::ArtMethod* method) {
SandHook
::
CastArtMethod
::
accessFlag
->
set
(
method
,
accessFlag
);
}
bool
doHookWithReplacement
(
art
::
mirror
::
ArtMethod
*
originMethod
,
art
::
mirror
::
ArtMethod
*
hookMethod
,
art
::
mirror
::
ArtMethod
*
backupMethod
)
{
if
(
SDK_INT
>=
ANDROID_N
)
{
disableCompilable
(
originMethod
);
disableCompilable
(
hookMethod
);
}
if
(
SDK_INT
>=
ANDROID_O
)
{
disableInterpreterForO
(
originMethod
);
}
SandHook
::
HookTrampoline
*
hookTrampoline
=
trampolineManager
.
installReplacementTrampoline
(
originMethod
,
hookMethod
,
backupMethod
);
if
(
hookTrampoline
!=
nullptr
)
{
SandHook
::
CastArtMethod
::
entryPointQuickCompiled
->
set
(
originMethod
,
hookTrampoline
->
replacement
->
getCode
());
hookTrampoline
->
replacement
->
flushCache
(
reinterpret_cast
<
Size
>
(
originMethod
),
100
);
}
}
bool
doHookWithInline
(
JNIEnv
*
env
,
art
::
mirror
::
ArtMethod
*
originMethod
,
art
::
mirror
::
ArtMethod
*
hookMethod
,
art
::
mirror
::
ArtMethod
*
backupMethod
)
{
// uint32_t accessFlag = SandHook::CastArtMethod::accessFlag->get(*originMethod);
// SandHook::CastArtMethod::accessFlag->set(hookMethod, accessFlag);
bool
isInterpreter
=
SandHook
::
CastArtMethod
::
entryPointQuickCompiled
->
get
(
*
hookMethod
)
==
SandHook
::
CastArtMethod
::
quickToInterpreterBridge
;
if
(
isInterpreter
)
{
Size
threadId
=
getAddressFromJavaByCallMethod
(
env
,
"com/swift/sandhook/SandHook"
,
"getThreadId"
);
compileMethod
(
hookMethod
,
reinterpret_cast
<
void
*>
(
threadId
));
}
SandHook
::
HookTrampoline
*
hookTrampoline
=
trampolineManager
.
installInlineTrampoline
(
originMethod
,
hookMethod
,
backupMethod
);
hookTrampoline
->
inlineSecondory
->
flushCache
(
reinterpret_cast
<
Size
>
(
hookMethod
),
100
);
}
extern
"C"
JNIEXPORT
jboolean
JNICALL
Java_com_swift_sandhook_SandHook_hookMethod
(
JNIEnv
*
env
,
jclass
type
,
jobject
originMethod
,
...
...
@@ -40,25 +78,24 @@ Java_com_swift_sandhook_SandHook_hookMethod(JNIEnv *env, jclass type, jobject or
art
::
mirror
::
ArtMethod
*
hook
=
reinterpret_cast
<
art
::
mirror
::
ArtMethod
*>
(
env
->
FromReflectedMethod
(
hookMethod
));
art
::
mirror
::
ArtMethod
*
backup
=
backupMethod
==
NULL
?
nullptr
:
reinterpret_cast
<
art
::
mirror
::
ArtMethod
*>
(
env
->
FromReflectedMethod
(
backupMethod
));
// if (SandHook::CastArtMethod::entryPointQuickCompiled->get(*origin) == SandHook::CastArtMethod::quickToInterpreterBridge) {
// return JNI_FALSE;
// }
if
(
SDK_INT
>=
ANDROID_N
)
{
disableCompilable
(
origin
);
disableCompilable
(
hook
);
}
if
(
SDK_INT
>=
ANDROID_O
)
{
disableInterpreterForO
(
origin
);
}
bool
isInterpreter
=
SandHook
::
CastArtMethod
::
entryPointQuickCompiled
->
get
(
*
origin
)
==
SandHook
::
CastArtMethod
::
quickToInterpreterBridge
;
SandHook
::
HookTrampoline
*
hookTrampoline
=
trampolineManager
.
installReplacementTrampoline
(
origin
,
hook
,
backup
);
if
(
hookTrampoline
!=
nullptr
)
{
SandHook
::
CastArtMethod
::
entryPointQuickCompiled
->
set
(
origin
,
hookTrampoline
->
replacement
->
getCode
());
hookTrampoline
->
replacement
->
flushCache
(
reinterpret_cast
<
uint64_t
>
(
origin
),
100
);
if
(
isInterpreter
)
{
if
(
SDK_INT
>=
ANDROID_N
)
{
Size
threadId
=
getAddressFromJavaByCallMethod
(
env
,
"com/swift/sandhook/SandHook"
,
"getThreadId"
);
if
(
compileMethod
(
origin
,
reinterpret_cast
<
void
*>
(
threadId
))
&&
SandHook
::
CastArtMethod
::
entryPointQuickCompiled
->
get
(
*
origin
)
!=
SandHook
::
CastArtMethod
::
quickToInterpreterBridge
)
{
doHookWithInline
(
env
,
origin
,
hook
,
backup
);
}
else
{
doHookWithReplacement
(
origin
,
hook
,
backup
);
}
}
else
{
doHookWithReplacement
(
origin
,
hook
,
backup
);
}
}
else
{
doHookWithInline
(
env
,
origin
,
hook
,
backup
);
}
return
JNI_TRUE
;
}
\ No newline at end of file
}
app/src/main/cpp/trampoline/arch/arm64.S
View file @
beabc0fb
...
...
@@ -33,9 +33,9 @@ FUNCTION_START(INLINE_HOOK_TRAMPOLINE)
ldr Reg1, addr_origin_art_method
cmp RegMethod, Reg1
bne go_to_origin_code
ldr Reg
0
, addr_hook_art_method
ldr Reg
Method
, addr_hook_art_method
ldr Reg1, offset_entry_code2
add Reg1, Reg
0
, Reg1
add Reg1, Reg
Method
, Reg1
ldr Reg1, [Reg1]
br Reg1
go_to_origin_code:
...
...
app/src/main/cpp/trampoline/trampoline.h
View file @
beabc0fb
...
...
@@ -10,6 +10,7 @@
#include "../includes/arch.h"
#include "./arch/base.h"
#include "stdlib.h"
#include <sys/mman.h>
#define Code unsigned char *
...
...
@@ -86,6 +87,7 @@ namespace SandHook {
void
setExecuteSpace
(
Code
start
)
{
code
=
start
;
memcpy
(
code
,
tempCode
,
codeLen
);
flushCache
(
reinterpret_cast
<
Size
>
(
code
),
codeLen
);
}
void
codeCopy
(
Code
src
,
Size
targetOffset
,
Size
len
)
{
memcpy
(
reinterpret_cast
<
void
*>
((
Size
)
code
+
targetOffset
),
src
,
len
);
...
...
@@ -94,10 +96,12 @@ namespace SandHook {
bool
flushCache
(
Size
addr
,
Size
len
)
{
#if defined(__arm__)
//clearCacheArm32(reinterpret_cast<char*>(addr), reinterpret_cast<char*>(addr + len));
int
i
=
cacheflush
(
addr
,
addr
+
len
,
0
);
if
(
i
==
-
1
)
{
return
false
;
}
return
true
;
#elif defined(__aarch64__)
char
*
begin
=
reinterpret_cast
<
char
*>
(
addr
);
__builtin___clear_cache
(
begin
,
begin
+
len
);
...
...
app/src/main/cpp/utils/fake_dlfcn.cpp
0 → 100644
View file @
beabc0fb
// Copyright (c) 2016 avs333
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <elf.h>
#include <android/log.h>
#include "fake_dlfcn.h"
#define TAG_NAME "test2:fake_dlfcn"
#define log_info(fmt,args...) __android_log_print(ANDROID_LOG_INFO, TAG_NAME, (const char *) fmt, ##args)
#define log_err(fmt,args...) __android_log_print(ANDROID_LOG_ERROR, TAG_NAME, (const char *) fmt, ##args)
//#ifdef LOG_DBG
#define log_dbg log_info
//#else
//#define log_dbg(...)
//#endif
#ifdef __arm__
#define Elf_Ehdr Elf32_Ehdr
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#elif defined(__aarch64__)
#define Elf_Ehdr Elf64_Ehdr
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#else
#error "Arch unknown, please port me"
#endif
struct
ctx
{
void
*
load_addr
;
void
*
dynstr
;
void
*
dynsym
;
int
nsyms
;
off_t
bias
;
};
extern
"C"
{
int
fake_dlclose
(
void
*
handle
)
{
if
(
handle
)
{
struct
ctx
*
ctx
=
(
struct
ctx
*
)
handle
;
if
(
ctx
->
dynsym
)
free
(
ctx
->
dynsym
);
/* we're saving dynsym and dynstr */
if
(
ctx
->
dynstr
)
free
(
ctx
->
dynstr
);
/* from library file just in case */
free
(
ctx
);
}
return
0
;
}
/* flags are ignored */
void
*
fake_dlopen
(
const
char
*
libpath
,
int
flags
)
{
FILE
*
maps
;
char
buff
[
256
];
struct
ctx
*
ctx
=
0
;
off_t
load_addr
,
size
;
int
k
,
fd
=
-
1
,
found
=
0
;
void
*
shoff
;
Elf_Ehdr
*
elf
=
(
Elf_Ehdr
*
)
MAP_FAILED
;
#define fatal(fmt, args...) do { log_err(fmt,##args); goto err_exit; } while(0)
maps
=
fopen
(
"/proc/self/maps"
,
"r"
);
if
(
!
maps
)
fatal
(
"failed to open maps"
);
while
(
!
found
&&
fgets
(
buff
,
sizeof
(
buff
),
maps
))
if
(
strstr
(
buff
,
"r-xp"
)
&&
strstr
(
buff
,
libpath
))
found
=
1
;
fclose
(
maps
);
if
(
!
found
)
fatal
(
"%s not found in my userspace"
,
libpath
);
if
(
sscanf
(
buff
,
"%lx"
,
&
load_addr
)
!=
1
)
fatal
(
"failed to read load address for %s"
,
libpath
);
log_info
(
"%s loaded in Android at 0x%08lx"
,
libpath
,
load_addr
);
/* Now, mmap the same library once again */
fd
=
open
(
libpath
,
O_RDONLY
);
if
(
fd
<
0
)
fatal
(
"failed to open %s"
,
libpath
);
size
=
lseek
(
fd
,
0
,
SEEK_END
);
if
(
size
<=
0
)
fatal
(
"lseek() failed for %s"
,
libpath
);
elf
=
(
Elf_Ehdr
*
)
mmap
(
0
,
size
,
PROT_READ
,
MAP_SHARED
,
fd
,
0
);
close
(
fd
);
fd
=
-
1
;
if
(
elf
==
MAP_FAILED
)
fatal
(
"mmap() failed for %s"
,
libpath
);
ctx
=
(
struct
ctx
*
)
calloc
(
1
,
sizeof
(
struct
ctx
));
if
(
!
ctx
)
fatal
(
"no memory for %s"
,
libpath
);
ctx
->
load_addr
=
(
void
*
)
load_addr
;
shoff
=
((
void
*
)
elf
)
+
elf
->
e_shoff
;
for
(
k
=
0
;
k
<
elf
->
e_shnum
;
k
++
,
shoff
+=
elf
->
e_shentsize
)
{
Elf_Shdr
*
sh
=
(
Elf_Shdr
*
)
shoff
;
log_dbg
(
"%s: k=%d shdr=%p type=%x"
,
__func__
,
k
,
sh
,
sh
->
sh_type
);
switch
(
sh
->
sh_type
)
{
case
SHT_DYNSYM
:
if
(
ctx
->
dynsym
)
fatal
(
"%s: duplicate DYNSYM sections"
,
libpath
);
/* .dynsym */
ctx
->
dynsym
=
malloc
(
sh
->
sh_size
);
if
(
!
ctx
->
dynsym
)
fatal
(
"%s: no memory for .dynsym"
,
libpath
);
memcpy
(
ctx
->
dynsym
,
((
void
*
)
elf
)
+
sh
->
sh_offset
,
sh
->
sh_size
);
ctx
->
nsyms
=
(
sh
->
sh_size
/
sizeof
(
Elf_Sym
));
break
;
case
SHT_STRTAB
:
if
(
ctx
->
dynstr
)
break
;
/* .dynstr is guaranteed to be the first STRTAB */
ctx
->
dynstr
=
malloc
(
sh
->
sh_size
);
if
(
!
ctx
->
dynstr
)
fatal
(
"%s: no memory for .dynstr"
,
libpath
);
memcpy
(
ctx
->
dynstr
,
((
void
*
)
elf
)
+
sh
->
sh_offset
,
sh
->
sh_size
);
break
;
case
SHT_PROGBITS
:
if
(
!
ctx
->
dynstr
||
!
ctx
->
dynsym
)
break
;
/* won't even bother checking against the section name */
ctx
->
bias
=
(
off_t
)
sh
->
sh_addr
-
(
off_t
)
sh
->
sh_offset
;
k
=
elf
->
e_shnum
;
/* exit for */
break
;
}
}
munmap
(
elf
,
size
);
elf
=
0
;
if
(
!
ctx
->
dynstr
||
!
ctx
->
dynsym
)
fatal
(
"dynamic sections not found in %s"
,
libpath
);
#undef fatal
log_dbg
(
"%s: ok, dynsym = %p, dynstr = %p"
,
libpath
,
ctx
->
dynsym
,
ctx
->
dynstr
);
return
ctx
;
err_exit
:
if
(
fd
>=
0
)
close
(
fd
);
if
(
elf
!=
MAP_FAILED
)
munmap
(
elf
,
size
);
fake_dlclose
(
ctx
);
return
0
;
}
void
*
fake_dlsym
(
void
*
handle
,
const
char
*
name
)
{
int
k
;
struct
ctx
*
ctx
=
(
struct
ctx
*
)
handle
;
Elf_Sym
*
sym
=
(
Elf_Sym
*
)
ctx
->
dynsym
;
char
*
strings
=
(
char
*
)
ctx
->
dynstr
;
for
(
k
=
0
;
k
<
ctx
->
nsyms
;
k
++
,
sym
++
)
if
(
strcmp
(
strings
+
sym
->
st_name
,
name
)
==
0
)
{
/* NB: sym->st_value is an offset into the section for relocatables,
but a VMA for shared libs or exe files, so we have to subtract the bias */
void
*
ret
=
ctx
->
load_addr
+
sym
->
st_value
-
ctx
->
bias
;
log_info
(
"%s found at %p"
,
name
,
ret
);
return
ret
;
}
return
0
;
}
}
app/src/main/cpp/utils/fake_dlfcn.h
0 → 100644
View file @
beabc0fb
// Copyright (c) 2016 avs333
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef UTILS_DLFCN_H
#define UTILS_DLFCN_H
#include <cstdlib>
#include <string.h>
#include <unistd.h>
extern
"C"
{
void
*
fake_dlopen
(
const
char
*
libpath
,
int
flags
);
void
*
fake_dlsym
(
void
*
handle
,
const
char
*
name
);
};
#endif //UTILS_DLFCN_H
app/src/main/cpp/utils/hide_api.h
0 → 100644
View file @
beabc0fb
//
// Created by swift on 2019/1/21.
//
#ifndef SANDHOOK_HIDE_API_H
#define SANDHOOK_HIDE_API_H
#include <jni.h>
#include "fake_dlfcn.h"
#include "dlfcn.h"
void
*
(
*
jitLoad
)(
bool
*
)
=
nullptr
;
void
*
jitCompilerHandle
=
nullptr
;
bool
(
*
jitCompileMethod
)(
void
*
,
void
*
,
void
*
,
bool
)
=
nullptr
;
void
initHideApi
(
JNIEnv
*
env
,
int
SDK_VERSION
)
{
if
(
SDK_VERSION
>=
24
)
{
void
*
handle
;
void
*
jit_lib
;
if
(
sizeof
(
void
*
)
==
8
)
{
handle
=
fake_dlopen
(
"/system/lib64/libart.so"
,
RTLD_NOW
);
jit_lib
=
fake_dlopen
(
"/system/lib64/libart-compiler.so"
,
RTLD_NOW
);
}
else
{
handle
=
fake_dlopen
(
"/system/lib/libart.so"
,
RTLD_NOW
);
jit_lib
=
fake_dlopen
(
"/system/lib/libart-compiler.so"
,
RTLD_NOW
);
}
jitCompileMethod
=
(
bool
(
*
)(
void
*
,
void
*
,
void
*
,
bool
))
fake_dlsym
(
jit_lib
,
"jit_compile_method"
);
jitLoad
=
reinterpret_cast
<
void
*
(
*
)(
bool
*
)
>
(
fake_dlsym
(
jit_lib
,
"jit_load"
));
bool
generate_debug_info
=
false
;
jitCompilerHandle
=
(
jitLoad
)(
&
generate_debug_info
);
}
}
bool
compileMethod
(
void
*
artMethod
,
void
*
thread
)
{
return
jitCompileMethod
(
jitCompilerHandle
,
artMethod
,
thread
,
false
);
}
#endif //SANDHOOK_HIDE_API_H
app/src/main/java/com/swift/sandhook/MainActivity.java
View file @
beabc0fb
...
...
@@ -71,7 +71,7 @@ public class MainActivity extends AppCompatActivity {
return
true
;
}
public
void
methodBeHooked
(
Bundle
bundle
)
{
public
static
void
methodBeHooked
(
Bundle
bundle
)
{
int
a
=
1
+
2
;
int
b
=
a
+
3
;
Log
.
e
(
"gy"
,
"not hooked"
+
b
+
bundle
);
...
...
app/src/main/java/com/swift/sandhook/SandHook.java
View file @
beabc0fb
...
...
@@ -15,6 +15,7 @@ public class SandHook {
public
static
Class
artMethodClass
;
public
static
Field
nativePeerField
;
public
static
Method
testOffsetMethod1
;
public
static
Method
testOffsetMethod2
;
public
static
Object
testOffsetArtMethod1
;
...
...
@@ -29,15 +30,25 @@ public class SandHook {
private
static
boolean
init
()
{
initTestOffset
();
initThreadPeer
();
SandHookMethodResolver
.
init
();
return
initNative
(
Build
.
VERSION
.
SDK_INT
);
}
private
static
void
initThreadPeer
()
{
try
{
nativePeerField
=
getField
(
Thread
.
class
,
"nativePeer"
);
}
catch
(
NoSuchFieldException
e
)
{
}
}
public
static
void
addHookClass
(
Class
...
hookWrapperClass
)
throws
HookErrorException
{
HookWrapper
.
addHookClass
(
hookWrapperClass
);
}
public
static
void
hook
(
@NonNull
Member
target
,
@NonNull
Method
hook
,
@Nullable
Method
backup
)
{
hook
.
setAccessible
(
true
);
hookMethod
(
target
,
hook
,
backup
);
}
...
...
@@ -110,6 +121,16 @@ public class SandHook {
throw
new
NoSuchFieldException
(
fieldName
);
}
public
static
long
getThreadId
()
{
if
(
nativePeerField
==
null
)
return
0
;
try
{
return
(
long
)
nativePeerField
.
get
(
Thread
.
currentThread
());
}
catch
(
IllegalAccessException
e
)
{
return
0
;
}
}
private
static
native
boolean
initNative
(
int
sdk
);
private
static
native
boolean
hookMethod
(
Member
originMethod
,
Method
hookMethod
,
Method
backupMethod
);
...
...
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