Search in sources :

Example 1 with ExcHandlerAttr

use of jadx.core.dex.trycatch.ExcHandlerAttr in project jadx by skylot.

the class RegionMaker method processExcHandler.

private void processExcHandler(ExceptionHandler handler, Set<BlockNode> exits) {
    BlockNode start = handler.getHandlerBlock();
    if (start == null) {
        return;
    }
    RegionStack stack = new RegionStack(mth);
    BlockNode dom;
    if (handler.isFinally()) {
        SplitterBlockAttr splitterAttr = start.get(AType.SPLITTER_BLOCK);
        if (splitterAttr == null) {
            return;
        }
        dom = splitterAttr.getBlock();
    } else {
        dom = start;
        stack.addExits(exits);
    }
    BitSet domFrontier = dom.getDomFrontier();
    List<BlockNode> handlerExits = BlockUtils.bitSetToBlocks(mth, domFrontier);
    boolean inLoop = mth.getLoopForBlock(start) != null;
    for (BlockNode exit : handlerExits) {
        if ((!inLoop || BlockUtils.isPathExists(start, exit)) && RegionUtils.isRegionContainsBlock(mth.getRegion(), exit)) {
            stack.addExit(exit);
        }
    }
    handler.setHandlerRegion(makeRegion(start, stack));
    ExcHandlerAttr excHandlerAttr = start.get(AType.EXC_HANDLER);
    if (excHandlerAttr == null) {
        LOG.warn("Missing exception handler attribute for start block");
    } else {
        handler.getHandlerRegion().addAttr(excHandlerAttr);
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) ExcHandlerAttr(jadx.core.dex.trycatch.ExcHandlerAttr) SplitterBlockAttr(jadx.core.dex.trycatch.SplitterBlockAttr) BitSet(java.util.BitSet)

Example 2 with ExcHandlerAttr

use of jadx.core.dex.trycatch.ExcHandlerAttr in project jadx by skylot.

the class BlockExceptionHandler method markExceptionHandlers.

/**
	 * Set exception handler attribute for whole block
	 */
private static void markExceptionHandlers(BlockNode block) {
    if (block.getInstructions().isEmpty()) {
        return;
    }
    InsnNode me = block.getInstructions().get(0);
    ExcHandlerAttr handlerAttr = me.get(AType.EXC_HANDLER);
    if (handlerAttr == null || me.getType() != InsnType.MOVE_EXCEPTION) {
        return;
    }
    ExceptionHandler excHandler = handlerAttr.getHandler();
    block.addAttr(handlerAttr);
    // set correct type for 'move-exception' operation
    ArgType type = excHandler.isCatchAll() ? ArgType.THROWABLE : excHandler.getCatchType().getType();
    RegisterArg resArg = me.getResult();
    resArg = InsnArg.reg(resArg.getRegNum(), type);
    me.setResult(resArg);
    me.add(AFlag.DONT_INLINE);
    excHandler.setArg(resArg);
}
Also used : ExceptionHandler(jadx.core.dex.trycatch.ExceptionHandler) ArgType(jadx.core.dex.instructions.args.ArgType) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) ExcHandlerAttr(jadx.core.dex.trycatch.ExcHandlerAttr)

Example 3 with ExcHandlerAttr

use of jadx.core.dex.trycatch.ExcHandlerAttr in project jadx by skylot.

the class ModVisitor method processMoveException.

private static void processMoveException(MethodNode mth, BlockNode block, InsnNode insn, InstructionRemover remover) {
    ExcHandlerAttr excHandlerAttr = block.get(AType.EXC_HANDLER);
    if (excHandlerAttr == null) {
        return;
    }
    ExceptionHandler excHandler = excHandlerAttr.getHandler();
    // result arg used both in this insn and exception handler,
    RegisterArg resArg = insn.getResult();
    ArgType type = excHandler.isCatchAll() ? ArgType.THROWABLE : excHandler.getCatchType().getType();
    String name = excHandler.isCatchAll() ? "th" : "e";
    if (resArg.getName() == null) {
        resArg.setName(name);
    }
    SSAVar sVar = insn.getResult().getSVar();
    if (sVar.getUseCount() == 0) {
        excHandler.setArg(new NamedArg(name, type));
        remover.add(insn);
    } else if (sVar.isUsedInPhi()) {
        // exception var moved to external variable => replace with 'move' insn
        InsnNode moveInsn = new InsnNode(InsnType.MOVE, 1);
        moveInsn.setResult(insn.getResult());
        NamedArg namedArg = new NamedArg(name, type);
        moveInsn.addArg(namedArg);
        excHandler.setArg(namedArg);
        replaceInsn(block, 0, moveInsn);
    }
}
Also used : ExceptionHandler(jadx.core.dex.trycatch.ExceptionHandler) ArgType(jadx.core.dex.instructions.args.ArgType) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) ExcHandlerAttr(jadx.core.dex.trycatch.ExcHandlerAttr) SSAVar(jadx.core.dex.instructions.args.SSAVar) NamedArg(jadx.core.dex.instructions.args.NamedArg)

Example 4 with ExcHandlerAttr

use of jadx.core.dex.trycatch.ExcHandlerAttr in project jadx by skylot.

the class MethodNode method initTryCatches.

private void initTryCatches(Code mthCode) {
    InsnNode[] insnByOffset = instructions;
    CatchHandler[] catchBlocks = mthCode.getCatchHandlers();
    Try[] tries = mthCode.getTries();
    if (catchBlocks.length == 0 && tries.length == 0) {
        return;
    }
    int hc = 0;
    Set<Integer> addrs = new HashSet<Integer>();
    List<TryCatchBlock> catches = new ArrayList<TryCatchBlock>(catchBlocks.length);
    for (CatchHandler handler : catchBlocks) {
        TryCatchBlock tcBlock = new TryCatchBlock();
        catches.add(tcBlock);
        for (int i = 0; i < handler.getAddresses().length; i++) {
            int addr = handler.getAddresses()[i];
            ClassInfo type = ClassInfo.fromDex(parentClass.dex(), handler.getTypeIndexes()[i]);
            tcBlock.addHandler(this, addr, type);
            addrs.add(addr);
            hc++;
        }
        int addr = handler.getCatchAllAddress();
        if (addr >= 0) {
            tcBlock.addHandler(this, addr, null);
            addrs.add(addr);
            hc++;
        }
    }
    if (hc > 0 && hc != addrs.size()) {
        // each handler must be only in one try/catch block
        for (TryCatchBlock ct1 : catches) {
            for (TryCatchBlock ct2 : catches) {
                if (ct1 != ct2 && ct2.containsAllHandlers(ct1)) {
                    for (ExceptionHandler h : ct1.getHandlers()) {
                        ct2.removeHandler(this, h);
                        h.setTryBlock(ct1);
                    }
                }
            }
        }
    }
    // attach EXC_HANDLER attributes to instructions
    addrs.clear();
    for (TryCatchBlock ct : catches) {
        for (ExceptionHandler eh : ct.getHandlers()) {
            int addr = eh.getHandleOffset();
            ExcHandlerAttr ehAttr = new ExcHandlerAttr(ct, eh);
            insnByOffset[addr].addAttr(ehAttr);
        }
    }
    // attach TRY_ENTER, TRY_LEAVE attributes to instructions
    for (Try aTry : tries) {
        int catchNum = aTry.getCatchHandlerIndex();
        TryCatchBlock catchBlock = catches.get(catchNum);
        int offset = aTry.getStartAddress();
        int end = offset + aTry.getInstructionCount() - 1;
        InsnNode insn = insnByOffset[offset];
        insn.add(AFlag.TRY_ENTER);
        while (offset <= end && offset >= 0) {
            insn = insnByOffset[offset];
            catchBlock.addInsn(insn);
            offset = InsnDecoder.getNextInsnOffset(insnByOffset, offset);
        }
        if (insnByOffset[end] != null) {
            insnByOffset[end].add(AFlag.TRY_LEAVE);
        } else {
            insn.add(AFlag.TRY_LEAVE);
        }
    }
}
Also used : ExcHandlerAttr(jadx.core.dex.trycatch.ExcHandlerAttr) ArrayList(java.util.ArrayList) CatchHandler(com.android.dex.Code.CatchHandler) ExceptionHandler(jadx.core.dex.trycatch.ExceptionHandler) Try(com.android.dex.Code.Try) TryCatchBlock(jadx.core.dex.trycatch.TryCatchBlock) HashSet(java.util.HashSet) ClassInfo(jadx.core.dex.info.ClassInfo)

Example 5 with ExcHandlerAttr

use of jadx.core.dex.trycatch.ExcHandlerAttr in project jadx by skylot.

the class BlockExceptionHandler method processExceptionHandlers.

private static void processExceptionHandlers(MethodNode mth, BlockNode block) {
    ExcHandlerAttr handlerAttr = block.get(AType.EXC_HANDLER);
    if (handlerAttr == null) {
        return;
    }
    ExceptionHandler excHandler = handlerAttr.getHandler();
    excHandler.addBlock(block);
    for (BlockNode node : BlockUtils.collectBlocksDominatedBy(block, block)) {
        excHandler.addBlock(node);
    }
    for (BlockNode excBlock : excHandler.getBlocks()) {
        // remove 'monitor-exit' from exception handler blocks
        InstructionRemover remover = new InstructionRemover(mth, excBlock);
        for (InsnNode insn : excBlock.getInstructions()) {
            if (insn.getType() == InsnType.MONITOR_ENTER) {
                break;
            }
            if (insn.getType() == InsnType.MONITOR_EXIT) {
                remover.add(insn);
            }
        }
        remover.perform();
        // if 'throw' in exception handler block have 'catch' - merge these catch blocks
        for (InsnNode insn : excBlock.getInstructions()) {
            CatchAttr catchAttr = insn.get(AType.CATCH_BLOCK);
            if (catchAttr == null) {
                continue;
            }
            if (insn.getType() == InsnType.THROW || onlyAllHandler(catchAttr.getTryBlock())) {
                TryCatchBlock handlerBlock = handlerAttr.getTryBlock();
                TryCatchBlock catchBlock = catchAttr.getTryBlock();
                handlerBlock.merge(mth, catchBlock);
            }
        }
    }
}
Also used : ExceptionHandler(jadx.core.dex.trycatch.ExceptionHandler) BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) ExcHandlerAttr(jadx.core.dex.trycatch.ExcHandlerAttr) CatchAttr(jadx.core.dex.trycatch.CatchAttr) TryCatchBlock(jadx.core.dex.trycatch.TryCatchBlock) InstructionRemover(jadx.core.utils.InstructionRemover)

Aggregations

ExcHandlerAttr (jadx.core.dex.trycatch.ExcHandlerAttr)6 ExceptionHandler (jadx.core.dex.trycatch.ExceptionHandler)4 BlockNode (jadx.core.dex.nodes.BlockNode)3 InsnNode (jadx.core.dex.nodes.InsnNode)3 ArgType (jadx.core.dex.instructions.args.ArgType)2 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)2 SplitterBlockAttr (jadx.core.dex.trycatch.SplitterBlockAttr)2 TryCatchBlock (jadx.core.dex.trycatch.TryCatchBlock)2 CatchHandler (com.android.dex.Code.CatchHandler)1 Try (com.android.dex.Code.Try)1 ClassInfo (jadx.core.dex.info.ClassInfo)1 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)1 NamedArg (jadx.core.dex.instructions.args.NamedArg)1 SSAVar (jadx.core.dex.instructions.args.SSAVar)1 CatchAttr (jadx.core.dex.trycatch.CatchAttr)1 InstructionRemover (jadx.core.utils.InstructionRemover)1 ArrayList (java.util.ArrayList)1 BitSet (java.util.BitSet)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1