From e4b6d8612d8429e7ec91ab5828b91eb9270bdea5 Mon Sep 17 00:00:00 2001 From: swift_gan <939543405@qq.com> Date: Tue, 16 Jul 2019 08:58:35 +0800 Subject: [PATCH 1/3] [SingleInstHook]impl arm64 --- .../main/java/com/swift/sandhook/MyApp.java | 2 + .../cpp/archs/arm/arm64/hook/hook_arm64.cpp | 47 +++++++ .../cpp/archs/arm/arm64/hook/hook_arm64.h | 8 ++ nativehook/src/main/cpp/hook/hook.cpp | 27 +++- nativehook/src/main/cpp/includes/hook.h | 15 ++ nativehook/src/main/cpp/sandhook_native.cpp | 130 ++++++++++++++++++ 6 files changed, 227 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/swift/sandhook/MyApp.java b/app/src/main/java/com/swift/sandhook/MyApp.java index 68c8ed39..7e261b2c 100644 --- a/app/src/main/java/com/swift/sandhook/MyApp.java +++ b/app/src/main/java/com/swift/sandhook/MyApp.java @@ -37,6 +37,8 @@ public void onCreate() { SandHookConfig.SDK_INT = 29; } + NativeHook.test(); + SandHook.disableVMInline(); SandHook.tryDisableProfile(getPackageName()); SandHook.disableDex2oatInline(false); diff --git a/nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp b/nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp index c65d8964..b3cafd31 100644 --- a/nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp +++ b/nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp @@ -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(origin)); + AssemblerA64 assembler_inline(&inline_buffer); + CodeContainer* code_container_inline = &assembler_inline.code_container; + + //build inline trampoline +#define __ assembler_inline. + __ Hvc(static_cast(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(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(hook_info.replace); +} diff --git a/nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.h b/nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.h index a5c252be..767679ff 100644 --- a/nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.h +++ b/nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.h @@ -5,6 +5,7 @@ #pragma once #include "hook.h" +#include 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 hook_infos; }; } } diff --git a/nativehook/src/main/cpp/hook/hook.cpp b/nativehook/src/main/cpp/hook/hook.cpp index 9b947cdc..9fcec9e5 100644 --- a/nativehook/src/main/cpp/hook/hook.cpp +++ b/nativehook/src/main/cpp/hook/hook.cpp @@ -1,8 +1,8 @@ // // 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(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 diff --git a/nativehook/src/main/cpp/includes/hook.h b/nativehook/src/main/cpp/includes/hook.h index 716e4014..0e5c579b 100644 --- a/nativehook/src/main/cpp/includes/hook.h +++ b/nativehook/src/main/cpp/includes/hook.h @@ -5,6 +5,7 @@ #pragma once #include +#include #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: diff --git a/nativehook/src/main/cpp/sandhook_native.cpp b/nativehook/src/main/cpp/sandhook_native.cpp index 481f6ae5..8381b223 100644 --- a/nativehook/src/main/cpp/sandhook_native.cpp +++ b/nativehook/src/main/cpp/sandhook_native.cpp @@ -3,6 +3,8 @@ // #include +#include +#include #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 *unit, void *pc) override { + BaseInst* instruction = reinterpret_cast(unit); + instruction->Assemble(); + return true; + } +}; + +extern "C" +JNIEXPORT void JNICALL +Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1) { + + + dosth4Backup = reinterpret_cast(InlineHook::instance->SingleInstHook( + reinterpret_cast(do4), + reinterpret_cast(do4replace))); + + + do4(); + + if (sizeof(void*) == 8) { + heapPreForkBackup = reinterpret_cast(SandInlineHookSym("/system/lib64/libart.so", "_ZN3art2gc4Heap13PreZygoteForkEv", + reinterpret_cast(myHeapPreFork))); + innerSuspendVM = reinterpret_cast(SandInlineHookSym("/system/lib64/libart.so", "_ZN3art3Dbg9SuspendVMEv", + reinterpret_cast(SuspendVMReplace))); + } else { + heapPreForkBackup = reinterpret_cast(SandInlineHookSym("/system/lib/libart.so", "_ZN3art2gc4Heap13PreZygoteForkEv", + reinterpret_cast(myHeapPreFork))); + innerSuspendVM = reinterpret_cast(SandInlineHookSym("/system/lib/libart.so", "_ZN3art3Dbg9SuspendVMEv", + reinterpret_cast(SuspendVMReplace))); + } + + void* do3P = reinterpret_cast(do3); + + InlineHook::instance->BreakPoint(reinterpret_cast((Addr)do3), breakCallback); + + LOGE("ok"); + + do3(100, 2); + + +} + extern "C" EXPORT void* SandGetSym(const char* so, const char* symb) { From 7a2b7b8f612eb6c7ddb1cdd0743fc7ffd0e7e928 Mon Sep 17 00:00:00 2001 From: swift_gan <939543405@qq.com> Date: Tue, 16 Jul 2019 17:17:11 +0800 Subject: [PATCH 2/3] [SingleInstHook]impl arm32 --- .../arm/arm32/assembler/assembler_arm32.cpp | 4 ++ .../arm/arm32/assembler/assembler_arm32.h | 2 + .../cpp/archs/arm/arm32/hook/hook_arm32.cpp | 63 ++++++++++++++++++- .../cpp/archs/arm/arm32/hook/hook_arm32.h | 15 +++-- .../archs/arm/arm32/inst/inst_code_arm32.h | 1 + .../archs/arm/arm32/inst/inst_struct_t32.h | 9 +++ .../cpp/archs/arm/arm32/inst/inst_t32.cpp | 16 +++++ .../main/cpp/archs/arm/arm32/inst/inst_t32.h | 17 +++++ .../cpp/archs/arm/arm64/hook/hook_arm64.cpp | 6 +- 9 files changed, 122 insertions(+), 11 deletions(-) diff --git a/nativehook/src/main/cpp/archs/arm/arm32/assembler/assembler_arm32.cpp b/nativehook/src/main/cpp/archs/arm/arm32/assembler/assembler_arm32.cpp index a51298fe..2af203bd 100644 --- a/nativehook/src/main/cpp/archs/arm/arm32/assembler/assembler_arm32.cpp +++ b/nativehook/src/main/cpp/archs/arm/arm32/assembler/assembler_arm32.cpp @@ -177,4 +177,8 @@ void AssemblerA32::Nop16() { Mov(IP, IP); } +void AssemblerA32::Hvc(U16 num) { + Emit(reinterpret_cast(new INST_T32(HVC)(num))); +} + diff --git a/nativehook/src/main/cpp/archs/arm/arm32/assembler/assembler_arm32.h b/nativehook/src/main/cpp/archs/arm/arm32/assembler/assembler_arm32.h index d6337d3b..a46ccab5 100644 --- a/nativehook/src/main/cpp/archs/arm/arm32/assembler/assembler_arm32.h +++ b/nativehook/src/main/cpp/archs/arm/arm32/assembler/assembler_arm32.h @@ -77,6 +77,8 @@ namespace SandHook { void Nop16(); + void Hvc(U16 num); + public: CodeContainer code_container = CodeContainer(nullptr); }; diff --git a/nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.cpp b/nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.cpp index e0ecedbe..c4c4eb66 100644 --- a/nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.cpp +++ b/nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.cpp @@ -3,6 +3,7 @@ // #include +#include #include "code_relocate_arm32.h" #include "hook_arm32.h" #include "code_buffer.h" @@ -18,7 +19,7 @@ using namespace SandHook::Utils; #include "assembler_arm32.h" using namespace SandHook::RegistersA32; void *InlineHookArm32Android::Hook(void *origin, void *replace) { - AutoLock lock(hookLock); + AutoLock lock(hook_lock); void* origin_code; if (IsThumbCode((Addr) origin)) { @@ -74,7 +75,7 @@ IMPORT_SHELLCODE(BP_SHELLCODE) IMPORT_LABEL(callback_addr_s, Addr) IMPORT_LABEL(origin_addr_s, Addr) bool InlineHookArm32Android::BreakPoint(void *origin, void (*callback)(REG *)) { - AutoLock lock(hookLock); + AutoLock lock(hook_lock); void* origin_code; if (IsThumbCode((Addr) origin)) { @@ -126,3 +127,61 @@ bool InlineHookArm32Android::BreakPoint(void *origin, void (*callback)(REG *)) { return true; } + +void *InlineHookArm32Android::SingleInstHook(void *origin, void *replace) { + if (!InitForSingleInstHook()) { + return nullptr; + } + AutoLock lock(hook_lock); + + void* origin_code; + if (IsThumbCode((Addr) origin)) { + origin_code = GetThumbCodeAddress(origin); + } else { + LOGE("hook %d error!, only support thumb2 now!", origin); + return nullptr; + } + + void* backup = nullptr; + AssemblerA32 assembler_backup(backup_buffer); + + StaticCodeBuffer inline_buffer = StaticCodeBuffer(reinterpret_cast(origin_code)); + AssemblerA32 assembler_inline(&inline_buffer); + CodeContainer* code_container_inline = &assembler_inline.code_container; + + //build inline trampoline +#define __ assembler_inline. + __ Hvc(static_cast(hook_infos.size())); +#undef __ + + //build backup method + CodeRelocateA32 relocate = CodeRelocateA32(assembler_backup); + backup = relocate.Relocate(origin, code_container_inline->Size(), nullptr); +#define __ assembler_backup. + Label* origin_addr_label = new Label(); + ALIGN_FOR_LDR + __ Ldr(PC, origin_addr_label); + __ Emit(origin_addr_label); + __ Emit((Addr) GetThumbPC(reinterpret_cast(reinterpret_cast(origin_code) + relocate.cur_offset))); + __ Finish(); +#undef __ + + hook_infos.push_back({origin, replace, GetThumbPC(backup)}); + + //commit inline trampoline + assembler_inline.Finish(); + return GetThumbPC(backup); +} + +void InlineHookArm32Android::ExceptionHandler(int num, sigcontext *context) { + InstT32 *code = reinterpret_cast(context->arm_pc); + if (!IS_OPCODE_T32(*code, HVC)) { + abort(); + } + INST_T32(HVC) hvc(code); + hvc.Disassemble(); + if (hvc.imme >= hook_infos.size()) + return; + HookInfo &hook_info = hook_infos[hvc.imme]; + context->arm_pc = reinterpret_cast(hook_info.replace); +} diff --git a/nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.h b/nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.h index cc20ba26..0c4136b7 100644 --- a/nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.h +++ b/nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.h @@ -5,24 +5,23 @@ #pragma once #include "hook.h" +#include namespace SandHook { namespace Hook { class InlineHookArm32Android : public InlineHook { public: - inline InlineHookArm32Android() { - hookLock = new std::mutex(); - }; - inline ~InlineHookArm32Android() { - delete hookLock; - } void *Hook(void *origin, void *replace) override; bool BreakPoint(void *point, void (*callback)(REG *)) override; - protected: - std::mutex* hookLock; + void *SingleInstHook(void *origin, void *replace) override; + + void ExceptionHandler(int num, sigcontext *context) override; + + private: + std::vector hook_infos; }; } diff --git a/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_code_arm32.h b/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_code_arm32.h index bfccd633..222d70ac 100644 --- a/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_code_arm32.h +++ b/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_code_arm32.h @@ -40,4 +40,5 @@ enum class InstCodeT32 : InstCode { LDR_UIMM, MOV_MOVT_IMM, SUB_IMM, + HVC }; \ No newline at end of file diff --git a/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_struct_t32.h b/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_struct_t32.h index e4c86c7e..df51d3ae 100644 --- a/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_struct_t32.h +++ b/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_struct_t32.h @@ -95,3 +95,12 @@ DEFINE_STRUCT_T32(SUB_IMM) { InstT32 imm3:3; InstT32 opcode2:1; }; + +DEFINE_OPCODE_T32(HVC_1, 0b111101111110) +DEFINE_OPCODE_T32(HVC_2, 0b1000) +DEFINE_STRUCT_T32(HVC) { + InstT32 imm4:4; + InstT32 opcode1:12; + InstT32 imm12:12; + InstT32 opcode2:4; +}; diff --git a/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_t32.cpp b/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_t32.cpp index 1bc8f825..db2759be 100644 --- a/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_t32.cpp +++ b/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_t32.cpp @@ -239,3 +239,19 @@ void T32_LDR_IMM::Assemble() { T32_SUB_IMM::T32_SUB_IMM(void *inst) : InstructionT32(inst) { } + + +T32_HVC::T32_HVC(void *inst) : InstructionT32(inst) {} + +T32_HVC::T32_HVC(U16 imme) : imme(imme) {} + +void T32_HVC::Disassemble() { + imme = static_cast(COMBINE(Get()->imm4, Get()->imm12, 12)); +} + +void T32_HVC::Assemble() { + SET_OPCODE_MULTI(HVC, 1); + SET_OPCODE_MULTI(HVC, 2); + Get()->imm12 = BITS(imme, 0, 11); + Get()->imm4 = BITS(imme, 12, 15); +} diff --git a/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_t32.h b/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_t32.h index fe051df7..2f2fca83 100644 --- a/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_t32.h +++ b/nativehook/src/main/cpp/archs/arm/arm32/inst/inst_t32.h @@ -280,6 +280,23 @@ namespace SandHook { }; + + DEFINE_INST(HVC) { + public: + T32_HVC(void *inst); + + T32_HVC(U16 imme); + + DEFINE_IS_EXT(HVC, TEST_INST_OPCODE(HVC, 1) && TEST_INST_OPCODE(HVC, 2)) + + void Disassemble() override; + + void Assemble() override; + + public: + U16 imme; + }; + } } diff --git a/nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp b/nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp index b3cafd31..8954409c 100644 --- a/nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp +++ b/nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp @@ -2,6 +2,7 @@ // Created by swift on 2019/5/23. // +#include #include "hook_arm64.h" #include "code_buffer.h" #include "lock.h" @@ -170,7 +171,10 @@ void *InlineHookArm64Android::SingleInstHook(void *origin, void *replace) { } void InlineHookArm64Android::ExceptionHandler(int num, sigcontext *context) { - void *code = reinterpret_cast(context->pc); + InstA64 *code = reinterpret_cast(context->pc); + if (!IS_OPCODE_A64(*code, EXCEPTION_GEN)) { + abort(); + } INST_A64(EXCEPTION_GEN) hvc(code); hvc.Disassemble(); if (hvc.imme >= hook_infos.size()) From b685a174344dd713281b011cd3fb90b6e84d2e82 Mon Sep 17 00:00:00 2001 From: swift_gan <939543405@qq.com> Date: Tue, 16 Jul 2019 17:24:31 +0800 Subject: [PATCH 3/3] [SingleInstHook]tweak code --- .../main/java/com/swift/sandhook/MyApp.java | 3 - nativehook/src/main/cpp/elf/elf.cpp | 10 +- nativehook/src/main/cpp/includes/elf.h | 6 +- nativehook/src/main/cpp/sandhook_native.cpp | 150 ++---------------- nativehook/src/main/cpp/sandhook_native.h | 6 + 5 files changed, 31 insertions(+), 144 deletions(-) diff --git a/app/src/main/java/com/swift/sandhook/MyApp.java b/app/src/main/java/com/swift/sandhook/MyApp.java index 7e261b2c..981796f7 100644 --- a/app/src/main/java/com/swift/sandhook/MyApp.java +++ b/app/src/main/java/com/swift/sandhook/MyApp.java @@ -5,7 +5,6 @@ import android.os.Build; import android.util.Log; -import com.swift.sandhook.nativehook.NativeHook; import com.swift.sandhook.test.TestClass; import com.swift.sandhook.testHookers.ActivityHooker; import com.swift.sandhook.testHookers.CtrHook; @@ -37,8 +36,6 @@ public void onCreate() { SandHookConfig.SDK_INT = 29; } - NativeHook.test(); - SandHook.disableVMInline(); SandHook.tryDisableProfile(getPackageName()); SandHook.disableDex2oatInline(false); diff --git a/nativehook/src/main/cpp/elf/elf.cpp b/nativehook/src/main/cpp/elf/elf.cpp index 662c7015..a368816c 100644 --- a/nativehook/src/main/cpp/elf/elf.cpp +++ b/nativehook/src/main/cpp/elf/elf.cpp @@ -90,7 +90,7 @@ ElfImg::ElfImg(const char *elf) { } //load module rang - baseInRam = getModuleBase(elf); + baseInRam = GetModuleBase(elf); } ElfImg::~ElfImg() { @@ -105,7 +105,7 @@ ElfImg::~ElfImg() { } } -Elf_Addr ElfImg::getSymbOffset(const char *name) { +Elf_Addr ElfImg::GetSymOffset(const char *name) { Elf_Addr _offset = 0; //search dynmtab @@ -139,8 +139,8 @@ Elf_Addr ElfImg::getSymbOffset(const char *name) { return 0; } -Elf_Addr ElfImg::getSymbAddress(const char *name) { - Elf_Addr offset = getSymbOffset(name); +Elf_Addr ElfImg::GetSymAddress(const char *name) { + Elf_Addr offset = GetSymOffset(name); if (offset > 0 && baseInRam != nullptr) { return static_cast((size_t) baseInRam + offset - bias); } else { @@ -148,7 +148,7 @@ Elf_Addr ElfImg::getSymbAddress(const char *name) { } } -void *ElfImg::getModuleBase(const char *name) { +void *ElfImg::GetModuleBase(const char *name) { FILE *maps; char buff[256]; off_t load_addr; diff --git a/nativehook/src/main/cpp/includes/elf.h b/nativehook/src/main/cpp/includes/elf.h index 74272ea7..d3dd6169 100644 --- a/nativehook/src/main/cpp/includes/elf.h +++ b/nativehook/src/main/cpp/includes/elf.h @@ -44,11 +44,11 @@ namespace SandHook { ElfImg(const char* elf); - Elf_Addr getSymbOffset(const char* name); + Elf_Addr GetSymOffset(const char *name); - static void* getModuleBase(const char* name); + static void* GetModuleBase(const char *name); - Elf_Addr getSymbAddress(const char* name); + Elf_Addr GetSymAddress(const char *name); ~ElfImg(); diff --git a/nativehook/src/main/cpp/sandhook_native.cpp b/nativehook/src/main/cpp/sandhook_native.cpp index 8381b223..386cb0c6 100644 --- a/nativehook/src/main/cpp/sandhook_native.cpp +++ b/nativehook/src/main/cpp/sandhook_native.cpp @@ -3,8 +3,6 @@ // #include -#include -#include #include "sandhook_native.h" #include "hook.h" #include "elf.h" @@ -12,139 +10,10 @@ 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 *unit, void *pc) override { - BaseInst* instruction = reinterpret_cast(unit); - instruction->Assemble(); - return true; - } -}; - -extern "C" -JNIEXPORT void JNICALL -Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1) { - - - dosth4Backup = reinterpret_cast(InlineHook::instance->SingleInstHook( - reinterpret_cast(do4), - reinterpret_cast(do4replace))); - - - do4(); - - if (sizeof(void*) == 8) { - heapPreForkBackup = reinterpret_cast(SandInlineHookSym("/system/lib64/libart.so", "_ZN3art2gc4Heap13PreZygoteForkEv", - reinterpret_cast(myHeapPreFork))); - innerSuspendVM = reinterpret_cast(SandInlineHookSym("/system/lib64/libart.so", "_ZN3art3Dbg9SuspendVMEv", - reinterpret_cast(SuspendVMReplace))); - } else { - heapPreForkBackup = reinterpret_cast(SandInlineHookSym("/system/lib/libart.so", "_ZN3art2gc4Heap13PreZygoteForkEv", - reinterpret_cast(myHeapPreFork))); - innerSuspendVM = reinterpret_cast(SandInlineHookSym("/system/lib/libart.so", "_ZN3art3Dbg9SuspendVMEv", - reinterpret_cast(SuspendVMReplace))); - } - - void* do3P = reinterpret_cast(do3); - - InlineHook::instance->BreakPoint(reinterpret_cast((Addr)do3), breakCallback); - - LOGE("ok"); - - do3(100, 2); - - -} - - extern "C" EXPORT void* SandGetSym(const char* so, const char* symb) { ElfImg elfImg(so); - return reinterpret_cast(elfImg.getSymbAddress(symb)); + return reinterpret_cast(elfImg.GetSymAddress(symb)); } extern "C" @@ -155,13 +24,28 @@ EXPORT void* SandInlineHook(void* origin, void* replace) { extern "C" EXPORT void* SandInlineHookSym(const char* so, const char* symb, void* replace) { ElfImg elfImg(so); - void* origin = reinterpret_cast(elfImg.getSymbAddress(symb)); + void* origin = reinterpret_cast(elfImg.GetSymAddress(symb)); if (origin == nullptr) return nullptr; return InlineHook::instance->Hook(origin, replace); } +extern "C" +EXPORT void* SandSingleInstHook(void* origin, void* replace) { + return InlineHook::instance->SingleInstHook(origin, replace); +} + +extern "C" +EXPORT void* SandSingleInstHookSym(const char* so, const char* symb, void* replace) { + ElfImg elfImg(so); + void* origin = reinterpret_cast(elfImg.GetSymAddress(symb)); + + if (origin == nullptr) + return nullptr; + return InlineHook::instance->SingleInstHook(origin, replace); +} + extern "C" EXPORT bool SandBreakpoint(void* origin, void (*callback)(REG[])) { return InlineHook::instance->BreakPoint(origin, callback); diff --git a/nativehook/src/main/cpp/sandhook_native.h b/nativehook/src/main/cpp/sandhook_native.h index 2d9ac947..08b74c0a 100644 --- a/nativehook/src/main/cpp/sandhook_native.h +++ b/nativehook/src/main/cpp/sandhook_native.h @@ -17,5 +17,11 @@ EXPORT void* SandInlineHook(void* origin, void* replace); extern "C" EXPORT void* SandInlineHookSym(const char* so, const char* symb, void* replace); +extern "C" +EXPORT void* SandSingleInstHook(void* origin, void* replace); + +extern "C" +EXPORT void* SandSingleInstHookSym(const char* so, const char* symb, void* replace); + extern "C" EXPORT bool SandBreakpoint(void* origin, void (*callback)(REG[])); \ No newline at end of file