From 72a50eae437b6fc15340d2de49bdaecefaf8cd21 Mon Sep 17 00:00:00 2001 From: Skylot Date: Mon, 11 Aug 2014 22:25:26 +0400 Subject: [PATCH] core: fix missing blocks in loop region --- .../jadx/core/dex/regions/LoopRegion.java | 2 +- .../dex/visitors/regions/RegionMaker.java | 18 +++++- .../tests/internal/others/TestLoopInTry2.java | 55 +++++++++++++++++++ 3 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 jadx-core/src/test/java/jadx/tests/internal/others/TestLoopInTry2.java diff --git a/jadx-core/src/main/java/jadx/core/dex/regions/LoopRegion.java b/jadx-core/src/main/java/jadx/core/dex/regions/LoopRegion.java index 52180bac0..278936df9 100644 --- a/jadx-core/src/main/java/jadx/core/dex/regions/LoopRegion.java +++ b/jadx-core/src/main/java/jadx/core/dex/regions/LoopRegion.java @@ -138,6 +138,6 @@ public final class LoopRegion extends AbstractRegion { @Override public String toString() { - return "LOOP"; + return "LOOP: " + baseString(); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java index 5a993a5d9..2c39c05c9 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java @@ -213,7 +213,21 @@ public class RegionMaker { } stack.addExit(out); BlockNode loopBody = condInfo.getThenBlock(); - loopRegion.setBody(makeRegion(loopBody, stack)); + Region body = makeRegion(loopBody, stack); + // add blocks from loop start to first condition block + BlockNode conditionBlock = condInfo.getIfBlock(); + if (loopStart != conditionBlock) { + Set blocks = BlockUtils.getAllPathsBlocks(loopStart, conditionBlock); + blocks.remove(conditionBlock); + for (BlockNode block : blocks) { + if (block.getInstructions().isEmpty() + && !block.contains(AFlag.SKIP) + && !RegionUtils.isRegionContainsBlock(body, block)) { + body.add(block); + } + } + } + loopRegion.setBody(body); } stack.pop(); return out; @@ -569,7 +583,7 @@ public class RegionMaker { Set exits = new HashSet(); for (BlockNode splitter : splitters) { for (BlockNode handler : blocks) { - List s = splitter.getCleanSuccessors(); + List s = splitter.getSuccessors(); if (s.isEmpty()) { LOG.debug(ErrorsCounter.formatErrorMsg(mth, "No successors for splitter: " + splitter)); continue; diff --git a/jadx-core/src/test/java/jadx/tests/internal/others/TestLoopInTry2.java b/jadx-core/src/test/java/jadx/tests/internal/others/TestLoopInTry2.java new file mode 100644 index 000000000..27b900c76 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/internal/others/TestLoopInTry2.java @@ -0,0 +1,55 @@ +package jadx.tests.internal.others; + +import jadx.api.InternalJadxTest; +import jadx.core.dex.nodes.ClassNode; +import jadx.core.dex.nodes.DexNode; +import jadx.core.dex.nodes.MethodNode; +import jadx.core.utils.exceptions.DecodeException; + +import java.io.EOFException; + +import org.junit.Test; + +import com.android.dex.Code; +import com.android.dx.io.instructions.DecodedInstruction; +import com.android.dx.io.instructions.ShortArrayCodeInput; + +import static jadx.tests.utils.JadxMatchers.containsOne; +import static org.junit.Assert.assertThat; + +public class TestLoopInTry2 extends InternalJadxTest { + + public static class TestCls { + private MethodNode method; + private DexNode dex; + private DecodedInstruction[] insnArr; + + public void test(Code mthCode) throws DecodeException { + short[] encodedInstructions = mthCode.getInstructions(); + int size = encodedInstructions.length; + DecodedInstruction[] decoded = new DecodedInstruction[size]; + ShortArrayCodeInput in = new ShortArrayCodeInput(encodedInstructions); + try { + while (in.hasMore()) { + decoded[in.cursor()] = DecodedInstruction.decode(in); + } + } catch (EOFException e) { + throw new DecodeException(method, "", e); + } + insnArr = decoded; + } + } + + @Test + public void test() { + ClassNode cls = getClassNode(TestCls.class); + String code = cls.getCode().toString(); + System.out.println(code); + + assertThat(code, containsOne("try {")); + assertThat(code, containsOne("while (in.hasMore()) {")); + assertThat(code, containsOne("decoded[in.cursor()] = DecodedInstruction.decode(in);")); + assertThat(code, containsOne("} catch (EOFException e) {")); + assertThat(code, containsOne("throw new DecodeException")); + } +}