Commit 9bdcf2b6 authored by swift_gan's avatar swift_gan Committed by swift_gan

finish a64decoder

parent 2f998a19
...@@ -53,3 +53,7 @@ void SandHook::Assembler::AssemblerA64::Movn(RegisterA64 &rd, U64 imme, ...@@ -53,3 +53,7 @@ void SandHook::Assembler::AssemblerA64::Movn(RegisterA64 &rd, U64 imme,
INST_A64(MOV_WIDE)::Shift shift) { INST_A64(MOV_WIDE)::Shift shift) {
MoveWide(rd, INST_A64(MOV_WIDE)::MOV_WideOp_N, imme, shift); MoveWide(rd, INST_A64(MOV_WIDE)::MOV_WideOp_N, imme, shift);
} }
void SandHook::Assembler::AssemblerA64::Emit(Unit<Base> &unit) {
codeContainer.append(&unit);
}
...@@ -18,6 +18,10 @@ namespace SandHook { ...@@ -18,6 +18,10 @@ namespace SandHook {
AssemblerA64(CodeBuffer* codeBuffer); AssemblerA64(CodeBuffer* codeBuffer);
void* finish(); void* finish();
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);
...@@ -28,6 +32,8 @@ namespace SandHook { ...@@ -28,6 +32,8 @@ namespace SandHook {
void Mov(XRegister& rd, U64 imme); void Mov(XRegister& rd, U64 imme);
private: private:
CodeContainer codeContainer = CodeContainer(nullptr); CodeContainer codeContainer = CodeContainer(nullptr);
}; };
......
...@@ -2,4 +2,45 @@ ...@@ -2,4 +2,45 @@
// Created by swift on 2019/5/6. // Created by swift on 2019/5/6.
// //
#include <inst_arm64.h>
#include "decoder_arm64.h" #include "decoder_arm64.h"
using namespace SandHook::Decoder;
#define CASE(X) \
if (IS_OPCODE(*pc, X)) { \
STRUCT_A64(X) *s = reinterpret_cast<STRUCT_A64(X) *>(pc); \
unit = reinterpret_cast<Unit<Base> *>(new INST_A64(X)(*s)); \
goto label_matched; \
}
void Arm64Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor) {
InstA64 *pc = reinterpret_cast<InstA64 *>(codeStart);
Addr endAddr = (Addr) codeStart + codeLen;
Unit<Base>* unit = nullptr;
while((Addr) pc < endAddr) {
CASE(MOV_WIDE)
CASE(MOV_REG)
CASE(ADR_ADRP)
CASE(LDR_LIT)
CASE(STR_IMM)
CASE(STR_UIMM)
CASE(B_BL)
CASE(B_COND)
CASE(BR_BLR_RET)
CASE(CBZ_CBNZ)
CASE(TBZ_TBNZ)
CASE(SUB_EXT_REG)
CASE(SVC)
CASE(EXCEPTION_GEN)
label_matched:
if (unit == nullptr) {
unit = reinterpret_cast<Unit<Base> *>(new A64_UNKNOW(*reinterpret_cast<STRUCT_A64(UNKNOW) *>(pc)));
}
if (!visitor.visit(unit, pc)) {
break;
}
pc = reinterpret_cast<InstA64 *>((Addr)pc + unit->size());
unit = nullptr;
}
}
...@@ -10,8 +10,9 @@ ...@@ -10,8 +10,9 @@
namespace SandHook { namespace SandHook {
namespace Decoder { namespace Decoder {
class Arm64Decoder { class Arm64Decoder : public InstDecoder {
public:
void decode(void *codeStart, Addr codeLen, InstVisitor &visitor) override;
}; };
} }
......
...@@ -16,13 +16,9 @@ U32 InstructionA64<InstStruct>::size() { ...@@ -16,13 +16,9 @@ U32 InstructionA64<InstStruct>::size() {
//Unknow //Unknow
A64_UNKNOW::A64_UNKNOW(A64_STRUCT_UNKNOW *inst) : InstructionA64(inst) {
} A64_UNKNOW::A64_UNKNOW(STRUCT_A64(UNKNOW) &inst) : InstructionA64(&inst) {
A64_UNKNOW::A64_UNKNOW(STRUCT_A64(UNKNOW) &inst) {
inst_backup = inst; inst_backup = inst;
this->set(&inst_backup);
} }
//PC Rel Inst //PC Rel Inst
...@@ -48,8 +44,8 @@ bool A64_INST_PC_REL<Inst>::pcRelate() { ...@@ -48,8 +44,8 @@ bool A64_INST_PC_REL<Inst>::pcRelate() {
A64_ADR_ADRP::A64_ADR_ADRP() {} A64_ADR_ADRP::A64_ADR_ADRP() {}
A64_ADR_ADRP::A64_ADR_ADRP(STRUCT_A64(ADR_ADRP) *inst) : A64_INST_PC_REL(inst) { A64_ADR_ADRP::A64_ADR_ADRP(STRUCT_A64(ADR_ADRP) &inst) : A64_INST_PC_REL(&inst) {
decode(inst); decode(&inst);
} }
Off A64_ADR_ADRP::getImmPCOffset() { Off A64_ADR_ADRP::getImmPCOffset() {
...@@ -120,8 +116,8 @@ void A64_MOV_WIDE::decode(STRUCT_A64(MOV_WIDE) *inst) { ...@@ -120,8 +116,8 @@ void A64_MOV_WIDE::decode(STRUCT_A64(MOV_WIDE) *inst) {
A64_B_BL::A64_B_BL() {} A64_B_BL::A64_B_BL() {}
A64_B_BL::A64_B_BL(STRUCT_A64(B_BL) *inst) : A64_INST_PC_REL(inst) { A64_B_BL::A64_B_BL(STRUCT_A64(B_BL) &inst) : A64_INST_PC_REL(&inst) {
decode(inst); decode(&inst);
} }
A64_B_BL::A64_B_BL(A64_B_BL::OP op, Off offset) : op(op), offset(offset) { A64_B_BL::A64_B_BL(A64_B_BL::OP op, Off offset) : op(op), offset(offset) {
...@@ -157,8 +153,8 @@ void A64_B_BL::assembler() { ...@@ -157,8 +153,8 @@ void A64_B_BL::assembler() {
A64_CBZ_CBNZ::A64_CBZ_CBNZ() {} A64_CBZ_CBNZ::A64_CBZ_CBNZ() {}
A64_CBZ_CBNZ::A64_CBZ_CBNZ(STRUCT_A64(CBZ_CBNZ) *inst) : A64_INST_PC_REL(inst) { A64_CBZ_CBNZ::A64_CBZ_CBNZ(STRUCT_A64(CBZ_CBNZ) &inst) : A64_INST_PC_REL(&inst) {
decode(inst); decode(&inst);
} }
A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Off offset, RegisterA64 *rt) : op(op), A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Off offset, RegisterA64 *rt) : op(op),
...@@ -192,8 +188,8 @@ void A64_CBZ_CBNZ::assembler() { ...@@ -192,8 +188,8 @@ void A64_CBZ_CBNZ::assembler() {
A64_B_COND::A64_B_COND() {} A64_B_COND::A64_B_COND() {}
A64_B_COND::A64_B_COND(STRUCT_A64(B_COND) *inst) : A64_INST_PC_REL(inst) { A64_B_COND::A64_B_COND(STRUCT_A64(B_COND) &inst) : A64_INST_PC_REL(&inst) {
decode(inst); decode(&inst);
} }
A64_B_COND::A64_B_COND(Condition condition, Off offset) : condition(condition), offset(offset) {} A64_B_COND::A64_B_COND(Condition condition, Off offset) : condition(condition), offset(offset) {}
...@@ -257,8 +253,8 @@ void A64_TBZ_TBNZ::assembler() { ...@@ -257,8 +253,8 @@ void A64_TBZ_TBNZ::assembler() {
A64_LDR_LIT::A64_LDR_LIT() {} A64_LDR_LIT::A64_LDR_LIT() {}
A64_LDR_LIT::A64_LDR_LIT(STRUCT_A64(LDR_LIT) *inst) : A64_INST_PC_REL(inst) { A64_LDR_LIT::A64_LDR_LIT(STRUCT_A64(LDR_LIT) &inst) : A64_INST_PC_REL(&inst) {
decode(inst); decode(&inst);
} }
...@@ -528,3 +524,7 @@ void A64_EXCEPTION_GEN::assembler() { ...@@ -528,3 +524,7 @@ void A64_EXCEPTION_GEN::assembler() {
A64_SVC::A64_SVC(U16 imme) : A64_EXCEPTION_GEN(XXC, EL1,imme) {} A64_SVC::A64_SVC(U16 imme) : A64_EXCEPTION_GEN(XXC, EL1,imme) {}
A64_SVC::A64_SVC() {}
A64_SVC::A64_SVC(STRUCT_A64(SVC) &inst) : A64_EXCEPTION_GEN(inst) {}
...@@ -179,7 +179,7 @@ namespace SandHook { ...@@ -179,7 +179,7 @@ namespace SandHook {
class INST_A64(UNKNOW) : public InstructionA64<STRUCT_A64(UNKNOW)> { class INST_A64(UNKNOW) : public InstructionA64<STRUCT_A64(UNKNOW)> {
public: public:
A64_UNKNOW(STRUCT_A64(UNKNOW) *inst);
A64_UNKNOW(STRUCT_A64(UNKNOW) &inst); A64_UNKNOW(STRUCT_A64(UNKNOW) &inst);
DEFINE_INST_CODE(UNKNOW) DEFINE_INST_CODE(UNKNOW)
...@@ -221,7 +221,7 @@ namespace SandHook { ...@@ -221,7 +221,7 @@ namespace SandHook {
A64_ADR_ADRP(); A64_ADR_ADRP();
A64_ADR_ADRP(STRUCT_A64(ADR_ADRP) *inst); A64_ADR_ADRP(STRUCT_A64(ADR_ADRP) &inst);
A64_ADR_ADRP(OP op, RegisterA64 *rd, S64 imme); A64_ADR_ADRP(OP op, RegisterA64 *rd, S64 imme);
...@@ -320,7 +320,7 @@ namespace SandHook { ...@@ -320,7 +320,7 @@ namespace SandHook {
A64_B_BL(); A64_B_BL();
A64_B_BL(STRUCT_A64(B_BL) *inst); A64_B_BL(STRUCT_A64(B_BL) &inst);
A64_B_BL(OP op, Off offset); A64_B_BL(OP op, Off offset);
...@@ -363,7 +363,7 @@ namespace SandHook { ...@@ -363,7 +363,7 @@ namespace SandHook {
A64_CBZ_CBNZ(); A64_CBZ_CBNZ();
A64_CBZ_CBNZ(STRUCT_A64(CBZ_CBNZ) *inst); A64_CBZ_CBNZ(STRUCT_A64(CBZ_CBNZ) &inst);
A64_CBZ_CBNZ(OP op, Off offset, RegisterA64 *rt); A64_CBZ_CBNZ(OP op, Off offset, RegisterA64 *rt);
...@@ -390,7 +390,7 @@ namespace SandHook { ...@@ -390,7 +390,7 @@ namespace SandHook {
public: public:
A64_B_COND(); A64_B_COND();
A64_B_COND(STRUCT_A64(B_COND) *inst); A64_B_COND(STRUCT_A64(B_COND) &inst);
A64_B_COND(Condition condition, Off offset); A64_B_COND(Condition condition, Off offset);
...@@ -454,7 +454,7 @@ namespace SandHook { ...@@ -454,7 +454,7 @@ namespace SandHook {
A64_LDR_LIT(); A64_LDR_LIT();
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);
...@@ -669,6 +669,10 @@ namespace SandHook { ...@@ -669,6 +669,10 @@ namespace SandHook {
public: public:
A64_SVC(U16 imme); A64_SVC(U16 imme);
A64_SVC();
A64_SVC(STRUCT_A64(SVC) &inst);
DEFINE_IS_EXT(EXCEPTION_GEN, TEST_INST_OPCODE(EXCEPTION_GEN, 1) && TEST_INST_OPCODE(EXCEPTION_GEN, 2) && TEST_INST_FIELD(op, XXC) && TEST_INST_FIELD(ll, EL1)) DEFINE_IS_EXT(EXCEPTION_GEN, TEST_INST_OPCODE(EXCEPTION_GEN, 1) && TEST_INST_OPCODE(EXCEPTION_GEN, 2) && TEST_INST_FIELD(op, XXC) && TEST_INST_FIELD(ll, EL1))
DEFINE_INST_CODE(SVC) DEFINE_INST_CODE(SVC)
......
...@@ -14,26 +14,6 @@ ...@@ -14,26 +14,6 @@
#define DEFINE_OPCODE(X, V) const U32 OPCODE_A64(X) = V; #define DEFINE_OPCODE(X, V) const U32 OPCODE_A64(X) = V;
#define DEFINE_STRUCT_A64(X) struct STRUCT_A64(X) : public Base #define DEFINE_STRUCT_A64(X) struct STRUCT_A64(X) : public Base
enum InstructionFields {
// Registers.
kRdShift = 0,
kRdBits = 5,
kRnShift = 5,
kRnBits = 5,
kRaShift = 10,
kRaBits = 5,
kRmShift = 16,
kRmBits = 5,
kRtShift = 0,
kRtBits = 5,
kRt2Shift = 10,
kRt2Bits = 5,
kRsShift = 16,
kRsBits = 5,
};
enum ImmBranchType { enum ImmBranchType {
UnknownBranchType = 0, UnknownBranchType = 0,
CondBranchType = 1, CondBranchType = 1,
...@@ -224,5 +204,9 @@ DEFINE_STRUCT_A64(EXCEPTION_GEN) { ...@@ -224,5 +204,9 @@ DEFINE_STRUCT_A64(EXCEPTION_GEN) {
InstA64 opcode1:8; InstA64 opcode1:8;
}; };
struct STRUCT_A64(SVC) : STRUCT_A64(EXCEPTION_GEN) {
};
#endif //SANDHOOK_NH_INST_AARCH64_H #endif //SANDHOOK_NH_INST_AARCH64_H
...@@ -15,12 +15,13 @@ namespace SandHook { ...@@ -15,12 +15,13 @@ namespace SandHook {
class InstVisitor { class InstVisitor {
public: public:
virtual bool visit(Instruction<void>* inst, Addr offset, Addr length) = 0; //need free unit
virtual bool visit(Unit<Base>* unit, void* pc) = 0;
}; };
class InstDecoder { class InstDecoder {
public: public:
virtual void decode(void* codeStart, Addr codeLen, InstVisitor* visitor) = 0; virtual void decode(void* codeStart, Addr codeLen, InstVisitor& visitor) = 0;
}; };
......
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
#include <sys/mman.h> #include <sys/mman.h>
#include "sandhook_native.h" #include "sandhook_native.h"
#include "inst_arm64.h" #include "inst_arm64.h"
#include "decoder_arm64.h"
using namespace SandHook::Asm;
using namespace SandHook::Decoder;
bool memUnprotect(Addr addr, Addr len) { bool memUnprotect(Addr addr, Addr len) {
long pagesize = 4096; long pagesize = 4096;
...@@ -26,6 +30,12 @@ void do1() { ...@@ -26,6 +30,12 @@ void do1() {
do2(); do2();
} }
class Visitor : public InstVisitor {
bool visit(Unit<Base> *unit, void *pc) override {
return true;
}
};
extern "C" extern "C"
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1) { Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1) {
...@@ -40,7 +50,7 @@ Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1) ...@@ -40,7 +50,7 @@ Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1)
if (IS_OPCODE(*codebl, B_BL)) { if (IS_OPCODE(*codebl, B_BL)) {
//decode //decode
A64_B_BL a64bl(reinterpret_cast<STRUCT_A64(B_BL)*>(codebl)); A64_B_BL a64bl(*reinterpret_cast<STRUCT_A64(B_BL)*>(codebl));
Off off = a64bl.offset; Off off = a64bl.offset;
void (*dosth2)() =reinterpret_cast<void (*)()>(a64bl.getImmPCOffsetTarget()); void (*dosth2)() =reinterpret_cast<void (*)()>(a64bl.getImmPCOffsetTarget());
dosth2(); dosth2();
...@@ -60,4 +70,12 @@ Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1) ...@@ -60,4 +70,12 @@ Java_com_swift_sandhook_nativehook_NativeHook_test(JNIEnv *env, jclass jclass1)
str.get(); str.get();
} }
Arm64Decoder arm64Decoder = Arm64Decoder();
Visitor visitor = Visitor();
arm64Decoder.decode(reinterpret_cast<void *>(do1), 4 * 8, visitor);
} }
\ 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