Commit 415861dd authored by swift_gan's avatar swift_gan Committed by swift_gan

[NativeHook]try support arm32 replace

parent 5a5f9c34
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Created by swift on 2019/5/23. // Created by swift on 2019/5/23.
// //
#include <log.h>
#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"
...@@ -19,13 +20,12 @@ using namespace SandHook::RegistersA32; ...@@ -19,13 +20,12 @@ using namespace SandHook::RegistersA32;
void *InlineHookArm32Android::inlineHook(void *origin, void *replace) { void *InlineHookArm32Android::inlineHook(void *origin, void *replace) {
AutoLock lock(hookLock); AutoLock lock(hookLock);
void* originCode = origin; void* originCode;
if (isThumbCode((Addr)origin)) { if (isThumbCode((Addr)origin)) {
originCode = getThumbCodeAddress(origin); originCode = getThumbCodeAddress(origin);
} } else {
LOGE("hook %d error!, only support thumb2 now!", origin);
if (isThumbCode((Addr)origin)) { return nullptr;
replace = getThumbPC(replace);
} }
void* backup = nullptr; void* backup = nullptr;
...@@ -37,10 +37,16 @@ void *InlineHookArm32Android::inlineHook(void *origin, void *replace) { ...@@ -37,10 +37,16 @@ void *InlineHookArm32Android::inlineHook(void *origin, void *replace) {
//build inline trampoline //build inline trampoline
#define __ assemblerInline. #define __ assemblerInline.
Label* target_addr_label = new Label(); if (isThumbCode((Addr) replace)) {
Label *target_addr_label = new Label();
__ Ldr(PC, target_addr_label); __ Ldr(PC, target_addr_label);
__ Emit(target_addr_label); __ Emit(target_addr_label);
__ Emit((Addr)replace); __ Emit((Addr) replace);
} else {
//to arm mode
__ Mov(IP, (Addr) replace);
__ Bx(IP);
}
#undef __ #undef __
//build backup method //build backup method
...@@ -64,14 +70,15 @@ IMPORT_LABEL(origin_addr_s, Addr) ...@@ -64,14 +70,15 @@ 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(hookLock);
void* originCode = origin; void* originCode;
if (isThumbCode((Addr)origin)) { if (isThumbCode((Addr)origin)) {
originCode = getThumbCodeAddress(origin); originCode = getThumbCodeAddress(origin);
} else {
LOGE("hook %d error!, only support thumb2 now!", origin);
return false;
} }
if (isThumbCode((Addr)origin)) { bool callbackThumb = isThumbCode((Addr) callback);
callback = reinterpret_cast<void (*)(REG *)>(getThumbPC((void*)callback));
}
void* backup = nullptr; void* backup = nullptr;
AssemblerA32 assemblerBackup(backupBuffer); AssemblerA32 assemblerBackup(backupBuffer);
...@@ -81,7 +88,7 @@ bool InlineHookArm32Android::breakPoint(void *origin, void (*callback)(REG *)) { ...@@ -81,7 +88,7 @@ bool InlineHookArm32Android::breakPoint(void *origin, void (*callback)(REG *)) {
//build backup method //build backup method
CodeRelocateA32 relocate = CodeRelocateA32(assemblerBackup); CodeRelocateA32 relocate = CodeRelocateA32(assemblerBackup);
backup = relocate.relocate(origin, 4 * 2, nullptr); backup = relocate.relocate(origin, callbackThumb ? (4 * 2) : (4 * 2 + 2), nullptr);
#define __ assemblerBackup. #define __ assemblerBackup.
__ Mov(IP ,(Addr) getThumbPC(reinterpret_cast<void *>((Addr)originCode + relocate.curOffset))); __ Mov(IP ,(Addr) getThumbPC(reinterpret_cast<void *>((Addr)originCode + relocate.curOffset)));
__ Bx(IP); __ Bx(IP);
...@@ -95,10 +102,15 @@ bool InlineHookArm32Android::breakPoint(void *origin, void (*callback)(REG *)) { ...@@ -95,10 +102,15 @@ bool InlineHookArm32Android::breakPoint(void *origin, void (*callback)(REG *)) {
//build inline trampoline //build inline trampoline
#define __ assemblerInline. #define __ assemblerInline.
Label* target_addr_label = new Label(); if (callbackThumb) {
Label *target_addr_label = new Label();
__ Ldr(PC, target_addr_label); __ Ldr(PC, target_addr_label);
__ Emit(target_addr_label); __ Emit(target_addr_label);
__ Emit((Addr) trampoline); __ Emit((Addr) trampoline);
} else {
__ Mov(IP, (Addr) trampoline);
__ Bx(IP);
}
__ finish(); __ finish();
#undef __ #undef __
......
...@@ -38,6 +38,8 @@ return ENUM_VALUE(InstCodeA64, InstCodeA64::X); \ ...@@ -38,6 +38,8 @@ return ENUM_VALUE(InstCodeA64, InstCodeA64::X); \
#define DEFINE_INST(X) class INST_A64(X) : public InstructionA64<STRUCT_A64(X)> #define DEFINE_INST(X) class INST_A64(X) : public InstructionA64<STRUCT_A64(X)>
#define CAST_A64(X,V) reinterpret_cast<SandHook::AsmA64::INST_A64(X) *>(V)
using namespace SandHook::RegistersA64; using namespace SandHook::RegistersA64;
using namespace SandHook::Asm; using namespace SandHook::Asm;
......
...@@ -11,6 +11,14 @@ ...@@ -11,6 +11,14 @@
using namespace SandHook::Decoder; using namespace SandHook::Decoder;
bool DefaultVisitor::visit(Unit<Base> *unit, void *pc) {
bool res = visitor(unit, pc);
delete unit;
return res;
}
DefaultVisitor::DefaultVisitor(bool (*visitor)(Unit<Base> *, void *)) : visitor(visitor) {}
//do not support now //do not support now
InstDecoder* Disassembler::get(Arch arch) { InstDecoder* Disassembler::get(Arch arch) {
switch (arch) { switch (arch) {
......
...@@ -16,12 +16,28 @@ namespace SandHook { ...@@ -16,12 +16,28 @@ namespace SandHook {
class InstVisitor { class InstVisitor {
public: public:
//need free unit //need free unit
virtual bool visit(Unit<Base>* unit, void* pc) = 0; virtual bool visit(Unit<Base>* unit, void* pc) {
delete unit;
return false;
};
};
class DefaultVisitor : public InstVisitor {
public:
DefaultVisitor(bool (*visitor)(Unit<Base> *, void *));
bool visit(Unit<Base> *unit, void *pc) override;
private:
bool (*visitor)(Unit<Base>*, void*);
}; };
class InstDecoder { class InstDecoder {
public: public:
virtual void decode(void* codeStart, Addr codeLen, InstVisitor& visitor, bool onlyPcRelInst = false) = 0; virtual void decode(void* codeStart, Addr codeLen, InstVisitor& visitor, bool onlyPcRelInst = false) = 0;
inline void decode(void* codeStart, Addr codeLen, bool (*visitor)(Unit<Base>*, void*), bool onlyPcRelInst = false) {
InstVisitor vis = DefaultVisitor(visitor);
decode(codeStart, codeLen, vis, onlyPcRelInst);
};
}; };
......
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