use of jadx.core.dex.nodes.IBlock in project jadx by skylot.
the class CheckRegions method visit.
@Override
public void visit(MethodNode mth) throws JadxException {
if (mth.isNoCode() || mth.getBasicBlocks().isEmpty() || mth.contains(AType.JADX_ERROR)) {
return;
}
// check if all blocks included in regions
final Set<BlockNode> blocksInRegions = new HashSet<BlockNode>();
DepthRegionTraversal.traverse(mth, new AbstractRegionVisitor() {
@Override
public void processBlock(MethodNode mth, IBlock container) {
if (!(container instanceof BlockNode)) {
return;
}
BlockNode block = (BlockNode) container;
if (blocksInRegions.add(block)) {
return;
}
if (!block.contains(AFlag.RETURN) && !block.contains(AFlag.SKIP) && !block.contains(AFlag.SYNTHETIC) && !block.getInstructions().isEmpty()) {
// TODO
// mth.add(AFlag.INCONSISTENT_CODE);
LOG.debug(" Duplicated block: {} in {}", block, mth);
}
}
});
if (mth.getBasicBlocks().size() != blocksInRegions.size()) {
for (BlockNode block : mth.getBasicBlocks()) {
if (!blocksInRegions.contains(block) && !block.getInstructions().isEmpty() && !block.contains(AFlag.SKIP)) {
mth.add(AFlag.INCONSISTENT_CODE);
LOG.debug(" Missing block: {} in {}", block, mth);
}
}
}
// check loop conditions
DepthRegionTraversal.traverse(mth, new AbstractRegionVisitor() {
@Override
public boolean enterRegion(MethodNode mth, IRegion region) {
if (region instanceof LoopRegion) {
BlockNode loopHeader = ((LoopRegion) region).getHeader();
if (loopHeader != null && loopHeader.getInstructions().size() != 1) {
ErrorsCounter.methodError(mth, "Incorrect condition in loop: " + loopHeader);
}
}
return true;
}
});
}
use of jadx.core.dex.nodes.IBlock in project jadx by skylot.
the class RegionMaker method processHandlersOutBlocks.
/**
* Search handlers successor blocks not included in any region.
*/
protected IRegion processHandlersOutBlocks(MethodNode mth, Set<TryCatchBlock> tcs) {
Set<IBlock> allRegionBlocks = new HashSet<IBlock>();
RegionUtils.getAllRegionBlocks(mth.getRegion(), allRegionBlocks);
Set<IBlock> succBlocks = new HashSet<IBlock>();
for (TryCatchBlock tc : tcs) {
for (ExceptionHandler handler : tc.getHandlers()) {
IContainer region = handler.getHandlerRegion();
if (region != null) {
IBlock lastBlock = RegionUtils.getLastBlock(region);
if (lastBlock instanceof BlockNode) {
succBlocks.addAll(((BlockNode) lastBlock).getSuccessors());
}
RegionUtils.getAllRegionBlocks(region, allRegionBlocks);
}
}
}
succBlocks.removeAll(allRegionBlocks);
if (succBlocks.isEmpty()) {
return null;
}
Region excOutRegion = new Region(mth.getRegion());
for (IBlock block : succBlocks) {
if (block instanceof BlockNode) {
excOutRegion.add(makeRegion((BlockNode) block, new RegionStack(mth)));
}
}
return excOutRegion;
}
use of jadx.core.dex.nodes.IBlock in project jadx by skylot.
the class DebugUtils method printRegionsWithBlock.
public static void printRegionsWithBlock(MethodNode mth, final BlockNode block) {
final Set<IRegion> regions = new LinkedHashSet<IRegion>();
DepthRegionTraversal.traverse(mth, new TracedRegionVisitor() {
@Override
public void processBlockTraced(MethodNode mth, IBlock container, IRegion currentRegion) {
if (block.equals(container)) {
regions.add(currentRegion);
}
}
});
LOG.debug(" Found block: {} in regions: {}", block, regions);
}
use of jadx.core.dex.nodes.IBlock in project jadx by skylot.
the class DebugUtils method printRegion.
private static void printRegion(MethodNode mth, IRegion region, String indent, boolean printInsns) {
LOG.debug("{}{}", indent, region);
indent += "| ";
for (IContainer container : region.getSubBlocks()) {
if (container instanceof IRegion) {
printRegion(mth, (IRegion) container, indent, printInsns);
} else {
LOG.debug("{}{} {}", indent, container, container.getAttributesString());
if (printInsns && container instanceof IBlock) {
IBlock block = (IBlock) container;
printInsns(mth, indent, block);
}
}
}
}
use of jadx.core.dex.nodes.IBlock in project jadx by skylot.
the class RegionUtils method hasExitEdge.
public static boolean hasExitEdge(IContainer container) {
if (container instanceof IBlock) {
InsnNode lastInsn = BlockUtils.getLastInsn((IBlock) container);
if (lastInsn == null) {
return false;
}
InsnType type = lastInsn.getType();
return type == InsnType.RETURN || type == InsnType.CONTINUE || type == InsnType.BREAK || type == InsnType.THROW;
} else if (container instanceof IBranchRegion) {
for (IContainer br : ((IBranchRegion) container).getBranches()) {
if (br == null || !hasExitEdge(br)) {
return false;
}
}
return true;
} else if (container instanceof IRegion) {
IRegion region = (IRegion) container;
List<IContainer> blocks = region.getSubBlocks();
return !blocks.isEmpty() && hasExitEdge(blocks.get(blocks.size() - 1));
} else {
throw new JadxRuntimeException(unknownContainerType(container));
}
}
Aggregations