Commit 9455db22 authored by swift_gan's avatar swift_gan

[NativeHook]add simple nativehook & disable dex2oat

parent 2bc5ab99
...@@ -37,6 +37,7 @@ public class MyApp extends Application { ...@@ -37,6 +37,7 @@ public class MyApp extends Application {
SandHook.disableVMInline(); SandHook.disableVMInline();
SandHook.tryDisableProfile(getPackageName()); SandHook.tryDisableProfile(getPackageName());
SandHook.disableDex2oatInline(true);
if (SandHookConfig.SDK_INT >= Build.VERSION_CODES.P) { if (SandHookConfig.SDK_INT >= Build.VERSION_CODES.P) {
SandHook.passApiCheck(); SandHook.passApiCheck();
......
...@@ -33,6 +33,7 @@ add_library( # Sets the name of the library. ...@@ -33,6 +33,7 @@ add_library( # Sets the name of the library.
src/main/cpp/trampoline/arch/arm64.S src/main/cpp/trampoline/arch/arm64.S
src/main/cpp/inst/insts_arm32.cpp src/main/cpp/inst/insts_arm32.cpp
src/main/cpp/inst/insts_arm64.cpp src/main/cpp/inst/insts_arm64.cpp
src/main/cpp/nativehook/native_hook.cpp
) )
# Searches for a specified prebuilt library and stores the path as a # Searches for a specified prebuilt library and stores the path as a
......
//
// Created by SwiftGan on 2019/4/12.
//
#ifndef SANDHOOK_NATIVE_HOOK_H
#define SANDHOOK_NATIVE_HOOK_H
#include "sandhook.h"
namespace SandHook {
class NativeHook {
public:
static bool hookDex2oat(bool disableDex2oat);
};
}
#endif //SANDHOOK_NATIVE_HOOK_H
//
// Created by SwiftGan on 2019/4/12.
//
#ifndef SANDHOOK_SANDHOOK_H
#define SANDHOOK_SANDHOOK_H
#include <jni.h>
extern "C"
JNIEXPORT bool nativeHookNoBackup(void* origin, void* hook);
#endif //SANDHOOK_SANDHOOK_H
...@@ -30,6 +30,8 @@ namespace SandHook { ...@@ -30,6 +30,8 @@ namespace SandHook {
Trampoline* inlineJump = nullptr; Trampoline* inlineJump = nullptr;
Trampoline* inlineSecondory = nullptr; Trampoline* inlineSecondory = nullptr;
Trampoline* callOrigin = nullptr; Trampoline* callOrigin = nullptr;
Trampoline* hookNative = nullptr;
Code originCode = nullptr; Code originCode = nullptr;
}; };
...@@ -43,9 +45,13 @@ namespace SandHook { ...@@ -43,9 +45,13 @@ namespace SandHook {
Code allocExecuteSpace(Size size); Code allocExecuteSpace(Size size);
//java hook
HookTrampoline* installReplacementTrampoline(mirror::ArtMethod* originMethod, mirror::ArtMethod* hookMethod, mirror::ArtMethod* backupMethod); HookTrampoline* installReplacementTrampoline(mirror::ArtMethod* originMethod, mirror::ArtMethod* hookMethod, mirror::ArtMethod* backupMethod);
HookTrampoline* installInlineTrampoline(mirror::ArtMethod* originMethod, mirror::ArtMethod* hookMethod, mirror::ArtMethod* backupMethod); HookTrampoline* installInlineTrampoline(mirror::ArtMethod* originMethod, mirror::ArtMethod* hookMethod, mirror::ArtMethod* backupMethod);
//native hook
HookTrampoline* installNativeHookTrampolineNoBackup(void* origin, void* hook);
bool canSafeInline(mirror::ArtMethod* method); bool canSafeInline(mirror::ArtMethod* method);
uint32_t sizeOfEntryCode(mirror::ArtMethod* method); uint32_t sizeOfEntryCode(mirror::ArtMethod* method);
......
//
// Created by SwiftGan on 2019/4/12.
//
#include <syscall.h>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include "../includes/native_hook.h"
#include "../includes/arch.h"
#include "../includes/log.h"
extern int SDK_INT;
int inline getArrayItemCount(char *const array[]) {
int i;
for (i = 0; array[i]; ++i);
return i;
}
char **build_new_env(char *const envp[]) {
char *provided_ld_preload = NULL;
int provided_ld_preload_index = -1;
int orig_envp_count = getArrayItemCount(envp);
for (int i = 0; i < orig_envp_count; i++) {
if (strstr(envp[i], "compiler-filter")) {
provided_ld_preload = envp[i];
provided_ld_preload_index = i;
}
}
char ld_preload[40];
if (provided_ld_preload) {
sprintf(ld_preload, "--compiler-filter=%s", "speed");
}
int new_envp_count = orig_envp_count;
if (SDK_INT >= ANDROID_M) {
new_envp_count = orig_envp_count + 1;
}
char **new_envp = (char **) malloc(new_envp_count * sizeof(char *));
int cur = 0;
for (int i = 0; i < orig_envp_count; ++i) {
if (i != provided_ld_preload_index) {
new_envp[cur++] = envp[i];
} else {
new_envp[i] = ld_preload;
}
}
if (new_envp_count != orig_envp_count) {
new_envp[new_envp_count - 1] = (char *) (SDK_INT > ANDROID_N2 ? "--inline-max-code-units=0" : "--inline-depth-limit=0");
}
return new_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")) {
char **new_envp = build_new_env(envp);
LOGE("dex2oat by disable inline!");
int ret = static_cast<int>(syscall(__NR_execve, pathname, argv, new_envp));
free(new_envp);
return ret;
}
int ret = static_cast<int>(syscall(__NR_execve, pathname, argv, envp));
return ret;
}
extern "C" int fake_execve_disable_oat(const char *pathname, char *argv[], char *const envp[]) {
LOGE("skip dex2oat!");
if (strstr(pathname, "dex2oat")) {
LOGE("skip dex2oat!");
return -1;
}
return static_cast<int>(syscall(__NR_execve, pathname, argv, envp));
}
namespace SandHook {
volatile bool hasHookedDex2oat = false;
bool NativeHook::hookDex2oat(bool disableDex2oat) {
if (hasHookedDex2oat)
return false;
hasHookedDex2oat = true;
return nativeHookNoBackup(reinterpret_cast<void *>(execve),
reinterpret_cast<void *>(disableDex2oat ? fake_execve_disable_oat : fake_execve_disable_inline));
}
}
#include <jni.h> #include "includes/sandhook.h"
#include "includes/cast_art_method.h" #include "includes/cast_art_method.h"
#include "includes/trampoline_manager.h" #include "includes/trampoline_manager.h"
#include "includes/hide_api.h" #include "includes/hide_api.h"
#include "includes/cast_compiler_options.h" #include "includes/cast_compiler_options.h"
#include "includes/log.h" #include "includes/log.h"
#include "includes/native_hook.h"
#include <jni.h>
SandHook::TrampolineManager trampolineManager; SandHook::TrampolineManager trampolineManager;
...@@ -320,6 +323,12 @@ Java_com_swift_sandhook_SandHook_disableVMInline(JNIEnv *env, jclass type) { ...@@ -320,6 +323,12 @@ Java_com_swift_sandhook_SandHook_disableVMInline(JNIEnv *env, jclass type) {
return static_cast<jboolean>(disableJitInline(compilerOptions)); return static_cast<jboolean>(disableJitInline(compilerOptions));
} }
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_swift_sandhook_SandHook_disableDex2oatInline(JNIEnv *env, jclass type, jboolean disableDex2oat) {
return static_cast<jboolean>(SandHook::NativeHook::hookDex2oat(disableDex2oat));
}
extern "C" extern "C"
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_swift_sandhook_ClassNeverCall_neverCallNative(JNIEnv *env, jobject instance) { Java_com_swift_sandhook_ClassNeverCall_neverCallNative(JNIEnv *env, jobject instance) {
...@@ -342,6 +351,20 @@ Java_com_swift_sandhook_test_TestClass_jni_1test(JNIEnv *env, jobject instance) ...@@ -342,6 +351,20 @@ Java_com_swift_sandhook_test_TestClass_jni_1test(JNIEnv *env, jobject instance)
int b = a + 1; int b = a + 1;
} }
//native hook
extern "C"
JNIEXPORT bool nativeHookNoBackup(void* origin, void* hook) {
if (origin == nullptr || hook == nullptr)
return false;
SandHook::StopTheWorld stopTheWorld;
return trampolineManager.installNativeHookTrampolineNoBackup(origin, hook) != nullptr;
}
static JNINativeMethod jniSandHook[] = { static JNINativeMethod jniSandHook[] = {
{ {
"initNative", "initNative",
...@@ -407,6 +430,11 @@ static JNINativeMethod jniSandHook[] = { ...@@ -407,6 +430,11 @@ static JNINativeMethod jniSandHook[] = {
"disableVMInline", "disableVMInline",
"()Z", "()Z",
(void *) Java_com_swift_sandhook_SandHook_disableVMInline (void *) Java_com_swift_sandhook_SandHook_disableVMInline
},
{
"disableDex2oatInline",
"(Z)Z",
(void *) Java_com_swift_sandhook_SandHook_disableDex2oatInline
} }
}; };
......
...@@ -282,4 +282,33 @@ namespace SandHook { ...@@ -282,4 +282,33 @@ namespace SandHook {
return nullptr; return nullptr;
} }
HookTrampoline* TrampolineManager::installNativeHookTrampolineNoBackup(void *origin,
void *hook) {
HookTrampoline* hookTrampoline = new HookTrampoline();
DirectJumpTrampoline* directJumpTrampoline = new DirectJumpTrampoline();
if (!memUnprotect(reinterpret_cast<Size>(origin), directJumpTrampoline->getCodeLen())) {
LOGE("hook error due to can not write origin code!");
goto label_error;
}
directJumpTrampoline->init();
checkThumbCode(directJumpTrampoline, reinterpret_cast<Code>(origin));
if (directJumpTrampoline->isThumbCode()) {
origin = directJumpTrampoline->getThumbCodeAddress(reinterpret_cast<Code>(origin));
}
directJumpTrampoline->setExecuteSpace(reinterpret_cast<Code>(origin));
directJumpTrampoline->setJumpTarget(reinterpret_cast<Code>(hook));
hookTrampoline->inlineJump = directJumpTrampoline;
directJumpTrampoline->flushCache(reinterpret_cast<Size>(origin), directJumpTrampoline->getCodeLen());
hookTrampoline->hookNative = directJumpTrampoline;
return hookTrampoline;
label_error:
delete hookTrampoline;
delete directJumpTrampoline;
return nullptr;
}
} }
...@@ -363,6 +363,8 @@ public class SandHook { ...@@ -363,6 +363,8 @@ public class SandHook {
public static native boolean disableVMInline(); public static native boolean disableVMInline();
public static native boolean disableDex2oatInline(boolean disableDex2oat);
@FunctionalInterface @FunctionalInterface
public interface HookModeCallBack { public interface HookModeCallBack {
int hookMode(Member originMethod); int hookMode(Member originMethod);
......
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