Commit e46299fd authored by swift_gan's avatar swift_gan Committed by swift_gan

almost done

parent ea147c93
...@@ -32,6 +32,7 @@ add_library( # Sets the name of the library. ...@@ -32,6 +32,7 @@ add_library( # Sets the name of the library.
src/main/cpp/assembler/assembler.cpp src/main/cpp/assembler/assembler.cpp
src/main/cpp/buffer/code_buffer.cpp src/main/cpp/buffer/code_buffer.cpp
src/main/cpp/utils/platform.cpp src/main/cpp/utils/platform.cpp
src/main/cpp/hook/hook.cpp
) )
......
...@@ -27,6 +27,15 @@ void *AssemblerA64::finish() { ...@@ -27,6 +27,15 @@ void *AssemblerA64::finish() {
return reinterpret_cast<void *>(codeContainer.startPc); return reinterpret_cast<void *>(codeContainer.startPc);
} }
void AssemblerA64::Emit(U64 data64) {
Emit(reinterpret_cast<Unit<Base>*>(new Data64(data64)));
}
void AssemblerA64::Emit(U32 data32) {
Emit(reinterpret_cast<Unit<Base>*>(new Data32(data32)));
}
void AssemblerA64::Emit(Unit<Base> *unit) { void AssemblerA64::Emit(Unit<Base> *unit) {
codeContainer.append(unit); codeContainer.append(unit);
} }
...@@ -151,6 +160,10 @@ void AssemblerA64::Ldr(RegisterA64 &rt, const MemOperand &memOperand) { ...@@ -151,6 +160,10 @@ void AssemblerA64::Ldr(RegisterA64 &rt, const MemOperand &memOperand) {
} }
} }
void AssemblerA64::Ldr(RegisterA64 &rt, Label &label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDR_LIT)(rt.isX() ? INST_A64(LDR_LIT)::LDR_X : INST_A64(LDR_LIT)::LDR_W, rt, label)));
}
void AssemblerA64::Ldrsw(XRegister &rt, const MemOperand& memOperand) { void AssemblerA64::Ldrsw(XRegister &rt, const MemOperand& memOperand) {
if (memOperand.addr_mode == Offset) { if (memOperand.addr_mode == Offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDRSW_UIMM)(rt, memOperand))); Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDRSW_UIMM)(rt, memOperand)));
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#ifndef SANDHOOK_NH_ASSEMBLER_A64_H #ifndef SANDHOOK_NH_ASSEMBLER_A64_H
#define SANDHOOK_NH_ASSEMBLER_A64_H #define SANDHOOK_NH_ASSEMBLER_A64_H
#include <assembler.h> #include "assembler.h"
#include "register_a64.h" #include "register_a64.h"
#include "inst_arm64.h" #include "inst_arm64.h"
...@@ -22,10 +22,10 @@ namespace SandHook { ...@@ -22,10 +22,10 @@ namespace SandHook {
void* getPC(); void* getPC();
void* finish(); void* finish();
void Emit(U32 data32);
void Emit(U64 data64);
void Emit(Unit<Base>* unit); void Emit(Unit<Base>* unit);
void MoveWide(RegisterA64& rd, INST_A64(MOV_WIDE)::OP op, U64 imme, INST_A64(MOV_WIDE)::Shift shift); void MoveWide(RegisterA64& rd, INST_A64(MOV_WIDE)::OP op, U64 imme, INST_A64(MOV_WIDE)::Shift shift);
void Movz(RegisterA64& rd, U64 imme, INST_A64(MOV_WIDE)::Shift shift); void Movz(RegisterA64& rd, U64 imme, INST_A64(MOV_WIDE)::Shift shift);
...@@ -61,6 +61,8 @@ namespace SandHook { ...@@ -61,6 +61,8 @@ namespace SandHook {
void Str(RegisterA64& rt, const MemOperand& memOperand); void Str(RegisterA64& rt, const MemOperand& memOperand);
void Ldr(RegisterA64& rt, const MemOperand& memOperand); void Ldr(RegisterA64& rt, const MemOperand& memOperand);
void Ldr(RegisterA64& rt, Label& label);
void Ldrsw(XRegister& rt, const MemOperand& memOperand); void Ldrsw(XRegister& rt, const MemOperand& memOperand);
void Pop(RegisterA64& rt); void Pop(RegisterA64& rt);
......
...@@ -23,6 +23,10 @@ void Arm64Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor) { ...@@ -23,6 +23,10 @@ void Arm64Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor) {
CASE(MOV_REG) CASE(MOV_REG)
CASE(ADR_ADRP) CASE(ADR_ADRP)
CASE(LDR_LIT) CASE(LDR_LIT)
CASE(LDR_IMM)
CASE(LDR_UIMM)
CASE(LDRSW_IMM)
CASE(LDRSW_UIMM)
CASE(STR_IMM) CASE(STR_IMM)
CASE(STR_UIMM) CASE(STR_UIMM)
CASE(B_BL) CASE(B_BL)
......
...@@ -300,14 +300,22 @@ A64_LDR_LIT::A64_LDR_LIT(STRUCT_A64(LDR_LIT) &inst) : A64_INST_PC_REL(&inst) { ...@@ -300,14 +300,22 @@ A64_LDR_LIT::A64_LDR_LIT(STRUCT_A64(LDR_LIT) &inst) : A64_INST_PC_REL(&inst) {
decode(&inst); decode(&inst);
} }
A64_LDR_LIT::A64_LDR_LIT(A64_LDR_LIT::OP op, RegisterA64 &rt, Off offset) : op(op), rt(&rt),
A64_LDR_LIT::A64_LDR_LIT(A64_LDR_LIT::OP op, RegisterA64 *rt, Off offset) : op(op), rt(rt),
offset(offset) {} offset(offset) {}
A64_LDR_LIT::A64_LDR_LIT(A64_LDR_LIT::OP op, RegisterA64 &rt, Label& label) : op(op), rt(&rt) {
bindLabel(label);
}
Off A64_LDR_LIT::getImmPCOffset() { Off A64_LDR_LIT::getImmPCOffset() {
return signExtend64(19 + 2, COMBINE(get()->imm19, 0b00, 2)); return signExtend64(19 + 2, COMBINE(get()->imm19, 0b00, 2));
} }
void A64_LDR_LIT::onOffsetApply(Off offset) {
this->offset = offset;
get()->imm19 = TruncateToUint19(offset >> 2);
}
void A64_LDR_LIT::decode(STRUCT_A64(LDR_LIT) *inst) { void A64_LDR_LIT::decode(STRUCT_A64(LDR_LIT) *inst) {
op = OP(inst->op); op = OP(inst->op);
if (op == LDR_W) { if (op == LDR_W) {
...@@ -699,9 +707,9 @@ void A64_LDR_UIMM::assembler() { ...@@ -699,9 +707,9 @@ void A64_LDR_UIMM::assembler() {
A64_LDRSW_IMM::A64_LDRSW_IMM() {} A64_LDRSW_IMM::A64_LDRSW_IMM() {}
A64_LDRSW_IMM::A64_LDRSW_IMM(INST_A64(LDRSW_IMM) &inst) : A64_LDR_IMM(inst) {} A64_LDRSW_IMM::A64_LDRSW_IMM(STRUCT_A64(LDRSW_IMM) &inst) : A64_LDR_IMM(inst) {}
A64_LDRSW_IMM::A64_LDRSW_IMM(XRegister &rt, const MemOperand &operand) : A64_LDR_IMM(rt, A64_LDRSW_IMM::A64_LDRSW_IMM(RegisterA64 &rt, const MemOperand &operand) : A64_LDR_IMM(rt,
operand) {} operand) {}
void A64_LDRSW_IMM::decode(STRUCT_A64(LDR_IMM) *inst) { void A64_LDRSW_IMM::decode(STRUCT_A64(LDR_IMM) *inst) {
......
...@@ -468,7 +468,9 @@ namespace SandHook { ...@@ -468,7 +468,9 @@ namespace SandHook {
A64_LDR_LIT(STRUCT_A64(LDR_LIT) &inst); A64_LDR_LIT(STRUCT_A64(LDR_LIT) &inst);
A64_LDR_LIT(OP op, RegisterA64 *rt, Off offset); A64_LDR_LIT(OP op, RegisterA64 &rt, Off offset);
A64_LDR_LIT(OP op, RegisterA64 &rt, Label& label);
DEFINE_IS(LDR_LIT) DEFINE_IS(LDR_LIT)
...@@ -476,6 +478,8 @@ namespace SandHook { ...@@ -476,6 +478,8 @@ namespace SandHook {
Off getImmPCOffset() override; Off getImmPCOffset() override;
void onOffsetApply(Off offset) override;
void decode(STRUCT_A64(LDR_LIT) *inst) override; void decode(STRUCT_A64(LDR_LIT) *inst) override;
void assembler() override; void assembler() override;
...@@ -729,9 +733,9 @@ namespace SandHook { ...@@ -729,9 +733,9 @@ namespace SandHook {
public: public:
A64_LDRSW_IMM(); A64_LDRSW_IMM();
A64_LDRSW_IMM(INST_A64(LDRSW_IMM) &inst); A64_LDRSW_IMM(STRUCT_A64(LDRSW_IMM) &inst);
A64_LDRSW_IMM(XRegister &rt, const MemOperand &operand); A64_LDRSW_IMM(RegisterA64 &rt, const MemOperand &operand);
DEFINE_IS_EXT(LDRSW_IMM, TEST_INST_FIELD(opcode, OPCODE_A64(LDRSW_IMM)) && TEST_INST_FIELD(size, Size32)) DEFINE_IS_EXT(LDRSW_IMM, TEST_INST_FIELD(opcode, OPCODE_A64(LDRSW_IMM)) && TEST_INST_FIELD(size, Size32))
...@@ -740,7 +744,7 @@ namespace SandHook { ...@@ -740,7 +744,7 @@ namespace SandHook {
void decode(STRUCT_A64(LDR_IMM) *inst) override; void decode(STRUCT_A64(LDR_IMM) *inst) override;
void assembler() override; void assembler() override;
}; };
class INST_A64(LDRSW_UIMM) : public INST_A64(LDR_UIMM) { class INST_A64(LDRSW_UIMM) : public INST_A64(LDR_UIMM) {
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// //
#include "code_relocate_a64.h" #include "code_relocate_a64.h"
#include "decoder_arm64.h"
#define __ assemblerA64-> #define __ assemblerA64->
...@@ -17,14 +18,23 @@ CodeRelocateA64::CodeRelocateA64(AssemblerA64 &assembler) : CodeRelocate(assembl ...@@ -17,14 +18,23 @@ CodeRelocateA64::CodeRelocateA64(AssemblerA64 &assembler) : CodeRelocate(assembl
this->assemblerA64 = &assembler; this->assemblerA64 = &assembler;
} }
void CodeRelocateA64::relocate(void *startPc, void *toPc, Addr len) throw(ErrorCodeException) { void* CodeRelocateA64::relocate(void *startPc, Addr len, void *toPc = nullptr) throw(ErrorCodeException) {
assemblerA64->allocBufferFirst(static_cast<U32>(len * 8));
void* curPc = assemblerA64->getPC();
Arm64Decoder decoder = Arm64Decoder();
if (toPc == nullptr) {
decoder.decode(startPc, len, *this);
} else {
//TODO
}
return curPc;
} }
void CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) { void* CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) {
void* curPc = assemblerA64->getPC();
if (!instruction->pcRelate()) { if (!instruction->pcRelate()) {
__ Emit(instruction); __ Emit(instruction);
return; return curPc;
} }
switch (instruction->instCode()) { switch (instruction->instCode()) {
CASE(B_BL) CASE(B_BL)
...@@ -36,6 +46,7 @@ void CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) throw ...@@ -36,6 +46,7 @@ void CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) throw
default: default:
__ Emit(instruction); __ Emit(instruction);
} }
return curPc;
} }
IMPL_RELOCATE(B_BL) { IMPL_RELOCATE(B_BL) {
...@@ -133,3 +144,8 @@ IMPL_RELOCATE(LDR_LIT) { ...@@ -133,3 +144,8 @@ IMPL_RELOCATE(LDR_LIT) {
IMPL_RELOCATE(ADR_ADRP) { IMPL_RELOCATE(ADR_ADRP) {
__ Mov(*inst->rd, inst->getImmPCOffsetTarget()); __ Mov(*inst->rd, inst->getImmPCOffsetTarget());
} }
bool CodeRelocateA64::visit(Unit<Base> *unit, void *pc) {
relocate(reinterpret_cast<Instruction<Base> *>(unit), assemblerA64->getPC());
return true;
}
...@@ -20,9 +20,11 @@ namespace SandHook { ...@@ -20,9 +20,11 @@ namespace SandHook {
public: public:
CodeRelocateA64(AssemblerA64 &assembler); CodeRelocateA64(AssemblerA64 &assembler);
void relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) override; void* relocate(Instruction<Base> *instruction, void *toPc) throw(ErrorCodeException) override;
void relocate(void *startPc, void *toPc, Addr len) throw(ErrorCodeException) override; void* relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) override;
bool visit(Unit<Base> *unit, void *pc) override;
DEFINE_RELOCATE(B_BL) DEFINE_RELOCATE(B_BL)
......
...@@ -70,3 +70,14 @@ void CodeContainer::allocBufferFirst(U32 size) { ...@@ -70,3 +70,14 @@ void CodeContainer::allocBufferFirst(U32 size) {
startPc = reinterpret_cast<Addr>(codeBuffer->getBuffer(size)); startPc = reinterpret_cast<Addr>(codeBuffer->getBuffer(size));
curPc = startPc; curPc = startPc;
} }
CodeContainer::~CodeContainer() {
std::list<Unit<Base>*>::iterator unit;
for(unit = units.begin();unit != units.end(); ++unit) {
delete (*unit);
}
}
Addr CodeContainer::size() {
return curPc - startPc;
}
...@@ -37,8 +37,7 @@ label_alloc_new_space: ...@@ -37,8 +37,7 @@ label_alloc_new_space:
return mmapRes; return mmapRes;
} }
AndroidCodeBuffer::AndroidCodeBuffer() {}
StaticCodeBuffer::StaticCodeBuffer(Addr pc) : pc(pc) {} StaticCodeBuffer::StaticCodeBuffer(Addr pc) : pc(pc) {}
......
...@@ -12,6 +12,9 @@ namespace SandHook { ...@@ -12,6 +12,9 @@ namespace SandHook {
namespace Assembler { namespace Assembler {
class AndroidCodeBuffer : public CodeBuffer { class AndroidCodeBuffer : public CodeBuffer {
public: public:
AndroidCodeBuffer();
void *getBuffer(U32 bufferSize) override; void *getBuffer(U32 bufferSize) override;
protected: protected:
......
//
// Created by swift on 2019/5/14.
//
#include "hook.h"
#include "../buffer/code_buffer.h"
#include "../../../../../hooklib/src/main/cpp/utils/lock.h"
using namespace SandHook::Hook;
using namespace SandHook::Decoder;
using namespace SandHook::Asm;
using namespace SandHook::Assembler;
#include "assembler_a64.h"
#include "../archs/arm64/relocate/code_relocate_a64.h"
AndroidCodeBuffer* backupBuffer = new AndroidCodeBuffer();
void *InlineHookArm64Android::inlineHook(void *origin, void *replace) {
AutoLock lock(hookLock);
void* backup = nullptr;
AssemblerA64 assemblerBackup(backupBuffer);
CodeContainer* codeContainerBackup = &assemblerBackup.codeContainer;
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;
}
...@@ -37,6 +37,10 @@ namespace SandHook { ...@@ -37,6 +37,10 @@ namespace SandHook {
void append(Unit<Base>* unit); void append(Unit<Base>* unit);
void commit(); void commit();
Addr size();
virtual ~CodeContainer();
public: public:
//before commit is virtual address so = 0, after commit is real address //before commit is virtual address so = 0, after commit is real address
Addr startPc = 0; Addr startPc = 0;
......
...@@ -20,7 +20,14 @@ typedef int32_t S32; ...@@ -20,7 +20,14 @@ typedef int32_t S32;
typedef int64_t S64; typedef int64_t S64;
typedef size_t Addr; typedef size_t Addr;
//32bit
#if defined(__i386__) || defined(__arm__)
typedef S32 Off;
//64bit
#elif defined(__aarch64__) || defined(__x86_64__)
typedef S64 Off; typedef S64 Off;
#endif
const int PTR_BYTE = sizeof(void*); const int PTR_BYTE = sizeof(void*);
......
...@@ -21,8 +21,8 @@ namespace SandHook { ...@@ -21,8 +21,8 @@ namespace SandHook {
CodeRelocate(CodeContainer &codeContainer) : codeContainer(&codeContainer) {} CodeRelocate(CodeContainer &codeContainer) : codeContainer(&codeContainer) {}
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, void* toPc, Addr len) throw(ErrorCodeException) = 0; virtual void* relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) = 0;
private: private:
CodeContainer* codeContainer; CodeContainer* codeContainer;
......
//
// Created by swift on 2019/5/14.
//
#ifndef SANDHOOK_NH_HOOK_H
#define SANDHOOK_NH_HOOK_H
#include <mutex>
#include <hook.h>
#include <decoder.h>
#include "hook.h"
#include "assembler.h"
#include "code_relocate.h"
namespace SandHook {
namespace Hook {
class InlineHook {
public:
//return == backup method
virtual void* inlineHook(void* origin, void* replace) = 0;
};
class InlineHookArm64Android : InlineHook {
public:
void *inlineHook(void *origin, void *replace) override;
protected:
std::mutex* hookLock = new std::mutex();
};
}
}
#endif //SANDHOOK_NH_HOOK_H
...@@ -7,9 +7,13 @@ ...@@ -7,9 +7,13 @@
#include "sandhook_native.h" #include "sandhook_native.h"
#include "inst_arm64.h" #include "inst_arm64.h"
#include "decoder_arm64.h" #include "decoder_arm64.h"
#include "hook.h"
using namespace SandHook::Asm; using namespace SandHook::Asm;
using namespace SandHook::Decoder; using namespace SandHook::Decoder;
using namespace SandHook::Hook;
void (*dosth3Backup)() = nullptr;
bool memUnprotect(Addr addr, Addr len) { bool memUnprotect(Addr addr, Addr len) {
long pagesize = 4096; long pagesize = 4096;
...@@ -24,6 +28,24 @@ bool memUnprotect(Addr addr, Addr len) { ...@@ -24,6 +28,24 @@ bool memUnprotect(Addr addr, Addr len) {
void do2() { void do2() {
int a = 1 + 1; int a = 1 + 1;
int b = 1 + 1;
int c = 1 + 1;
int d = 1 + 1;
}
void do3() {
int a = 1 + 1;
int b = 1 + 1;
int c = 1 + 1;
int d = a + b + c;
}
void do3replace() {
int a = 1 + 1;
int b = 1 + 1;
int c = 1 + 1;
int d = 1 + 1;
dosth3Backup();
} }
void do1() { void do1() {
...@@ -76,6 +98,12 @@ Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1) ...@@ -76,6 +98,12 @@ Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1)
arm64Decoder.decode(reinterpret_cast<void *>(do1), 4 * 8, visitor); arm64Decoder.decode(reinterpret_cast<void *>(do1), 4 * 8, visitor);
InlineHookArm64Android inlineHookArm64Android = InlineHookArm64Android();
dosth3Backup = reinterpret_cast<void (*)()>(inlineHookArm64Android.inlineHook(
reinterpret_cast<void *>(do3),
reinterpret_cast<void *>(do3replace)));
do3();
} }
\ 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