@Nonnull private BuilderPackedSwitchPayload newBuilderPackedSwitchPayload(@Nonnull MethodLocation location, @Nonnull int[] codeAddressToIndex, @Nonnull PackedSwitchPayload instruction) { List<? extends SwitchElement> switchElements = instruction.getSwitchElements(); if (switchElements.size() == 0) { return new BuilderPackedSwitchPayload(0, null); } MethodLocation switchLocation = findSwitchForPayload(location); int baseAddress; if (switchLocation == null) { baseAddress = 0; } else { baseAddress = switchLocation.codeAddress; } List<Label> labels = Lists.newArrayList(); for (SwitchElement element : switchElements) { labels.add(newLabel(codeAddressToIndex, element.getOffset() + baseAddress)); } return new BuilderPackedSwitchPayload(switchElements.get(0).getKey(), labels); }
switchElement.getOffset()); if (targetInstruction == null) { throw new AnalysisException("Invalid switch target offset");
if(sourceAddress != null) { for(SwitchElement switchElement : ((SwitchPayload) bbinsn.instruction).getSwitchElements()){ offset = switchElement.getOffset() + (int)sourceAddress; if(bbinsn.destinations == null) bbinsn.destinations = new ArrayList<Integer>();
@Nonnull private BuilderSparseSwitchPayload newBuilderSparseSwitchPayload(@Nonnull MethodLocation location, @Nonnull int[] codeAddressToIndex, @Nonnull SparseSwitchPayload instruction) { List<? extends SwitchElement> switchElements = instruction.getSwitchElements(); if (switchElements.size() == 0) { return new BuilderSparseSwitchPayload(null); } MethodLocation switchLocation = findSwitchForPayload(location); int baseAddress; if (switchLocation == null) { baseAddress = 0; } else { baseAddress = switchLocation.codeAddress; } List<SwitchLabelElement> labelElements = Lists.newArrayList(); for (SwitchElement element : switchElements) { labelElements.add(new SwitchLabelElement(element.getKey(), newLabel(codeAddressToIndex, element.getOffset() + baseAddress))); } return new BuilderSparseSwitchPayload(labelElements); }
for (SwitchElement switchElement: switchPayload.getSwitchElements()) { AnalyzedInstruction targetInstruction = analyzedInstructions.get(instructionCodeAddress + switchElement.getOffset());
@Override public Op create(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation, VirtualMachine vm) { SwitchPayload instr = (SwitchPayload) location.getInstruction(); TIntIntMap targetKeyToOffset = new TIntIntHashMap(); for (SwitchElement element : instr.getSwitchElements()) { targetKeyToOffset.put(element.getKey(), element.getOffset()); } return new SwitchPayloadOp(location, addressToLocation, targetKeyToOffset); }
switchElement.getOffset()); if (targetInstruction == null) { throw new AnalysisException("Invalid switch target offset");
@Test public void payloadOpHasExpectedToString() { when(instruction.getOpcode()).thenReturn(Opcode.PACKED_SWITCH_PAYLOAD); List<SwitchElement> elements = new LinkedList<SwitchElement>(); doReturn(elements).when((SwitchPayload) instruction).getSwitchElements(); SwitchElement element1 = mock(SwitchElement.class); when(element1.getKey()).thenReturn(1); when(element1.getOffset()).thenReturn(10); SwitchElement element2 = mock(SwitchElement.class); when(element2.getKey()).thenReturn(2); when(element2.getOffset()).thenReturn(20); elements.add(element2); elements.add(element1); op = (SwitchPayloadOp) opFactory.create(location, addressToLocation, vm); assertEquals("packed-switch-payload [1 -> :addr_10, 2 -> :addr_20]", op.toString()); }
@Override protected Stmt switchStatement(DexBody body, Instruction targetData, Local key) { PackedSwitchPayload i = (PackedSwitchPayload) targetData; List<? extends SwitchElement> seList = i.getSwitchElements(); // the default target always follows the switch statement int defaultTargetAddress = codeAddress + instruction.getCodeUnits(); Unit defaultTarget = body.instructionAtAddress(defaultTargetAddress).getUnit(); List<IntConstant> lookupValues = new ArrayList<IntConstant>(); List<Unit> targets = new ArrayList<Unit>(); for (SwitchElement se : seList) { lookupValues.add(IntConstant.v(se.getKey())); int offset = se.getOffset(); targets.add(body.instructionAtAddress(codeAddress + offset).getUnit()); } LookupSwitchStmt switchStmt = Jimple.v().newLookupSwitchStmt(key, lookupValues, targets, defaultTarget); setUnit(switchStmt); if (IDalvikTyper.ENABLE_DVKTYPER) { DalvikTyper.v().setType(switchStmt.getKeyBox(), IntType.v(), true); } return switchStmt; }
@Override protected Stmt switchStatement(DexBody body, Instruction targetData, Local key) { SparseSwitchPayload i = (SparseSwitchPayload) targetData; List<? extends SwitchElement> seList = i.getSwitchElements(); // the default target always follows the switch statement int defaultTargetAddress = codeAddress + instruction.getCodeUnits(); Unit defaultTarget = body.instructionAtAddress(defaultTargetAddress).getUnit(); List<IntConstant> lookupValues = new ArrayList<IntConstant>(); List<Unit> targets = new ArrayList<Unit>(); for (SwitchElement se : seList) { lookupValues.add(IntConstant.v(se.getKey())); int offset = se.getOffset(); targets.add(body.instructionAtAddress(codeAddress + offset).getUnit()); } LookupSwitchStmt switchStmt = Jimple.v().newLookupSwitchStmt(key, lookupValues, targets, defaultTarget); setUnit(switchStmt); addTags(switchStmt); if (IDalvikTyper.ENABLE_DVKTYPER) { DalvikTyper.v().setType(switchStmt.getKeyBox(), IntType.v(), true); } return switchStmt; }
public SparseSwitchPad(SwitchPayload inst, int defaultOffset) { int i = 0; this.values = new int[ inst.getSwitchElements().size() ]; this.offsets = new int[ inst.getSwitchElements().size() ]; for(SwitchElement elt : inst.getSwitchElements()) { values[i] = elt.getKey(); offsets[i++] = elt.getOffset(); } this.defaultOffset = defaultOffset; }