Commit 7a2b7b8f authored by swift_gan's avatar swift_gan Committed by swift_gan

[SingleInstHook]impl arm32

parent e4b6d861
...@@ -177,4 +177,8 @@ void AssemblerA32::Nop16() { ...@@ -177,4 +177,8 @@ void AssemblerA32::Nop16() {
Mov(IP, IP); Mov(IP, IP);
} }
void AssemblerA32::Hvc(U16 num) {
Emit(reinterpret_cast<BaseUnit*>(new INST_T32(HVC)(num)));
}
...@@ -77,6 +77,8 @@ namespace SandHook { ...@@ -77,6 +77,8 @@ namespace SandHook {
void Nop16(); void Nop16();
void Hvc(U16 num);
public: public:
CodeContainer code_container = CodeContainer(nullptr); CodeContainer code_container = CodeContainer(nullptr);
}; };
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// //
#include <log.h> #include <log.h>
#include <cstdlib>
#include "code_relocate_arm32.h" #include "code_relocate_arm32.h"
#include "hook_arm32.h" #include "hook_arm32.h"
#include "code_buffer.h" #include "code_buffer.h"
...@@ -18,7 +19,7 @@ using namespace SandHook::Utils; ...@@ -18,7 +19,7 @@ using namespace SandHook::Utils;
#include "assembler_arm32.h" #include "assembler_arm32.h"
using namespace SandHook::RegistersA32; using namespace SandHook::RegistersA32;
void *InlineHookArm32Android::Hook(void *origin, void *replace) { void *InlineHookArm32Android::Hook(void *origin, void *replace) {
AutoLock lock(hookLock); AutoLock lock(hook_lock);
void* origin_code; void* origin_code;
if (IsThumbCode((Addr) origin)) { if (IsThumbCode((Addr) origin)) {
...@@ -74,7 +75,7 @@ IMPORT_SHELLCODE(BP_SHELLCODE) ...@@ -74,7 +75,7 @@ IMPORT_SHELLCODE(BP_SHELLCODE)
IMPORT_LABEL(callback_addr_s, Addr) IMPORT_LABEL(callback_addr_s, Addr)
IMPORT_LABEL(origin_addr_s, Addr) IMPORT_LABEL(origin_addr_s, Addr)
bool InlineHookArm32Android::BreakPoint(void *origin, void (*callback)(REG *)) { bool InlineHookArm32Android::BreakPoint(void *origin, void (*callback)(REG *)) {
AutoLock lock(hookLock); AutoLock lock(hook_lock);
void* origin_code; void* origin_code;
if (IsThumbCode((Addr) origin)) { if (IsThumbCode((Addr) origin)) {
...@@ -126,3 +127,61 @@ bool InlineHookArm32Android::BreakPoint(void *origin, void (*callback)(REG *)) { ...@@ -126,3 +127,61 @@ bool InlineHookArm32Android::BreakPoint(void *origin, void (*callback)(REG *)) {
return true; 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);
}
...@@ -5,24 +5,23 @@ ...@@ -5,24 +5,23 @@
#pragma once #pragma once
#include "hook.h" #include "hook.h"
#include <vector>
namespace SandHook { namespace SandHook {
namespace Hook { namespace Hook {
class InlineHookArm32Android : public InlineHook { class InlineHookArm32Android : public InlineHook {
public: public:
inline InlineHookArm32Android() {
hookLock = new std::mutex();
};
inline ~InlineHookArm32Android() {
delete hookLock;
}
void *Hook(void *origin, void *replace) override; void *Hook(void *origin, void *replace) override;
bool BreakPoint(void *point, void (*callback)(REG *)) override; bool BreakPoint(void *point, void (*callback)(REG *)) override;
protected: void *SingleInstHook(void *origin, void *replace) override;
std::mutex* hookLock;
void ExceptionHandler(int num, sigcontext *context) override;
private:
std::vector<HookInfo> hook_infos;
}; };
} }
......
...@@ -40,4 +40,5 @@ enum class InstCodeT32 : InstCode { ...@@ -40,4 +40,5 @@ enum class InstCodeT32 : InstCode {
LDR_UIMM, LDR_UIMM,
MOV_MOVT_IMM, MOV_MOVT_IMM,
SUB_IMM, SUB_IMM,
HVC
}; };
\ No newline at end of file
...@@ -95,3 +95,12 @@ DEFINE_STRUCT_T32(SUB_IMM) { ...@@ -95,3 +95,12 @@ DEFINE_STRUCT_T32(SUB_IMM) {
InstT32 imm3:3; InstT32 imm3:3;
InstT32 opcode2:1; 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;
};
...@@ -239,3 +239,19 @@ void T32_LDR_IMM::Assemble() { ...@@ -239,3 +239,19 @@ void T32_LDR_IMM::Assemble() {
T32_SUB_IMM::T32_SUB_IMM(void *inst) : InstructionT32(inst) { 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);
}
...@@ -280,6 +280,23 @@ namespace SandHook { ...@@ -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;
};
} }
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Created by swift on 2019/5/23. // Created by swift on 2019/5/23.
// //
#include <cstdlib>
#include "hook_arm64.h" #include "hook_arm64.h"
#include "code_buffer.h" #include "code_buffer.h"
#include "lock.h" #include "lock.h"
...@@ -170,7 +171,10 @@ void *InlineHookArm64Android::SingleInstHook(void *origin, void *replace) { ...@@ -170,7 +171,10 @@ void *InlineHookArm64Android::SingleInstHook(void *origin, void *replace) {
} }
void InlineHookArm64Android::ExceptionHandler(int num, sigcontext *context) { void InlineHookArm64Android::ExceptionHandler(int num, sigcontext *context) {
void *code = reinterpret_cast<void*>(context->pc); InstA64 *code = reinterpret_cast<InstA64*>(context->pc);
if (!IS_OPCODE_A64(*code, EXCEPTION_GEN)) {
abort();
}
INST_A64(EXCEPTION_GEN) hvc(code); INST_A64(EXCEPTION_GEN) hvc(code);
hvc.Disassemble(); hvc.Disassemble();
if (hvc.imme >= hook_infos.size()) if (hvc.imme >= hook_infos.size())
......
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