Search in sources :

Example 1 with SmaliBaseVisitor

use of com.googlecode.d2j.smali.antlr4.SmaliBaseVisitor in project dex2jar by pxb1988.

the class AntlrSmaliUtil method acceptCode.

private static void acceptCode(SmaliParser.SMethodContext ctx, final M m, DexMethodVisitor dexMethodVisitor) {
    if (ctx == null || dexMethodVisitor == null) {
        return;
    }
    final DexCodeVisitor dexCodeVisitor = dexMethodVisitor.visitCode();
    if (dexCodeVisitor == null) {
        return;
    }
    final SmaliCodeVisitor scv = new SmaliCodeVisitor(dexCodeVisitor);
    final DexDebugVisitor dexDebugVisitor = scv.visitDebug();
    final List<SmaliParser.SInstructionContext> instructionContexts = ctx.sInstruction();
    final SmaliBaseVisitor v = new SmaliBaseVisitor() {

        @Override
        public Object visitFregisters(SmaliParser.FregistersContext ctx) {
            return null;
        }

        @Override
        public Object visitFlocals(SmaliParser.FlocalsContext ctx) {
            return null;
        }

        @Override
        public Object visitFline(SmaliParser.FlineContext ctx) {
            if (dexDebugVisitor != null) {
                DexLabel dexLabel = new DexLabel();
                scv.visitLabel(dexLabel);
                dexDebugVisitor.visitLineNumber(Utils.parseInt(ctx.line.getText()), dexLabel);
            }
            return null;
        }

        @Override
        public Object visitFend(SmaliParser.FendContext ctx) {
            if (dexDebugVisitor != null) {
                DexLabel dexLabel = new DexLabel();
                scv.visitLabel(dexLabel);
                int reg = m.pareReg(ctx.r.getText());
                dexDebugVisitor.visitEndLocal(reg, dexLabel);
            }
            return null;
        }

        @Override
        public Object visitFlocal(SmaliParser.FlocalContext ctx) {
            if (dexDebugVisitor != null) {
                DexLabel dexLabel = new DexLabel();
                scv.visitLabel(dexLabel);
                int reg = m.pareReg(ctx.r.getText());
                String name;
                String type;
                if (ctx.v1 != null) {
                    Field fld = parseFieldAndUnescape("Lt;", ctx.v1.getText());
                    name = fld.getName();
                    type = fld.getType();
                } else if (ctx.v2 != null) {
                    String txt = ctx.v2.getText();
                    int i = findString(txt, 1, txt.length(), '\"');
                    name = unescapeStr(txt.substring(0, i + 1));
                    type = unEscapeId(txt.substring(i + 2));
                } else {
                    if (ctx.name2 != null) {
                        name = unescapeStr(ctx.name2.getText());
                    } else {
                        name = unEscapeId(ctx.name1.getText());
                    }
                    type = unEscapeId(ctx.type.getText());
                }
                String sig = ctx.sig == null ? null : unescapeStr(ctx.sig.getText());
                dexDebugVisitor.visitStartLocal(reg, dexLabel, name, type, sig);
            }
            return null;
        }

        @Override
        public Object visitFrestart(SmaliParser.FrestartContext ctx) {
            if (dexDebugVisitor != null) {
                DexLabel dexLabel = new DexLabel();
                scv.visitLabel(dexLabel);
                int reg = m.pareReg(ctx.r.getText());
                dexDebugVisitor.visitRestartLocal(reg, dexLabel);
            }
            return null;
        }

        @Override
        public Object visitFprologue(SmaliParser.FprologueContext ctx) {
            if (dexDebugVisitor != null) {
                DexLabel dexLabel = new DexLabel();
                scv.visitLabel(dexLabel);
                dexDebugVisitor.visitPrologue(dexLabel);
            }
            return null;
        }

        Map<String, DexLabel> labelMap = new HashMap<>();

        @Override
        public Object visitSLabel(SmaliParser.SLabelContext ctx) {
            scv.visitLabel(getLabel(ctx.label.getText()));
            return null;
        }

        @Override
        public Object visitFspareswitch(SmaliParser.FspareswitchContext ctx) {
            List<TerminalNode> ints = ctx.INT();
            List<TerminalNode> ts = ctx.LABEL();
            int[] cases = new int[ts.size()];
            DexLabel[] labels = new DexLabel[ts.size()];
            for (int i = 0; i < ts.size(); i++) {
                cases[i] = parseInt(ints.get(i).getSymbol().getText());
                labels[i] = getLabel(ts.get(i).getSymbol().getText());
            }
            scv.dSparseSwitch(cases, labels);
            return null;
        }

        @Override
        public Object visitFarraydata(SmaliParser.FarraydataContext ctx) {
            int size = parseInt(ctx.size.getText());
            List<SmaliParser.SBaseValueContext> ts = ctx.sBaseValue();
            byte[] ps = new byte[ts.size()];
            for (int i = 0; i < ts.size(); i++) {
                ps[i] = ((Number) parseBaseValue(ts.get(i))).byteValue();
            }
            scv.dArrayData(size, ps);
            return null;
        }

        Op getOp(Token t) {
            return Utils.getOp(t.getText());
        }

        @Override
        public Object visitF0x(SmaliParser.F0xContext ctx) {
            scv.visitStmt0R(getOp(ctx.op));
            return null;
        }

        @Override
        public Object visitF0t(SmaliParser.F0tContext ctx) {
            scv.visitJumpStmt(getOp(ctx.op), 0, 0, getLabel(ctx.target.getText()));
            return null;
        }

        @Override
        public Object visitF1x(SmaliParser.F1xContext ctx) {
            scv.visitStmt1R(getOp(ctx.op), m.pareReg(ctx.r1.getText()));
            return null;
        }

        @Override
        public Object visitFconst(SmaliParser.FconstContext ctx) {
            Op op = getOp(ctx.op);
            int r = m.pareReg(ctx.r1.getText());
            Token cst = ctx.cst;
            switch(op) {
                case CONST_STRING:
                case CONST_STRING_JUMBO:
                    scv.visitConstStmt(op, r, unescapeStr(cst.getText()));
                    break;
                case CONST_CLASS:
                    scv.visitConstStmt(op, r, new DexType(unEscapeId(cst.getText())));
                    break;
                case CHECK_CAST:
                case NEW_INSTANCE:
                    scv.visitTypeStmt(op, r, 0, unEscapeId(cst.getText()));
                    break;
                case CONST_WIDE:
                    scv.visitConstStmt(op, r, cst.getType() == SmaliLexer.INT ? ((long) parseInt(cst.getText())) : parseLong(cst.getText()));
                    break;
                case CONST_WIDE_16:
                    {
                        long v;
                        if (cst.getType() == SmaliLexer.LONG) {
                            v = parseLong(cst.getText());
                        } else {
                            v = (short) parseInt(cst.getText());
                        }
                        scv.visitConstStmt(op, r, v);
                    }
                    break;
                case CONST_WIDE_32:
                    {
                        long v;
                        if (cst.getType() == SmaliLexer.LONG) {
                            v = parseLong(cst.getText());
                        } else {
                            v = parseInt(cst.getText());
                        }
                        scv.visitConstStmt(op, r, v);
                    }
                    break;
                case CONST_WIDE_HIGH16:
                    {
                        long v;
                        if (cst.getType() == SmaliLexer.LONG) {
                            v = parseLong(cst.getText());
                        } else {
                            v = (short) parseInt(cst.getText());
                            v <<= 48;
                        }
                        scv.visitConstStmt(op, r, v);
                    }
                    break;
                case CONST:
                case CONST_4:
                case CONST_16:
                    {
                        int v = parseInt(cst.getText());
                        scv.visitConstStmt(op, r, v);
                    }
                    break;
                case CONST_HIGH16:
                    {
                        int v = parseInt(cst.getText());
                        v <<= 16;
                        scv.visitConstStmt(op, r, v);
                    }
                    break;
                default:
                    throw new RuntimeException();
            }
            return null;
        }

        @Override
        public Object visitFf1c(SmaliParser.Ff1cContext ctx) {
            int r = m.pareReg(ctx.r1.getText());
            Field field = parseFieldAndUnescape(ctx.fld.getText());
            scv.visitFieldStmt(getOp(ctx.op), r, 0, field);
            return null;
        }

        @Override
        public Object visitFt2c(SmaliParser.Ft2cContext ctx) {
            int r1 = m.pareReg(ctx.r1.getText());
            int r2 = m.pareReg(ctx.r2.getText());
            scv.visitTypeStmt(getOp(ctx.op), r1, r2, unEscapeId(ctx.type.getText()));
            return null;
        }

        @Override
        public Object visitFf2c(SmaliParser.Ff2cContext ctx) {
            int r1 = m.pareReg(ctx.r1.getText());
            int r2 = m.pareReg(ctx.r2.getText());
            scv.visitFieldStmt(getOp(ctx.op), r1, r2, parseFieldAndUnescape(ctx.fld.getText()));
            return null;
        }

        @Override
        public Object visitF2x(SmaliParser.F2xContext ctx) {
            int r1 = m.pareReg(ctx.r1.getText());
            int r2 = m.pareReg(ctx.r2.getText());
            scv.visitStmt2R(getOp(ctx.op), r1, r2);
            return null;
        }

        @Override
        public Object visitF3x(SmaliParser.F3xContext ctx) {
            int r1 = m.pareReg(ctx.r1.getText());
            int r2 = m.pareReg(ctx.r2.getText());
            int r3 = m.pareReg(ctx.r3.getText());
            scv.visitStmt3R(getOp(ctx.op), r1, r2, r3);
            return null;
        }

        @Override
        public Object visitFt5c(SmaliParser.Ft5cContext ctx) {
            Op op = getOp(ctx.op);
            List<TerminalNode> ts = ctx.REGISTER();
            int[] rs = new int[ts.size()];
            for (int i = 0; i < ts.size(); i++) {
                rs[i] = m.pareReg(ts.get(i).getSymbol().getText());
            }
            scv.visitFilledNewArrayStmt(op, rs, unEscapeId(ctx.type.getText()));
            return null;
        }

        @Override
        public Object visitFm5c(SmaliParser.Fm5cContext ctx) {
            Op op = getOp(ctx.op);
            List<TerminalNode> ts = ctx.REGISTER();
            int[] rs = new int[ts.size()];
            for (int i = 0; i < ts.size(); i++) {
                rs[i] = m.pareReg(ts.get(i).getSymbol().getText());
            }
            scv.visitMethodStmt(op, rs, parseMethodAndUnescape(ctx.method.getText()));
            return null;
        }

        @Override
        public Object visitFmrc(SmaliParser.FmrcContext ctx) {
            if (ctx.rstart != null) {
                int start = m.pareReg(ctx.rstart.getText());
                int end = m.pareReg(ctx.rend.getText());
                int size = end - start + 1;
                int[] rs = new int[size];
                for (int i = 0; i < size; i++) {
                    rs[i] = start + i;
                }
                scv.visitMethodStmt(getOp(ctx.op), rs, parseMethodAndUnescape(ctx.method.getText()));
            } else {
                scv.visitMethodStmt(getOp(ctx.op), new int[0], parseMethodAndUnescape(ctx.method.getText()));
            }
            return null;
        }

        @Override
        public Object visitFtrc(SmaliParser.FtrcContext ctx) {
            if (ctx.rstart != null) {
                int start = m.pareReg(ctx.rstart.getText());
                int end = m.pareReg(ctx.rend.getText());
                int size = end - start + 1;
                int[] rs = new int[size];
                for (int i = 0; i < size; i++) {
                    rs[i] = start + i;
                }
                scv.visitFilledNewArrayStmt(getOp(ctx.op), rs, unEscapeId(ctx.type.getText()));
            } else {
                scv.visitFilledNewArrayStmt(getOp(ctx.op), new int[0], unEscapeId(ctx.type.getText()));
            }
            return null;
        }

        @Override
        public Object visitF31t(SmaliParser.F31tContext ctx) {
            scv.visitF31tStmt(getOp(ctx.op), m.pareReg(ctx.r1.getText()), getLabel(ctx.label.getText()));
            return null;
        }

        @Override
        public Object visitF1t(SmaliParser.F1tContext ctx) {
            scv.visitJumpStmt(getOp(ctx.op), m.pareReg(ctx.r1.getText()), 0, getLabel(ctx.label.getText()));
            return null;
        }

        @Override
        public Object visitF2t(SmaliParser.F2tContext ctx) {
            scv.visitJumpStmt(getOp(ctx.op), m.pareReg(ctx.r1.getText()), m.pareReg(ctx.r2.getText()), getLabel(ctx.label.getText()));
            return null;
        }

        @Override
        public Object visitF2sb(SmaliParser.F2sbContext ctx) {
            scv.visitStmt2R1N(getOp(ctx.op), m.pareReg(ctx.r1.getText()), m.pareReg(ctx.r2.getText()), parseInt(ctx.lit.getText()));
            return null;
        }

        @Override
        public Object visitFpackageswitch(SmaliParser.FpackageswitchContext ctx) {
            int start = parseInt(ctx.start.getText());
            List<TerminalNode> ts = ctx.LABEL();
            DexLabel[] labels = new DexLabel[ts.size()];
            for (int i = 0; i < ts.size(); i++) {
                labels[i] = getLabel(ts.get(i).getSymbol().getText());
            }
            scv.dPackedSwitch(start, labels);
            return null;
        }

        @Override
        public Object visitFcache(SmaliParser.FcacheContext ctx) {
            scv.visitTryCatch(getLabel(ctx.start.getText()), getLabel(ctx.end.getText()), new DexLabel[] { getLabel(ctx.handle.getText()) }, new String[] { unEscapeId(ctx.type.getText()) });
            return null;
        }

        @Override
        public Object visitFcacheall(SmaliParser.FcacheallContext ctx) {
            scv.visitTryCatch(getLabel(ctx.start.getText()), getLabel(ctx.end.getText()), new DexLabel[] { getLabel(ctx.handle.getText()) }, new String[] { null });
            return null;
        }

        DexLabel getLabel(String name) {
            DexLabel dexLabel = labelMap.get(name);
            if (dexLabel == null) {
                dexLabel = new DexLabel();
                labelMap.put(name, dexLabel);
            }
            return dexLabel;
        }

        @Override
        public Object visitFepiogue(SmaliParser.FepiogueContext ctx) {
            if (dexDebugVisitor != null) {
                DexLabel dexLabel = new DexLabel();
                scv.visitLabel(dexLabel);
                dexDebugVisitor.visitEpiogue(dexLabel);
            }
            return null;
        }
    };
    scv.visitRegister(m.total);
    if (dexDebugVisitor != null) {
        for (int i = 0; i < m.paramNames.length; i++) {
            String name = m.paramNames[i];
            if (name != null) {
                dexDebugVisitor.visitParameterName(i, name);
            }
        }
    }
    for (SmaliParser.SInstructionContext instructionContext : instructionContexts) {
        ParserRuleContext parserRuleContext = (ParserRuleContext) instructionContext.getChild(0);
        parserRuleContext.accept(v);
    }
    scv.visitEnd();
}
Also used : Op(com.googlecode.d2j.reader.Op) Token(org.antlr.v4.runtime.Token) SmaliBaseVisitor(com.googlecode.d2j.smali.antlr4.SmaliBaseVisitor) ParserRuleContext(org.antlr.v4.runtime.ParserRuleContext) HashMap(java.util.HashMap) Map(java.util.Map) SmaliParser(com.googlecode.d2j.smali.antlr4.SmaliParser) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode)

Aggregations

Op (com.googlecode.d2j.reader.Op)1 SmaliBaseVisitor (com.googlecode.d2j.smali.antlr4.SmaliBaseVisitor)1 SmaliParser (com.googlecode.d2j.smali.antlr4.SmaliParser)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 ParserRuleContext (org.antlr.v4.runtime.ParserRuleContext)1 Token (org.antlr.v4.runtime.Token)1 TerminalNode (org.antlr.v4.runtime.tree.TerminalNode)1