Search in sources :

Example 1 with BlocksPair

use of jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair in project jadx by skylot.

the class BlockFinallyExtract method isStartBlock.

/**
	 * 'Finally' instructions can start in the middle of the first block.
	 */
private static BlocksRemoveInfo isStartBlock(BlockNode remBlock, BlockNode startBlock) {
    List<InsnNode> remInsns = remBlock.getInstructions();
    List<InsnNode> startInsns = startBlock.getInstructions();
    if (remInsns.size() < startInsns.size()) {
        return null;
    }
    // first - fast check
    int startPos = remInsns.size() - startInsns.size();
    int endPos = 0;
    if (!checkInsns(remInsns, startInsns, startPos, null)) {
        if (checkInsns(remInsns, startInsns, 0, null)) {
            startPos = 0;
            endPos = startInsns.size();
        } else {
            boolean found = false;
            for (int i = 1; i < startPos; i++) {
                if (checkInsns(remInsns, startInsns, i, null)) {
                    startPos = i;
                    endPos = startInsns.size() + i;
                    found = true;
                    break;
                }
            }
            if (!found) {
                return null;
            }
        }
    }
    BlocksPair startPair = new BlocksPair(remBlock, startBlock);
    BlocksRemoveInfo removeInfo = new BlocksRemoveInfo(startPair);
    removeInfo.setStartSplitIndex(startPos);
    removeInfo.setEndSplitIndex(endPos);
    if (endPos != 0) {
        removeInfo.setEnd(startPair);
    }
    // second - run checks again for collect registers mapping
    if (!checkInsns(remInsns, startInsns, startPos, removeInfo)) {
        return null;
    }
    return removeInfo;
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) BlocksPair(jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair) BlocksRemoveInfo(jadx.core.dex.visitors.blocksmaker.helpers.BlocksRemoveInfo)

Example 2 with BlocksPair

use of jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair in project jadx by skylot.

the class BlockFinallyExtract method removeInsns.

private static BlocksRemoveInfo removeInsns(MethodNode mth, BlockNode remBlock, List<BlockNode> blocks, BitSet bs) {
    if (blocks.isEmpty()) {
        return null;
    }
    BlockNode startBlock = blocks.get(0);
    BlocksRemoveInfo removeInfo = checkFromFirstBlock(remBlock, startBlock, bs);
    if (removeInfo == null) {
        return null;
    }
    Set<BlocksPair> outs = removeInfo.getOuts();
    if (outs.size() == 1) {
        return removeInfo;
    }
    // check if several 'return' blocks maps to one out
    if (mergeReturns(mth, outs)) {
        return removeInfo;
    }
    LOG.debug("Unexpected finally block outs count: {}", outs);
    return null;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) BlocksPair(jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair) BlocksRemoveInfo(jadx.core.dex.visitors.blocksmaker.helpers.BlocksRemoveInfo)

Example 3 with BlocksPair

use of jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair in project jadx by skylot.

the class BlockFinallyExtract method mergeReturns.

private static boolean mergeReturns(MethodNode mth, Set<BlocksPair> outs) {
    Set<BlockNode> rightOuts = new HashSet<BlockNode>();
    boolean allReturns = true;
    for (BlocksPair outPair : outs) {
        BlockNode first = outPair.getFirst();
        if (!first.isReturnBlock()) {
            allReturns = false;
        }
        rightOuts.add(outPair.getSecond());
    }
    if (!allReturns || rightOuts.size() != 1) {
        return false;
    }
    Iterator<BlocksPair> it = outs.iterator();
    while (it.hasNext()) {
        BlocksPair out = it.next();
        BlockNode returnBlock = out.getFirst();
        if (!returnBlock.contains(AFlag.ORIG_RETURN)) {
            markForRemove(mth, returnBlock);
            it.remove();
        }
    }
    return true;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) BlocksPair(jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair) HashSet(java.util.HashSet)

Example 4 with BlocksPair

use of jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair in project jadx by skylot.

the class BlockFinallyExtract method checkBlocksTree.

private static boolean checkBlocksTree(BlockNode remBlock, BlockNode startBlock, BlocksRemoveInfo removeInfo, BitSet bs) {
    // skip check on start block
    if (!removeInfo.getProcessed().isEmpty() && !sameBlocks(remBlock, startBlock, removeInfo)) {
        return false;
    }
    BlocksPair currentPair = new BlocksPair(remBlock, startBlock);
    removeInfo.getProcessed().add(currentPair);
    List<BlockNode> baseCS = startBlock.getCleanSuccessors();
    List<BlockNode> remCS = remBlock.getCleanSuccessors();
    if (baseCS.size() != remCS.size()) {
        removeInfo.getOuts().add(currentPair);
        return true;
    }
    for (int i = 0; i < baseCS.size(); i++) {
        BlockNode sBlock = baseCS.get(i);
        BlockNode rBlock = remCS.get(i);
        if (bs.get(sBlock.getId())) {
            if (removeInfo.getEndSplitIndex() != 0) {
                // end block is not correct
                return false;
            }
            if (!checkBlocksTree(rBlock, sBlock, removeInfo, bs)) {
                return false;
            }
        } else {
            removeInfo.getOuts().add(new BlocksPair(rBlock, sBlock));
        }
    }
    return true;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) BlocksPair(jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair)

Example 5 with BlocksPair

use of jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair in project jadx by skylot.

the class BlockFinallyExtract method sameBlocks.

private static boolean sameBlocks(BlockNode remBlock, BlockNode finallyBlock, BlocksRemoveInfo removeInfo) {
    List<InsnNode> first = remBlock.getInstructions();
    List<InsnNode> second = finallyBlock.getInstructions();
    if (first.size() < second.size()) {
        return false;
    }
    int size = second.size();
    for (int i = 0; i < size; i++) {
        if (!sameInsns(first.get(i), second.get(i), removeInfo)) {
            return false;
        }
    }
    if (first.size() > second.size()) {
        removeInfo.setEndSplitIndex(second.size());
        removeInfo.setEnd(new BlocksPair(remBlock, finallyBlock));
    }
    return true;
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) BlocksPair(jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair)

Aggregations

BlocksPair (jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair)7 BlockNode (jadx.core.dex.nodes.BlockNode)5 InsnNode (jadx.core.dex.nodes.InsnNode)3 BlocksRemoveInfo (jadx.core.dex.visitors.blocksmaker.helpers.BlocksRemoveInfo)3 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)1 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)1 ArrayList (java.util.ArrayList)1 BitSet (java.util.BitSet)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1