diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java index 91e59112d..9fe3e1996 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java @@ -29,6 +29,7 @@ import jadx.core.dex.info.MethodInfo; import jadx.core.dex.instructions.GotoNode; import jadx.core.dex.instructions.IfNode; import jadx.core.dex.instructions.InsnDecoder; +import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.SwitchNode; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.InsnArg; @@ -332,7 +333,7 @@ public class MethodNode extends LineAttrNode implements ILoadable, ICodeNode { InsnNode insn = null; while (offset <= end && offset >= 0) { insn = insnByOffset[offset]; - if (insn != null) { + if (insn != null && insn.getType() != InsnType.NOP) { if (tryBlockStarted) { catchBlock.addInsn(insn); } else if (insn.canThrowException()) { @@ -343,9 +344,7 @@ public class MethodNode extends LineAttrNode implements ILoadable, ICodeNode { } offset = InsnDecoder.getNextInsnOffset(insnByOffset, offset); } - if (insnByOffset[end] != null) { - insnByOffset[end].add(AFlag.TRY_LEAVE); - } else if (insn != null) { + if (tryBlockStarted && insn != null) { insn.add(AFlag.TRY_LEAVE); } } diff --git a/jadx-core/src/test/java/jadx/tests/api/SmaliTest.java b/jadx-core/src/test/java/jadx/tests/api/SmaliTest.java index 2821e8338..98e10a4c1 100644 --- a/jadx-core/src/test/java/jadx/tests/api/SmaliTest.java +++ b/jadx-core/src/test/java/jadx/tests/api/SmaliTest.java @@ -31,6 +31,13 @@ public abstract class SmaliTest extends IntegrationTest { return getClassNodeFromFile(outDex, clsName); } + /** + * Preferred method for one file smali test + */ + protected ClassNode getClassNodeFromSmali() { + return getClassNodeFromSmaliWithPkg(getTestPkg(), getTestName()); + } + protected ClassNode getClassNodeFromSmali(String clsName) { return getClassNodeFromSmali(clsName, clsName); } diff --git a/jadx-core/src/test/java/jadx/tests/integration/trycatch/TestTryCatchLastInsn.java b/jadx-core/src/test/java/jadx/tests/integration/trycatch/TestTryCatchLastInsn.java new file mode 100644 index 000000000..d604d3b6a --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/trycatch/TestTryCatchLastInsn.java @@ -0,0 +1,35 @@ +package jadx.tests.integration.trycatch; + +import org.junit.jupiter.api.Test; + +import jadx.core.dex.nodes.ClassNode; +import jadx.tests.api.SmaliTest; + +import static jadx.tests.api.utils.JadxMatchers.containsOne; +import static org.hamcrest.MatcherAssert.assertThat; + +public class TestTryCatchLastInsn extends SmaliTest { + + // @formatter:off + /* + public Exception test() { + ? r1 = "result"; // String + try { + r1 = call(); // Exception + } catch(Exception e) { + System.out.println(r1); // String + r1 = e; + } + return r1; + } + */ + // @formatter:on + + @Test + public void test() { + ClassNode cls = getClassNodeFromSmali(); + String code = cls.getCode().toString(); + + assertThat(code, containsOne("return call();")); + } +} diff --git a/jadx-core/src/test/smali/trycatch/TestTryCatchLastInsn.smali b/jadx-core/src/test/smali/trycatch/TestTryCatchLastInsn.smali new file mode 100644 index 000000000..e98f08aac --- /dev/null +++ b/jadx-core/src/test/smali/trycatch/TestTryCatchLastInsn.smali @@ -0,0 +1,34 @@ +.class public Ltrycatch/TestTryCatchLastInsn; +.super Ljava/lang/Object; +.source "TestTryCatchLastInsn.java" + +.method public test()Ljava/lang/Exception; + .registers 6 + + .prologue + const-string v1, "result" + + :try_start + invoke-direct {p0}, Ltrycatch/TestTryCatchLastInsn;->call()Ljava/lang/Exception; + move-result-object v1 + :try_end + .catch Ljava/lang/Exception; {:try_start .. :try_end} :catch + + :goto_return + return-object v1 + + :catch + move-exception v4 + sget-object v3, Ljava/lang/System;->out:Ljava/io/PrintStream; + invoke-virtual {v3, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V + move-object v1, v4 + goto :goto_return +.end method + + +.method private call()Ljava/lang/Exception; + .registers 2 + new-instance v0, Ljava/lang/Exception; + invoke-direct {v0}, Ljava/lang/Exception;->()V + return-object v0 +.end method