private static void executeParameterLogicWithUnknownParameter() throws VirtualMachineException { String methodSignature = "Lorg/cf/demosmali/Main;->parameterLogic(I)I"; // Execute with ambiguous / unknown parameters. This forces smalivm to take both execution paths. // You should see two prints, indicating it took both execution paths. ExecutionGraph graph = vm.execute(methodSignature); // Get the return value consensus over all possible execution paths. // These paths have different return values, so there's no consensus. HeapItem item = graph.getTerminatingRegisterConsensus(MethodState.ReturnRegister); System.out.println("With no context, returns an unknown integer: " + item); }
public ExecutionGraph execute(String methodSignature, ExecutionContext calleeContext, ExecutionContext callerContext, int[] parameterRegisters) throws VirtualMachineException { VirtualMethod virtualMethod = classManager.getMethod(methodSignature); if (virtualMethod == null) { throw new RuntimeException("Method signature not found: " + methodSignature); } return execute(virtualMethod, calleeContext, callerContext, parameterRegisters); }
public ExecutionGraph execute(String methodSignature) throws VirtualMachineException { VirtualMethod method = classManager.getMethod(methodSignature); if (method == null) { throw new RuntimeException("Method signature not found: " + methodSignature); } return execute(method); }
private static void executePrintParameter(int parameterValue) throws VirtualMachineException { String className = "Lorg/cf/demosmali/Main;"; String methodDescriptor = "printParameter(I)V"; // Execute method with context which contains the argument values. ExecutionContext context = vm.spawnRootContext(className, methodDescriptor); MethodState mState = context.getMethodState(); mState.assignParameter(3, parameterValue, "I"); vm.execute(className, methodDescriptor, context); }
private static void executeParameterLogicWithKnownParameter(int parameterValue) throws VirtualMachineException { String methodSignature = "Lorg/cf/demosmali/Main;->parameterLogic(I)I"; ExecutionContext context = vm.spawnRootContext(methodSignature); MethodState mState = context.getMethodState(); // This method has 4 locals (r0, r1, r2, r3). Since it's virtual (not static) the first parameter (p0 or r4) // is the 'this' reference, or contains a reference to the object. // First method parameter starts at r5, or parameter start + 1. mState.assignParameter(mState.getParameterStart() + 1, parameterValue, "I"); ExecutionGraph graph = vm.execute(methodSignature, context); HeapItem item = graph.getTerminatingRegisterConsensus(MethodState.ReturnRegister); System.out.println("With context, returns " + parameterValue + ": " + item); }
@Test public void executingAbstractMethodReturnsNull() throws VirtualMachineException { String methodName = "abstractMethod()Ljava/lang/String;"; exception.expect(IllegalArgumentException.class); vm.execute(CLASS_NAME + "->" + methodName); } }
@Test public void canCallHashCodeOfDynamicallyGeneratedClass() throws VirtualMachineException { String className = "Lhash_code;"; String methodName = "createInstance()V"; VirtualMachine vm = VMTester.spawnVM(); vm.execute(className, methodName); } }
@Test public void invokeSideEffectMethodHasStrongSideEffects() throws VirtualMachineException { String methodName = "invokeSideEffectMethod(Ljava/io/OutputStream;[B)V"; ExecutionGraph graph = vm.execute(CLASS_NAME, methodName); assertEquals(SideEffect.Level.STRONG, graph.getHighestSideEffectLevel()); }
@Test public void newInstanceNonLocalWhitelistedClassHasNoSideEffects() throws VirtualMachineException { String methodName = "newInstanceNonLocalWhitelistedClass()V"; ExecutionGraph graph = vm.execute(CLASS_NAME, methodName); assertEquals(SideEffect.Level.NONE, graph.getHighestSideEffectLevel()); }
@Test public void invokeWhitelistedMethodsHasNoSideEffects() throws VirtualMachineException { String methodName = "invokeWhitelistedMethods()V"; ExecutionGraph graph = vm.execute(CLASS_NAME, methodName); assertEquals(SideEffect.Level.NONE, graph.getHighestSideEffectLevel()); }
@Test public void newInstanceOfClassWithStaticInitializerWithWeakSideEffectsHasWeakSideEffects() throws VirtualMachineException { String methodName = "newInstanceOfClassWithStaticInitializerWithWeakSideEffects()V"; ExecutionGraph graph = vm.execute(CLASS_NAME, methodName); assertEquals(SideEffect.Level.WEAK, graph.getHighestSideEffectLevel()); }
@Test public void constOpsHaveNoSideEffects() throws VirtualMachineException { String methodName = "constOps()V"; ExecutionGraph graph = vm.execute(CLASS_NAME, methodName); assertEquals(SideEffect.Level.NONE, graph.getHighestSideEffectLevel()); }
@Test public void invokeOfNonAnalyzableMethodHasStrongSideEffects() throws VirtualMachineException { String methodName = "invokeOfNonAnalyzableMethod()V"; ExecutionGraph graph = vm.execute(CLASS_NAME, methodName); assertEquals(SideEffect.Level.STRONG, graph.getHighestSideEffectLevel()); }
@Test public void newInstanceOfMethodWithNoStaticInitializerHasNoSideEffects() throws VirtualMachineException { String methodName = "newInstanceOfMethodWithNoStaticInitializer()V"; ExecutionGraph graph = vm.execute(CLASS_NAME, methodName); assertEquals(SideEffect.Level.NONE, graph.getHighestSideEffectLevel()); }
@Test public void writeOutputStreamHasStrongSideEffects() throws VirtualMachineException { String methodName = "writeOutputStream(Ljava/io/OutputStream;[B)V"; ExecutionGraph graph = vm.execute(CLASS_NAME, methodName); assertEquals(SideEffect.Level.STRONG, graph.getHighestSideEffectLevel()); }
@Test public void emptyMethodHasNoSideEffects() throws VirtualMachineException { String methodName = "emptyMethod()V"; ExecutionGraph graph = vm.execute(CLASS_NAME, methodName); assertEquals(SideEffect.Level.NONE, graph.getHighestSideEffectLevel()); }
@Test public void newInstanceOfMethodWithStaticInitializerWithNoSideEffectsHasNoSideEffects() throws VirtualMachineException { String methodName = "newInstanceOfMethodWithStaticInitializerWithNoSideEffects()V"; ExecutionGraph graph = vm.execute(CLASS_NAME, methodName); assertEquals(SideEffect.Level.NONE, graph.getHighestSideEffectLevel()); }
@Test public void canInvokeImplemenetedAbstractMethod() throws VirtualMachineException { String methodName = "abstractMethod()Ljava/lang/String;"; ExecutionGraph graph = vm.execute(CLASS_NAME + "->" + methodName); HeapItem item = graph.getTerminatingRegisterConsensus(MethodState.ReturnRegister); String value = (String) item.getValue(); assertEquals(EXPECTED_VALUE, value); }
@Test public void canInvokeParentMethodOfChild() throws VirtualMachineException { String methodName = "callsParentMethod()Ljava/lang/String;"; ExecutionGraph graph = vm.execute(CLASS_NAME + "->" + methodName); HeapItem item = graph.getTerminatingRegisterConsensus(MethodState.ReturnRegister); assertEquals("parentMethod", item.getValue()); } }
@Test public void unsafeExceptionIsNotInstantiated() throws VirtualMachineException { String methodName = "createAndThrowException()V"; ExecutionGraph graph = vm.execute(CLASS_NAME, methodName); HeapItem item = graph.getTerminatingRegisterConsensus(0); assertEquals(EXCEPTION_CLASS_NAME, item.getType()); assertEquals(UninitializedInstance.class, item.getValue().getClass()); Instance instance = (Instance) item.getValue(); assertEquals(EXCEPTION_CLASS_NAME, instance.getType().getName()); }