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

[NativeHook]add CBZ LDR

parent 577759ea
......@@ -12,7 +12,9 @@ enum InstCodeA32 {
enum InstCodeT16 {
B,
B_COND,
BX_BLX
BX_BLX,
CBZ_CBNZ,
LDR_LIT
};
enum InstCodeT32 {
......
......@@ -38,7 +38,7 @@ DEFINE_STRUCT_T16(B) {
DEFINE_OPCODE_T16(B_COND, 0b1101)
DEFINE_STRUCT_T16(B_COND) {
InstT16 imm8;
InstT16 imm8:8;
InstT16 cond:4;
InstT16 opcode:4;
};
......@@ -53,6 +53,27 @@ DEFINE_STRUCT_T16(BX_BLX) {
InstT16 opcode1:8;
};
DEFINE_OPCODE_T16(CBZ_CBNZ_1, 0b1011)
DEFINE_OPCODE_T16(CBZ_CBNZ_2, 0b0)
DEFINE_OPCODE_T16(CBZ_CBNZ_3, 0b1)
DEFINE_STRUCT_T16(CBZ_CBNZ) {
InstT16 rn:3;
InstT16 imm5:5;
InstT16 opcode3:1;
InstT16 i:1;
InstT16 opcode2:1;
InstT16 op:1;
InstT16 opcode1:4;
};
DEFINE_OPCODE_T16(LDR_LIT, 0b01001)
DEFINE_STRUCT_T16(LDR_LIT) {
InstT16 imm8:8;
InstT16 rt:3;
InstT16 opcode:5;
};
#endif //SANDHOOK_NH_INST_STRUCT_T16_H
......@@ -13,6 +13,8 @@
using namespace SandHook::AsmA32;
//B
T16_B::T16_B() {}
T16_B::T16_B(T16_STRUCT_B *inst) : T16_INST_PC_REL(inst) {
......@@ -44,6 +46,8 @@ void T16_B::onOffsetApply(Off offset) {
}
//B Cond
T16_B_COND::T16_B_COND() {}
T16_B_COND::T16_B_COND(STRUCT_T16(B_COND) *inst) : T16_INST_PC_REL(inst) {
......@@ -77,6 +81,14 @@ Off T16_B_COND::getImmPCOffset() {
}
//BX BLX
T16_BX_BLX::T16_BX_BLX(T16_BX_BLX::OP op, RegisterA32 &rm) : op(op), rm(&rm) {}
T16_BX_BLX::T16_BX_BLX(T16_STRUCT_BX_BLX *inst) : T16_INST_PC_REL(inst) {
decode(inst);
}
void T16_BX_BLX::decode(STRUCT_T16(BX_BLX) *inst) {
DECODE_OP;
DECODE_RM(Reg);
......@@ -88,3 +100,77 @@ void T16_BX_BLX::assembler() {
ENCODE_OP;
ENCODE_RM;
}
//CBZ CBNZ
T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_STRUCT_CBZ_CBNZ *inst) : T16_INST_PC_REL(inst) {
decode(inst);
}
T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_CBZ_CBNZ::OP op, Off offset, RegisterA32 &rn) : op(op), offset(offset),
rn(&rn) {}
T16_CBZ_CBNZ::T16_CBZ_CBNZ(T16_CBZ_CBNZ::OP op, Label& label, RegisterA32 &rn) : op(op),
rn(&rn) {
bindLabel(label);
}
Off T16_CBZ_CBNZ::getImmPCOffset() {
return COMBINE(get()->i, get()->imm5, 5) << 2;
}
void T16_CBZ_CBNZ::decode(T16_STRUCT_CBZ_CBNZ *inst) {
offset = getImmPCOffset();
DECODE_RN(Reg);
DECODE_OP;
}
void T16_CBZ_CBNZ::assembler() {
SET_OPCODE_MULTI(CBZ_CBNZ, 1);
SET_OPCODE_MULTI(CBZ_CBNZ, 2);
SET_OPCODE_MULTI(CBZ_CBNZ, 3);
ENCODE_OP;
ENCODE_RN;
ENCODE_OFFSET(5, 2);
}
void T16_CBZ_CBNZ::onOffsetApply(Off offset) {
this->offset = offset;
ENCODE_OFFSET(5, 2);
}
//LDR_LIT
T16_LDR_LIT::T16_LDR_LIT(T16_STRUCT_LDR_LIT *inst) : T16_INST_PC_REL(inst) {
decode(inst);
}
T16_LDR_LIT::T16_LDR_LIT(Off offset, RegisterA32 &rt) : offset(offset), rt(&rt) {
}
Off T16_LDR_LIT::getImmPCOffset() {
return DECODE_OFFSET(8, 2);
}
Addr T16_LDR_LIT::getImmPCOffsetTarget() {
return RoundDown((Addr) getPC() + offset, 4);
}
void T16_LDR_LIT::onOffsetApply(Off offset) {
this->offset = offset;
ENCODE_OFFSET(8, 2);
}
void T16_LDR_LIT::decode(T16_STRUCT_LDR_LIT *inst) {
DECODE_RT(Reg);
offset = getImmPCOffset();
}
void T16_LDR_LIT::assembler() {
SET_OPCODE(LDR_LIT);
ENCODE_RT;
}
......@@ -163,7 +163,14 @@ namespace SandHook {
BLX = 0b1
};
private:
T16_BX_BLX(T16_STRUCT_BX_BLX *inst);
T16_BX_BLX(OP op, RegisterA32 &rm);
DEFINE_IS_EXT(BX_BLX, TEST_INST_OPCODE(BX_BLX, 1) && TEST_INST_OPCODE(BX_BLX, 2))
DEFINE_INST_CODE(BX_BLX)
void decode(T16_STRUCT_BX_BLX *inst) override;
void assembler() override;
......@@ -173,6 +180,67 @@ namespace SandHook {
RegisterA32* rm;
};
class INST_T16(CBZ_CBNZ) : public T16_INST_PC_REL<STRUCT_T16(CBZ_CBNZ)> {
public:
enum OP {
CBZ = 0b0,
CBNZ = 0b1
};
T16_CBZ_CBNZ(T16_STRUCT_CBZ_CBNZ *inst);
T16_CBZ_CBNZ(OP op, Off offset, RegisterA32 &rn);
T16_CBZ_CBNZ(OP op, Label& label, RegisterA32 &rn);
DEFINE_IS_EXT(CBZ_CBNZ, TEST_INST_OPCODE(CBZ_CBNZ, 1) && TEST_INST_OPCODE(CBZ_CBNZ, 2) && TEST_INST_OPCODE(CBZ_CBNZ, 3))
DEFINE_INST_CODE(CBZ_CBNZ)
void onOffsetApply(Off offset) override;
Off getImmPCOffset() override;
void decode(T16_STRUCT_CBZ_CBNZ *inst) override;
void assembler() override;
public:
OP op;
Off offset;
RegisterA32* rn;
};
class INST_T16(LDR_LIT) : T16_INST_PC_REL<STRUCT_T16(LDR_LIT)> {
public:
T16_LDR_LIT(T16_STRUCT_LDR_LIT *inst);
T16_LDR_LIT(Off offset, RegisterA32 &rt);
DEFINE_IS(LDR_LIT)
DEFINE_INST_CODE(LDR_LIT)
private:
Addr getImmPCOffsetTarget() override;
public:
Off getImmPCOffset() override;
void onOffsetApply(Off offset) override;
void decode(T16_STRUCT_LDR_LIT *inst) override;
void assembler() override;
public:
Off offset;
RegisterA32* rt;
};
}
}
......
......@@ -79,7 +79,7 @@ Off A64_ADR_ADRP::getImmPCOffset() {
}
Addr A64_ADR_ADRP::getImmPCOffsetTarget() {
void * base = AlignDown(getPC(), P_SIZE);
void* base = AlignDown(getPC(), P_SIZE);
return getImmPCOffset() + reinterpret_cast<Addr>(base);
}
......@@ -772,7 +772,7 @@ A64_LDRSW_UIMM::A64_LDRSW_UIMM(XRegister &rt, const MemOperand &operand) : A64_L
operand) {}
void A64_LDRSW_UIMM::decode(STRUCT_A64(LDR_UIMM) *inst) {
rt = XReg(static_cast<U8>(inst->rt));
DECODE_RT(XReg);
operand.base = XReg(static_cast<U8>(inst->rn));
operand.addr_mode = AddrMode::Offset;
scale = static_cast<U8>(inst->size);
......@@ -783,7 +783,7 @@ void A64_LDRSW_UIMM::decode(STRUCT_A64(LDR_UIMM) *inst) {
void A64_LDRSW_UIMM::assembler() {
SET_OPCODE(LDRSW_UIMM);
get()->size = Size32;
get()->rt = rt->getCode();
ENCODE_RT;
get()->rn = operand.base->getCode();
get()->imm12 = operand.offset >> Size32;
}
......@@ -7,6 +7,7 @@
#include <cstdint>
#include <cstring>
#include <type_traits>
#include "compiler.h"
typedef uint8_t U8;
......@@ -93,6 +94,21 @@ T AlignDown(T pointer,
return (T)(pointer_raw & ~mask);
}
template<typename T>
struct Identity {
using type = T;
};
template<typename T>
constexpr T RoundDown(T x, typename Identity<T>::type n) {
return (x & -n);
}
template<typename T>
constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) {
return RoundDown(x + n - 1, n);
}
#define FIT(value, align) value <= align ? align : ((value / align) + align)
#define OFFSET(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER)
......
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