public void test(Code mthCode) throws DecodeException { short[] encodedInstructions = mthCode.getInstructions(); int size = encodedInstructions.length; DecodedInstruction[] decoded = new DecodedInstruction[size]; ShortArrayCodeInput in = new ShortArrayCodeInput(encodedInstructions); try { while (in.hasMore()) { decoded[in.cursor()] = DecodedInstruction.decode(in); } } catch (EOFException e) { throw new DecodeException(method, "", e); } insnArr = decoded; } }
private InsnNode filledNewArray(DecodedInstruction insn, int offset, boolean isRange) { int resReg = getMoveResultRegister(insnArr, offset); ArgType arrType = dex.getType(insn.getIndex()); ArgType elType = arrType.getArrayElement(); boolean typeImmutable = elType.isPrimitive(); int regsCount = insn.getRegisterCount(); InsnArg[] regs = new InsnArg[regsCount]; if (isRange) { int r = insn.getA(); for (int i = 0; i < regsCount; i++) { regs[i] = InsnArg.reg(r, elType, typeImmutable); r++; } } else { for (int i = 0; i < regsCount; i++) { int regNum = InsnUtils.getArg(insn, i); regs[i] = InsnArg.reg(regNum, elType, typeImmutable); } } InsnNode node = new FilledNewArrayNode(elType, regs.length); node.setResult(resReg == -1 ? null : InsnArg.reg(resReg, arrType)); for (InsnArg arg : regs) { node.addArg(arg); } return node; }
private int getMoveResultRegister(DecodedInstruction[] insnArr, int offset) { int nextOffset = getNextInsnOffset(insnArr, offset); if (nextOffset >= 0) { DecodedInstruction next = insnArr[nextOffset]; int opc = next.getOpcode(); if (opc == Opcodes.MOVE_RESULT || opc == Opcodes.MOVE_RESULT_WIDE || opc == Opcodes.MOVE_RESULT_OBJECT) { return next.getA(); } } return -1; }
/** * Helper method that encodes any of the register-list formats. */ private static void encodeRegisterList(DecodedInstruction insn, CodeOutput out) { out.write(codeUnit(insn.getOpcode(), makeByte(insn.getE(), insn.getRegisterCount())), insn.getIndexUnit(), codeUnit(insn.getA(), insn.getB(), insn.getC(), insn.getD())); }
@Override public void encode(DecodedInstruction insn, CodeOutput out) { // See above. int opcode = insn.getOpcode(); int shift = (opcode == Opcodes.CONST_HIGH16) ? 16 : 48; short literal = (short) (insn.getLiteral() >> shift); out.write(codeUnit(opcode, insn.getA()), literal); } },
/** * Helper method that encodes any of the three-unit register-range formats. */ private static void encodeRegisterRange(DecodedInstruction insn, CodeOutput out) { out.write(codeUnit(insn.getOpcode(), insn.getRegisterCount()), insn.getIndexUnit(), insn.getAUnit()); }
@Override public void encode(DecodedInstruction insn, CodeOutput out) { out.write( codeUnit(insn.getOpcode(), makeByte(insn.getA(), insn.getB())), insn.getIndexUnit()); } },
public void visit(DecodedInstruction[] all, DecodedInstruction one) { int fieldId = one.getIndex(); int mappedId = indexMap.adjustField(fieldId); boolean isJumbo = (one.getOpcode() == Opcodes.CONST_STRING_JUMBO); jumboCheck(isJumbo, mappedId); mappedInstructions[mappedAt++] = one.withIndex(mappedId); } }
@Override public void encode(DecodedInstruction insn, CodeOutput out) { short relativeTarget = insn.getTargetUnit(out.cursor()); out.write( codeUnit(insn.getOpcode(), makeByte(insn.getA(), insn.getB())), relativeTarget); } },
@Override public void encode(DecodedInstruction insn, CodeOutput out) { out.write( codeUnit(insn.getOpcode(), makeByte(insn.getA(), insn.getB())), insn.getLiteralUnit()); } },
/** * Gets the D register number, as a nibble. This will throw if the * value is out of the range of an unsigned nibble. */ public final short getDNibble() { int d = getD(); if ((d & ~0xf) != 0) { throw new DexException("Register D out of range: " + Hex.u8(d)); } return (short) d; }
@Override public void encode(DecodedInstruction insn, CodeOutput out) { int index = insn.getIndex(); out.write( insn.getOpcodeUnit(), unit0(index), unit1(index), insn.getRegisterCountUnit(), insn.getAUnit()); } },
@NotNull private InsnNode decode(DecodedInstruction insn, int offset) throws DecodeException { switch (insn.getOpcode()) { case Opcodes.NOP: case Opcodes.PACKED_SWITCH_PAYLOAD: InsnNode constStrInsn = new ConstStringNode(dex.getString(insn.getIndex())); constStrInsn.setResult(InsnArg.reg(insn, 0, ArgType.STRING)); return constStrInsn; InsnNode constClsInsn = new ConstClassNode(dex.getType(insn.getIndex())); constClsInsn.setResult(InsnArg.reg(insn, 0, ArgType.CLASS)); return constClsInsn; case Opcodes.GOTO_16: case Opcodes.GOTO_32: return new GotoNode(insn.getTarget()); InsnNode instInsn = new IndexInsnNode(InsnType.INSTANCE_OF, dex.getType(insn.getIndex()), 1); instInsn.setResult(InsnArg.reg(insn, 0, ArgType.BOOLEAN)); instInsn.addArg(InsnArg.reg(insn, 1, ArgType.UNKNOWN_OBJECT)); ArgType castType = dex.getType(insn.getIndex()); InsnNode checkCastInsn = new IndexInsnNode(InsnType.CHECK_CAST, castType, 1); checkCastInsn.setResult(InsnArg.reg(insn, 0, castType)); case Opcodes.IGET_WIDE: case Opcodes.IGET_OBJECT: FieldInfo igetFld = FieldInfo.fromDex(dex, insn.getIndex()); InsnNode igetInsn = new IndexInsnNode(InsnType.IGET, igetFld, 1);
@Override public void encode(DecodedInstruction insn, CodeOutput out) { out.write( codeUnit(insn.getOpcodeUnit(), makeByte(insn.getA(), insn.getB()))); } },
@Override public void encode(DecodedInstruction insn, CodeOutput out) { short relativeTarget = insn.getTargetUnit(out.cursor()); out.write(codeUnit(insn.getOpcode(), insn.getA()), relativeTarget); } },