Commit e4b6d861 authored by swift_gan's avatar swift_gan Committed by swift_gan

[SingleInstHook]impl arm64

parent f9a5dd10
......@@ -37,6 +37,8 @@ public class MyApp extends Application {
SandHookConfig.SDK_INT = 29;
}
NativeHook.test();
SandHook.disableVMInline();
SandHook.tryDisableProfile(getPackageName());
SandHook.disableDex2oatInline(false);
......
......@@ -131,3 +131,50 @@ bool InlineHookArm64Android::BreakPoint(void *point, void (*callback)(REG regs[]
return true;
}
void *InlineHookArm64Android::SingleInstHook(void *origin, void *replace) {
if (!InitForSingleInstHook()) {
return nullptr;
}
AutoLock lock(hook_lock);
void* backup = nullptr;
AssemblerA64 assembler_backup(backup_buffer);
StaticCodeBuffer inline_buffer = StaticCodeBuffer(reinterpret_cast<Addr>(origin));
AssemblerA64 assembler_inline(&inline_buffer);
CodeContainer* code_container_inline = &assembler_inline.code_container;
//build inline trampoline
#define __ assembler_inline.
__ Hvc(static_cast<U16>(hook_infos.size()));
#undef __
//build backup method
CodeRelocateA64 relocate = CodeRelocateA64(assembler_backup);
backup = relocate.Relocate(origin, code_container_inline->Size(), nullptr);
#define __ assembler_backup.
Label* origin_addr_label = new Label();
__ Ldr(IP1, origin_addr_label);
__ Br(IP1);
__ Emit(origin_addr_label);
__ Emit((Addr) origin + code_container_inline->Size());
__ Finish();
#undef __
hook_infos.push_back({origin, replace, backup});
//commit inline trampoline
assembler_inline.Finish();
return backup;
}
void InlineHookArm64Android::ExceptionHandler(int num, sigcontext *context) {
void *code = reinterpret_cast<void*>(context->pc);
INST_A64(EXCEPTION_GEN) hvc(code);
hvc.Disassemble();
if (hvc.imme >= hook_infos.size())
return;
HookInfo &hook_info = hook_infos[hvc.imme];
context->pc = reinterpret_cast<U64>(hook_info.replace);
}
......@@ -5,6 +5,7 @@
#pragma once
#include "hook.h"
#include <vector>
namespace SandHook {
namespace Hook {
......@@ -12,6 +13,13 @@ namespace SandHook {
public:
void *Hook(void *origin, void *replace) override;
bool BreakPoint(void *point, void (*callback)(REG[])) override;
void *SingleInstHook(void *origin, void *replace) override;
void ExceptionHandler(int num, sigcontext *context) override;
private:
std::vector<HookInfo> hook_infos;
};
}
}
//
// Created by swift on 2019/5/14.
//
#include "hook.h"
#include "lock.h"
#if defined(__arm__)
#include "hook_arm32.h"
......@@ -11,6 +11,7 @@
#endif
using namespace SandHook::Hook;
using namespace SandHook::Utils;
CodeBuffer* InlineHook::backup_buffer = new AndroidCodeBuffer();
......@@ -18,4 +19,26 @@ CodeBuffer* InlineHook::backup_buffer = new AndroidCodeBuffer();
InlineHook* InlineHook::instance = new InlineHookArm32Android();
#elif defined(__aarch64__)
InlineHook* InlineHook::instance = new InlineHookArm64Android();
#endif
\ No newline at end of file
#endif
void InterruptHandler(int signum, siginfo_t* siginfo, void* uc) {
if (signum != SIGILL)
return;
sigcontext &context = reinterpret_cast<ucontext_t *>(uc)->uc_mcontext;
InlineHook::instance->ExceptionHandler(signum, &context);
}
bool InlineHook::InitForSingleInstHook() {
AutoLock lock(hook_lock);
if (inited)
return true;
struct sigaction sig{};
sigemptyset(&sig.sa_mask);
// Notice: remove this flag if needed.
sig.sa_flags = SA_SIGINFO;
sig.sa_sigaction = InterruptHandler;
if (sigaction(SIGILL, &sig, nullptr) != -1) {
inited = true;
}
return inited;
}
\ No newline at end of file
......@@ -5,6 +5,7 @@
#pragma once
#include <mutex>
#include <atomic>
#include "code_buffer.h"
#include "decoder.h"
......@@ -16,6 +17,12 @@ typedef Addr REG;
namespace SandHook {
namespace Hook {
struct HookInfo {
void *origin;
void *replace;
void *backup;
};
class InlineHook {
public:
//return == backup method
......@@ -23,7 +30,15 @@ namespace SandHook {
virtual bool BreakPoint(void *point, void (*callback)(REG[])) {
return false;
};
virtual void *SingleInstHook(void *origin, void *replace) {
return nullptr;
};
virtual void ExceptionHandler(int num, sigcontext *context) {};
protected:
virtual bool InitForSingleInstHook();
bool inited = false;
static CodeBuffer* backup_buffer;
std::mutex hook_lock;
public:
......
......@@ -3,6 +3,8 @@
//
#include <jni.h>
#include <sys/mman.h>
#include <log.h>
#include "sandhook_native.h"
#include "hook.h"
#include "elf.h"
......@@ -10,6 +12,134 @@
using namespace SandHook::Hook;
using namespace SandHook::Elf;
int m1 = 5;
int m3 = 1036;
int m2 = 1035;
int m4 = 5;
void (*dosth3Backup)(int, int) = nullptr;
void (*dosth4Backup)() = nullptr;
void (*dosth4Backup2)() = nullptr;
void (*innerSuspendVM)() = nullptr;
static void (*heapPreForkBackup)(void *) = nullptr;
static void myHeapPreFork(void *heap) {
heapPreForkBackup(heap);
}
void SuspendVMReplace() {
LOGE("VM Suspend!");
innerSuspendVM();
}
void do2() {
int a = 1 + 1;
int b = 1 + 1;
int c = 1 + 1;
int d = 1 + 1;
}
void do3(int x, int y) {
do2();
int a = 1 + 1;
int b = 1 + 1;
int c = 1 + 1;
int d = a + b + c;
LOGE("do3 = %d", y);
}
void do5() {
LOGE("x = %d", 5);
}
void do4() {
int a = 1 + 1;
int b = a + 1;
int d = a + 1;
int e = a + 1;
LOGE("x = %d", 7);
}
void do4replace() {
int a = 1 + 1;
int b = 1 + 1;
int c = 1 + 1;
int d = 1 + 1;
dosth4Backup();
}
void do4replace2() {
int a = 1 + 1;
int c = 1 + 1;
int d = 1 + 1;
dosth4Backup2();
}
void do3replace(int x, int y) {
int a = 1 + 1;
int b = 1 + 1;
int c = 1 + 1;
int d = 1 + 1;
dosth3Backup(x, y);
}
void do1() {
do2();
}
void breakCallback(REG regs[]) {
LOGE("breakCallback = %d SP = %d", regs[0], regs);
}
class Visitor : public InstVisitor {
bool Visit(Unit<Base> *unit, void *pc) override {
BaseInst* instruction = reinterpret_cast<BaseInst *>(unit);
instruction->Assemble();
return true;
}
};
extern "C"
JNIEXPORT void JNICALL
Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1) {
dosth4Backup = reinterpret_cast<void (*)()>(InlineHook::instance->SingleInstHook(
reinterpret_cast<void *>(do4),
reinterpret_cast<void *>(do4replace)));
do4();
if (sizeof(void*) == 8) {
heapPreForkBackup = reinterpret_cast<void (*)(void *)>(SandInlineHookSym("/system/lib64/libart.so", "_ZN3art2gc4Heap13PreZygoteForkEv",
reinterpret_cast<void *>(myHeapPreFork)));
innerSuspendVM = reinterpret_cast<void (*)()>(SandInlineHookSym("/system/lib64/libart.so", "_ZN3art3Dbg9SuspendVMEv",
reinterpret_cast<void *>(SuspendVMReplace)));
} else {
heapPreForkBackup = reinterpret_cast<void (*)(void *)>(SandInlineHookSym("/system/lib/libart.so", "_ZN3art2gc4Heap13PreZygoteForkEv",
reinterpret_cast<void *>(myHeapPreFork)));
innerSuspendVM = reinterpret_cast<void (*)()>(SandInlineHookSym("/system/lib/libart.so", "_ZN3art3Dbg9SuspendVMEv",
reinterpret_cast<void *>(SuspendVMReplace)));
}
void* do3P = reinterpret_cast<void *>(do3);
InlineHook::instance->BreakPoint(reinterpret_cast<void *>((Addr)do3), breakCallback);
LOGE("ok");
do3(100, 2);
}
extern "C"
EXPORT void* SandGetSym(const char* so, const char* symb) {
......
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