private void analyzeBinaryOp(@Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull RegisterType destRegisterType, boolean checkForBoolean) { if (checkForBoolean) { ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; RegisterType source1RegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); RegisterType source2RegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterC()); if (BooleanCategories.get(source1RegisterType.category) && BooleanCategories.get(source2RegisterType.category)) { destRegisterType = RegisterType.BOOLEAN_TYPE; } } setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, destRegisterType); }
private void analyzeAgetObject(@Nonnull AnalyzedInstruction analyzedInstruction) { ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); if (arrayRegisterType.category != RegisterType.NULL) { if (arrayRegisterType.category != RegisterType.REFERENCE || !(arrayRegisterType.type instanceof ArrayProto)) { throw new AnalysisException("aget-object used with non-array register: %s", arrayRegisterType.toString()); } ArrayProto arrayProto = (ArrayProto)arrayRegisterType.type; String elementType = arrayProto.getImmediateElementType(); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.getRegisterType(RegisterType.REFERENCE, classPath.getClass(elementType))); } else { // If the array register is null, we can assume that the destination register was meant to be a reference // type, so we set the destination to NULL. This is the same behavior as dalvik's verifier setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.NULL_TYPE); } }
private void analyzeAgetWide(@Nonnull AnalyzedInstruction analyzedInstruction) { ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); if (arrayRegisterType.category != RegisterType.NULL) { if (arrayRegisterType.category != RegisterType.REFERENCE || !(arrayRegisterType.type instanceof ArrayProto)) { throw new AnalysisException("aget-wide used with non-array register: %s", arrayRegisterType.toString()); } ArrayProto arrayProto = (ArrayProto)arrayRegisterType.type; if (arrayProto.dimensions != 1) { throw new AnalysisException("aget-wide used with multi-dimensional array: %s", arrayRegisterType.toString()); } char arrayBaseType = arrayProto.getElementType().charAt(0); if (arrayBaseType == 'J') { setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.LONG_LO_TYPE); } else if (arrayBaseType == 'D') { setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.DOUBLE_LO_TYPE); } else { throw new AnalysisException("aget-wide used with narrow array: %s", arrayRegisterType); } } else { // If the array register is null, we can assume that the destination register was meant to be a wide type. // This is the same behavior as dalvik's verifier setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.LONG_LO_TYPE); } }
private void analyzeBinaryOp(@Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull RegisterType destRegisterType, boolean checkForBoolean) { if (checkForBoolean) { ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; RegisterType source1RegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); RegisterType source2RegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterC()); if (BooleanCategories.get(source1RegisterType.category) && BooleanCategories.get(source2RegisterType.category)) { destRegisterType = RegisterType.BOOLEAN_TYPE; } } setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, destRegisterType); }
private void analyzeBinaryOp(@Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull RegisterType destRegisterType, boolean checkForBoolean) { if (checkForBoolean) { ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; RegisterType source1RegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); RegisterType source2RegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterC()); if (BooleanCategories.get(source1RegisterType.category) && BooleanCategories.get(source2RegisterType.category)) { destRegisterType = RegisterType.BOOLEAN_TYPE; } } setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, destRegisterType); }
ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.getInstruction(); registers.set(instruction.getRegisterA()); registers.set(instruction.getRegisterB()); registers.set(instruction.getRegisterC()); } else if (analyzedInstruction.getInstruction() instanceof TwoRegisterInstruction) {
private void analyzeAgetObject(@Nonnull AnalyzedInstruction analyzedInstruction) { ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); if (arrayRegisterType.category != RegisterType.NULL) { if (arrayRegisterType.category != RegisterType.REFERENCE || !(arrayRegisterType.type instanceof ArrayProto)) { throw new AnalysisException("aget-object used with non-array register: %s", arrayRegisterType.toString()); } ArrayProto arrayProto = (ArrayProto)arrayRegisterType.type; String elementType = arrayProto.getImmediateElementType(); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.getRegisterType(RegisterType.REFERENCE, classPath.getClass(elementType))); } else { // If the array register is null, we can assume that the destination register was meant to be a reference // type, so we set the destination to NULL. This is the same behavior as dalvik's verifier setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.NULL_TYPE); } }
ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.getInstruction(); registers.set(instruction.getRegisterA()); registers.set(instruction.getRegisterB()); registers.set(instruction.getRegisterC()); } else if (analyzedInstruction.getInstruction() instanceof TwoRegisterInstruction) {
ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.getInstruction(); registers.set(instruction.getRegisterA()); registers.set(instruction.getRegisterB()); registers.set(instruction.getRegisterC()); } else if (analyzedInstruction.getInstruction() instanceof TwoRegisterInstruction) {
private void analyzeAgetObject(@Nonnull AnalyzedInstruction analyzedInstruction) { ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); if (arrayRegisterType.category != RegisterType.NULL) { if (arrayRegisterType.category != RegisterType.REFERENCE || !(arrayRegisterType.type instanceof ArrayProto)) { throw new AnalysisException("aget-object used with non-array register: %s", arrayRegisterType.toString()); } ArrayProto arrayProto = (ArrayProto)arrayRegisterType.type; String elementType = arrayProto.getImmediateElementType(); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.getRegisterType(RegisterType.REFERENCE, classPath.getClass(elementType))); } else { // If the array register is null, we can assume that the destination register was meant to be a reference // type, so we set the destination to NULL. This is the same behavior as dalvik's verifier setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.NULL_TYPE); } }
ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.getInstruction(); registers.set(instruction.getRegisterA()); registers.set(instruction.getRegisterB()); registers.set(instruction.getRegisterC()); } else if (analyzedInstruction.getInstruction() instanceof TwoRegisterInstruction) {
private void analyzeAgetWide(@Nonnull AnalyzedInstruction analyzedInstruction) { ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); if (arrayRegisterType.category != RegisterType.NULL) { if (arrayRegisterType.category != RegisterType.REFERENCE || !(arrayRegisterType.type instanceof ArrayProto)) { throw new AnalysisException("aget-wide used with non-array register: %s", arrayRegisterType.toString()); } ArrayProto arrayProto = (ArrayProto)arrayRegisterType.type; if (arrayProto.dimensions != 1) { throw new AnalysisException("aget-wide used with multi-dimensional array: %s", arrayRegisterType.toString()); } char arrayBaseType = arrayProto.getElementType().charAt(0); if (arrayBaseType == 'J') { setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.LONG_LO_TYPE); } else if (arrayBaseType == 'D') { setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.DOUBLE_LO_TYPE); } else { throw new AnalysisException("aget-wide used with narrow array: %s", arrayRegisterType); } } else { // If the array register is null, we can assume that the destination register was meant to be a wide type. // This is the same behavior as dalvik's verifier setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.LONG_LO_TYPE); } }
private void analyzeAgetWide(@Nonnull AnalyzedInstruction analyzedInstruction) { ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); if (arrayRegisterType.category != RegisterType.NULL) { if (arrayRegisterType.category != RegisterType.REFERENCE || !(arrayRegisterType.type instanceof ArrayProto)) { throw new AnalysisException("aget-wide used with non-array register: %s", arrayRegisterType.toString()); } ArrayProto arrayProto = (ArrayProto)arrayRegisterType.type; if (arrayProto.dimensions != 1) { throw new AnalysisException("aget-wide used with multi-dimensional array: %s", arrayRegisterType.toString()); } char arrayBaseType = arrayProto.getElementType().charAt(0); if (arrayBaseType == 'J') { setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.LONG_LO_TYPE); } else if (arrayBaseType == 'D') { setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.DOUBLE_LO_TYPE); } else { throw new AnalysisException("aget-wide used with narrow array: %s", arrayRegisterType); } } else { // If the array register is null, we can assume that the destination register was meant to be a wide type. // This is the same behavior as dalvik's verifier setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.LONG_LO_TYPE); } }