Skip to content

Commit

Permalink
Merge pull request #23 from ganyao114/short_method
Browse files Browse the repository at this point in the history
single instruction hook
  • Loading branch information
ganyao114 committed Jul 16, 2019
2 parents 14dae38 + b685a17 commit d92dd97
Show file tree
Hide file tree
Showing 17 changed files with 247 additions and 24 deletions.
1 change: 0 additions & 1 deletion app/src/main/java/com/swift/sandhook/MyApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,8 @@ void AssemblerA32::Nop16() {
Mov(IP, IP);
}

void AssemblerA32::Hvc(U16 num) {
Emit(reinterpret_cast<BaseUnit*>(new INST_T32(HVC)(num)));
}


Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ namespace SandHook {

void Nop16();

void Hvc(U16 num);

public:
CodeContainer code_container = CodeContainer(nullptr);
};
Expand Down
63 changes: 61 additions & 2 deletions nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//

#include <log.h>
#include <cstdlib>
#include "code_relocate_arm32.h"
#include "hook_arm32.h"
#include "code_buffer.h"
Expand All @@ -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)) {
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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<Addr>(origin_code));
AssemblerA32 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
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<void *>(reinterpret_cast<Addr>(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<InstT32*>(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<U32>(hook_info.replace);
}
15 changes: 7 additions & 8 deletions nativehook/src/main/cpp/archs/arm/arm32/hook/hook_arm32.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,23 @@
#pragma once

#include "hook.h"
#include <vector>

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<HookInfo> hook_infos;
};

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ enum class InstCodeT32 : InstCode {
LDR_UIMM,
MOV_MOVT_IMM,
SUB_IMM,
HVC
};
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
16 changes: 16 additions & 0 deletions nativehook/src/main/cpp/archs/arm/arm32/inst/inst_t32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<U16>(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);
}
17 changes: 17 additions & 0 deletions nativehook/src/main/cpp/archs/arm/arm32/inst/inst_t32.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

}
}

Expand Down
51 changes: 51 additions & 0 deletions nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Created by swift on 2019/5/23.
//

#include <cstdlib>
#include "hook_arm64.h"
#include "code_buffer.h"
#include "lock.h"
Expand Down Expand Up @@ -131,3 +132,53 @@ 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) {
InstA64 *code = reinterpret_cast<InstA64*>(context->pc);
if (!IS_OPCODE_A64(*code, EXCEPTION_GEN)) {
abort();
}
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);
}
8 changes: 8 additions & 0 deletions nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,21 @@
#pragma once

#include "hook.h"
#include <vector>

namespace SandHook {
namespace Hook {
class InlineHookArm64Android : public InlineHook {
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;
};
}
}
10 changes: 5 additions & 5 deletions nativehook/src/main/cpp/elf/elf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ ElfImg::ElfImg(const char *elf) {
}

//load module rang
baseInRam = getModuleBase(elf);
baseInRam = GetModuleBase(elf);
}

ElfImg::~ElfImg() {
Expand All @@ -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
Expand Down Expand Up @@ -139,16 +139,16 @@ 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<Elf_Addr>((size_t) baseInRam + offset - bias);
} else {
return 0;
}
}

void *ElfImg::getModuleBase(const char *name) {
void *ElfImg::GetModuleBase(const char *name) {
FILE *maps;
char buff[256];
off_t load_addr;
Expand Down
27 changes: 25 additions & 2 deletions nativehook/src/main/cpp/hook/hook.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//
// Created by swift on 2019/5/14.
//

#include "hook.h"
#include "lock.h"

#if defined(__arm__)
#include "hook_arm32.h"
Expand All @@ -11,11 +11,34 @@
#endif

using namespace SandHook::Hook;
using namespace SandHook::Utils;

CodeBuffer* InlineHook::backup_buffer = new AndroidCodeBuffer();

#if defined(__arm__)
InlineHook* InlineHook::instance = new InlineHookArm32Android();
#elif defined(__aarch64__)
InlineHook* InlineHook::instance = new InlineHookArm64Android();
#endif
#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;
}
6 changes: 3 additions & 3 deletions nativehook/src/main/cpp/includes/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
Loading

0 comments on commit d92dd97

Please sign in to comment.