protected void writeRegister(IndentingWriter writer, int registerNumber) throws IOException { methodDef.registerFormatter.writeTo(writer, registerNumber); }
private List<MethodItem> getMethodItems() { ArrayList<MethodItem> methodItems = new ArrayList<MethodItem>(); if ((classDef.options.registerInfo != 0) || (classDef.options.normalizeVirtualMethods) || (classDef.options.deodex && needsAnalyzed())) { addAnalyzedInstructionMethodItems(methodItems); } else { addInstructionMethodItems(methodItems); } addTries(methodItems); if (classDef.options.debugInfo) { addDebugInfo(methodItems); } if (classDef.options.sequentialLabels) { setLabelSequentialNumbers(); } for (LabelMethodItem labelMethodItem: labelCache.getLabels()) { methodItems.add(labelMethodItem); } Collections.sort(methodItems); return methodItems; }
private void setLabelSequentialNumbers() { HashMap<String, Integer> nextLabelSequenceByType = new HashMap<String, Integer>(); ArrayList<LabelMethodItem> sortedLabels = new ArrayList<LabelMethodItem>(labelCache.getLabels()); //sort the labels by their location in the method Collections.sort(sortedLabels); for (LabelMethodItem labelMethodItem: sortedLabels) { Integer labelSequence = nextLabelSequenceByType.get(labelMethodItem.getLabelPrefix()); if (labelSequence == null) { labelSequence = 0; } labelMethodItem.setLabelSequence(labelSequence); nextLabelSequenceByType.put(labelMethodItem.getLabelPrefix(), labelSequence + 1); } }
if (reference instanceof CallSiteReference) { referenceWritable = indentingWriter -> { ReferenceFormatter.writeCallSiteReference(indentingWriter, (CallSiteReference)reference); }; } else { String referenceString = writeInvalidItemIndex(ex, referenceInstruction.getReferenceType(), writer); referenceWritable = indentingWriter -> writer.write(referenceString); } catch (InvalidItemIndex ex) { commentOutInstruction = true; String referenceString = writeInvalidItemIndex(ex, dualReferenceInstruction.getReferenceType2(), writer); referenceWritable2 = indentingWriter -> indentingWriter.write(referenceString); int baseAddress = methodDef.getPackedSwitchBaseAddress( this.codeAddress + ((Instruction31t)instruction).getCodeOffset()); if (baseAddress == -1) { baseAddress = methodDef.getSparseSwitchBaseAddress( this.codeAddress + ((Instruction31t)instruction).getCodeOffset()); if (baseAddress == -1) { case FILL_ARRAY_DATA: try { methodDef.findPayloadOffset(this.codeAddress + ((Instruction31t)instruction).getCodeOffset(), Opcode.ARRAY_PAYLOAD); } catch (InvalidSwitchPayload ex) {
public void writeTo(IndentingWriter writer) throws IOException { writeClass(writer); writeSuper(writer); writeSourceFile(writer); writeInterfaces(writer); writeAnnotations(writer); Set<String> staticFields = writeStaticFields(writer); writeInstanceFields(writer, staticFields); Set<String> directMethods = writeDirectMethods(writer); writeVirtualMethods(writer, directMethods); }
if (analysisException != null) { methodItems.add(new CommentMethodItem( String.format("AnalysisException: %s", analysisException.getMessage()), analysisException.codeAddress, Integer.MIN_VALUE)); AnalyzedInstruction instruction = instructions.get(i); MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem( this, currentCodeAddress, instruction.getInstruction()); methodItems.add(new CommentedOutMethodItem( InstructionMethodItemFactory.makeInstructionFormatMethodItem( this, currentCodeAddress, instruction.getOriginalInstruction()))); methodItems.add(new BlankMethodItem(currentCodeAddress)); !instruction.getInstruction().getOpcode().format.isPayloadFormat) { methodItems.add( new PreInstructionRegisterInfoMethodItem(classDef.options.registerInfo, methodAnalyzer, registerFormatter, instruction, currentCodeAddress)); new PostInstructionRegisterInfoMethodItem(registerFormatter, instruction, currentCodeAddress));
writeAccessFlags(writer, method.getAccessFlags()); writer.write(method.getName()); writer.write("("); writeParameters(writer, method, methodParameters, classDef.options); registerFormatter = new RegisterFormatter(classDef.options, methodImpl.getRegisterCount(), parameterRegisterCount); containingClass = method.getDefiningClass(); AnnotationFormatter.writeTo(writer, method.getAnnotations(), containingClass); List<MethodItem> methodItems = getMethodItems(); for (MethodItem methodItem: methodItems) { if (methodItem.writeTo(writer)) { writer.write('\n');
private static String baksmali(DexBackedClassDef def) throws IOException { baksmaliOptions opts = new baksmaliOptions(); opts.outputDebugInfo = false; opts.syntheticAccessorResolver = new SyntheticAccessorResolver(Collections.EMPTY_LIST); ClassDefinition classDefinition = new ClassDefinition(opts, def); StringWriter bufWriter = new StringWriter(); IndentingWriter writer = new IndentingWriter(bufWriter); classDefinition.writeTo((IndentingWriter) writer); writer.flush(); return bufWriter.toString(); } }
Instruction instruction = effectiveInstructions.get(i); MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, currentCodeAddress, instruction); methodItems.add(new BlankMethodItem(currentCodeAddress)); classDef.options.syntheticAccessorResolver.getAccessedMember(methodReference); if (accessedMember != null) { methodItems.add(new SyntheticAccessCommentMethodItem(accessedMember, currentCodeAddress));
public static void writeEmptyMethodTo(IndentingWriter writer, Method method, BaksmaliOptions options) throws IOException { writer.write(".method "); writeAccessFlags(writer, method.getAccessFlags()); writer.write(method.getName()); writer.write("("); ImmutableList<MethodParameter> methodParameters = ImmutableList.copyOf(method.getParameters()); for (MethodParameter parameter: methodParameters) { writer.write(parameter.getType()); } writer.write(")"); writer.write(method.getReturnType()); writer.write('\n'); writer.indent(4); writeParameters(writer, method, methodParameters, options); String containingClass = null; if (options.implicitReferences) { containingClass = method.getDefiningClass(); } AnnotationFormatter.writeTo(writer, method.getAnnotations(), containingClass); writer.deindent(4); writer.write(".end method\n"); }
ReferenceFormatter.writeStringReference(writer, parameterName); containingClass = method.getDefiningClass(); AnnotationFormatter.writeTo(writer, annotations, containingClass); writer.deindent(4); writer.write(".end param\n");
int targetOffset = codeOffset + ((OffsetInstruction)instruction).getCodeOffset(); try { targetOffset = findPayloadOffset(targetOffset, Opcode.PACKED_SWITCH_PAYLOAD); } catch (InvalidSwitchPayload ex) { valid = false; if (packedSwitchMap.get(targetOffset, -1) != -1) { Instruction payloadInstruction = findSwitchPayload(targetOffset, Opcode.PACKED_SWITCH_PAYLOAD); targetOffset = endOffset; effectiveInstructions.set(i, new ImmutableInstruction31t(opcode, int targetOffset = codeOffset + ((OffsetInstruction)instruction).getCodeOffset(); try { targetOffset = findPayloadOffset(targetOffset, Opcode.SPARSE_SWITCH_PAYLOAD); } catch (InvalidSwitchPayload ex) { valid = false; if (sparseSwitchMap.get(targetOffset, -1) != -1) { Instruction payloadInstruction = findSwitchPayload(targetOffset, Opcode.SPARSE_SWITCH_PAYLOAD); targetOffset = endOffset; effectiveInstructions.set(i, new ImmutableInstruction31t(opcode,
public Instruction findSwitchPayload(int targetOffset, Opcode type) { int targetIndex; try { targetIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(targetOffset); } catch (InvalidInstructionOffset ex) { throw new InvalidSwitchPayload(targetOffset); } //TODO: does dalvik let you pad with multiple nops? //TODO: does dalvik let a switch instruction point to a non-payload instruction? Instruction instruction = instructions.get(targetIndex); if (instruction.getOpcode() != type) { // maybe it's pointing to a NOP padding instruction. Look at the next instruction if (instruction.getOpcode() == Opcode.NOP) { targetIndex += 1; if (targetIndex < instructions.size()) { instruction = instructions.get(targetIndex); if (instruction.getOpcode() == type) { return instruction; } } } throw new InvalidSwitchPayload(targetOffset); } else { return instruction; } }
public boolean equals(Object o) { if (!(o instanceof LabelMethodItem)) { return false; } return this.compareTo((MethodItem)o) == 0; }
protected void writeInvokeRangeRegisters(IndentingWriter writer) throws IOException { RegisterRangeInstruction instruction = (RegisterRangeInstruction)this.instruction; int regCount = instruction.getRegisterCount(); if (regCount == 0) { writer.write("{}"); } else { int startRegister = instruction.getStartRegister(); methodDef.registerFormatter.writeRegisterRange(writer, startRegister, startRegister+regCount-1); } }
CatchMethodItem catchMethodItem = new CatchMethodItem(classDef.options, labelCache, lastCoveredAddress, handler.getExceptionType(), startAddress, endAddress, handlerAddress); methodItems.add(catchMethodItem);
public void writeTargetTo(IndentingWriter writer) throws IOException { target.writeTo(writer); } }
public void writeTo(IndentingWriter writer) throws IOException { writeClass(writer); writeSuper(writer); writeSourceFile(writer); writeInterfaces(writer); writeAnnotations(writer); Set<String> staticFields = writeStaticFields(writer); writeInstanceFields(writer, staticFields); Set<String> directMethods = writeDirectMethods(writer); writeVirtualMethods(writer, directMethods); }
public int findPayloadOffset(int targetOffset, Opcode type) { int targetIndex; try { targetIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(targetOffset); } catch (InvalidInstructionOffset ex) { throw new InvalidSwitchPayload(targetOffset); } //TODO: does dalvik let you pad with multiple nops? //TODO: does dalvik let a switch instruction point to a non-payload instruction? Instruction instruction = instructions.get(targetIndex); if (instruction.getOpcode() != type) { // maybe it's pointing to a NOP padding instruction. Look at the next instruction if (instruction.getOpcode() == Opcode.NOP) { targetIndex += 1; if (targetIndex < instructions.size()) { instruction = instructions.get(targetIndex); if (instruction.getOpcode() == type) { return instructionOffsetMap.getInstructionCodeOffset(targetIndex); } } } throw new InvalidSwitchPayload(targetOffset); } else { return targetOffset; } }
public boolean equals(Object o) { if (!(o instanceof LabelMethodItem)) { return false; } return this.compareTo((MethodItem)o) == 0; }