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

[NativeHook]fix decode of SUB IMM

parent 876f3a32
......@@ -34,6 +34,7 @@ void Arm32Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, b
while((Addr) pc < endAddr) {
bool thumb32 = isThumb32(*reinterpret_cast<InstT16*>(pc));
if (thumb && thumb32) {
CASE_T32(SUB_IMM)
CASE_T32(B32)
CASE_T32(LDR_LIT)
if (!onlyPcRelInst) {
......
......@@ -39,7 +39,8 @@ enum class InstCodeT32 {
LDR_LIT,
LDR_IMM,
LDR_UIMM,
MOV_MOVT_IMM
MOV_MOVT_IMM,
SUB_IMM,
};
#endif //SANDHOOK_INST_CODE_ARM32_H
......@@ -83,6 +83,18 @@ DEFINE_STRUCT_T32(MOV_MOVT_IMM) {
InstT32 opcode2:1;
};
DEFINE_OPCODE_T32(SUB_IMM_1, 0b11110)
DEFINE_OPCODE_T32(SUB_IMM_2, 0b0)
DEFINE_STRUCT_T32(SUB_IMM) {
InstT32 rn:T32_REG_WIDE;
InstT32 S:1;
InstT32 op:5;
InstT32 i:1;
InstT32 opcode1:5;
InstT32 imm8:8;
InstT32 rd:T32_REG_WIDE;
InstT32 imm3:3;
InstT32 opcode2:1;
};
#endif //SANDHOOK_NH_INST_STRUCT_T32_H
......@@ -44,7 +44,7 @@ T32_B32::T32_B32(T32_B32::OP op, T32_B32::X x, Label &label) : op(op), x(x) {
Off T32_B32::getImmPCOffset() {
U32 S = get()->S;
U32 imm21 = COMBINE(get()->imm10, get()->imm11, 11);
if (get()->X == 0) {
if (get()->X == 0 && op == BL) {
imm21 &= ~(1 << 0);
}
U32 i1 = !(get()->J1 ^ S);
......@@ -86,7 +86,7 @@ void T32_B32::assembler() {
}
Addr T32_B32::getImmPCOffsetTarget() {
if (x == arm) {
if (x == arm && op == BL) {
void* base = reinterpret_cast<void *>(ALIGN((Addr) getPC(), 4));
return offset + reinterpret_cast<Addr>(base);
} else {
......@@ -249,3 +249,9 @@ void T32_LDR_IMM::assembler() {
valid = false;
}
}
T32_SUB_IMM::T32_SUB_IMM(T32_STRUCT_SUB_IMM *inst) : InstructionT32(inst) {
decode(inst);
}
......@@ -148,7 +148,7 @@ namespace SandHook {
DEFINE_INST_CODE(B32)
DEFINE_IS(B32)
DEFINE_IS_EXT(B32, TEST_INST_FIELD(opcode, OPCODE_T32(B32)) && (TEST_INST_FIELD(op, B) || TEST_INST_FIELD(op, BL)))
Addr getImmPCOffsetTarget() override;
......@@ -212,7 +212,7 @@ namespace SandHook {
T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Label& label);
DEFINE_IS(LDR_LIT)
DEFINE_IS_EXT(LDR_LIT, TEST_INST_FIELD(opcode, OPCODE_T32(LDR_LIT)) && (TEST_INST_FIELD(op, LDR) || TEST_INST_FIELD(op, LDRB) || TEST_INST_FIELD(op, LDRH)))
DEFINE_INST_CODE(LDR_LIT)
......@@ -246,7 +246,7 @@ namespace SandHook {
T32_MOV_MOVT_IMM(OP op, RegisterA32 &rd, U16 imm16);
DEFINE_IS_EXT(MOV_MOVT_IMM, TEST_INST_OPCODE(MOV_MOVT_IMM, 1) && TEST_INST_OPCODE(MOV_MOVT_IMM, 2))
DEFINE_IS_EXT(MOV_MOVT_IMM, TEST_INST_OPCODE(MOV_MOVT_IMM, 1) && TEST_INST_OPCODE(MOV_MOVT_IMM, 2) && (TEST_INST_FIELD(op, MOV) || TEST_INST_FIELD(op, MOVT)))
DEFINE_INST_CODE(MOV_MOVT_IMM)
......@@ -290,6 +290,22 @@ namespace SandHook {
MemOperand operand;
};
class INST_T32(SUB_IMM) : public InstructionT32<STRUCT_T32(SUB_IMM)> {
public:
enum OP {
T3 = 0b01101,
T4 = 0b10101
};
T32_SUB_IMM(T32_STRUCT_SUB_IMM *inst);
DEFINE_IS_EXT(SUB_IMM, TEST_INST_OPCODE(SUB_IMM, 1) && TEST_INST_OPCODE(SUB_IMM, 2) && (TEST_INST_FIELD(op, T3) || TEST_INST_FIELD(op, T4)))
DEFINE_INST_CODE(SUB_IMM)
};
}
}
......
......@@ -221,7 +221,7 @@ IMPL_RELOCATE(T32, B32) {
if (inRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) {
inst->ref();
inst->bindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst));
__ Emit(reinterpret_cast<Instruction<Base> *>(inst));
return;
}
......@@ -230,28 +230,14 @@ IMPL_RELOCATE(T32, B32) {
if (inst->x == T32_B32::thumb) {
//Thumb mode
if (inst->op == T32_B32::BL) {
Addr lr = reinterpret_cast<Addr>(toPc);
lr += 2 * 2; // 2级流水线
lr += 2 * 4; // Mov + Movt 长度
lr += 4; // Ldr Lit 长度
lr += 4; // targetAddr 长度
__ Mov(LR, lr);
}
targetAddr = reinterpret_cast<Addr>(getThumbPC(reinterpret_cast<void *>(targetAddr)));
Label* target_label = new Label();
__ Ldr(PC, target_label);
__ Emit(target_label);
__ Emit(reinterpret_cast<Addr>(targetAddr));
} else {
//to A32 mode
}
__ Mov(IP, targetAddr);
if (inst->op == T32_B32::BL) {
__ Blx(IP);
} else {
__ Bx(IP);
}
}
}
......
......@@ -82,13 +82,18 @@ namespace SandHook {
l.addBinder(this);
}
virtual void decode(Inst* inst) {}
virtual void decode(Inst* inst) {
inst_backup = *inst;
}
virtual void assembler() {}
virtual void assembler() {
this->set(inst_backup);
}
protected:
bool valid = true;
Label* label = nullptr;
Inst inst_backup;
};
class Void : public Unit<Base> {
......
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