Search in sources :

Example 21 with InsnArg

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

the class SSATransform method renameVar.

private static void renameVar(MethodNode mth, SSAVar[] vars, int[] vers, BlockNode block) {
    SSAVar[] inputVars = Arrays.copyOf(vars, vars.length);
    for (InsnNode insn : block.getInstructions()) {
        if (insn.getType() != InsnType.PHI) {
            for (InsnArg arg : insn.getArguments()) {
                if (!arg.isRegister()) {
                    continue;
                }
                RegisterArg reg = (RegisterArg) arg;
                int regNum = reg.getRegNum();
                SSAVar var = vars[regNum];
                if (var == null) {
                    throw new JadxRuntimeException("Not initialized variable reg: " + regNum + ", insn: " + insn + ", block:" + block + ", method: " + mth);
                }
                var.use(reg);
            }
        }
        RegisterArg result = insn.getResult();
        if (result != null) {
            int regNum = result.getRegNum();
            vars[regNum] = newSSAVar(mth, vers, result, regNum);
        }
    }
    for (BlockNode s : block.getSuccessors()) {
        PhiListAttr phiList = s.get(AType.PHI_LIST);
        if (phiList == null) {
            continue;
        }
        for (PhiInsn phiInsn : phiList.getList()) {
            int regNum = phiInsn.getResult().getRegNum();
            SSAVar var = vars[regNum];
            if (var == null) {
                continue;
            }
            RegisterArg arg = phiInsn.bindArg(block);
            var.use(arg);
            var.setUsedInPhi(phiInsn);
        }
    }
    for (BlockNode domOn : block.getDominatesOn()) {
        renameVar(mth, vars, vers, domOn);
    }
    System.arraycopy(inputVars, 0, vars, 0, vars.length);
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar) PhiInsn(jadx.core.dex.instructions.PhiInsn) InsnArg(jadx.core.dex.instructions.args.InsnArg) PhiListAttr(jadx.core.dex.attributes.nodes.PhiListAttr) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Example 22 with InsnArg

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

the class PostTypeInference method process.

public static boolean process(MethodNode mth, InsnNode insn) {
    DexNode dex = mth.dex();
    switch(insn.getType()) {
        case CONST:
            RegisterArg res = insn.getResult();
            LiteralArg litArg = (LiteralArg) insn.getArg(0);
            if (res.getType().isObject()) {
                long lit = litArg.getLiteral();
                if (lit != 0) {
                    // incorrect literal value for object
                    ArgType type = lit == 1 ? ArgType.BOOLEAN : ArgType.INT;
                    // can't merge with object -> force it
                    litArg.setType(type);
                    res.getSVar().setType(type);
                    return true;
                }
            }
            return litArg.merge(dex, res);
        case MOVE:
            {
                boolean change = false;
                if (insn.getResult().merge(dex, insn.getArg(0))) {
                    change = true;
                }
                if (insn.getArg(0).merge(dex, insn.getResult())) {
                    change = true;
                }
                return change;
            }
        case AGET:
            return fixArrayTypes(dex, insn.getArg(0), insn.getResult());
        case APUT:
            return fixArrayTypes(dex, insn.getArg(0), insn.getArg(2));
        case IF:
            {
                boolean change = false;
                if (insn.getArg(1).merge(dex, insn.getArg(0))) {
                    change = true;
                }
                if (insn.getArg(0).merge(dex, insn.getArg(1))) {
                    change = true;
                }
                return change;
            }
        // check argument types for overloaded methods
        case INVOKE:
            {
                boolean change = false;
                InvokeNode inv = (InvokeNode) insn;
                MethodInfo callMth = inv.getCallMth();
                MethodNode node = mth.dex().resolveMethod(callMth);
                if (node != null && node.isArgsOverload()) {
                    List<ArgType> args = callMth.getArgumentsTypes();
                    int j = inv.getArgsCount() - 1;
                    for (int i = args.size() - 1; i >= 0; i--) {
                        ArgType argType = args.get(i);
                        InsnArg insnArg = inv.getArg(j--);
                        if (insnArg.isRegister() && !argType.equals(insnArg.getType())) {
                            insnArg.setType(argType);
                            change = true;
                        }
                    }
                }
                return change;
            }
        case CHECK_CAST:
            {
                ArgType castType = (ArgType) ((IndexInsnNode) insn).getIndex();
                RegisterArg result = insn.getResult();
                ArgType resultType = result.getType();
                // don't override generic types of same base class
                boolean skip = castType.isObject() && resultType.isObject() && castType.getObject().equals(resultType.getObject());
                if (!skip) {
                    // workaround for compiler bug (see TestDuplicateCast)
                    result.getSVar().setType(castType);
                }
                return true;
            }
        case PHI:
        case MERGE:
            {
                ArgType type = insn.getResult().getType();
                if (!type.isTypeKnown()) {
                    for (InsnArg arg : insn.getArguments()) {
                        if (arg.getType().isTypeKnown()) {
                            type = arg.getType();
                            break;
                        }
                    }
                }
                boolean changed = false;
                if (updateType(insn.getResult(), type)) {
                    changed = true;
                }
                for (int i = 0; i < insn.getArgsCount(); i++) {
                    RegisterArg arg = (RegisterArg) insn.getArg(i);
                    if (updateType(arg, type)) {
                        changed = true;
                    }
                }
                return changed;
            }
        default:
            break;
    }
    return false;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) MethodNode(jadx.core.dex.nodes.MethodNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) DexNode(jadx.core.dex.nodes.DexNode) InvokeNode(jadx.core.dex.instructions.InvokeNode) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) MethodInfo(jadx.core.dex.info.MethodInfo) List(java.util.List) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Example 23 with InsnArg

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

the class BlockUtils method foundWrappedInsn.

private static InsnArg foundWrappedInsn(InsnNode container, InsnNode insn) {
    for (InsnArg arg : container.getArguments()) {
        if (arg.isInsnWrap()) {
            InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
            if (wrapInsn == insn) {
                return arg;
            }
            InsnArg res = foundWrappedInsn(wrapInsn, insn);
            if (res != null) {
                return res;
            }
        }
    }
    if (container instanceof TernaryInsn) {
        return foundWrappedInsnInCondition(((TernaryInsn) container).getCondition(), insn);
    }
    return null;
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) TernaryInsn(jadx.core.dex.instructions.mods.TernaryInsn) InsnArg(jadx.core.dex.instructions.args.InsnArg) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg)

Example 24 with InsnArg

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

the class DebugUtils method checkPHI.

private static void checkPHI(MethodNode mth) {
    for (BlockNode block : mth.getBasicBlocks()) {
        List<PhiInsn> phis = new ArrayList<PhiInsn>();
        for (InsnNode insn : block.getInstructions()) {
            if (insn.getType() == InsnType.PHI) {
                PhiInsn phi = (PhiInsn) insn;
                phis.add(phi);
                if (phi.getArgsCount() != phi.getBlockBinds().size()) {
                    throw new JadxRuntimeException("Incorrect args and binds in PHI");
                }
                if (phi.getArgsCount() == 0) {
                    throw new JadxRuntimeException("No args and binds in PHI");
                }
                for (InsnArg arg : insn.getArguments()) {
                    if (arg instanceof RegisterArg) {
                        BlockNode b = phi.getBlockByArg((RegisterArg) arg);
                        if (b == null) {
                            throw new JadxRuntimeException("Predecessor block not found");
                        }
                    } else {
                        throw new JadxRuntimeException("Not register in phi insn");
                    }
                }
            }
        }
        PhiListAttr phiListAttr = block.get(AType.PHI_LIST);
        if (phiListAttr == null) {
            if (!phis.isEmpty()) {
                throw new JadxRuntimeException("Missing PHI list attribute");
            }
        } else {
            List<PhiInsn> phiList = phiListAttr.getList();
            if (phiList.isEmpty()) {
                throw new JadxRuntimeException("Empty PHI list attribute");
            }
            if (!phis.containsAll(phiList) || !phiList.containsAll(phis)) {
                throw new JadxRuntimeException("Instructions not match");
            }
        }
    }
    for (SSAVar ssaVar : mth.getSVars()) {
        PhiInsn usedInPhi = ssaVar.getUsedInPhi();
        if (usedInPhi != null) {
            boolean found = false;
            for (RegisterArg useArg : ssaVar.getUseList()) {
                InsnNode parentInsn = useArg.getParentInsn();
                if (parentInsn != null && parentInsn == usedInPhi) {
                    found = true;
                }
            }
            if (!found) {
                throw new JadxRuntimeException("Used in phi incorrect");
            }
        }
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) PhiInsn(jadx.core.dex.instructions.PhiInsn) SSAVar(jadx.core.dex.instructions.args.SSAVar) InsnArg(jadx.core.dex.instructions.args.InsnArg) PhiListAttr(jadx.core.dex.attributes.nodes.PhiListAttr) ArrayList(java.util.ArrayList) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Example 25 with InsnArg

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

the class InstructionRemover method unbindInsn.

public static void unbindInsn(MethodNode mth, InsnNode insn) {
    unbindResult(mth, insn);
    for (InsnArg arg : insn.getArguments()) {
        unbindArgUsage(mth, arg);
    }
    if (insn.getType() == InsnType.PHI) {
        for (InsnArg arg : insn.getArguments()) {
            if (arg instanceof RegisterArg) {
                fixUsedInPhiFlag((RegisterArg) arg);
            }
        }
    }
    insn.add(AFlag.INCONSISTENT_CODE);
}
Also used : RegisterArg(jadx.core.dex.instructions.args.RegisterArg) InsnArg(jadx.core.dex.instructions.args.InsnArg)

Aggregations

InsnArg (jadx.core.dex.instructions.args.InsnArg)52 InsnNode (jadx.core.dex.nodes.InsnNode)32 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)24 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)19 InsnWrapArg (jadx.core.dex.instructions.args.InsnWrapArg)15 ArgType (jadx.core.dex.instructions.args.ArgType)9 SSAVar (jadx.core.dex.instructions.args.SSAVar)9 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)8 BlockNode (jadx.core.dex.nodes.BlockNode)8 FieldNode (jadx.core.dex.nodes.FieldNode)7 FieldInfo (jadx.core.dex.info.FieldInfo)6 ArithNode (jadx.core.dex.instructions.ArithNode)5 InvokeNode (jadx.core.dex.instructions.InvokeNode)5 ConstClassNode (jadx.core.dex.instructions.ConstClassNode)4 PhiInsn (jadx.core.dex.instructions.PhiInsn)4 ClassNode (jadx.core.dex.nodes.ClassNode)4 PhiListAttr (jadx.core.dex.attributes.nodes.PhiListAttr)3 MethodInfo (jadx.core.dex.info.MethodInfo)3 SwitchNode (jadx.core.dex.instructions.SwitchNode)3 MethodNode (jadx.core.dex.nodes.MethodNode)3