private static Set<Integer> getNormalRegistersAssigned(MethodState mState) { Set<Integer> assigned = new HashSet<>(); for (int register : mState.getRegistersAssigned()) { if (register < 0) { continue; } assigned.add(register); } for (int i = 0; i < mState.getParameterCount(); i++) { int parameterRegister = mState.getParameterStart() + i; assigned.remove(parameterRegister); } return assigned; }
boolean isLocal = register < getParameterStart(); if (!isLocal) { ctx.append("(p").append(register - getParameterStart()).append(')');
@SuppressWarnings({ "unchecked" }) private Object invokeEnumInit(MethodState mState, String name, ClassLoader classLoader) throws ClassNotFoundException { /* * Enums can't be instantiated by calling newInstance() on the constructor, * even with setAccessible(true). It fails with InstantiationException. * http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9 */ HeapItem instance = mState.peekParameter(mState.getParameterStart()); String enumType = ClassNameUtils.internalToSource(instance.getType()); Class<? extends Enum> enumClass = (Class<? extends Enum>) classLoader.loadClass(enumType); try { return Enum.valueOf(enumClass, name); } catch (IllegalArgumentException e) { enumAnalyzer.analyze(enumClass); name = enumAnalyzer.getObfuscatedName(name); return Enum.valueOf(enumClass, name); } }
sb.append(mState.getParameterStart() - 1); // p0 for instance method if (op.toString().startsWith(sb.toString())) { invalidAddresses.add(address);
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); }
private boolean allArgumentsKnown(MethodState mState) { for (int parameterRegister = mState.getParameterStart(); parameterRegister < mState.getRegisterCount(); ) { HeapItem item = mState.peekParameter(parameterRegister); if (item.isUnknown()) { return false; } String type = item.getType(); parameterRegister += Utils.getRegisterSize(type); } return true; }
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); } }
if (methodSignature.contains(";-><init>(")) { int calleeInstanceRegister = calleeContext.getMethodState().getParameterStart(); HeapItem newInstance = graph.getTerminatingRegisterConsensus(calleeInstanceRegister); int instanceRegister = parameterRegisters[0];
MethodState callerMethodState = callerContext.getMethodState(); List<String> parameterTypes = calledMethod.getParameterTypeNames(); int parameterRegister = graph.getNodePile(0).get(0).getContext().getMethodState().getParameterStart(); for (int parameterIndex = 0; parameterIndex < parameterTypes.size(); parameterIndex++) { String type = parameterTypes.get(parameterIndex);
@Test public void methodStateForVirtualMethodCreatedCorrectly() throws VirtualMachineException { String methodDescriptor = "someString()Ljava/lang/String;"; VirtualMethod method = vm.getClassManager().getMethod(CLASS_NAME, methodDescriptor); ExecutionContext spawnedContext = new ExecutionContext(vm, method); ClassState templateClassState = TemplateStateFactory.forClass(spawnedContext, method.getDefiningClass()); spawnedContext.setClassState(templateClassState); MethodState templateMethodState = TemplateStateFactory.forMethod(spawnedContext); spawnedContext.setMethodState(templateMethodState); assertEquals(2, templateMethodState.getRegisterCount()); assertEquals(1, templateMethodState.getParameterCount()); int instanceRegister = templateMethodState.getParameterStart(); assertEquals(1, instanceRegister); HeapItem instanceItem = templateMethodState.peekRegister(instanceRegister); assertEquals(CLASS_NAME, instanceItem.getType()); assertEquals(UnknownValue.class, instanceItem.getValue().getClass()); }
@Test public void methodStateForObjectInitializationMethodCreatedCorrectly() throws VirtualMachineException { String methodDescriptor = "<init>()V"; VirtualMethod method = vm.getClassManager().getMethod(CLASS_NAME, methodDescriptor); ExecutionContext spawnedContext = new ExecutionContext(vm, method); ClassState templateClassState = TemplateStateFactory.forClass(spawnedContext, method.getDefiningClass()); spawnedContext.setClassState(templateClassState); MethodState templateMethodState = TemplateStateFactory.forMethod(spawnedContext); spawnedContext.setMethodState(templateMethodState); assertEquals(1, templateMethodState.getRegisterCount()); assertEquals(1, templateMethodState.getParameterCount()); int instanceRegister = templateMethodState.getParameterStart(); assertEquals(0, instanceRegister); HeapItem instanceItem = templateMethodState.peekRegister(instanceRegister); assertEquals(CLASS_NAME, instanceItem.getType()); assertEquals(UninitializedInstance.class, instanceItem.getValue().getClass()); }