Search in sources :

Example 31 with JadxRuntimeException

use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.

the class IfMakerHelper method getCrossBlock.

private static BlockNode getCrossBlock(BlockNode first, BlockNode second) {
    if (isSameBlocks(first, second)) {
        return second;
    }
    BlockNode firstSkip = BlockUtils.skipSyntheticSuccessor(first);
    if (isSameBlocks(firstSkip, second)) {
        return second;
    }
    BlockNode secondSkip = BlockUtils.skipSyntheticSuccessor(second);
    if (isSameBlocks(firstSkip, secondSkip) || isSameBlocks(first, secondSkip)) {
        return secondSkip;
    }
    throw new JadxRuntimeException("Unexpected merge pattern");
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Example 32 with JadxRuntimeException

use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.

the class BlockFinallyExtract method applyRemove.

private static boolean applyRemove(MethodNode mth, BlocksRemoveInfo removeInfo) {
    BlockNode remBlock = removeInfo.getStart().getFirst();
    BlockNode startBlock = removeInfo.getStart().getSecond();
    if (remBlock.contains(AFlag.REMOVE)) {
        // already processed
        return true;
    }
    if (remBlock.getPredecessors().size() != 1) {
        LOG.warn("Finally extract failed: remBlock pred: {}, {}, method: {}", remBlock, remBlock.getPredecessors(), mth);
        return false;
    }
    BlockNode remBlockPred = remBlock.getPredecessors().get(0);
    removeInfo.setStartPredecessor(remBlockPred);
    int startSplitIndex = removeInfo.getStartSplitIndex();
    int endSplitIndex = removeInfo.getEndSplitIndex();
    if (removeInfo.getStart().equals(removeInfo.getEnd())) {
        removeInfo.setEndSplitIndex(endSplitIndex - startSplitIndex);
    }
    // split start block (remBlock)
    if (startSplitIndex > 0) {
        remBlock = splitBlock(mth, remBlock, startSplitIndex);
        // change start block in removeInfo
        removeInfo.getProcessed().remove(removeInfo.getStart());
        BlocksPair newStart = new BlocksPair(remBlock, startBlock);
        //			removeInfo.setStart(newStart);
        removeInfo.getProcessed().add(newStart);
    }
    // split end block
    if (endSplitIndex > 0) {
        BlocksPair end = removeInfo.getEnd();
        BlockNode newOut = splitBlock(mth, end.getFirst(), endSplitIndex);
        for (BlockNode s : newOut.getSuccessors()) {
            BlocksPair replaceOut = null;
            Iterator<BlocksPair> it = removeInfo.getOuts().iterator();
            while (it.hasNext()) {
                BlocksPair outPair = it.next();
                if (outPair.getFirst().equals(s)) {
                    it.remove();
                    replaceOut = new BlocksPair(newOut, outPair.getSecond());
                    break;
                }
            }
            if (replaceOut != null) {
                removeInfo.getOuts().add(replaceOut);
            }
        }
    }
    BlocksPair out = removeInfo.getOuts().iterator().next();
    BlockNode rOut = out.getFirst();
    BlockNode sOut = out.getSecond();
    // redirect out edges
    List<BlockNode> filtPreds = BlockUtils.filterPredecessors(sOut);
    if (filtPreds.size() > 1) {
        BlockNode pred = sOut.getPredecessors().get(0);
        BlockNode newPred = BlockSplitter.insertBlockBetween(mth, pred, sOut);
        for (BlockNode predBlock : new ArrayList<BlockNode>(sOut.getPredecessors())) {
            if (predBlock != newPred) {
                removeConnection(predBlock, sOut);
                connect(predBlock, newPred);
            }
        }
        rOut.getPredecessors().clear();
        addIgnoredEdge(newPred, rOut);
        connect(newPred, rOut);
    } else if (filtPreds.size() == 1) {
        BlockNode pred = filtPreds.get(0);
        BlockNode repl = removeInfo.getBySecond(pred);
        if (repl == null) {
            LOG.error("Block not found by {}, in {}, method: {}", pred, removeInfo, mth);
            return false;
        }
        removeConnection(pred, rOut);
        addIgnoredEdge(repl, rOut);
        connect(repl, rOut);
    } else {
        throw new JadxRuntimeException("Finally extract failed, unexpected preds: " + filtPreds + " for " + sOut + ", method: " + mth);
    }
    // redirect input edges
    for (BlockNode pred : new ArrayList<BlockNode>(remBlock.getPredecessors())) {
        BlockNode middle = insertBlockBetween(mth, pred, remBlock);
        removeConnection(middle, remBlock);
        connect(middle, startBlock);
        addIgnoredEdge(middle, startBlock);
        connect(middle, rOut);
    }
    // mark blocks for remove
    markForRemove(mth, remBlock);
    for (BlocksPair pair : removeInfo.getProcessed()) {
        markForRemove(mth, pair.getFirst());
        BlockNode second = pair.getSecond();
        second.updateCleanSuccessors();
    }
    return true;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) ArrayList(java.util.ArrayList) BlocksPair(jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Example 33 with JadxRuntimeException

use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.

the class ExportGradleProject method init.

public void init() {
    try {
        FileUtils.makeDirsForFile(srcOutDir);
        FileUtils.makeDirsForFile(resOutDir);
        saveBuildGradle();
        skipGeneratedClasses();
    } catch (Exception e) {
        throw new JadxRuntimeException("Gradle export failed", e);
    }
}
Also used : JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) IOException(java.io.IOException)

Example 34 with JadxRuntimeException

use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.

the class EliminatePhiNodes method replaceMerge.

/**
	 * Replace 'MERGE' with 'PHI' insn.
	 */
private void replaceMerge(MethodNode mth, BlockNode block, InsnNode insn) {
    if (insn.getArgsCount() != 2) {
        throw new JadxRuntimeException("Unexpected count of arguments in merge insn: " + insn);
    }
    RegisterArg oldArg = (RegisterArg) insn.getArg(1);
    RegisterArg newArg = (RegisterArg) insn.getArg(0);
    int newRegNum = newArg.getRegNum();
    if (oldArg.getRegNum() == newRegNum) {
        throw new JadxRuntimeException("Unexpected register number in merge insn: " + insn);
    }
    SSAVar oldSVar = oldArg.getSVar();
    RegisterArg assignArg = oldSVar.getAssign();
    InsnNode assignParentInsn = assignArg.getParentInsn();
    BlockNode assignBlock = BlockUtils.getBlockByInsn(mth, assignParentInsn);
    if (assignBlock == null) {
        throw new JadxRuntimeException("Unknown assign block for " + assignParentInsn);
    }
    BlockNode assignPred = null;
    for (BlockNode pred : block.getPredecessors()) {
        if (BlockUtils.isPathExists(assignBlock, pred)) {
            assignPred = pred;
            break;
        }
    }
    if (assignPred == null) {
        throw new JadxRuntimeException("Assign predecessor not found for " + assignBlock + " from " + block);
    }
    // all checks passed
    RegisterArg newAssignArg = oldArg.duplicate(newRegNum, null);
    SSAVar newSVar = mth.makeNewSVar(newRegNum, mth.getNextSVarVersion(newRegNum), newAssignArg);
    newSVar.setName(oldSVar.getName());
    newSVar.setType(assignArg.getType());
    if (assignParentInsn != null) {
        assignParentInsn.setResult(newAssignArg);
    }
    for (RegisterArg useArg : oldSVar.getUseList()) {
        RegisterArg newUseArg = useArg.duplicate(newRegNum, newSVar);
        InsnNode parentInsn = useArg.getParentInsn();
        if (parentInsn != null) {
            newSVar.use(newUseArg);
            parentInsn.replaceArg(useArg, newUseArg);
        }
    }
    block.getInstructions().remove(0);
    PhiInsn phiInsn = SSATransform.addPhi(mth, block, newRegNum);
    phiInsn.setResult(insn.getResult());
    phiInsn.bindArg(newAssignArg.duplicate(), assignPred);
    phiInsn.bindArg(newArg.duplicate(), BlockUtils.selectOtherSafe(assignPred, block.getPredecessors()));
}
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) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Example 35 with JadxRuntimeException

use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.

the class LiveVarAnalysis method processLiveInfo.

private void processLiveInfo() {
    int bbCount = mth.getBasicBlocks().size();
    int regsCount = mth.getRegsCount();
    BitSet[] liveIn = initBitSetArray(bbCount, regsCount);
    List<BlockNode> blocks = mth.getBasicBlocks();
    int blocksSize = blocks.size();
    boolean changed;
    int k = 0;
    do {
        changed = false;
        for (int i = 0; i < blocksSize; i++) {
            BlockNode block = blocks.get(i);
            int blockId = block.getId();
            BitSet prevIn = liveIn[blockId];
            BitSet newIn = new BitSet(regsCount);
            List<BlockNode> successors = block.getSuccessors();
            for (int s = 0, successorsSize = successors.size(); s < successorsSize; s++) {
                newIn.or(liveIn[successors.get(s).getId()]);
            }
            newIn.andNot(defs[blockId]);
            newIn.or(uses[blockId]);
            if (!prevIn.equals(newIn)) {
                changed = true;
                liveIn[blockId] = newIn;
            }
        }
        if (k++ > 1000) {
            throw new JadxRuntimeException("Live variable analysis reach iterations limit");
        }
    } while (changed);
    this.liveIn = liveIn;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) BitSet(java.util.BitSet) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Aggregations

JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)35 BlockNode (jadx.core.dex.nodes.BlockNode)14 InsnNode (jadx.core.dex.nodes.InsnNode)8 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)6 ArrayList (java.util.ArrayList)6 ArgType (jadx.core.dex.instructions.args.ArgType)5 BitSet (java.util.BitSet)5 SSAVar (jadx.core.dex.instructions.args.SSAVar)4 PhiInsn (jadx.core.dex.instructions.PhiInsn)3 InsnArg (jadx.core.dex.instructions.args.InsnArg)3 ClassNode (jadx.core.dex.nodes.ClassNode)3 IContainer (jadx.core.dex.nodes.IContainer)3 IRegion (jadx.core.dex.nodes.IRegion)3 File (java.io.File)3 ZipEntry (java.util.zip.ZipEntry)3 LoopInfo (jadx.core.dex.attributes.nodes.LoopInfo)2 PhiListAttr (jadx.core.dex.attributes.nodes.PhiListAttr)2 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)2 FieldNode (jadx.core.dex.nodes.FieldNode)2 IBlock (jadx.core.dex.nodes.IBlock)2