From f02a33ace3b451420c2a7113840c2a514133644d Mon Sep 17 00:00:00 2001 From: Skylot Date: Wed, 19 Jun 2019 20:38:50 +0300 Subject: [PATCH] fix: ignore NOPs in try-catch (#668) --- .../java/jadx/core/dex/nodes/MethodNode.java | 7 ++-- .../test/java/jadx/tests/api/SmaliTest.java | 7 ++++ .../trycatch/TestTryCatchLastInsn.java | 35 +++++++++++++++++++ .../smali/trycatch/TestTryCatchLastInsn.smali | 34 ++++++++++++++++++ 4 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 jadx-core/src/test/java/jadx/tests/integration/trycatch/TestTryCatchLastInsn.java create mode 100644 jadx-core/src/test/smali/trycatch/TestTryCatchLastInsn.smali 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 91e59112..9fe3e199 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 2821e833..98e10a4c 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 00000000..d604d3b6 --- /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 00000000..e98f08aa --- /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 -- GitLab