@Override public void visitJumpStmt(Op op, int a, int b, DexLabel label) { if (op.format == InstructionFormat.kFmt21t || op.format == InstructionFormat.kFmt31t) { out.s(op.displayName + " " + reg(a) + ", " + xLabel(label)); } else if (op.format == InstructionFormat.kFmt22t) { out.s(op.displayName + " " + reg(a) + ", " + reg(b) + ", " + xLabel(label)); } else { out.s(op.displayName + " " + xLabel(label)); } }
@Override public void visitEnd() { for (Map.Entry<DexLabel, Object> e : this.appendLast) { visitLabel(e.getKey()); Object v = e.getValue(); if (v instanceof SparseSwitchStmt) { out.push(); for (int i = 0; i < ss.cases.length; i++) { out.s("%d -> %s", ss.cases[i], xLabel(ss.labels[i])); out.push(); for (DexLabel label : ps.labels) { out.s(xLabel(label));
@Override public void visitTryCatch(DexLabel start, DexLabel end, DexLabel[] handler, String[] type) { for (int i = 0; i < type.length; i++) { String t = type[i]; if (t == null) { out.s(".catchall { %s .. %s } %s", xLabel(start), xLabel(end), xLabel(handler[i])); } else { out.s(".catch %s { %s .. %s } %s", t, xLabel(start), xLabel(end), xLabel(handler[i])); } } }
DexCodeVisitor dexCodeVisitor = new BaksmaliCodeDumper(out, useParameterRegisters, useLocals, nextLabelNumber, codeNode.totalRegister - inRegs, usedLabel, debugLabelMap); accept(out, codeNode, dexCodeVisitor);
@Override public void visitLabel(DexLabel label) { if (usedLabel.contains(label)) { out.s(xLabel(label)); } List<DexDebugNode.DexDebugOpNode> dOps = debugLabelMap.get(label); if (dOps != null) { for (DexDebugNode.DexDebugOpNode dOp : dOps) { dOp.accept(debugDumper); } } }
@Override public void visitPackedSwitchStmt(Op op, int ra, int first_case, DexLabel[] labels) { DexLabel dx = new DexLabel(); dx.displayName = "L" + nextLabelNumber++; usedLabel.add(dx); out.s(op.displayName + " " + reg(ra) + ", " + xLabel(dx)); appendLast.add(new AbstractMap.SimpleEntry<DexLabel, Object>(dx, new PackedSwitchStmt(first_case, labels))); }
@Override public void visitRestartLocal(int reg, DexLabel label) { out.s(".restart local %s", reg(reg)); } };
@Override public void visitSparseSwitchStmt(Op op, int ra, int[] cases, DexLabel[] labels) { DexLabel dx = new DexLabel(); dx.displayName = "L" + nextLabelNumber++; usedLabel.add(dx); out.s(op.displayName + " " + reg(ra) + ", " + xLabel(dx)); appendLast.add(new AbstractMap.SimpleEntry<DexLabel, Object>(dx, new SparseSwitchStmt(cases, labels))); }
@Override public void visitStmt1R(Op op, int a) { out.s(op.displayName + " " + reg(a)); }
@Override public void visitEndLocal(int reg, DexLabel label) { out.s(".end local %s", reg(reg)); }
@Override public void visitFieldStmt(Op op, int a, int b, Field field) { if (op.format == InstructionFormat.kFmt22c) {// iget,iput out.s("%s %s, %s, %s", op.displayName, reg(a), reg(b), BaksmaliDumper.escapeField(field)); } else { out.s("%s %s, %s", op.displayName, reg(a), BaksmaliDumper.escapeField(field)); } }
@Override public void visitFilledNewArrayStmt(Op op, int[] args, String type) { if (args.length > 0) { if (op.format == InstructionFormat.kFmt3rc) { // invoke-x/range out.s("%s { %d .. %d }, %s", op.displayName, reg(args[0]), reg(args[args.length - 1]), BaksmaliDumper.escapeType(type)); } else { StringBuilder buff = new StringBuilder(); boolean first = true; for (int i : args) { if (first) { first = false; } else { buff.append(", "); } buff.append(reg(i)); } out.s("%s { %s }, %s", op.displayName, buff, BaksmaliDumper.escapeType(type)); } } else { out.s("%s { }, %s", op.displayName, BaksmaliDumper.escapeType(type)); } }
@Override public void visitMethodStmt(Op op, int[] args, String name, Proto proto, MethodHandle bsm, Object... bsmArgs) { StringBuilder sb = new StringBuilder(); sb.append("{ ").append( BaksmaliDumper.escapeValue(bsm)).append(", ").append(BaksmaliDumper.escapeValue(name)).append(", ").append(BaksmaliDumper.escapeMethodDesc(proto)); for(Object o: bsmArgs) { sb.append(", ").append(BaksmaliDumper.escapeValue(o)); } sb.append("}"); if (args.length > 0) { if (op.format == InstructionFormat.kFmt3rc) { // invoke-x/range out.s("%s { %s .. %s }, %s", op.displayName, reg(args[0]), reg(args[args.length - 1]), sb); } else { boolean first = true; StringBuilder buff = new StringBuilder(); for (int i : args) { if (first) { first = false; } else { buff.append(", "); } buff.append(reg(i)); } out.s("%s { %s }, %s", op.displayName, buff, sb); } } else { out.s("%s { }, %s", op.displayName, sb); } }
@Override public void visitMethodStmt(Op op, int[] args, Method method) { if (args.length > 0) { if (op.format == InstructionFormat.kFmt3rc) { // invoke-x/range out.s("%s { %s .. %s }, %s", op.displayName, reg(args[0]), reg(args[args.length - 1]), BaksmaliDumper.escapeMethod(method)); } else { boolean first = true; StringBuilder buff = new StringBuilder(); for (int i : args) { if (first) { first = false; } else { buff.append(", "); } buff.append(reg(i)); } out.s("%s { %s }, %s", op.displayName, buff, BaksmaliDumper.escapeMethod(method)); } } else { out.s("%s { }, %s", op.displayName, BaksmaliDumper.escapeMethod(method)); } }
@Override public void visitStartLocal(int reg, DexLabel label, String name, String type, String signature) { super.visitStartLocal(reg, label, name, type, signature); if (signature == null) { out.s(".local %s, %s:%s", reg(reg), BaksmaliDumper.escapeValue(name), type); } else { out.s(".local %s, %s:%s, %s", reg(reg), BaksmaliDumper.escapeValue(name), type, BaksmaliDumper.escapeValue(signature)); } }