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 ...@@ -34,6 +34,7 @@ void Arm32Decoder::decode(void *codeStart, Addr codeLen, InstVisitor &visitor, b
while((Addr) pc < endAddr) { while((Addr) pc < endAddr) {
bool thumb32 = isThumb32(*reinterpret_cast<InstT16*>(pc)); bool thumb32 = isThumb32(*reinterpret_cast<InstT16*>(pc));
if (thumb && thumb32) { if (thumb && thumb32) {
CASE_T32(SUB_IMM)
CASE_T32(B32) CASE_T32(B32)
CASE_T32(LDR_LIT) CASE_T32(LDR_LIT)
if (!onlyPcRelInst) { if (!onlyPcRelInst) {
......
...@@ -39,7 +39,8 @@ enum class InstCodeT32 { ...@@ -39,7 +39,8 @@ enum class InstCodeT32 {
LDR_LIT, LDR_LIT,
LDR_IMM, LDR_IMM,
LDR_UIMM, LDR_UIMM,
MOV_MOVT_IMM MOV_MOVT_IMM,
SUB_IMM,
}; };
#endif //SANDHOOK_INST_CODE_ARM32_H #endif //SANDHOOK_INST_CODE_ARM32_H
...@@ -83,6 +83,18 @@ DEFINE_STRUCT_T32(MOV_MOVT_IMM) { ...@@ -83,6 +83,18 @@ DEFINE_STRUCT_T32(MOV_MOVT_IMM) {
InstT32 opcode2:1; 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 #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) { ...@@ -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() { Off T32_B32::getImmPCOffset() {
U32 S = get()->S; U32 S = get()->S;
U32 imm21 = COMBINE(get()->imm10, get()->imm11, 11); U32 imm21 = COMBINE(get()->imm10, get()->imm11, 11);
if (get()->X == 0) { if (get()->X == 0 && op == BL) {
imm21 &= ~(1 << 0); imm21 &= ~(1 << 0);
} }
U32 i1 = !(get()->J1 ^ S); U32 i1 = !(get()->J1 ^ S);
...@@ -86,7 +86,7 @@ void T32_B32::assembler() { ...@@ -86,7 +86,7 @@ void T32_B32::assembler() {
} }
Addr T32_B32::getImmPCOffsetTarget() { Addr T32_B32::getImmPCOffsetTarget() {
if (x == arm) { if (x == arm && op == BL) {
void* base = reinterpret_cast<void *>(ALIGN((Addr) getPC(), 4)); void* base = reinterpret_cast<void *>(ALIGN((Addr) getPC(), 4));
return offset + reinterpret_cast<Addr>(base); return offset + reinterpret_cast<Addr>(base);
} else { } else {
...@@ -249,3 +249,9 @@ void T32_LDR_IMM::assembler() { ...@@ -249,3 +249,9 @@ void T32_LDR_IMM::assembler() {
valid = false; valid = false;
} }
} }
T32_SUB_IMM::T32_SUB_IMM(T32_STRUCT_SUB_IMM *inst) : InstructionT32(inst) {
decode(inst);
}
...@@ -148,7 +148,7 @@ namespace SandHook { ...@@ -148,7 +148,7 @@ namespace SandHook {
DEFINE_INST_CODE(B32) 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; Addr getImmPCOffsetTarget() override;
...@@ -212,7 +212,7 @@ namespace SandHook { ...@@ -212,7 +212,7 @@ namespace SandHook {
T32_LDR_LIT(OP op, S s, RegisterA32 &rt, Label& label); 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) DEFINE_INST_CODE(LDR_LIT)
...@@ -246,7 +246,7 @@ namespace SandHook { ...@@ -246,7 +246,7 @@ namespace SandHook {
T32_MOV_MOVT_IMM(OP op, RegisterA32 &rd, U16 imm16); 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) DEFINE_INST_CODE(MOV_MOVT_IMM)
...@@ -290,6 +290,22 @@ namespace SandHook { ...@@ -290,6 +290,22 @@ namespace SandHook {
MemOperand operand; 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) { ...@@ -221,7 +221,7 @@ IMPL_RELOCATE(T32, B32) {
if (inRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) { if (inRelocateRange(CODE_OFFSET(inst), sizeof(InstT16))) {
inst->ref(); inst->ref();
inst->bindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset)); inst->bindLabel(*getLaterBindLabel(CODE_OFFSET(inst) + curOffset));
__ Emit(reinterpret_cast<Instruction<Base>*>(inst)); __ Emit(reinterpret_cast<Instruction<Base> *>(inst));
return; return;
} }
...@@ -230,27 +230,13 @@ IMPL_RELOCATE(T32, B32) { ...@@ -230,27 +230,13 @@ IMPL_RELOCATE(T32, B32) {
if (inst->x == T32_B32::thumb) { if (inst->x == T32_B32::thumb) {
//Thumb mode //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))); targetAddr = reinterpret_cast<Addr>(getThumbPC(reinterpret_cast<void *>(targetAddr)));
Label* target_label = new Label(); }
__ Ldr(PC, target_label); __ Mov(IP, targetAddr);
__ Emit(target_label); if (inst->op == T32_B32::BL) {
__ Emit(reinterpret_cast<Addr>(targetAddr)); __ Blx(IP);
} else { } else {
//to A32 mode __ Bx(IP);
__ Mov(IP, targetAddr);
if (inst->op == T32_B32::BL) {
__ Blx(IP);
} else {
__ Bx(IP);
}
} }
} }
......
...@@ -82,13 +82,18 @@ namespace SandHook { ...@@ -82,13 +82,18 @@ namespace SandHook {
l.addBinder(this); 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: protected:
bool valid = true; bool valid = true;
Label* label = nullptr; Label* label = nullptr;
Inst inst_backup;
}; };
class Void : public Unit<Base> { 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