Search in sources :

Example 1 with CodegenException

use of jadx.core.utils.exceptions.CodegenException in project jadx by skylot.

the class InsnGen method makeInsn.

protected boolean makeInsn(InsnNode insn, CodeWriter code, Flags flag) throws CodegenException {
    try {
        Set<Flags> state = EnumSet.noneOf(Flags.class);
        if (flag == Flags.BODY_ONLY || flag == Flags.BODY_ONLY_NOWRAP) {
            state.add(flag);
            makeInsnBody(code, insn, state);
        } else {
            if (flag != Flags.INLINE) {
                code.startLineWithNum(insn.getSourceLine());
            }
            if (insn.getResult() != null && !insn.contains(AFlag.ARITH_ONEARG)) {
                assignVar(code, insn);
                code.add(" = ");
            }
            makeInsnBody(code, insn, state);
            if (flag != Flags.INLINE) {
                code.add(';');
            }
        }
    } catch (Throwable th) {
        throw new CodegenException(mth, "Error generate insn: " + insn, th);
    }
    return true;
}
Also used : CodegenException(jadx.core.utils.exceptions.CodegenException)

Example 2 with CodegenException

use of jadx.core.utils.exceptions.CodegenException in project jadx by skylot.

the class InsnGen method addArg.

public void addArg(CodeWriter code, InsnArg arg, boolean wrap) throws CodegenException {
    if (arg.isRegister()) {
        code.add(mgen.getNameGen().useArg((RegisterArg) arg));
    } else if (arg.isLiteral()) {
        code.add(lit((LiteralArg) arg));
    } else if (arg.isInsnWrap()) {
        Flags flag = wrap ? Flags.BODY_ONLY : Flags.BODY_ONLY_NOWRAP;
        makeInsn(((InsnWrapArg) arg).getWrapInsn(), code, flag);
    } else if (arg.isNamed()) {
        code.add(((Named) arg).getName());
    } else if (arg.isField()) {
        FieldArg f = (FieldArg) arg;
        if (f.isStatic()) {
            staticField(code, f.getField());
        } else {
            instanceField(code, f.getField(), f.getInstanceArg());
        }
    } else {
        throw new CodegenException("Unknown arg type " + arg);
    }
}
Also used : Named(jadx.core.dex.instructions.args.Named) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) CodegenException(jadx.core.utils.exceptions.CodegenException) FieldArg(jadx.core.dex.instructions.args.FieldArg)

Example 3 with CodegenException

use of jadx.core.utils.exceptions.CodegenException in project jadx by skylot.

the class DebugUtils method printInsns.

private static void printInsns(MethodNode mth, String indent, IBlock block) {
    for (InsnNode insn : block.getInstructions()) {
        try {
            MethodGen mg = MethodGen.getFallbackMethodGen(mth);
            InsnGen ig = new InsnGen(mg, true);
            CodeWriter code = new CodeWriter();
            ig.makeInsn(insn, code);
            String insnStr = code.toString().substring(CodeWriter.NL.length());
            LOG.debug("{} - {}", indent, insnStr);
        } catch (CodegenException e) {
            LOG.debug("{} - {}", indent, insn);
        }
    }
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) InsnGen(jadx.core.codegen.InsnGen) CodegenException(jadx.core.utils.exceptions.CodegenException) CodeWriter(jadx.core.codegen.CodeWriter) MethodGen(jadx.core.codegen.MethodGen)

Example 4 with CodegenException

use of jadx.core.utils.exceptions.CodegenException in project jadx by skylot.

the class IntegrationTest method decompileWithoutUnload.

private void decompileWithoutUnload(JadxDecompiler d, ClassNode cls) {
    cls.load();
    List<IDexTreeVisitor> passes = Jadx.getPassesList(d.getArgs(), new File(outDir));
    for (IDexTreeVisitor visitor : passes) {
        DepthTraversal.visit(visitor, cls);
    }
    try {
        new CodeGen(d.getArgs()).visit(cls);
    } catch (CodegenException e) {
        e.printStackTrace();
        fail(e.getMessage());
    }
// don't unload class
}
Also used : IDexTreeVisitor(jadx.core.dex.visitors.IDexTreeVisitor) CodegenException(jadx.core.utils.exceptions.CodegenException) CodeGen(jadx.core.codegen.CodeGen) File(java.io.File)

Example 5 with CodegenException

use of jadx.core.utils.exceptions.CodegenException in project jadx by skylot.

the class InsnGen method makeInsnBody.

private void makeInsnBody(CodeWriter code, InsnNode insn, Set<Flags> state) throws CodegenException {
    switch(insn.getType()) {
        case CONST_STR:
            String str = ((ConstStringNode) insn).getString();
            code.add(mth.dex().root().getStringUtils().unescapeString(str));
            break;
        case CONST_CLASS:
            ArgType clsType = ((ConstClassNode) insn).getClsType();
            useType(code, clsType);
            code.add(".class");
            break;
        case CONST:
            LiteralArg arg = (LiteralArg) insn.getArg(0);
            code.add(lit(arg));
            break;
        case MOVE:
            addArg(code, insn.getArg(0), false);
            break;
        case CHECK_CAST:
        case CAST:
            {
                boolean wrap = state.contains(Flags.BODY_ONLY);
                if (wrap) {
                    code.add('(');
                }
                code.add('(');
                useType(code, (ArgType) ((IndexInsnNode) insn).getIndex());
                code.add(") ");
                addArg(code, insn.getArg(0), true);
                if (wrap) {
                    code.add(')');
                }
                break;
            }
        case ARITH:
            makeArith((ArithNode) insn, code, state);
            break;
        case NEG:
            {
                boolean wrap = state.contains(Flags.BODY_ONLY);
                if (wrap) {
                    code.add('(');
                }
                code.add('-');
                addArg(code, insn.getArg(0));
                if (wrap) {
                    code.add(')');
                }
                break;
            }
        case RETURN:
            if (insn.getArgsCount() != 0) {
                code.add("return ");
                addArg(code, insn.getArg(0), false);
            } else {
                code.add("return");
            }
            break;
        case BREAK:
            code.add("break");
            LoopLabelAttr labelAttr = insn.get(AType.LOOP_LABEL);
            if (labelAttr != null) {
                code.add(' ').add(mgen.getNameGen().getLoopLabel(labelAttr));
            }
            break;
        case CONTINUE:
            code.add("continue");
            break;
        case THROW:
            code.add("throw ");
            addArg(code, insn.getArg(0), true);
            break;
        case CMP_L:
        case CMP_G:
            code.add('(');
            addArg(code, insn.getArg(0));
            code.add(" > ");
            addArg(code, insn.getArg(1));
            code.add(" ? 1 : (");
            addArg(code, insn.getArg(0));
            code.add(" == ");
            addArg(code, insn.getArg(1));
            code.add(" ? 0 : -1))");
            break;
        case INSTANCE_OF:
            {
                boolean wrap = state.contains(Flags.BODY_ONLY);
                if (wrap) {
                    code.add('(');
                }
                addArg(code, insn.getArg(0));
                code.add(" instanceof ");
                useType(code, (ArgType) ((IndexInsnNode) insn).getIndex());
                if (wrap) {
                    code.add(')');
                }
                break;
            }
        case CONSTRUCTOR:
            makeConstructor((ConstructorInsn) insn, code);
            break;
        case INVOKE:
            makeInvoke((InvokeNode) insn, code);
            break;
        case NEW_ARRAY:
            {
                ArgType arrayType = ((NewArrayNode) insn).getArrayType();
                code.add("new ");
                useType(code, arrayType.getArrayRootElement());
                code.add('[');
                addArg(code, insn.getArg(0));
                code.add(']');
                int dim = arrayType.getArrayDimension();
                for (int i = 0; i < dim - 1; i++) {
                    code.add("[]");
                }
                break;
            }
        case ARRAY_LENGTH:
            addArg(code, insn.getArg(0));
            code.add(".length");
            break;
        case FILLED_NEW_ARRAY:
            filledNewArray((FilledNewArrayNode) insn, code);
            break;
        case AGET:
            addArg(code, insn.getArg(0));
            code.add('[');
            addArg(code, insn.getArg(1), false);
            code.add(']');
            break;
        case APUT:
            addArg(code, insn.getArg(0));
            code.add('[');
            addArg(code, insn.getArg(1), false);
            code.add("] = ");
            addArg(code, insn.getArg(2), false);
            break;
        case IGET:
            {
                FieldInfo fieldInfo = (FieldInfo) ((IndexInsnNode) insn).getIndex();
                instanceField(code, fieldInfo, insn.getArg(0));
                break;
            }
        case IPUT:
            {
                FieldInfo fieldInfo = (FieldInfo) ((IndexInsnNode) insn).getIndex();
                instanceField(code, fieldInfo, insn.getArg(1));
                code.add(" = ");
                addArg(code, insn.getArg(0), false);
                break;
            }
        case SGET:
            staticField(code, (FieldInfo) ((IndexInsnNode) insn).getIndex());
            break;
        case SPUT:
            FieldInfo field = (FieldInfo) ((IndexInsnNode) insn).getIndex();
            staticField(code, field);
            code.add(" = ");
            addArg(code, insn.getArg(0), false);
            break;
        case STR_CONCAT:
            boolean wrap = state.contains(Flags.BODY_ONLY);
            if (wrap) {
                code.add('(');
            }
            for (Iterator<InsnArg> it = insn.getArguments().iterator(); it.hasNext(); ) {
                addArg(code, it.next());
                if (it.hasNext()) {
                    code.add(" + ");
                }
            }
            if (wrap) {
                code.add(')');
            }
            break;
        case MONITOR_ENTER:
            if (isFallback()) {
                code.add("monitor-enter(");
                addArg(code, insn.getArg(0));
                code.add(')');
            }
            break;
        case MONITOR_EXIT:
            if (isFallback()) {
                code.add("monitor-exit(");
                addArg(code, insn.getArg(0));
                code.add(')');
            }
            break;
        case TERNARY:
            makeTernary((TernaryInsn) insn, code, state);
            break;
        case ONE_ARG:
            addArg(code, insn.getArg(0));
            break;
        /* fallback mode instructions */
        case IF:
            fallbackOnlyInsn(insn);
            IfNode ifInsn = (IfNode) insn;
            code.add("if (");
            addArg(code, insn.getArg(0));
            code.add(' ');
            code.add(ifInsn.getOp().getSymbol()).add(' ');
            addArg(code, insn.getArg(1));
            code.add(") goto ").add(MethodGen.getLabelName(ifInsn.getTarget()));
            break;
        case GOTO:
            fallbackOnlyInsn(insn);
            code.add("goto ").add(MethodGen.getLabelName(((GotoNode) insn).getTarget()));
            break;
        case MOVE_EXCEPTION:
            fallbackOnlyInsn(insn);
            code.add("move-exception");
            break;
        case SWITCH:
            fallbackOnlyInsn(insn);
            SwitchNode sw = (SwitchNode) insn;
            code.add("switch(");
            addArg(code, insn.getArg(0));
            code.add(") {");
            code.incIndent();
            for (int i = 0; i < sw.getCasesCount(); i++) {
                String key = sw.getKeys()[i].toString();
                code.startLine("case ").add(key).add(": goto ");
                code.add(MethodGen.getLabelName(sw.getTargets()[i])).add(';');
            }
            code.startLine("default: goto ");
            code.add(MethodGen.getLabelName(sw.getDefaultCaseOffset())).add(';');
            code.decIndent();
            code.startLine('}');
            break;
        case FILL_ARRAY:
            fallbackOnlyInsn(insn);
            FillArrayNode arrayNode = (FillArrayNode) insn;
            Object data = arrayNode.getData();
            String arrStr;
            if (data instanceof int[]) {
                arrStr = Arrays.toString((int[]) data);
            } else if (data instanceof short[]) {
                arrStr = Arrays.toString((short[]) data);
            } else if (data instanceof byte[]) {
                arrStr = Arrays.toString((byte[]) data);
            } else if (data instanceof long[]) {
                arrStr = Arrays.toString((long[]) data);
            } else {
                arrStr = "?";
            }
            code.add('{').add(arrStr.substring(1, arrStr.length() - 1)).add('}');
            break;
        case NEW_INSTANCE:
            // only fallback - make new instance in constructor invoke
            fallbackOnlyInsn(insn);
            code.add("new ").add(insn.getResult().getType().toString());
            break;
        case PHI:
        case MERGE:
            fallbackOnlyInsn(insn);
            code.add(insn.getType().toString()).add("(");
            for (InsnArg insnArg : insn.getArguments()) {
                addArg(code, insnArg);
                code.add(' ');
            }
            code.add(")");
            break;
        default:
            throw new CodegenException(mth, "Unknown instruction: " + insn.getType());
    }
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) CodegenException(jadx.core.utils.exceptions.CodegenException) LoopLabelAttr(jadx.core.dex.attributes.nodes.LoopLabelAttr) ConstStringNode(jadx.core.dex.instructions.ConstStringNode) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) IfNode(jadx.core.dex.instructions.IfNode) SwitchNode(jadx.core.dex.instructions.SwitchNode) FillArrayNode(jadx.core.dex.instructions.FillArrayNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) ConstClassNode(jadx.core.dex.instructions.ConstClassNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) FieldInfo(jadx.core.dex.info.FieldInfo) GotoNode(jadx.core.dex.instructions.GotoNode)

Aggregations

CodegenException (jadx.core.utils.exceptions.CodegenException)6 InsnNode (jadx.core.dex.nodes.InsnNode)2 CodeGen (jadx.core.codegen.CodeGen)1 CodeWriter (jadx.core.codegen.CodeWriter)1 InsnGen (jadx.core.codegen.InsnGen)1 MethodGen (jadx.core.codegen.MethodGen)1 LoopLabelAttr (jadx.core.dex.attributes.nodes.LoopLabelAttr)1 FieldInfo (jadx.core.dex.info.FieldInfo)1 ConstClassNode (jadx.core.dex.instructions.ConstClassNode)1 ConstStringNode (jadx.core.dex.instructions.ConstStringNode)1 FillArrayNode (jadx.core.dex.instructions.FillArrayNode)1 GotoNode (jadx.core.dex.instructions.GotoNode)1 IfNode (jadx.core.dex.instructions.IfNode)1 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)1 SwitchNode (jadx.core.dex.instructions.SwitchNode)1 ArgType (jadx.core.dex.instructions.args.ArgType)1 FieldArg (jadx.core.dex.instructions.args.FieldArg)1 InsnArg (jadx.core.dex.instructions.args.InsnArg)1 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)1 Named (jadx.core.dex.instructions.args.Named)1