private void analyzeConstString(@Nonnull AnalyzedInstruction analyzedInstruction) { TypeProto stringClass = classPath.getClass("Ljava/lang/String;"); RegisterType stringType = RegisterType.getRegisterType(RegisterType.REFERENCE, stringClass); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, stringType); }
ClassProto superclassProto = (ClassProto) classPath.getClass(superclass); for (String superclassInterface: superclassProto.getInterfaces().keySet()) { interfaces.put(superclassInterface, null); for (String interfaceType: getClassDef().getInterfaces()) { if (!interfaces.containsKey(interfaceType)) { ClassProto interfaceProto = (ClassProto)classPath.getClass(interfaceType); try { for (Entry<String, ClassDef> entry: interfaceProto.getInterfaces().entrySet()) {
private void analyzeConstClass(@Nonnull AnalyzedInstruction analyzedInstruction) { TypeProto classClass = classPath.getClass("Ljava/lang/Class;"); RegisterType classType = RegisterType.getRegisterType(RegisterType.REFERENCE, classClass); setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, classType); }
ClassProto interfaceProto = (ClassProto) classPath.getClass(interfaceType); for (String superInterface: interfaceProto.getInterfaces().keySet()) { if (!interfaces.containsKey(superInterface)) { try { if (superclass != null) { ClassProto superclassProto = (ClassProto) classPath.getClass(superclass); for (String superclassInterface: superclassProto.getInterfaces().keySet()) { if (!interfaces.containsKey(superclassInterface)) {
private boolean isOverridableByDefaultMethod(@Nonnull Method method) { ClassProto classProto = (ClassProto)classPath.getClass(method.getDefiningClass()); return classProto.isInterface(); }
superclassType = getSuperclass(); } catch (UnresolvedClassException ex) { vtable.addAll(((ClassProto)classPath.getClass("Ljava/lang/Object;")).getVtable()); vtableFullyResolved = false; return vtable; ClassProto superclass = (ClassProto) classPath.getClass(superclassType); vtable.addAll(superclass.getVtable()); ClassProto existingInterface = (ClassProto)classPath.getClass( defaultMethods.get(defaultMethodIndex).getDefiningClass()); if (!existingInterface.implementsInterface(interfaceMethod.getDefiningClass())) { if (!AccessFlags.ABSTRACT.isSet(interfaceMethod.getAccessFlags())) { ClassProto existingInterface = (ClassProto)classPath.getClass( mirandaMethods.get(mirandaMethodIndex).getDefiningClass()); if (!existingInterface.implementsInterface(interfaceMethod.getDefiningClass())) {
@Nonnull public static RegisterType getRegisterType(@Nonnull ClassPath classPath, @Nonnull CharSequence type) { switch (type.charAt(0)) { case 'Z': return BOOLEAN_TYPE; case 'B': return BYTE_TYPE; case 'S': return SHORT_TYPE; case 'C': return CHAR_TYPE; case 'I': return INTEGER_TYPE; case 'F': return FLOAT_TYPE; case 'J': return LONG_LO_TYPE; case 'D': return DOUBLE_LO_TYPE; case 'L': case '[': return getRegisterType(REFERENCE, classPath.getClass(type)); default: throw new AnalysisException("Invalid type: " + type); } }
assert objectRegisterTypeProto != null; TypeProto classTypeProto = classPath.getClass(objectRegisterTypeProto.getType()); FieldReference resolvedField = classTypeProto.getFieldByOffset(fieldOffset); FieldReference newResolvedField = classPath.getClass(fieldClass.getType()).getFieldByOffset(fieldOffset); if (newResolvedField == null) { throw new ExceptionWithContext("Couldn't find accessible class while resolving field %s",
/** * Checks if the interface method overrides the virtual or interface method2 * @param method A Method from an interface * @param method2 A Method from an interface or a class * @return true if the interface method overrides the virtual or interface method2 */ private boolean interfaceMethodOverrides(@Nonnull Method method, @Nonnull Method method2) { ClassProto classProto = (ClassProto)classPath.getClass(method2.getDefiningClass()); if (classProto.isInterface()) { ClassProto targetClassProto = (ClassProto)classPath.getClass(method.getDefiningClass()); return targetClassProto.implementsInterface(method2.getDefiningClass()); } else { return false; } }
if (isSuper) { TypeProto typeProto = classPath.getClass(method.getDefiningClass()); TypeProto superType; superType = classPath.getClass(superclassType); } else { if (classPath.getClass(resolvedMethod.getDefiningClass()).isInterface()) { resolvedMethod = new ReparentedMethodReference(resolvedMethod, objectRegisterTypeProto.getType()); } else if (!isSuper && !TypeUtils.canAccessClass( classPath.getClass(methodClass.getType()).getMethodByVtableIndex(methodIndex); if (newResolvedMethod == null) { throw new ExceptionWithContext("Couldn't find accessible class while resolving method %s",
@Nullable private MethodReference normalizeMethodReference(@Nonnull MethodReference methodRef) { TypeProto typeProto = classPath.getClass(methodRef.getDefiningClass()); int methodIndex; try { ClassProto thisClass = (ClassProto)classPath.getClass(method.getDefiningClass()); break; typeProto = classPath.getClass(superType); Method resolvedMethod = typeProto.getMethodByVtableIndex(methodIndex); if (resolvedMethod == null) {
superclassType = getSuperclass(); } catch (UnresolvedClassException ex) { vtable.addAll(((ClassProto)classPath.getClass("Ljava/lang/Object;")).getVtable()); vtableFullyResolved = false; return vtable; ClassProto superclass = (ClassProto) classPath.getClass(superclassType); vtable.addAll(superclass.getVtable());
superclassType = getSuperclass(); } catch (UnresolvedClassException ex) { vtable.addAll(((ClassProto)classPath.getClass("Ljava/lang/Object;")).getVtable()); vtableFullyResolved = false; return vtable; ClassProto superclass = (ClassProto) classPath.getClass(superclassType); vtable.addAll(superclass.getVtable()); ClassProto existingInterface = (ClassProto)classPath.getClass( defaultMethods.get(defaultMethodIndex).getDefiningClass()); if (!existingInterface.implementsInterface(interfaceMethod.getDefiningClass())) { if (!AccessFlags.ABSTRACT.isSet(interfaceMethod.getAccessFlags())) { ClassProto existingInterface = (ClassProto)classPath.getClass( mirandaMethods.get(mirandaMethodIndex).getDefiningClass()); if (!existingInterface.implementsInterface(interfaceMethod.getDefiningClass())) {
private void analyzeMoveException(@Nonnull AnalyzedInstruction analyzedInstruction) { int instructionAddress = getInstructionAddress(analyzedInstruction); RegisterType exceptionType = RegisterType.UNKNOWN_TYPE; for (TryBlock<? extends ExceptionHandler> tryBlock: methodImpl.getTryBlocks()) { for (ExceptionHandler handler: tryBlock.getExceptionHandlers()) { if (handler.getHandlerCodeAddress() == instructionAddress) { String type = handler.getExceptionType(); if (type == null) { exceptionType = RegisterType.getRegisterType(RegisterType.REFERENCE, classPath.getClass("Ljava/lang/Throwable;")); } else { exceptionType = RegisterType.getRegisterType(RegisterType.REFERENCE, classPath.getClass(type)) .merge(exceptionType); } } } } if (exceptionType.category == RegisterType.UNKNOWN) { throw new AnalysisException("move-exception must be the first instruction in an exception handler block"); } setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, exceptionType); }
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); } }
setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, RegisterType.getRegisterType(RegisterType.UNINIT_THIS, classPath.getClass(method.getDefiningClass()))); } else { setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, RegisterType.getRegisterType(RegisterType.REFERENCE, classPath.getClass(method.getDefiningClass())));
ClassProto superclass = null; if (superclassType != null) { superclass = (ClassProto) classPath.getClass(superclassType); startFieldOffset = superclass.getNextFieldOffset();
if (superclassType != null) { ClassProto superclass = (ClassProto) classPath.getClass(superclassType); SparseArray<FieldReference> superFields = superclass.getInstanceFields(); FieldReference field = null;
@Override @Nullable public Method getMethodByVtableIndex(int vtableIndex) { return classPath.getClass("Ljava/lang/Object;").getMethodByVtableIndex(vtableIndex); }
public void superclassTest(ClassPath classPath, String commonSuperclass, String type1, String type2) { TypeProto commonSuperclassProto = classPath.getClass(commonSuperclass); TypeProto type1Proto = classPath.getClass(type1); TypeProto type2Proto = classPath.getClass(type2); Assert.assertSame(commonSuperclassProto, type1Proto.getCommonSuperclass(type2Proto)); Assert.assertSame(commonSuperclassProto, type2Proto.getCommonSuperclass(type1Proto)); }