Commit 5e1e5cb7 authored by swift_gan's avatar swift_gan Committed by swift_gan

[NativeHook]fix thumb32 encode

parent 1162fbfb
...@@ -25,6 +25,7 @@ add_library( # Sets the name of the library. ...@@ -25,6 +25,7 @@ add_library( # Sets the name of the library.
src/main/cpp/archs/arm/arm64/register/register_list_arm64.cpp src/main/cpp/archs/arm/arm64/register/register_list_arm64.cpp
src/main/cpp/archs/arm/arm64/decoder/decoder_arm64.cpp src/main/cpp/archs/arm/arm64/decoder/decoder_arm64.cpp
src/main/cpp/archs/arm/arm64/relocate/code_relocate_arm64.cpp src/main/cpp/archs/arm/arm64/relocate/code_relocate_arm64.cpp
src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp
src/main/cpp/archs/arm/arm32/inst/inst_arm32.cpp src/main/cpp/archs/arm/arm32/inst/inst_arm32.cpp
src/main/cpp/archs/arm/arm32/inst/inst_t32.cpp src/main/cpp/archs/arm/arm32/inst/inst_t32.cpp
src/main/cpp/archs/arm/arm32/inst/inst_t16.cpp src/main/cpp/archs/arm/arm32/inst/inst_t16.cpp
...@@ -32,6 +33,8 @@ add_library( # Sets the name of the library. ...@@ -32,6 +33,8 @@ add_library( # Sets the name of the library.
src/main/cpp/archs/arm/arm32/register/register_list_arm32.cpp src/main/cpp/archs/arm/arm32/register/register_list_arm32.cpp
src/main/cpp/archs/arm/arm32/assembler/assembler_arm32.cpp src/main/cpp/archs/arm/arm32/assembler/assembler_arm32.cpp
src/main/cpp/archs/arm/arm32/decoder/decoder_arm32.cpp src/main/cpp/archs/arm/arm32/decoder/decoder_arm32.cpp
src/main/cpp/archs/arm/arm32/hook/hook_arm32.cpp
src/main/cpp/archs/arm/arm32/relocate/code_relocate_arm32.cpp
src/main/cpp/relocate/code_relocate.cpp src/main/cpp/relocate/code_relocate.cpp
src/main/cpp/elf/elf.cpp src/main/cpp/elf/elf.cpp
src/main/cpp/assembler/assembler.cpp src/main/cpp/assembler/assembler.cpp
...@@ -54,10 +57,13 @@ include_directories( ...@@ -54,10 +57,13 @@ include_directories(
src/main/cpp/archs/arm/arm64/decoder src/main/cpp/archs/arm/arm64/decoder
src/main/cpp/archs/arm/arm64/assembler src/main/cpp/archs/arm/arm64/assembler
src/main/cpp/archs/arm/arm64/relocate src/main/cpp/archs/arm/arm64/relocate
src/main/cpp/archs/arm/arm64/hook
src/main/cpp/archs/arm/arm32/inst src/main/cpp/archs/arm/arm32/inst
src/main/cpp/archs/arm/arm32/register src/main/cpp/archs/arm/arm32/register
src/main/cpp/archs/arm/arm32/assembler src/main/cpp/archs/arm/arm32/assembler
src/main/cpp/archs/arm/arm32/decoder src/main/cpp/archs/arm/arm32/decoder
src/main/cpp/archs/arm/arm32/hook
src/main/cpp/archs/arm/arm32/relocate
) )
# 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 swift on 2019/5/23.
//
#include "code_relocate_arm32.h"
#include "hook_arm32.h"
#include "code_buffer.h"
#include "lock.h"
using namespace SandHook::Hook;
using namespace SandHook::Decoder;
using namespace SandHook::Asm;
using namespace SandHook::Assembler;
using namespace SandHook::Utils;
#include "assembler_arm32.h"
using namespace SandHook::RegistersA32;
void *InlineHookArm32Android::inlineHook(void *origin, void *replace) {
AutoLock lock(hookLock);
void* originCode = origin;
if (isThumbCode(reinterpret_cast<Addr>(origin))) {
originCode = getThumbCodeAddress(origin);
}
if (isThumbCode(reinterpret_cast<Addr>(replace))) {
replace = getThumbPC(replace);
}
void* backup = nullptr;
AssemblerA32 assemblerBackup(backupBuffer);
StaticCodeBuffer inlineBuffer = StaticCodeBuffer(reinterpret_cast<Addr>(originCode));
AssemblerA32 assemblerInline(&inlineBuffer);
CodeContainer* codeContainerInline = &assemblerInline.codeContainer;
//build inline trampoline
#define __ assemblerInline.
Label* target_addr_label = new Label();
__ Ldr(PC, target_addr_label);
__ Emit(target_addr_label);
__ Emit(reinterpret_cast<Addr>(replace));
#undef __
//build backup method
CodeRelocateA32 relocate = CodeRelocateA32(assemblerBackup);
backup = relocate.relocate(origin, codeContainerInline->size(), nullptr);
#define __ assemblerBackup.
Label* origin_addr_label = new Label();
__ Ldr(PC, origin_addr_label);
__ Emit(origin_addr_label);
__ Emit((Addr) getThumbPC(reinterpret_cast<void *>(reinterpret_cast<Addr>(originCode) + codeContainerInline->size())));
__ finish();
#undef __
//commit inline trampoline
assemblerInline.finish();
return getThumbPC(backup);
}
\ No newline at end of file
//
// Created by swift on 2019/5/23.
//
#ifndef SANDHOOK_HOOK_ARM32_H
#define SANDHOOK_HOOK_ARM32_H
#include "hook.h"
namespace SandHook {
namespace Hook {
class InlineHookArm32Android : public InlineHook {
public:
inline InlineHookArm32Android() {
hookLock = new std::mutex();
};
inline ~InlineHookArm32Android() {
delete hookLock;
}
void *inlineHook(void *origin, void *replace) override;
protected:
std::mutex* hookLock;
};
}
}
#endif //SANDHOOK_HOOK_ARM32_H
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#define DECODE_OFFSET(bits, ext) signExtend32(bits + ext, COMBINE(get()->imm##bits, 0, ext)) #define DECODE_OFFSET(bits, ext) signExtend32(bits + ext, COMBINE(get()->imm##bits, 0, ext))
#define ENCODE_OFFSET(bits, ext) get()->imm##bits = TruncateToUint##bits(offset >> ext) #define ENCODE_OFFSET(bits, ext) get()->imm##bits = TruncateToUint##bits(offset >> ext)
#define CODE_OFFSET(I) inst->offset + 2 * inst->size()
using namespace SandHook::RegistersA32; using namespace SandHook::RegistersA32;
namespace SandHook { namespace SandHook {
...@@ -161,6 +163,7 @@ namespace SandHook { ...@@ -161,6 +163,7 @@ namespace SandHook {
} }
std::ostream& operator<<(std::ostream& os, RegisterList registers); std::ostream& operator<<(std::ostream& os, RegisterList registers);
} }
} }
......
...@@ -24,34 +24,33 @@ DEFINE_STRUCT_T32(UNKNOW) { ...@@ -24,34 +24,33 @@ DEFINE_STRUCT_T32(UNKNOW) {
DEFINE_OPCODE_T32(B32, 0b11110) DEFINE_OPCODE_T32(B32, 0b11110)
DEFINE_STRUCT_T32(B32) { DEFINE_STRUCT_T32(B32) {
InstT32 imm10:10;
InstT32 S:1;
InstT32 opcode:5;
InstT32 imm11:11; InstT32 imm11:11;
InstT32 J2:1; InstT32 J2:1;
InstT32 X:1; InstT32 X:1;
InstT32 J1:1; InstT32 J1:1;
InstT32 op:2; InstT32 op:2;
InstT32 imm10:10;
InstT32 S:1;
InstT32 opcode:5;
}; };
DEFINE_OPCODE_T32(LDR_LIT, 0b111100) DEFINE_OPCODE_T32(LDR_LIT, 0b11111000)
DEFINE_STRUCT_T32(LDR_LIT) { DEFINE_STRUCT_T32(LDR_LIT) {
InstT32 imm12:12;
InstT32 rt:T32_REG_WIDE;
InstT32 op:7; InstT32 op:7;
InstT32 U:1; InstT32 U:1;
InstT32 S:1; InstT32 opcode:8;
InstT32 opcode:7; InstT32 imm12:12;
InstT32 rt:T32_REG_WIDE;
}; };
//ldr imm T3 //ldr imm T3
DEFINE_OPCODE_T32(LDR_UIMM, 0b111110001101) DEFINE_OPCODE_T32(LDR_UIMM, 0b111110001101)
DEFINE_STRUCT_T32(LDR_UIMM) { DEFINE_STRUCT_T32(LDR_UIMM) {
InstT32 imm12:12;
InstT32 rt:T32_REG_WIDE;
InstT32 rn:T32_REG_WIDE; InstT32 rn:T32_REG_WIDE;
InstT32 opcode:12; InstT32 opcode:12;
InstT32 imm12:12;
InstT32 rt:T32_REG_WIDE;
}; };
...@@ -59,28 +58,28 @@ DEFINE_STRUCT_T32(LDR_UIMM) { ...@@ -59,28 +58,28 @@ DEFINE_STRUCT_T32(LDR_UIMM) {
DEFINE_OPCODE_T32(LDR_IMM_1, 0b11111000) DEFINE_OPCODE_T32(LDR_IMM_1, 0b11111000)
DEFINE_OPCODE_T32(LDR_IMM_2, 0b1) DEFINE_OPCODE_T32(LDR_IMM_2, 0b1)
DEFINE_STRUCT_T32(LDR_IMM) { DEFINE_STRUCT_T32(LDR_IMM) {
InstT32 rn:T32_REG_WIDE;
InstT32 op:4;
InstT32 opcode1:8;
InstT32 imm8:8; InstT32 imm8:8;
InstT32 W:1; InstT32 W:1;
InstT32 U:1; InstT32 U:1;
InstT32 P:1; InstT32 P:1;
InstT32 opcode2:1; InstT32 opcode2:1;
InstT32 rt:T32_REG_WIDE; InstT32 rt:T32_REG_WIDE;
InstT32 rn:T32_REG_WIDE;
InstT32 op:4;
InstT32 opcode1:8;
}; };
DEFINE_OPCODE_T32(MOV_MOVT_IMM_1, 0b11110) DEFINE_OPCODE_T32(MOV_MOVT_IMM_1, 0b11110)
DEFINE_OPCODE_T32(MOV_MOVT_IMM_2, 0b0) DEFINE_OPCODE_T32(MOV_MOVT_IMM_2, 0b0)
DEFINE_STRUCT_T32(MOV_MOVT_IMM) { DEFINE_STRUCT_T32(MOV_MOVT_IMM) {
InstT32 imm8:8;
InstT32 rd:4;
InstT32 imm3:3;
InstT32 opcode2:1;
InstT32 imm4:4; InstT32 imm4:4;
InstT32 op:6; InstT32 op:6;
InstT32 i:1; InstT32 i:1;
InstT32 opcode1:5; InstT32 opcode1:5;
InstT32 imm8:8;
InstT32 rd:4;
InstT32 imm3:3;
InstT32 opcode2:1;
}; };
......
...@@ -255,11 +255,8 @@ namespace SandHook { ...@@ -255,11 +255,8 @@ namespace SandHook {
DEFINE_INST_CODE(LDR_LIT) DEFINE_INST_CODE(LDR_LIT)
private:
Addr getImmPCOffsetTarget() override; Addr getImmPCOffsetTarget() override;
public:
Off getImmPCOffset() override; Off getImmPCOffset() override;
void onOffsetApply(Off offset) override; void onOffsetApply(Off offset) override;
......
...@@ -120,6 +120,17 @@ Off T32_LDR_LIT::getImmPCOffset() { ...@@ -120,6 +120,17 @@ Off T32_LDR_LIT::getImmPCOffset() {
return get()->U == add ? get()->imm12 : -get()->imm12; return get()->U == add ? get()->imm12 : -get()->imm12;
} }
void T32_LDR_LIT::onOffsetApply(Off offset) {
this->offset = offset;
if (offset >= 0) {
get()->U = add;
get()->imm12 = static_cast<InstT32>(offset);
} else {
get()->U = cmp;
get()->imm12 = static_cast<InstT32>(-offset);
}
}
void T32_LDR_LIT::decode(T32_STRUCT_LDR_LIT *inst) { void T32_LDR_LIT::decode(T32_STRUCT_LDR_LIT *inst) {
DECODE_OP; DECODE_OP;
DECODE_RT(Reg); DECODE_RT(Reg);
...@@ -140,7 +151,6 @@ void T32_LDR_LIT::assembler() { ...@@ -140,7 +151,6 @@ void T32_LDR_LIT::assembler() {
} }
T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM() {} T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM() {}
T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM(T32_STRUCT_MOV_MOVT_IMM *inst) : InstructionT32(inst) {} T32_MOV_MOVT_IMM::T32_MOV_MOVT_IMM(T32_STRUCT_MOV_MOVT_IMM *inst) : InstructionT32(inst) {}
......
...@@ -193,8 +193,8 @@ namespace SandHook { ...@@ -193,8 +193,8 @@ namespace SandHook {
}; };
enum S { enum S {
cmp = 0, cmp = 0b0,
add = 1 add = 0b1
}; };
T32_LDR_LIT(); T32_LDR_LIT();
...@@ -211,6 +211,8 @@ namespace SandHook { ...@@ -211,6 +211,8 @@ namespace SandHook {
Off getImmPCOffset() override; Off getImmPCOffset() override;
void onOffsetApply(Off offset) override;
void decode(T32_STRUCT_LDR_LIT *inst) override; void decode(T32_STRUCT_LDR_LIT *inst) override;
void assembler() override; void assembler() override;
......
//
// Created by swift on 2019/5/23.
//
#include "code_relocate_arm32.h"
#include "decoder.h"
#include "lock.h"
using namespace SandHook::RegistersA32;
using namespace SandHook::AsmA32;
using namespace SandHook::Utils;
using namespace SandHook::Decoder;
#define __ assemblerA32->
#define IMPL_RELOCATE(T, X) void CodeRelocateA32::relocate_##T##_##X (INST_##T(X)* inst, void* toPc) throw(ErrorCodeException)
#define CASE(T, X) \
case ENUM_VALUE(InstCode##T, InstCode##T::X): \
relocate_##T##_##X(reinterpret_cast<INST_##T(X)*>(instruction), toPc); \
break;
CodeRelocateA32::CodeRelocateA32(AssemblerA32 &assembler) : CodeRelocate(assembler.codeContainer) {
this->assemblerA32 = &assembler;
}
bool CodeRelocateA32::visit(Unit<Base> *unit, void *pc) {
relocate(reinterpret_cast<Instruction<Base> *>(unit), __ getPC());
curOffset += unit->size();
return true;
}
void* CodeRelocateA32::relocate(void *startPc, Addr len, void *toPc = nullptr) throw(ErrorCodeException) {
AutoLock autoLock(relocateLock);
startAddr = reinterpret_cast<Addr>(startPc);
if (isThumbCode(startAddr)) {
startAddr = reinterpret_cast<Addr>(getThumbCodeAddress(startPc));
}
length = len;
curOffset = 0;
__ allocBufferFirst(static_cast<U32>(len * 8));
void* curPc = __ getPC();
if (toPc == nullptr) {
Disassembler::get()->decode(startPc, len, *this);
} else {
//TODO
}
return curPc;
}
void* CodeRelocateA32::relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) {
void* curPc = __ getPC();
//insert later bind labels
__ Emit(getLaterBindLabel(curOffset));
if (!instruction->pcRelate()) {
__ Emit(instruction);
return curPc;
}
switch (instruction->instCode()) {
CASE(T16, B)
default:
__ Emit(instruction);
}
return curPc;
}
IMPL_RELOCATE(T16, B_COND) {
}
IMPL_RELOCATE(T16, B) {
Addr targetAddr = inst->getImmPCOffsetTarget();
if (inRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) {
__ B(getLaterBindLabel(CODE_OFFSET(inst) + curOffset));
return;
}
Label* target_label = new Label();
__ Ldr(PC, target_label);
__ Emit(target_label);
__ Emit((Addr) getThumbPC(reinterpret_cast<void *>(targetAddr)));
}
IMPL_RELOCATE(T16, BX_BLX) {
}
IMPL_RELOCATE(T16, CBZ_CBNZ) {
}
IMPL_RELOCATE(T16, LDR_LIT) {
}
IMPL_RELOCATE(T16, ADR) {
}
IMPL_RELOCATE(T32, B32) {
}
IMPL_RELOCATE(T32, LDR_LIT) {
}
\ No newline at end of file
//
// Created by swift on 2019/5/23.
//
#ifndef SANDHOOK_CODE_RELOCATE_ARM32_H
#define SANDHOOK_CODE_RELOCATE_ARM32_H
#include <mutex>
#include <map>
#include "code_relocate.h"
#include "assembler_arm32.h"
using namespace SandHook::Assembler;
using namespace SandHook::Decoder;
using namespace SandHook::AsmA32;
#define DEFINE_RELOCATE(T, X) void relocate_##T##_##X (INST_##T(X)* inst, void* toPc) throw(ErrorCodeException);
namespace SandHook {
namespace Asm {
class CodeRelocateA32 : public CodeRelocate {
public:
CodeRelocateA32(AssemblerA32 &assembler);
void* relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) override;
void* relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) override;
bool visit(Unit<Base> *unit, void *pc) override;
DEFINE_RELOCATE(T16, B_COND)
DEFINE_RELOCATE(T16, B)
DEFINE_RELOCATE(T16, BX_BLX)
DEFINE_RELOCATE(T16, CBZ_CBNZ)
DEFINE_RELOCATE(T16, LDR_LIT)
DEFINE_RELOCATE(T16, ADR)
DEFINE_RELOCATE(T32, B32)
DEFINE_RELOCATE(T32, LDR_LIT)
private:
AssemblerA32* assemblerA32;
};
}
}
#undef DEFINE_RELOCATE
#endif //SANDHOOK_CODE_RELOCATE_ARM32_H
//
// Created by swift on 2019/5/23.
//
#include "hook_arm64.h"
#include "code_buffer.h"
#include "lock.h"
using namespace SandHook::Hook;
using namespace SandHook::Decoder;
using namespace SandHook::Asm;
using namespace SandHook::Assembler;
using namespace SandHook::Utils;
#include "assembler_arm64.h"
#include "code_relocate_arm64.h"
using namespace SandHook::RegistersA64;
void *InlineHookArm64Android::inlineHook(void *origin, void *replace) {
AutoLock lock(hookLock);
void* backup = nullptr;
AssemblerA64 assemblerBackup(backupBuffer);
StaticCodeBuffer inlineBuffer = StaticCodeBuffer(reinterpret_cast<Addr>(origin));
AssemblerA64 assemblerInline(&inlineBuffer);
CodeContainer* codeContainerInline = &assemblerInline.codeContainer;
//build inline trampoline
#define __ assemblerInline.
Label* target_addr_label = new Label();
__ Ldr(IP1, target_addr_label);
__ Br(IP1);
__ Emit(target_addr_label);
__ Emit(reinterpret_cast<Addr>(replace));
#undef __
//build backup method
CodeRelocateA64 relocate = CodeRelocateA64(assemblerBackup);
backup = relocate.relocate(origin, codeContainerInline->size(), nullptr);
#define __ assemblerBackup.
Label* origin_addr_label = new Label();
__ Ldr(IP1, origin_addr_label);
__ Br(IP1);
__ Emit(origin_addr_label);
__ Emit(reinterpret_cast<Addr>(origin) + codeContainerInline->size());
__ finish();
#undef __
//commit inline trampoline
assemblerInline.finish();
return backup;
}
\ No newline at end of file
//
// Created by swift on 2019/5/23.
//
#ifndef SANDHOOK_HOOK_ARM64_H
#define SANDHOOK_HOOK_ARM64_H
#include "hook.h"
namespace SandHook {
namespace Hook {
class InlineHookArm64Android : public InlineHook {
public:
inline InlineHookArm64Android() {
hookLock = new std::mutex();
};
inline ~InlineHookArm64Android() {
delete hookLock;
}
void *inlineHook(void *origin, void *replace) override;
protected:
std::mutex* hookLock;
};
}
}
#endif //SANDHOOK_HOOK_ARM64_H
...@@ -3,9 +3,10 @@ ...@@ -3,9 +3,10 @@
// //
#include "code_relocate_arm64.h" #include "code_relocate_arm64.h"
#include "decoder_arm64.h" #include "decoder.h"
#include "lock.h" #include "lock.h"
using namespace SandHook::Decoder;
using namespace SandHook::RegistersA64; using namespace SandHook::RegistersA64;
using namespace SandHook::AsmA64; using namespace SandHook::AsmA64;
using namespace SandHook::Utils; using namespace SandHook::Utils;
...@@ -20,11 +21,11 @@ relocate_##X(reinterpret_cast<INST_A64(X)*>(instruction), toPc); \ ...@@ -20,11 +21,11 @@ relocate_##X(reinterpret_cast<INST_A64(X)*>(instruction), toPc); \
break; break;
CodeRelocateA64::CodeRelocateA64(AssemblerA64 &assembler) : CodeRelocate(assembler.codeContainer) { CodeRelocateA64::CodeRelocateA64(AssemblerA64 &assembler) : CodeRelocate(assembler.codeContainer) {
this->assemblerA64 = &assembler; assemblerA64 = &assembler;
} }
bool CodeRelocateA64::visit(Unit<Base> *unit, void *pc) { bool CodeRelocateA64::visit(Unit<Base> *unit, void *pc) {
relocate(reinterpret_cast<Instruction<Base> *>(unit), assemblerA64->getPC()); relocate(reinterpret_cast<Instruction<Base> *>(unit), __ getPC());
curOffset += unit->size(); curOffset += unit->size();
return true; return true;
} }
...@@ -34,11 +35,10 @@ void* CodeRelocateA64::relocate(void *startPc, Addr len, void *toPc = nullptr) t ...@@ -34,11 +35,10 @@ void* CodeRelocateA64::relocate(void *startPc, Addr len, void *toPc = nullptr) t
startAddr = reinterpret_cast<Addr>(startPc); startAddr = reinterpret_cast<Addr>(startPc);
length = len; length = len;
curOffset = 0; curOffset = 0;
assemblerA64->allocBufferFirst(static_cast<U32>(len * 8)); __ allocBufferFirst(static_cast<U32>(len * 8));
void* curPc = assemblerA64->getPC(); void* curPc = __ getPC();
Arm64Decoder decoder = Arm64Decoder();
if (toPc == nullptr) { if (toPc == nullptr) {
decoder.decode(startPc, len, *this); Disassembler::get()->decode(startPc, len, *this);
} else { } else {
//TODO //TODO
} }
...@@ -46,7 +46,7 @@ void* CodeRelocateA64::relocate(void *startPc, Addr len, void *toPc = nullptr) t ...@@ -46,7 +46,7 @@ void* CodeRelocateA64::relocate(void *startPc, Addr len, void *toPc = nullptr) t
} }
void* CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) { void* CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) {
void* curPc = assemblerA64->getPC(); void* curPc = __ getPC();
//insert later bind labels //insert later bind labels
__ Emit(getLaterBindLabel(curOffset)); __ Emit(getLaterBindLabel(curOffset));
...@@ -68,26 +68,6 @@ void* CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) thro ...@@ -68,26 +68,6 @@ void* CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) thro
return curPc; return curPc;
} }
//in range of copy
bool CodeRelocateA64::inRelocateRange(Off targetOffset, Addr targetLen) {
Off startP = curOffset + targetOffset;
Off endP = startP + targetLen;
return startP >= 0 && endP <= length;
}
Label *CodeRelocateA64::getLaterBindLabel(Addr offset) {
Label* label_per_unit = nullptr;
std::map<Addr,Label*>::iterator it = laterBindlabels->find(offset);
if (it != laterBindlabels->end()) {
label_per_unit = it->second;
}
if (label_per_unit == nullptr) {
label_per_unit = new Label();
laterBindlabels->insert(std::map<Addr, Label*>::value_type(offset, label_per_unit));
}
return label_per_unit;
}
IMPL_RELOCATE(B_BL) { IMPL_RELOCATE(B_BL) {
Addr targetAddr = inst->getImmPCOffsetTarget(); Addr targetAddr = inst->getImmPCOffsetTarget();
......
...@@ -29,10 +29,6 @@ namespace SandHook { ...@@ -29,10 +29,6 @@ namespace SandHook {
bool visit(Unit<Base> *unit, void *pc) override; bool visit(Unit<Base> *unit, void *pc) override;
bool inRelocateRange(Off targetOffset, Addr targetLen);
Label* getLaterBindLabel(Addr offset);
DEFINE_RELOCATE(B_BL) DEFINE_RELOCATE(B_BL)
DEFINE_RELOCATE(B_COND) DEFINE_RELOCATE(B_COND)
...@@ -46,22 +42,13 @@ namespace SandHook { ...@@ -46,22 +42,13 @@ namespace SandHook {
DEFINE_RELOCATE(ADR_ADRP) DEFINE_RELOCATE(ADR_ADRP)
~CodeRelocateA64() {
delete relocateLock;
delete laterBindlabels;
}
private: private:
AssemblerA64* assemblerA64; AssemblerA64* assemblerA64;
std::mutex* relocateLock = new std::mutex();
std::map<Addr, Label*>* laterBindlabels = new std::map<Addr, Label*>();
Addr startAddr;
Addr length;
Addr curOffset;
}; };
} }
} }
#undef DEFINE_RELOCATE
#endif //SANDHOOK_NH_CODE_RELOCATE_A64_H #endif //SANDHOOK_NH_CODE_RELOCATE_A64_H
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
using namespace SandHook::Decoder; using namespace SandHook::Decoder;
//do not support now //do not support now
InstDecoder* Decoder::get(Arch arch) { InstDecoder* Disassembler::get(Arch arch) {
switch (arch) { switch (arch) {
case arm32: case arm32:
return get(); return get();
...@@ -23,7 +23,7 @@ InstDecoder* Decoder::get(Arch arch) { ...@@ -23,7 +23,7 @@ InstDecoder* Decoder::get(Arch arch) {
} }
} }
InstDecoder *Decoder::get() { InstDecoder *Disassembler::get() {
#if defined(__arm__) #if defined(__arm__)
return Arm32Decoder::instant; return Arm32Decoder::instant;
#elif defined(__aarch64__) #elif defined(__aarch64__)
......
...@@ -4,54 +4,18 @@ ...@@ -4,54 +4,18 @@
#include "hook.h" #include "hook.h"
#include "code_buffer.h" #if defined(__arm__)
#include "lock.h" #include "hook_arm32.h"
#elif defined(__aarch64__)
#include "hook_arm64.h"
#endif
using namespace SandHook::Hook; using namespace SandHook::Hook;
using namespace SandHook::Decoder;
using namespace SandHook::Asm;
using namespace SandHook::Assembler;
using namespace SandHook::Utils;
AndroidCodeBuffer* InlineHook::backupBuffer = new AndroidCodeBuffer();
#if defined(__arm__)
#include "assembler_arm64.h" InlineHook* InlineHook::instance = new InlineHookArm32Android();
#include "code_relocate_arm64.h" #elif defined(__aarch64__)
#include "code_relocate_arm64.h" InlineHook* InlineHook::instance = new InlineHookArm64Android();
using namespace SandHook::RegistersA64; #endif
AndroidCodeBuffer* backupBuffer = new AndroidCodeBuffer(); \ No newline at end of file
void *InlineHookArm64Android::inlineHook(void *origin, void *replace) {
AutoLock lock(hookLock);
void* backup = nullptr;
AssemblerA64 assemblerBackup(backupBuffer);
StaticCodeBuffer inlineBuffer = StaticCodeBuffer(reinterpret_cast<Addr>(origin));
AssemblerA64 assemblerInline(&inlineBuffer);
CodeContainer* codeContainerInline = &assemblerInline.codeContainer;
//build inline trampoline
#define __ assemblerInline.
Label* target_addr_label = new Label();
__ Ldr(IP1, target_addr_label);
__ Br(IP1);
__ Emit(target_addr_label);
__ Emit(reinterpret_cast<Addr>(replace));
#undef __
//build backup method
CodeRelocateA64 relocate = CodeRelocateA64(assemblerBackup);
backup = relocate.relocate(origin, codeContainerInline->size(), nullptr);
#define __ assemblerBackup.
Label* origin_addr_label = new Label();
__ Ldr(IP1, origin_addr_label);
__ Br(IP1);
__ Emit(origin_addr_label);
__ Emit(reinterpret_cast<Addr>(origin) + codeContainerInline->size());
__ finish();
#undef __
//commit inline trampoline
assemblerInline.finish();
return backup;
}
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef SANDHOOK_NH_CODE_RELOCATE_H #ifndef SANDHOOK_NH_CODE_RELOCATE_H
#define SANDHOOK_NH_CODE_RELOCATE_H #define SANDHOOK_NH_CODE_RELOCATE_H
#include <mutex>
#include <map>
#include "exception.h" #include "exception.h"
#include "instruction.h" #include "instruction.h"
#include "assembler.h" #include "assembler.h"
...@@ -24,8 +26,22 @@ namespace SandHook { ...@@ -24,8 +26,22 @@ namespace SandHook {
virtual void* relocate(Instruction<Base> *instruction, void* toPc) throw(ErrorCodeException) = 0; virtual void* relocate(Instruction<Base> *instruction, void* toPc) throw(ErrorCodeException) = 0;
virtual void* relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) = 0; virtual void* relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) = 0;
private: bool inRelocateRange(Off targetOffset, Addr targetLen);
Label* getLaterBindLabel(Addr offset);
virtual ~CodeRelocate() {
delete relocateLock;
delete laterBindlabels;
}
protected:
CodeContainer* codeContainer; CodeContainer* codeContainer;
std::mutex* relocateLock = new std::mutex();
std::map<Addr, Label*>* laterBindlabels = new std::map<Addr, Label*>();
Addr startAddr;
Addr length;
Addr curOffset;
}; };
} }
......
...@@ -25,7 +25,7 @@ namespace SandHook { ...@@ -25,7 +25,7 @@ namespace SandHook {
}; };
class Decoder { class Disassembler {
public: public:
static InstDecoder* get(Arch arch); static InstDecoder* get(Arch arch);
static InstDecoder* get(); static InstDecoder* get();
......
...@@ -6,10 +6,9 @@ ...@@ -6,10 +6,9 @@
#define SANDHOOK_NH_HOOK_H #define SANDHOOK_NH_HOOK_H
#include <mutex> #include <mutex>
#include <hook.h>
#include <decoder.h>
#include "hook.h" #include "code_buffer.h"
#include "decoder.h"
#include "assembler.h" #include "assembler.h"
#include "code_relocate.h" #include "code_relocate.h"
...@@ -20,20 +19,11 @@ namespace SandHook { ...@@ -20,20 +19,11 @@ namespace SandHook {
public: public:
//return == backup method //return == backup method
virtual void* inlineHook(void* origin, void* replace) = 0; virtual void* inlineHook(void* origin, void* replace) = 0;
};
class InlineHookArm64Android : InlineHook {
public:
inline InlineHookArm64Android() {
hookLock = new std::mutex();
};
inline ~InlineHookArm64Android() {
delete hookLock;
}
void *inlineHook(void *origin, void *replace) override;
protected: protected:
std::mutex* hookLock; static AndroidCodeBuffer* backupBuffer;
public:
static InlineHook* instance;
}; };
} }
......
...@@ -3,3 +3,25 @@ ...@@ -3,3 +3,25 @@
// //
#include "code_relocate.h" #include "code_relocate.h"
using namespace SandHook::Asm;
//in range of copy
bool CodeRelocate::inRelocateRange(Off targetOffset, Addr targetLen) {
Off startP = curOffset + targetOffset;
Off endP = startP + targetLen;
return startP >= 0 && endP <= length;
}
Label *CodeRelocate::getLaterBindLabel(Addr offset) {
Label* label_per_unit = nullptr;
std::map<Addr,Label*>::iterator it = laterBindlabels->find(offset);
if (it != laterBindlabels->end()) {
label_per_unit = it->second;
}
if (label_per_unit == nullptr) {
label_per_unit = new Label();
laterBindlabels->insert(std::map<Addr, Label*>::value_type(offset, label_per_unit));
}
return label_per_unit;
}
\ No newline at end of file
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