Search in sources :

Example 21 with SSAVar

use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.

the class ConstInlineVisitor method replaceConst.

private static boolean replaceConst(MethodNode mth, InsnNode constInsn, long literal) {
    SSAVar sVar = constInsn.getResult().getSVar();
    List<RegisterArg> use = new ArrayList<RegisterArg>(sVar.getUseList());
    int replaceCount = 0;
    for (RegisterArg arg : use) {
        InsnNode useInsn = arg.getParentInsn();
        if (useInsn == null || useInsn.getType() == InsnType.PHI || useInsn.getType() == InsnType.MERGE) {
            continue;
        }
        LiteralArg litArg;
        ArgType argType = arg.getType();
        if (argType.isObject() && literal != 0) {
            argType = ArgType.NARROW_NUMBERS;
        }
        if (use.size() == 1 || arg.isTypeImmutable()) {
            // arg used only in one place
            litArg = InsnArg.lit(literal, argType);
        } else if (useInsn.getType() == InsnType.MOVE && !useInsn.getResult().getType().isTypeKnown()) {
            // save type for 'move' instructions (hard to find type in chains of 'move')
            litArg = InsnArg.lit(literal, argType);
        } else {
            // in most cases type not equal arg.getType()
            // just set unknown type and run type fixer
            litArg = InsnArg.lit(literal, ArgType.UNKNOWN);
        }
        if (useInsn.replaceArg(arg, litArg)) {
            fixTypes(mth, useInsn, litArg);
            replaceCount++;
            if (useInsn.getType() == InsnType.RETURN) {
                useInsn.setSourceLine(constInsn.getSourceLine());
            }
            FieldNode f = null;
            ArgType litArgType = litArg.getType();
            if (litArgType.isTypeKnown()) {
                f = mth.getParentClass().getConstFieldByLiteralArg(litArg);
            } else if (litArgType.contains(PrimitiveType.INT)) {
                f = mth.getParentClass().getConstField((int) literal, false);
            }
            if (f != null) {
                litArg.wrapInstruction(new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0));
            }
        }
    }
    return replaceCount == use.size();
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar) FieldNode(jadx.core.dex.nodes.FieldNode) ArrayList(java.util.ArrayList) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Example 22 with SSAVar

use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.

the class DebugInfoParser method merge.

private static void merge(InsnArg arg, LocalVar var) {
    if (arg == null || !arg.isRegister()) {
        return;
    }
    RegisterArg reg = (RegisterArg) arg;
    if (var.getRegNum() != reg.getRegNum()) {
        return;
    }
    boolean mergeRequired = false;
    SSAVar ssaVar = reg.getSVar();
    if (ssaVar != null) {
        int ssaEnd = ssaVar.getEndAddr();
        int ssaStart = ssaVar.getStartAddr();
        int localStart = var.getStartAddr();
        int localEnd = var.getEndAddr();
        boolean isIntersected = !(localEnd < ssaStart || ssaEnd < localStart);
        if (isIntersected && ssaEnd <= localEnd) {
            mergeRequired = true;
        }
    } else {
        mergeRequired = true;
    }
    if (mergeRequired) {
        reg.mergeDebugInfo(var.getType(), var.getName());
    }
}
Also used : RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar)

Example 23 with SSAVar

use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.

the class SSATransform method replacePhiWithMove.

private static boolean replacePhiWithMove(MethodNode mth, BlockNode block, PhiInsn phi, RegisterArg arg) {
    List<InsnNode> insns = block.getInstructions();
    int phiIndex = InsnList.getIndex(insns, phi);
    if (phiIndex == -1) {
        return false;
    }
    SSAVar assign = phi.getResult().getSVar();
    SSAVar argVar = arg.getSVar();
    if (argVar != null) {
        argVar.removeUse(arg);
        argVar.setUsedInPhi(null);
    }
    // try inline
    if (inlinePhiInsn(mth, block, phi)) {
        insns.remove(phiIndex);
    } else {
        assign.setUsedInPhi(null);
        InsnNode m = new InsnNode(InsnType.MOVE, 1);
        m.add(AFlag.SYNTHETIC);
        m.setResult(phi.getResult());
        m.addArg(arg);
        arg.getSVar().use(arg);
        insns.set(phiIndex, m);
    }
    return true;
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) SSAVar(jadx.core.dex.instructions.args.SSAVar)

Example 24 with SSAVar

use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.

the class TypeInference method visit.

@Override
public void visit(MethodNode mth) throws JadxException {
    if (mth.isNoCode()) {
        return;
    }
    DexNode dex = mth.dex();
    for (SSAVar var : mth.getSVars()) {
        // inference variable type
        ArgType type = processType(dex, var);
        if (type == null) {
            type = ArgType.UNKNOWN;
        }
        var.setType(type);
        // search variable name
        String name = processVarName(var);
        var.setName(name);
    }
    // fix type for vars used only in Phi nodes
    for (SSAVar sVar : mth.getSVars()) {
        PhiInsn phi = sVar.getUsedInPhi();
        if (phi != null) {
            processPhiNode(phi);
        }
    }
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) SSAVar(jadx.core.dex.instructions.args.SSAVar) PhiInsn(jadx.core.dex.instructions.PhiInsn) DexNode(jadx.core.dex.nodes.DexNode)

Example 25 with SSAVar

use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.

the class TypeInference method processPhiNode.

private static void processPhiNode(PhiInsn phi) {
    ArgType type = phi.getResult().getType();
    if (!type.isTypeKnown()) {
        for (InsnArg arg : phi.getArguments()) {
            if (arg.getType().isTypeKnown()) {
                type = arg.getType();
                break;
            }
        }
    }
    phi.getResult().setType(type);
    for (int i = 0; i < phi.getArgsCount(); i++) {
        RegisterArg arg = phi.getArg(i);
        arg.setType(type);
        SSAVar sVar = arg.getSVar();
        if (sVar != null) {
            sVar.setName(phi.getResult().getName());
        }
    }
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar) InsnArg(jadx.core.dex.instructions.args.InsnArg)

Aggregations

SSAVar (jadx.core.dex.instructions.args.SSAVar)28 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)22 InsnNode (jadx.core.dex.nodes.InsnNode)16 InsnArg (jadx.core.dex.instructions.args.InsnArg)9 PhiInsn (jadx.core.dex.instructions.PhiInsn)7 BlockNode (jadx.core.dex.nodes.BlockNode)7 ArgType (jadx.core.dex.instructions.args.ArgType)6 PhiListAttr (jadx.core.dex.attributes.nodes.PhiListAttr)5 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)5 ArrayList (java.util.ArrayList)5 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)4 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)3 FieldNode (jadx.core.dex.nodes.FieldNode)2 MethodNode (jadx.core.dex.nodes.MethodNode)2 ForEachLoop (jadx.core.dex.regions.loops.ForEachLoop)2 MethodParameters (jadx.core.dex.attributes.annotations.MethodParameters)1 FieldReplaceAttr (jadx.core.dex.attributes.nodes.FieldReplaceAttr)1 AccessInfo (jadx.core.dex.info.AccessInfo)1 ClassInfo (jadx.core.dex.info.ClassInfo)1 MethodInfo (jadx.core.dex.info.MethodInfo)1