public ExecutionGraph execute(String className, String methodDescriptor, ExecutionContext context) throws VirtualMachineException { return execute(className + "->" + methodDescriptor, context, null, null); }
@Override public void execute(VirtualMachine vm, Op op, ExecutionContext context) { MethodState mState = context.getMethodState(); String argumentType = mState.peekParameter(0).getType(); VirtualType virtualType = vm.getClassManager().getVirtualType(argumentType); try { Class<?> value = vm.getClassLoader().loadClass(virtualType.getBinaryName()); mState.assignReturnRegister(value, RETURN_TYPE); } catch (ClassNotFoundException e) { throw new RuntimeException("Class not found: " + argumentType, e); } }
public ExecutionContext spawnRootContext(String className, String methodDescriptor) { VirtualMethod method = getClassManager().getVirtualClass(className).getMethod(methodDescriptor); if (method == null) { throw new RuntimeException("Method signature not found: " + className + "->" + methodDescriptor); } return spawnRootContext(method); }
public ExecutionGraph execute(VirtualMethod method) throws VirtualMachineException { ExecutionContext context = spawnRootContext(method); return execute(method, context, null, null); }
public ExecutionGraph spawnInstructionGraph(String className, String methodDescriptor) { VirtualMethod method = getClassManager().getVirtualClass(className).getMethod(methodDescriptor); return spawnInstructionGraph(method); }
InvokeOp(MethodLocation location, MethodLocation child, VirtualMethod method, int[] parameterRegisters, VirtualMachine vm) { super(location, child); this.method = method; this.parameterRegisters = parameterRegisters; analyzedParameterTypes = new String[method.getParameterTypeNames().size()]; this.vm = vm; classManager = vm.getClassManager(); sideEffectLevel = SideEffect.Level.STRONG; }
@Before public void setUp() throws ClassNotFoundException { vm = mock(VirtualMachine.class); classManager = mock(ClassManager.class); when(vm.getClassManager()).thenReturn(classManager); classLoader = mock(SmaliClassLoader.class); when(vm.getClassLoader()).thenReturn(classLoader); configuration = mock(Configuration.class); when(vm.getConfiguration()).thenReturn(configuration); mState = mock(MethodState.class); context = mock(ExecutionContext.class); when(context.getMethodState()).thenReturn(mState); method = new java_lang_Class_forName(); op = mock(Op.class); exceptionFactory = mock(ExceptionFactory.class); when(vm.getExceptionFactory()).thenReturn(exceptionFactory); }
ClassManager classManager = vm.getClassManager(); Cloner cloner = cache.get(classManager); if (cloner != null) { Set<String> immutableClasses = vm.getConfiguration().getImmutableClasses(); ClassLoader classLoader = vm.getClassLoader();
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(); } }
@Override public Op create(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation, VirtualMachine vm) { MethodLocation child = Utils.getNextLocation(location, addressToLocation); Instruction21c instr = (Instruction21c) location.getInstruction(); int targetRegister = instr.getRegisterA(); TypeReference reference = (TypeReference) instr.getReference(); VirtualType referenceType = vm.getClassManager().getVirtualType(reference); return new CheckCastOp(location, child, targetRegister, referenceType, vm.getClassManager(), vm.getExceptionFactory()); }
if (vm.isSafe(virtualClass) || isClassInitialized(virtualClass)) { ExecutionContext initContext = vm.spawnRootContext(method); ClassState cState = initContext.peekClassState(virtualClass); initContext.initializeClass(cState, SideEffect.Level.NONE); graph = vm.execute(method, initContext, this, null); } catch (VirtualMachineException e) { log.warn(e.toString());
public ExecutionContext spawnRootContext(VirtualMethod method) { return spawnRootContext(method, null, 0); }
private static ExecutionContextMethod test(VirtualMachine vm, ExecutionContext context, String fieldName, String callingMethodSignature, boolean setAccessible) throws Exception { // Setup caller context ExecutionContext callerContext = vm.spawnRootContext(callingMethodSignature); Field callerContextField = ExecutionContext.class.getDeclaredField("callerContext"); callerContextField.setAccessible(true); callerContextField.set(context, callerContext); // Setup actual field to use as parameter ClassLoader classLoader = vm.getClassLoader(); Class<?> klazz = classLoader.loadClass(DUMMY_CLASS_NAME_BINARY); Constructor<?> ctor = klazz.getDeclaredConstructor(); ctor.setAccessible(true); Object instance = ctor.newInstance(); Field field = instance.getClass().getDeclaredField(fieldName); field.setAccessible(setAccessible); // Setup method state and arguments HeapItem fieldItem = new HeapItem(field, "Ljava/lang/reflect/Field;"); HeapItem instanceItem = new HeapItem(instance, DUMMY_CLASS_NAME); MethodState methodState = context.getMethodState(); methodState.pokeRegister(0, fieldItem); methodState.pokeRegister(1, instanceItem); ExecutionContextMethod fieldGet = new java_lang_reflect_Field_get(); fieldGet.execute(vm, null, context); return fieldGet; }
type = analyzedParameterTypes[i]; if (!type.equals(item.getType())) { VirtualType parameterType = vm.getClassManager().getVirtualType(type); VirtualType argumentType = vm.getClassManager().getVirtualType(item.getType()); if (vm.getConfiguration().isImmutable(type)) { if (log.isTraceEnabled()) { log.trace("{} is immutable", type);
private HeapItem getVirtualField(Field field, VirtualMachine vm, ExecutionContext context) { String className = ClassNameUtils.toInternal(field.getDeclaringClass()); VirtualClass fieldClass = vm.getClassManager().getVirtualClass(className); VirtualField virtualField = fieldClass.getField(field.getName()); StaticFieldAccessor accessor = vm.getStaticFieldAccessor(); return accessor.getField(context, virtualField); }
ExecutionGraph graph = null; try { graph = vm.execute(method); } catch (VirtualMachineException e) { System.err.println("Aborting execution; exception: " + e); vm.updateInstructionGraph(method);
@Override public ConstOp create(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation, VirtualMachine vm) { MethodLocation child = Utils.getNextLocation(location, addressToLocation); BuilderInstruction instruction = (BuilderInstruction) location.getInstruction(); int destRegister = ((OneRegisterInstruction) instruction).getRegisterA(); ConstantType constantType; Object literal; String opName = instruction.getOpcode().name; if (opName.matches("const-string(?:/jumbo)?")) { ReferenceInstruction instr = (ReferenceInstruction) location.getInstruction(); literal = ((StringReference) instr.getReference()).getString(); constantType = ConstantType.STRING; } else if (opName.endsWith("-class")) { // Don't lookup the class here. Defer to actual execution to handle any possible exceptions. ReferenceInstruction instr = (ReferenceInstruction) location.getInstruction(); Reference classRef = instr.getReference(); literal = ReferenceUtil.getReferenceString(classRef); constantType = ConstantType.CLASS; } else if (opName.contains("-wide")) { WideLiteralInstruction instr = (WideLiteralInstruction) location.getInstruction(); literal = instr.getWideLiteral(); constantType = ConstantType.WIDE; } else { NarrowLiteralInstruction instr = (NarrowLiteralInstruction) location.getInstruction(); literal = instr.getNarrowLiteral(); constantType = ConstantType.NARROW; } return new ConstOp(location, child, destRegister, constantType, literal, vm.getClassLoader(), vm.getExceptionFactory()); }
private HeapItem get(Field field, Object instance, String className, int accessFlags, ExecutionContext context, VirtualMachine vm, Op op) { if (vm.getConfiguration().isSafe(className)) { return getSafeField(field, instance, context, op, vm.getExceptionFactory()); } else { boolean isStatic = Modifier.isStatic(accessFlags); if (!isStatic) { // Instance field lookup isn't supported yet. String internalName = ClassNameUtils.toInternal(field.getType()); return HeapItem.newUnknown(internalName); } return getVirtualField(field, vm, context); } }
public ExecutionGraph execute(VirtualMethod virtualMethod, ExecutionContext calleeContext, ExecutionContext callerContext, int[] parameterRegisters) throws VirtualMachineException { if (!virtualMethod.hasImplementation()) { log.warn("Attempting to execute method without implementation: {}", virtualMethod); return null; } if (callerContext != null) { inheritClassStates(callerContext, calleeContext); } calleeContext.staticallyInitializeClassIfNecessary(virtualMethod.getDefiningClass()); ExecutionGraph graph = spawnInstructionGraph(virtualMethod); ExecutionNode rootNode = new ExecutionNode(graph.getRoot()); rootNode.setContext(calleeContext); graph.addNode(rootNode); ExecutionGraph execution = methodExecutor.execute(graph); if ((execution != null) && (callerContext != null)) { collapseMultiverse(virtualMethod, graph, callerContext, parameterRegisters); } return execution; }
@Before public void setUp() { vm = mock(VirtualMachine.class); mState = mock(MethodState.class); node = mock(ExecutionNode.class); location = mock(MethodLocation.class); when(location.getCodeAddress()).thenReturn(ADDRESS); ExceptionFactory exceptionFactory = mock(ExceptionFactory.class); when(vm.getExceptionFactory()).thenReturn(exceptionFactory); addressToLocation = new TIntObjectHashMap<MethodLocation>(); addressToLocation.put(ADDRESS, location); opFactory = new BinaryMathOpFactory(); }