Search in sources :

Example 6 with PhiInsn

use of jadx.core.dex.instructions.PhiInsn 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 7 with PhiInsn

use of jadx.core.dex.instructions.PhiInsn in project jadx by skylot.

the class SSATransform method removeBlockerInsns.

private static boolean removeBlockerInsns(MethodNode mth) {
    boolean removed = false;
    for (BlockNode block : mth.getBasicBlocks()) {
        PhiListAttr phiList = block.get(AType.PHI_LIST);
        if (phiList == null) {
            continue;
        }
        // check if args must be removed
        for (PhiInsn phi : phiList.getList()) {
            for (int i = 0; i < phi.getArgsCount(); i++) {
                RegisterArg arg = phi.getArg(i);
                InsnNode parentInsn = arg.getAssignInsn();
                if (parentInsn != null && parentInsn.contains(AFlag.REMOVE)) {
                    phi.removeArg(arg);
                    InstructionRemover.remove(mth, block, parentInsn);
                    removed = true;
                }
            }
        }
    }
    return removed;
}
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) PhiListAttr(jadx.core.dex.attributes.nodes.PhiListAttr)

Example 8 with PhiInsn

use of jadx.core.dex.instructions.PhiInsn in project jadx by skylot.

the class SSATransform method fixUselessPhi.

private static boolean fixUselessPhi(MethodNode mth) {
    boolean changed = false;
    List<PhiInsn> insnToRemove = new ArrayList<PhiInsn>();
    for (SSAVar var : mth.getSVars()) {
        // phi result not used
        if (var.getUseCount() == 0) {
            InsnNode assignInsn = var.getAssign().getParentInsn();
            if (assignInsn != null && assignInsn.getType() == InsnType.PHI) {
                insnToRemove.add((PhiInsn) assignInsn);
                changed = true;
            }
        }
    }
    for (BlockNode block : mth.getBasicBlocks()) {
        PhiListAttr phiList = block.get(AType.PHI_LIST);
        if (phiList == null) {
            continue;
        }
        Iterator<PhiInsn> it = phiList.getList().iterator();
        while (it.hasNext()) {
            PhiInsn phi = it.next();
            if (fixPhiWithSameArgs(mth, block, phi)) {
                it.remove();
                changed = true;
            }
        }
    }
    removePhiList(mth, insnToRemove);
    return changed;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) PhiInsn(jadx.core.dex.instructions.PhiInsn) SSAVar(jadx.core.dex.instructions.args.SSAVar) PhiListAttr(jadx.core.dex.attributes.nodes.PhiListAttr) ArrayList(java.util.ArrayList)

Example 9 with PhiInsn

use of jadx.core.dex.instructions.PhiInsn in project jadx by skylot.

the class LoopRegionVisitor method checkForIndexedLoop.

/**
	 * Check for indexed loop.
	 */
private static boolean checkForIndexedLoop(MethodNode mth, LoopRegion loopRegion, IfCondition condition) {
    InsnNode incrInsn = RegionUtils.getLastInsn(loopRegion);
    if (incrInsn == null) {
        return false;
    }
    RegisterArg incrArg = incrInsn.getResult();
    if (incrArg == null || incrArg.getSVar() == null || !incrArg.getSVar().isUsedInPhi()) {
        return false;
    }
    PhiInsn phiInsn = incrArg.getSVar().getUsedInPhi();
    if (phiInsn == null || phiInsn.getArgsCount() != 2 || !phiInsn.getArg(1).equals(incrArg) || incrArg.getSVar().getUseCount() != 1) {
        return false;
    }
    RegisterArg arg = phiInsn.getResult();
    List<RegisterArg> condArgs = condition.getRegisterArgs();
    if (!condArgs.contains(arg) || arg.getSVar().isUsedInPhi()) {
        return false;
    }
    RegisterArg initArg = phiInsn.getArg(0);
    InsnNode initInsn = initArg.getAssignInsn();
    if (initInsn == null || initArg.getSVar().getUseCount() != 1) {
        return false;
    }
    if (!usedOnlyInLoop(mth, loopRegion, arg)) {
        return false;
    }
    // can't make loop if argument from increment instruction is assign in loop
    List<RegisterArg> args = new LinkedList<RegisterArg>();
    incrInsn.getRegisterArgs(args);
    for (RegisterArg iArg : args) {
        if (assignOnlyInLoop(mth, loopRegion, iArg)) {
            return false;
        }
    }
    // all checks passed
    initInsn.add(AFlag.SKIP);
    incrInsn.add(AFlag.SKIP);
    LoopType arrForEach = checkArrayForEach(mth, initInsn, incrInsn, condition);
    if (arrForEach != null) {
        loopRegion.setType(arrForEach);
        return true;
    }
    loopRegion.setType(new ForLoop(initInsn, incrInsn));
    return true;
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) PhiInsn(jadx.core.dex.instructions.PhiInsn) ForLoop(jadx.core.dex.regions.loops.ForLoop) LoopType(jadx.core.dex.regions.loops.LoopType) LinkedList(java.util.LinkedList)

Example 10 with PhiInsn

use of jadx.core.dex.instructions.PhiInsn in project jadx by skylot.

the class InstructionRemover method fixUsedInPhiFlag.

public static void fixUsedInPhiFlag(RegisterArg useReg) {
    PhiInsn usedIn = null;
    for (RegisterArg reg : useReg.getSVar().getUseList()) {
        InsnNode parentInsn = reg.getParentInsn();
        if (parentInsn != null && parentInsn.getType() == InsnType.PHI && parentInsn.containsArg(useReg)) {
            usedIn = (PhiInsn) parentInsn;
        }
    }
    useReg.getSVar().setUsedInPhi(usedIn);
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) PhiInsn(jadx.core.dex.instructions.PhiInsn)

Aggregations

PhiInsn (jadx.core.dex.instructions.PhiInsn)16 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)11 InsnNode (jadx.core.dex.nodes.InsnNode)10 PhiListAttr (jadx.core.dex.attributes.nodes.PhiListAttr)8 BlockNode (jadx.core.dex.nodes.BlockNode)8 SSAVar (jadx.core.dex.instructions.args.SSAVar)7 InsnArg (jadx.core.dex.instructions.args.InsnArg)4 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)3 ArrayList (java.util.ArrayList)2 ArgType (jadx.core.dex.instructions.args.ArgType)1 TernaryInsn (jadx.core.dex.instructions.mods.TernaryInsn)1 DexNode (jadx.core.dex.nodes.DexNode)1 IContainer (jadx.core.dex.nodes.IContainer)1 ForLoop (jadx.core.dex.regions.loops.ForLoop)1 LoopType (jadx.core.dex.regions.loops.LoopType)1 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1