public void assignParameter(int parameterRegister, Object value, String type) { assignParameter(parameterRegister, new HeapItem(value, type)); }
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); }
mState.assignParameter(0, instanceItem); } else { HeapItem targetItem = mState.peekRegister(0);
public static MethodState forMethod(ExecutionContext context) { VirtualMethod method = context.getMethod(); int registerCount = method.getRegisterCount(); List<String> parameterTypes = method.getParameterTypeNames(); int parameterSize = Utils.getRegisterSize(parameterTypes); MethodState mState = new MethodState(context, registerCount, parameterTypes.size(), parameterSize); int firstParameter = mState.getParameterStart(); int parameterRegister = firstParameter; for (String type : parameterTypes) { HeapItem item; if (parameterRegister == firstParameter && !method.isStatic() && method.getName().equals("<init>")) { UninitializedInstance instance = new UninitializedInstance(method.getDefiningClass()); item = new HeapItem(instance, type); } else { item = HeapItem.newUnknown(type); } mState.assignParameter(parameterRegister, item); parameterRegister += Utils.getRegisterSize(type); } return mState; }
private void assignCalleeMethodArguments(MethodState callerState, MethodState calleeState) { int parameterRegister = calleeState.getParameterStart(); for (int i = 0; i < parameterRegisters.length; i++) { int callerRegister = parameterRegisters[i]; HeapItem item = callerState.readRegister(callerRegister); String parameterType = analyzedParameterTypes[i]; Object value = item.getValue(); if (item.isPrimitive() && !item.isUnknown()) { boolean hasNullByteValue = item.getType().equals("I") && value instanceof Number && item.asInteger() == 0; if (hasNullByteValue && ClassNameUtils.isObject(parameterType)) { value = null; } else { // The "I" type may actually be "S", "B", "C", etc. Cast to the given parameter type. value = Utils.castToPrimitive(value, parameterType); } } HeapItem parameterItem = new HeapItem(value, parameterType); calleeState.assignParameter(parameterRegister, parameterItem); parameterRegister += Utils.getRegisterSize(parameterType); } }