Search in sources :

Example 66 with BlockNode

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

the class DebugChecks method checkPHI.

private static void checkPHI(MethodNode mth) {
    for (BlockNode block : mth.getBasicBlocks()) {
        List<PhiInsn> phis = new ArrayList<>();
        for (InsnNode insn : block.getInstructions()) {
            if (insn.getType() == InsnType.PHI) {
                PhiInsn phi = (PhiInsn) insn;
                phis.add(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()) {
        for (PhiInsn usedInPhi : ssaVar.getUsedInPhi()) {
            boolean found = false;
            for (RegisterArg useArg : ssaVar.getUseList()) {
                InsnNode parentInsn = useArg.getParentInsn();
                if (parentInsn != null && parentInsn == usedInPhi) {
                    found = true;
                    break;
                }
            }
            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 67 with BlockNode

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

the class DebugChecks method checkMethod.

public static void checkMethod(MethodNode mth) {
    List<BlockNode> basicBlocks = mth.getBasicBlocks();
    if (Utils.isEmpty(basicBlocks)) {
        return;
    }
    for (BlockNode block : basicBlocks) {
        for (InsnNode insn : block.getInstructions()) {
            checkInsn(mth, insn);
        }
    }
    checkSSAVars(mth);
// checkPHI(mth);
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode)

Example 68 with BlockNode

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

the class TypeInferenceVisitor method tryInsertAdditionalMove.

private boolean tryInsertAdditionalMove(MethodNode mth) {
    int insnsAdded = 0;
    for (BlockNode block : mth.getBasicBlocks()) {
        PhiListAttr phiListAttr = block.get(AType.PHI_LIST);
        if (phiListAttr != null) {
            for (PhiInsn phiInsn : phiListAttr.getList()) {
                insnsAdded += tryInsertAdditionalInsn(mth, phiInsn);
            }
        }
    }
    if (insnsAdded == 0) {
        return false;
    }
    if (Consts.DEBUG_TYPE_INFERENCE) {
        mth.addDebugComment("Additional " + insnsAdded + " move instructions added to help type inference");
    }
    InitCodeVariables.rerun(mth);
    initTypeBounds(mth);
    if (runTypePropagation(mth) && checkTypes(mth)) {
        return true;
    }
    return tryDeduceTypes(mth);
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) PhiInsn(jadx.core.dex.instructions.PhiInsn) PhiListAttr(jadx.core.dex.attributes.nodes.PhiListAttr)

Example 69 with BlockNode

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

the class TypeInferenceVisitor method checkAndSplitConstInsn.

private boolean checkAndSplitConstInsn(MethodNode mth, SSAVar var) {
    ArgType type = var.getTypeInfo().getType();
    if (type.isTypeKnown() || var.isTypeImmutable()) {
        return false;
    }
    if (var.getUsedInPhi().size() < 2) {
        return false;
    }
    InsnNode assignInsn = var.getAssign().getAssignInsn();
    InsnNode constInsn = InsnUtils.checkInsnType(assignInsn, InsnType.CONST);
    if (constInsn == null) {
        return false;
    }
    BlockNode blockNode = BlockUtils.getBlockByInsn(mth, constInsn);
    if (blockNode == null) {
        return false;
    }
    // for every PHI make separate CONST insn
    boolean first = true;
    for (PhiInsn phiInsn : var.getUsedInPhi()) {
        if (first) {
            first = false;
            continue;
        }
        InsnNode copyInsn = constInsn.copyWithNewSsaVar(mth);
        copyInsn.add(AFlag.SYNTHETIC);
        BlockUtils.insertAfterInsn(blockNode, constInsn, copyInsn);
        RegisterArg phiArg = phiInsn.getArgBySsaVar(var);
        phiInsn.replaceArg(phiArg, copyInsn.getResult().duplicate());
    }
    return true;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) BlockNode(jadx.core.dex.nodes.BlockNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) PhiInsn(jadx.core.dex.instructions.PhiInsn)

Example 70 with BlockNode

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

the class TypeInferenceVisitor method insertAssignCast.

private boolean insertAssignCast(MethodNode mth, SSAVar var, ArgType castType) {
    RegisterArg assignArg = var.getAssign();
    InsnNode assignInsn = assignArg.getParentInsn();
    if (assignInsn == null || assignInsn.getType() == InsnType.PHI) {
        return false;
    }
    BlockNode assignBlock = BlockUtils.getBlockByInsn(mth, assignInsn);
    if (assignBlock == null) {
        return false;
    }
    RegisterArg newAssignArg = assignArg.duplicateWithNewSSAVar(mth);
    assignInsn.setResult(newAssignArg);
    IndexInsnNode castInsn = makeSoftCastInsn(assignArg, newAssignArg, castType);
    return BlockUtils.insertAfterInsn(assignBlock, assignInsn, castInsn);
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Aggregations

BlockNode (jadx.core.dex.nodes.BlockNode)220 InsnNode (jadx.core.dex.nodes.InsnNode)91 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)43 ArrayList (java.util.ArrayList)41 BitSet (java.util.BitSet)31 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)29 InsnArg (jadx.core.dex.instructions.args.InsnArg)25 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)21 ExceptionHandler (jadx.core.dex.trycatch.ExceptionHandler)19 PhiInsn (jadx.core.dex.instructions.PhiInsn)14 SSAVar (jadx.core.dex.instructions.args.SSAVar)14 Nullable (org.jetbrains.annotations.Nullable)14 LoopInfo (jadx.core.dex.attributes.nodes.LoopInfo)13 IRegion (jadx.core.dex.nodes.IRegion)13 HashSet (java.util.HashSet)13 MethodNode (jadx.core.dex.nodes.MethodNode)12 Region (jadx.core.dex.regions.Region)12 LoopRegion (jadx.core.dex.regions.loops.LoopRegion)12 InsnType (jadx.core.dex.instructions.InsnType)11 SynchronizedRegion (jadx.core.dex.regions.SynchronizedRegion)11