public Throwable build(Op op, Class<? extends Throwable> exceptionClass) { return build(op, exceptionClass, null); }
VirtualMachine(ClassManager manager, int maxAddressVisits, int maxCallDepth, int maxMethodVisits, int maxExecutionTime) { this.classManager = manager; classLoader = new SmaliClassLoader(classManager); methodExecutor = new MethodExecutor(classManager, maxCallDepth, maxAddressVisits, maxMethodVisits, maxExecutionTime); methodToTemplateExecutionGraph = new HashMap<>(); staticFieldAccessor = new StaticFieldAccessor(this); configuration = Configuration.instance(); exceptionFactory = new ExceptionFactory(this); }
public Throwable build(Op op, String className) { return build(op, className, null); }
APutOp(MethodLocation location, MethodLocation child, int putRegister, int arrayRegister, int indexRegister, ClassManager classManager, ExceptionFactory exceptionFactory) { super(location, child); valueRegister = putRegister; this.arrayRegister = arrayRegister; this.indexRegister = indexRegister; this.classManager = classManager; this.exceptionFactory = exceptionFactory; addException(exceptionFactory.build(this, NullPointerException.class)); addException(exceptionFactory.build(this, ArrayIndexOutOfBoundsException.class)); }
ArrayLengthOp(MethodLocation location, MethodLocation child, int destRegister, int arrayRegister, ExceptionFactory exceptionFactory) { super(location, child); this.destRegister = destRegister; this.arrayRegister = arrayRegister; addException(exceptionFactory.build(this, NullPointerException.class, "Attempt to get length of null array")); }
AGetOp(MethodLocation location, MethodLocation child, int valueRegister, int arrayRegister, int indexRegister, ExceptionFactory exceptionFactory) { super(location, child); this.valueRegister = valueRegister; this.arrayRegister = arrayRegister; this.indexRegister = indexRegister; this.exceptionFactory = exceptionFactory; addException(exceptionFactory.build(this, NullPointerException.class)); addException(exceptionFactory.build(this, ArrayIndexOutOfBoundsException.class)); }
public Throwable build(Op op, String className, String message) { String binaryName = ClassNameUtils.internalToBinary(className); try { @SuppressWarnings("unchecked") Class<Throwable> exceptionClass = (Class<Throwable>) vm.getClassLoader().loadClass(binaryName); return build(op, exceptionClass, message); } catch (Exception e) { e.printStackTrace(); } return new Exception(); } }
ConstOp(MethodLocation location, MethodLocation child, int destRegister, ConstantType constantType, Object literal, ClassLoader classLoader, ExceptionFactory exceptionFactory) { super(location, child); this.destRegister = destRegister; this.constantType = constantType; this.literal = literal; this.classLoader = classLoader; if (ConstantType.CLASS.equals(constantType)) { addException( exceptionFactory.build(this, ClassNotFoundException.class, (String) literal)); } }
private HeapItem getSafeField(Field field, Object instance, ExecutionContext context, Op op, ExceptionFactory exceptionFactory) { HeapItem item = null; try { Object getObject = field.get(instance); String type = ClassNameUtils.toInternal(field.getType()); item = new HeapItem(getObject, type); } catch (IllegalArgumentException | IllegalAccessException e) { String message = e.getMessage(); VirtualMethod callingMethod = context.getCallerContext().getMethod(); VirtualType callingClass = callingMethod.getDefiningClass(); message = message.replace(java_lang_reflect_Field_get.class.getName(), callingClass.getBinaryName()); Throwable exception = exceptionFactory.build(op, e.getClass(), message); setException(exception); } return item; }
private boolean checkAccess(VirtualType callingClass, VirtualType fieldClass, int accessFlags, Op op, ExceptionFactory exceptionFactory) { boolean isPublic = Modifier.isPublic(accessFlags); if (isPublic) { return true; } if (callingClass.equals(fieldClass)) { return true; } if (callingClass.isInnerClassOf(fieldClass)) { return true; } boolean isPrivate = Modifier.isPrivate(accessFlags); boolean isProtected = Modifier.isProtected(accessFlags); boolean isPackagePrivate = !(isProtected || isPrivate); if (isPrivate || (isProtected && !callingClass.instanceOf(fieldClass)) || (isPackagePrivate && !callingClass.isSamePackageOf(fieldClass))) { String error = callingClass.getBinaryName() + " can't access a member of " + fieldClass.getBinaryName() + " with modifiers \"" + Modifier.toString(accessFlags) + "\""; Throwable exception = exceptionFactory.build(op, IllegalAccessException.class, error); setException(exception); return false; } return true; }
private BinaryMathOp(MethodLocation location, MethodLocation child, int destRegister, int arg1Register, ExceptionFactory exceptionFactory) { super(location, child); this.destRegister = destRegister; this.arg1Register = arg1Register; mathOperator = getMathOp(getName()); mathOperandType = getMathOperandType(getName()); addException(exceptionFactory.build(this, ArithmeticException.class, "/ by zero")); }
@Test public void unknownClassNameThrowsExceptionAndAssignsNothing() throws Exception { String className = "Lunknown/Class;"; SideEffect.Level level = SideEffect.Level.NONE; VirtualClass virtualClass = setupClass(className, false, level); String binaryName = "unknown.Class"; HeapItem item = new HeapItem(binaryName, CommonTypes.STRING); when(mState.peekParameter(0)).thenReturn(item); when(classManager.getVirtualClass(className)).thenThrow(new RuntimeException()); Throwable exception = mock(Throwable.class); when(exceptionFactory.build(eq(op), eq(ClassNotFoundException.class), eq(binaryName))).thenReturn(exception); method.execute(vm, op, context); assertEquals(1, method.getExceptions().size()); Throwable actualException = method.getExceptions().iterator().next(); assertEquals(exception, actualException); verify(mState, times(0)).assignReturnRegister(any(UnknownValue.class), eq(CommonTypes.CLASS)); assertEquals(SideEffect.Level.NONE, method.getSideEffectLevel()); }
Throwable exception = exceptionFactory.build(this, NullPointerException.class); node.setException(exception); node.clearChildren(); String innerType = arrayItem.getType().replaceFirst("\\[", ""); if (index >= Array.getLength(array)) { Throwable exception = exceptionFactory.build(this, ArrayIndexOutOfBoundsException.class); node.setException(exception); node.clearChildren();
Throwable exception = vm.getExceptionFactory().build(op, ClassNotFoundException.class, binaryClassName); setException(exception);
if (throwsStoreException) { String storeType = ClassNameUtils.internalToBinary(valueItem.getType()); Throwable exception = exceptionFactory.build(this, ArrayStoreException.class, storeType); node.setException(exception); node.clearChildren(); Object array = arrayItem.getValue(); if (null == array) { Throwable exception = exceptionFactory.build(this, NullPointerException.class); node.setException(exception); node.clearChildren(); Throwable exception = exceptionFactory.build(this, ArrayIndexOutOfBoundsException.class); node.setException(exception); node.clearChildren();
@Override public void execute(ExecutionNode node, MethodState mState) { HeapItem item = mState.readRegister(targetRegister); boolean isInstance = isInstance(item, castType, classManager); if (isInstance) { node.clearExceptions(); mState.assignRegister(targetRegister, item.getValue(), castType.getName()); } else { // E.g. java.lang.ClassCastException: java.lang.String cannot be cast to java.io.File String error = ClassNameUtils.internalToBinary(item.getType()) + " cannot be cast to " + castType.getBinaryName(); Throwable exception = exceptionFactory.build(this, ClassCastException.class, error); node.setException(exception); if (!item.isUnknown()) { // Exception is certain to happen since we had all class information // exception is certain. node.clearChildren(); } } }