TCA smashableJccTarget(TCA jmp) {
  using namespace vixl;
  Instruction* b = Instruction::Cast(jmp);
  if (b->Bits(31, 24) != 0x54 || b->Bit(4) != 0) return nullptr;

  Instruction* br = Instruction::Cast(jmp + 8);
  if (br->Bits(31, 10) != 0x3587C0 || br->Bits(4, 0) != 0) return nullptr;

  uintptr_t dest = reinterpret_cast<uintptr_t>(jmp + 12);
  assertx((dest & 7) == 0);

  return *reinterpret_cast<TCA*>(dest);
}
TCA smashableCallTarget(TCA call) {
  using namespace vixl;
  Instruction* ldr = Instruction::Cast(call);
  if (ldr->Bits(31, 24) != 0x58) return nullptr;

  Instruction* blr = Instruction::Cast(call + 4);
  if (blr->Bits(31, 10) != 0x358FC0 || blr->Bits(4, 0) != 0) return nullptr;

  uintptr_t dest = reinterpret_cast<uintptr_t>(blr + 8);
  assertx((dest & 7) == 0);

  return *reinterpret_cast<TCA*>(dest);
}
TCA smashableJmpTarget(TCA jmp) {
  // This doesn't verify that each of the two or three instructions that make
  // up this sequence matches; just the first one and the indirect jump.
  using namespace vixl;
  Instruction* ldr = Instruction::Cast(jmp);
  if (ldr->Bits(31, 24) != 0x58) return nullptr;

  Instruction* br = Instruction::Cast(jmp + 4);
  if (br->Bits(31, 10) != 0x3587C0 || br->Bits(4, 0) != 0) return nullptr;

  uintptr_t dest = reinterpret_cast<uintptr_t>(jmp + 8);
  assertx((dest & 7) == 0);

  return *reinterpret_cast<TCA*>(dest);
}
Example #4
0
ConditionCode smashableJccCond(TCA inst) {
  using namespace vixl;

  Instruction* b = Instruction::Cast(inst);
  Instruction* ldr = b->NextInstruction();;
  Instruction* br = ldr->NextInstruction();
  Instruction* target = br->NextInstruction();
  DEBUG_ONLY Instruction* after = target->NextInstruction()->NextInstruction();
  DEBUG_ONLY const auto rd = ldr->Rd();

  assertx(b->IsCondBranchImm() &&
          b->ImmPCOffsetTarget() == after &&
          ldr->IsLoadLiteral() &&
          ldr->Mask(LoadLiteralMask) == LDR_x_lit &&
          ldr->ImmPCOffsetTarget() == target &&
          br->Mask(UnconditionalBranchToRegisterMask) == BR &&
          br->Rn() == rd);

  return arm::convertCC(InvertCondition(static_cast<Condition>(b->Bits(3, 0))));
}