Search in sources :

Example 66 with InsnNode

use of jadx.core.dex.nodes.InsnNode in project jadx by skylot.

the class RegionGen method makeLoop.

private CodeWriter makeLoop(LoopRegion region, CodeWriter code) throws CodegenException {
    BlockNode header = region.getHeader();
    if (header != null) {
        List<InsnNode> headerInsns = header.getInstructions();
        if (headerInsns.size() > 1) {
            ErrorsCounter.methodError(mth, "Found not inlined instructions from loop header");
            int last = headerInsns.size() - 1;
            for (int i = 0; i < last; i++) {
                InsnNode insn = headerInsns.get(i);
                makeInsn(insn, code);
            }
        }
    }
    LoopLabelAttr labelAttr = region.getInfo().getStart().get(AType.LOOP_LABEL);
    if (labelAttr != null) {
        code.startLine(mgen.getNameGen().getLoopLabel(labelAttr)).add(':');
    }
    IfCondition condition = region.getCondition();
    if (condition == null) {
        // infinite loop
        code.startLine("while (true) {");
        makeRegionIndent(code, region.getBody());
        code.startLine('}');
        return code;
    }
    ConditionGen conditionGen = new ConditionGen(this);
    LoopType type = region.getType();
    if (type != null) {
        if (type instanceof ForLoop) {
            ForLoop forLoop = (ForLoop) type;
            code.startLine("for (");
            makeInsn(forLoop.getInitInsn(), code, Flags.INLINE);
            code.add("; ");
            conditionGen.add(code, condition);
            code.add("; ");
            makeInsn(forLoop.getIncrInsn(), code, Flags.INLINE);
            code.add(") {");
            makeRegionIndent(code, region.getBody());
            code.startLine('}');
            return code;
        }
        if (type instanceof ForEachLoop) {
            ForEachLoop forEachLoop = (ForEachLoop) type;
            code.startLine("for (");
            declareVar(code, forEachLoop.getVarArg());
            code.add(" : ");
            addArg(code, forEachLoop.getIterableArg(), false);
            code.add(") {");
            makeRegionIndent(code, region.getBody());
            code.startLine('}');
            return code;
        }
        throw new JadxRuntimeException("Unknown loop type: " + type.getClass());
    }
    if (region.isConditionAtEnd()) {
        code.startLine("do {");
        makeRegionIndent(code, region.getBody());
        code.startLine("} while (");
        conditionGen.add(code, condition);
        code.add(");");
    } else {
        code.startLine("while (");
        conditionGen.add(code, condition);
        code.add(") {");
        makeRegionIndent(code, region.getBody());
        code.startLine('}');
    }
    return code;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) ForLoop(jadx.core.dex.regions.loops.ForLoop) LoopLabelAttr(jadx.core.dex.attributes.nodes.LoopLabelAttr) LoopType(jadx.core.dex.regions.loops.LoopType) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) IfCondition(jadx.core.dex.regions.conditions.IfCondition) ForEachLoop(jadx.core.dex.regions.loops.ForEachLoop)

Example 67 with InsnNode

use of jadx.core.dex.nodes.InsnNode in project jadx by skylot.

the class InsnGen method inlineMethod.

private boolean inlineMethod(MethodNode callMthNode, InvokeNode insn, CodeWriter code) throws CodegenException {
    MethodInlineAttr mia = callMthNode.get(AType.METHOD_INLINE);
    if (mia == null) {
        return false;
    }
    InsnNode inl = mia.getInsn();
    if (callMthNode.getMethodInfo().getArgumentsTypes().isEmpty()) {
        makeInsn(inl, code, Flags.BODY_ONLY);
    } else {
        // remap args
        InsnArg[] regs = new InsnArg[callMthNode.getRegsCount()];
        List<RegisterArg> callArgs = callMthNode.getArguments(true);
        for (int i = 0; i < callArgs.size(); i++) {
            InsnArg arg = insn.getArg(i);
            RegisterArg callArg = callArgs.get(i);
            regs[callArg.getRegNum()] = arg;
        }
        // replace args
        InsnNode inlCopy = inl.copy();
        List<RegisterArg> inlArgs = new ArrayList<RegisterArg>();
        inlCopy.getRegisterArgs(inlArgs);
        for (RegisterArg r : inlArgs) {
            int regNum = r.getRegNum();
            if (regNum >= regs.length) {
                LOG.warn("Unknown register number {} in method call: {} from {}", r, callMthNode, mth);
            } else {
                InsnArg repl = regs[regNum];
                if (repl == null) {
                    LOG.warn("Not passed register {} in method call: {} from {}", r, callMthNode, mth);
                } else {
                    inlCopy.replaceArg(r, repl);
                }
            }
        }
        makeInsn(inlCopy, code, Flags.BODY_ONLY);
    }
    return true;
}
Also used : IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) InsnArg(jadx.core.dex.instructions.args.InsnArg) ArrayList(java.util.ArrayList) MethodInlineAttr(jadx.core.dex.attributes.nodes.MethodInlineAttr)

Example 68 with InsnNode

use of jadx.core.dex.nodes.InsnNode in project jadx by skylot.

the class InsnGen method processVarArg.

/**
	 * Expand varArgs from filled array.
	 */
private boolean processVarArg(CodeWriter code, MethodNode callMth, InsnArg lastArg) throws CodegenException {
    if (callMth == null || !callMth.getAccessFlags().isVarArgs()) {
        return false;
    }
    if (!lastArg.getType().isArray() || !lastArg.isInsnWrap()) {
        return false;
    }
    InsnNode insn = ((InsnWrapArg) lastArg).getWrapInsn();
    if (insn.getType() == InsnType.FILLED_NEW_ARRAY) {
        int count = insn.getArgsCount();
        for (int i = 0; i < count; i++) {
            InsnArg elemArg = insn.getArg(i);
            addArg(code, elemArg, false);
            if (i < count - 1) {
                code.add(", ");
            }
        }
        return true;
    }
    return false;
}
Also used : IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg)

Example 69 with InsnNode

use of jadx.core.dex.nodes.InsnNode in project jadx by skylot.

the class MethodGen method addFallbackMethodCode.

public void addFallbackMethodCode(CodeWriter code) {
    if (mth.getInstructions() == null) {
        JadxErrorAttr errorAttr = mth.get(AType.JADX_ERROR);
        if (errorAttr == null || errorAttr.getCause() == null || !errorAttr.getCause().getClass().equals(DecodeException.class)) {
            // load original instructions
            try {
                mth.load();
                DepthTraversal.visit(new FallbackModeVisitor(), mth);
            } catch (DecodeException e) {
                LOG.error("Error reload instructions in fallback mode:", e);
                code.startLine("// Can't load method instructions: " + e.getMessage());
                return;
            }
        }
    }
    InsnNode[] insnArr = mth.getInstructions();
    if (insnArr == null) {
        code.startLine("// Can't load method instructions.");
        return;
    }
    if (mth.getThisArg() != null) {
        code.startLine(nameGen.useArg(mth.getThisArg())).add(" = this;");
    }
    addFallbackInsns(code, mth, insnArr, true);
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) FallbackModeVisitor(jadx.core.dex.visitors.FallbackModeVisitor) DecodeException(jadx.core.utils.exceptions.DecodeException) JadxErrorAttr(jadx.core.dex.attributes.nodes.JadxErrorAttr)

Example 70 with InsnNode

use of jadx.core.dex.nodes.InsnNode in project jadx by skylot.

the class MethodGen method addFallbackInsns.

public static void addFallbackInsns(CodeWriter code, MethodNode mth, InsnNode[] insnArr, boolean addLabels) {
    InsnGen insnGen = new InsnGen(getFallbackMethodGen(mth), true);
    for (InsnNode insn : insnArr) {
        if (insn == null || insn.getType() == InsnType.NOP) {
            continue;
        }
        if (addLabels && (insn.contains(AType.JUMP) || insn.contains(AType.EXC_HANDLER))) {
            code.decIndent();
            code.startLine(getLabelName(insn.getOffset()) + ":");
            code.incIndent();
        }
        try {
            if (insnGen.makeInsn(insn, code)) {
                CatchAttr catchAttr = insn.get(AType.CATCH_BLOCK);
                if (catchAttr != null) {
                    code.add("\t " + catchAttr);
                }
            }
        } catch (CodegenException e) {
            LOG.debug("Error generate fallback instruction: ", e.getCause());
            code.startLine("// error: " + insn);
        }
    }
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) CodegenException(jadx.core.utils.exceptions.CodegenException) CatchAttr(jadx.core.dex.trycatch.CatchAttr)

Aggregations

InsnNode (jadx.core.dex.nodes.InsnNode)123 BlockNode (jadx.core.dex.nodes.BlockNode)41 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)39 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)35 InsnArg (jadx.core.dex.instructions.args.InsnArg)32 InsnWrapArg (jadx.core.dex.instructions.args.InsnWrapArg)19 SSAVar (jadx.core.dex.instructions.args.SSAVar)16 ArrayList (java.util.ArrayList)14 ArgType (jadx.core.dex.instructions.args.ArgType)11 PhiInsn (jadx.core.dex.instructions.PhiInsn)10 FieldNode (jadx.core.dex.nodes.FieldNode)10 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)8 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)7 ClassNode (jadx.core.dex.nodes.ClassNode)7 MethodNode (jadx.core.dex.nodes.MethodNode)7 FieldInfo (jadx.core.dex.info.FieldInfo)6 ArithNode (jadx.core.dex.instructions.ArithNode)6 ConstructorInsn (jadx.core.dex.instructions.mods.ConstructorInsn)6 InsnType (jadx.core.dex.instructions.InsnType)5 IContainer (jadx.core.dex.nodes.IContainer)5