Commit c0b453cd authored by swift_gan's avatar swift_gan

Merge remote-tracking branch 'origin/master'

parents 1ca453e2 783d5bfa
...@@ -166,19 +166,31 @@ you must call backup method in hook method, if you want call it in other method, ...@@ -166,19 +166,31 @@ you must call backup method in hook method, if you want call it in other method,
because when ART trigger JIT from profiling, JIT will invoke -> ResolveCompilingMethodsClass -> ClassLinker::ResolveMethod -> CheckIncompatibleClassChange -> ThrowIncompatibleClassChangeError finally!!! because when ART trigger JIT from profiling, JIT will invoke -> ResolveCompilingMethodsClass -> ClassLinker::ResolveMethod -> CheckIncompatibleClassChange -> ThrowIncompatibleClassChangeError finally!!!
## Inline ## Disable Inline
### disable JIT inline ### JIT inline
We can do nothing to prevent some methods been inlined before app start, but we can try to disable VM Jit Inline after launch. We can do nothing to prevent some methods been inlined before app start, but we can try to disable VM Jit Inline after launch.
if you will hook some method that could be inlined, please call SandHook.disableVMInline()(OS >= 7.0) in Application.OnCreate() if you will hook some method that could be inlined, please call SandHook.disableVMInline()(OS >= 7.0) in Application.OnCreate()
### Inline by dex2oat
### Deoptimize #### Background dex2oat
You can also deoptimize a caller that inlined your hook method by SandHook.deCompile(caller), just implement >= 7.0 SandHook.tryDisableProfile(getPackageName());
#### dex2oat by DexClassLoader
SandHook.disableDex2oatInline(fullyDisableDex2oat);
or
ArtDexOptimizer.dexoatAndDisableInline to dex2oat manuly
### Deoptimize(Boot Image)
You can also deoptimize a caller that inlined your hook method by SandHook.deCompile(caller), just implement >= 7.0
## Hidden API ## Hidden API
...@@ -186,6 +198,12 @@ SandHook.passApiCheck(); ...@@ -186,6 +198,12 @@ SandHook.passApiCheck();
To bypass hidden api on P & Q To bypass hidden api on P & Q
# Native Hook
#include "includes/sandhook.h"
// can not call origin method now
bool nativeHookNoBackup(void* origin, void* hook);
# Demo # Demo
......
...@@ -20,6 +20,19 @@ int inline getArrayItemCount(char *const array[]) { ...@@ -20,6 +20,19 @@ int inline getArrayItemCount(char *const array[]) {
return i; return i;
} }
bool isSandHooker(char *const args[]) {
int orig_arg_count = getArrayItemCount(args);
for (int i = 0; i < orig_arg_count; i++) {
if (SDK_INT >= ANDROID_N && strstr(args[i], "SandHooker")) {
LOGE("skip dex2oat hooker!");
return true;
}
}
return false;
}
char **build_new_env(char *const envp[]) { char **build_new_env(char *const envp[]) {
char *provided_ld_preload = NULL; char *provided_ld_preload = NULL;
int provided_ld_preload_index = -1; int provided_ld_preload_index = -1;
...@@ -58,8 +71,11 @@ char **build_new_env(char *const envp[]) { ...@@ -58,8 +71,11 @@ char **build_new_env(char *const envp[]) {
} }
extern "C" int fake_execve_disable_inline(const char *pathname, char *argv[], char *const envp[]) { extern "C" int fake_execve_disable_inline(const char *pathname, char *argv[], char *const envp[]) {
LOGE("dex2oat by disable inline!");
if (strstr(pathname, "dex2oat")) { if (strstr(pathname, "dex2oat")) {
if (SDK_INT >= ANDROID_N && isSandHooker(argv)) {
LOGE("skip dex2oat!");
return -1;
}
char **new_envp = build_new_env(envp); char **new_envp = build_new_env(envp);
LOGE("dex2oat by disable inline!"); LOGE("dex2oat by disable inline!");
int ret = static_cast<int>(syscall(__NR_execve, pathname, argv, new_envp)); int ret = static_cast<int>(syscall(__NR_execve, pathname, argv, new_envp));
...@@ -71,7 +87,6 @@ extern "C" int fake_execve_disable_inline(const char *pathname, char *argv[], ch ...@@ -71,7 +87,6 @@ extern "C" int fake_execve_disable_inline(const char *pathname, char *argv[], ch
} }
extern "C" int fake_execve_disable_oat(const char *pathname, char *argv[], char *const envp[]) { extern "C" int fake_execve_disable_oat(const char *pathname, char *argv[], char *const envp[]) {
LOGE("skip dex2oat!");
if (strstr(pathname, "dex2oat")) { if (strstr(pathname, "dex2oat")) {
LOGE("skip dex2oat!"); LOGE("skip dex2oat!");
return -1; return -1;
......
...@@ -283,8 +283,7 @@ namespace SandHook { ...@@ -283,8 +283,7 @@ namespace SandHook {
} }
HookTrampoline* TrampolineManager::installNativeHookTrampolineNoBackup(void *origin, HookTrampoline* TrampolineManager::installNativeHookTrampolineNoBackup(void *origin,
void *hook) { void *hook) { HookTrampoline* hookTrampoline = new HookTrampoline();
HookTrampoline* hookTrampoline = new HookTrampoline();
DirectJumpTrampoline* directJumpTrampoline = new DirectJumpTrampoline(); DirectJumpTrampoline* directJumpTrampoline = new DirectJumpTrampoline();
if (!memUnprotect(reinterpret_cast<Size>(origin), directJumpTrampoline->getCodeLen())) { if (!memUnprotect(reinterpret_cast<Size>(origin), directJumpTrampoline->getCodeLen())) {
...@@ -293,10 +292,16 @@ namespace SandHook { ...@@ -293,10 +292,16 @@ namespace SandHook {
} }
directJumpTrampoline->init(); directJumpTrampoline->init();
#if defined(__arm__)
checkThumbCode(directJumpTrampoline, reinterpret_cast<Code>(origin)); checkThumbCode(directJumpTrampoline, reinterpret_cast<Code>(origin));
if (directJumpTrampoline->isThumbCode()) { if (directJumpTrampoline->isThumbCode()) {
origin = directJumpTrampoline->getThumbCodeAddress(reinterpret_cast<Code>(origin)); origin = directJumpTrampoline->getThumbCodeAddress(reinterpret_cast<Code>(origin));
} }
if (isThumbCode(reinterpret_cast<Size>(hook))) {
hook = directJumpTrampoline->getThumbCodePcAddress(reinterpret_cast<Code>(hook));
}
#endif
directJumpTrampoline->setExecuteSpace(reinterpret_cast<Code>(origin)); directJumpTrampoline->setExecuteSpace(reinterpret_cast<Code>(origin));
directJumpTrampoline->setJumpTarget(reinterpret_cast<Code>(hook)); directJumpTrampoline->setJumpTarget(reinterpret_cast<Code>(hook));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment