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.
src/main/cpp/assembler/assembler.cpp
src/main/cpp/buffer/code_buffer.cpp
src/main/cpp/utils/platform.cpp
src/main/cpp/hook/hook.cpp
)
......
......@@ -27,6 +27,15 @@ void *AssemblerA64::finish() {
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) {
codeContainer.append(unit);
}
......@@ -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) {
if (memOperand.addr_mode == Offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(LDRSW_UIMM)(rt, memOperand)));
......
......@@ -5,7 +5,7 @@
#ifndef SANDHOOK_NH_ASSEMBLER_A64_H
#define SANDHOOK_NH_ASSEMBLER_A64_H
#include <assembler.h>
#include "assembler.h"
#include "register_a64.h"
#include "inst_arm64.h"
......@@ -22,10 +22,10 @@ namespace SandHook {
void* getPC();
void* finish();
void Emit(U32 data32);
void Emit(U64 data64);
void Emit(Unit<Base>* unit);
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);
......@@ -61,6 +61,8 @@ namespace SandHook {
void Str(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 Pop(RegisterA64& rt);
......
......@@ -23,6 +23,10 @@ void Arm64Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor) {
CASE(MOV_REG)
CASE(ADR_ADRP)
CASE(LDR_LIT)
CASE(LDR_IMM)
CASE(LDR_UIMM)
CASE(LDRSW_IMM)
CASE(LDRSW_UIMM)
CASE(STR_IMM)
CASE(STR_UIMM)
CASE(B_BL)
......
......@@ -300,14 +300,22 @@ A64_LDR_LIT::A64_LDR_LIT(STRUCT_A64(LDR_LIT) &inst) : A64_INST_PC_REL(&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) {}
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() {
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) {
op = OP(inst->op);
if (op == LDR_W) {
......@@ -699,9 +707,9 @@ void A64_LDR_UIMM::assembler() {
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) {}
void A64_LDRSW_IMM::decode(STRUCT_A64(LDR_IMM) *inst) {
......
......@@ -468,7 +468,9 @@ namespace SandHook {
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)
......@@ -476,6 +478,8 @@ namespace SandHook {
Off getImmPCOffset() override;
void onOffsetApply(Off offset) override;
void decode(STRUCT_A64(LDR_LIT) *inst) override;
void assembler() override;
......@@ -729,9 +733,9 @@ namespace SandHook {
public:
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))
......@@ -740,7 +744,7 @@ namespace SandHook {
void decode(STRUCT_A64(LDR_IMM) *inst) override;
void assembler() override;
};
};
class INST_A64(LDRSW_UIMM) : public INST_A64(LDR_UIMM) {
......
......@@ -3,6 +3,7 @@
//
#include "code_relocate_a64.h"
#include "decoder_arm64.h"
#define __ assemblerA64->
......@@ -17,14 +18,23 @@ CodeRelocateA64::CodeRelocateA64(AssemblerA64 &assembler) : CodeRelocate(assembl
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()) {
__ Emit(instruction);
return;
return curPc;
}
switch (instruction->instCode()) {
CASE(B_BL)
......@@ -36,6 +46,7 @@ void CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) throw
default:
__ Emit(instruction);
}
return curPc;
}
IMPL_RELOCATE(B_BL) {
......@@ -133,3 +144,8 @@ IMPL_RELOCATE(LDR_LIT) {
IMPL_RELOCATE(ADR_ADRP) {
__ 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 {
public:
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)
......
......@@ -70,3 +70,14 @@ void CodeContainer::allocBufferFirst(U32 size) {
startPc = reinterpret_cast<Addr>(codeBuffer->getBuffer(size));
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:
return mmapRes;
}
AndroidCodeBuffer::AndroidCodeBuffer() {}
StaticCodeBuffer::StaticCodeBuffer(Addr pc) : pc(pc) {}
......
......@@ -12,6 +12,9 @@ namespace SandHook {
namespace Assembler {
class AndroidCodeBuffer : public CodeBuffer {
public:
AndroidCodeBuffer();
void *getBuffer(U32 bufferSize) override;
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 {
void append(Unit<Base>* unit);
void commit();
Addr size();
virtual ~CodeContainer();
public:
//before commit is virtual address so = 0, after commit is real address
Addr startPc = 0;
......
......@@ -20,7 +20,14 @@ typedef int32_t S32;
typedef int64_t S64;
typedef size_t Addr;
//32bit
#if defined(__i386__) || defined(__arm__)
typedef S32 Off;
//64bit
#elif defined(__aarch64__) || defined(__x86_64__)
typedef S64 Off;
#endif
const int PTR_BYTE = sizeof(void*);
......
......@@ -21,8 +21,8 @@ namespace SandHook {
CodeRelocate(CodeContainer &codeContainer) : codeContainer(&codeContainer) {}
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(Instruction<Base> *instruction, void* toPc) throw(ErrorCodeException) = 0;
virtual void* relocate(void *startPc, Addr len, void *toPc) throw(ErrorCodeException) = 0;
private:
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 @@
#include "sandhook_native.h"
#include "inst_arm64.h"
#include "decoder_arm64.h"
#include "hook.h"
using namespace SandHook::Asm;
using namespace SandHook::Decoder;
using namespace SandHook::Hook;
void (*dosth3Backup)() = nullptr;
bool memUnprotect(Addr addr, Addr len) {
long pagesize = 4096;
......@@ -24,6 +28,24 @@ bool memUnprotect(Addr addr, Addr len) {
void do2() {
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() {
......@@ -76,6 +98,12 @@ Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1)
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