From 3eee83c2f28b955fffd4c8d3d3e9613b2af85770 Mon Sep 17 00:00:00 2001 From: Skylot Date: Sun, 7 Jul 2019 14:18:21 +0300 Subject: [PATCH] fix: adjust insn reorder check in code shrink visitor (#695) --- .../core/dex/visitors/shrink/ArgsInfo.java | 11 ++++- .../conditions/TestConditions18.java | 37 +++++++++++++++ .../integration/inline/TestInlineInLoop.java | 47 ------------------- .../smali/conditions/TestConditions18.smali | 45 ++++++++++++++++++ 4 files changed, 91 insertions(+), 49 deletions(-) create mode 100644 jadx-core/src/test/java/jadx/tests/integration/conditions/TestConditions18.java delete mode 100644 jadx-core/src/test/java/jadx/tests/integration/inline/TestInlineInLoop.java create mode 100644 jadx-core/src/test/smali/conditions/TestConditions18.smali diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/shrink/ArgsInfo.java b/jadx-core/src/main/java/jadx/core/dex/visitors/shrink/ArgsInfo.java index e96e09532..e1dce902e 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/shrink/ArgsInfo.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/shrink/ArgsInfo.java @@ -93,14 +93,21 @@ final class ArgsInfo { movedSet.set(arg.getRegNum()); } } + boolean canReorder = startInfo.insn.canReorder(); for (int i = start; i < to; i++) { ArgsInfo argsInfo = argsList.get(i); if (argsInfo.getInlinedInsn() == this) { continue; } InsnNode curInsn = argsInfo.insn; - if (!curInsn.canReorder() || usedArgAssign(curInsn, movedSet)) { - return false; + if (canReorder) { + if (usedArgAssign(curInsn, movedSet)) { + return false; + } + } else { + if (!curInsn.canReorder() || usedArgAssign(curInsn, movedSet)) { + return false; + } } } return true; diff --git a/jadx-core/src/test/java/jadx/tests/integration/conditions/TestConditions18.java b/jadx-core/src/test/java/jadx/tests/integration/conditions/TestConditions18.java new file mode 100644 index 000000000..a1aae09c4 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/conditions/TestConditions18.java @@ -0,0 +1,37 @@ +package jadx.tests.integration.conditions; + +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 TestConditions18 extends SmaliTest { + + // @formatter:off + /* + public static class TestConditions18 { + private Map map; + + public boolean test(Object obj) { + return this == obj || ((obj instanceof TestConditions18) && st(this.map, ((TestConditions18) obj).map)); + } + + private static boolean st(Object obj, Object obj2) { + return false; + } + } + */ + // @formatter:on + + @Test + public void test() { + ClassNode cls = getClassNodeFromSmali(); + String code = cls.getCode().toString(); + + assertThat(code, containsOne("return this == obj" + + " || ((obj instanceof TestConditions18) && st(this.map, ((TestConditions18) obj).map));")); + } +} diff --git a/jadx-core/src/test/java/jadx/tests/integration/inline/TestInlineInLoop.java b/jadx-core/src/test/java/jadx/tests/integration/inline/TestInlineInLoop.java deleted file mode 100644 index f56373a91..000000000 --- a/jadx-core/src/test/java/jadx/tests/integration/inline/TestInlineInLoop.java +++ /dev/null @@ -1,47 +0,0 @@ -package jadx.tests.integration.inline; - -import org.junit.jupiter.api.Test; - -import jadx.core.dex.nodes.ClassNode; -import jadx.tests.api.IntegrationTest; - -import static jadx.tests.api.utils.JadxMatchers.containsOne; -import static org.hamcrest.MatcherAssert.assertThat; - -public class TestInlineInLoop extends IntegrationTest { - - public static class TestCls { - public static void main(String[] args) { - int a = 0; - int b = 4; - int c = 0; - while (a < 12) { - if (b + a < 9 && b < 8) { - if (b >= 2 && a > -1 && b < 6) { - System.out.println("OK"); - c = b + 1; - } - c = b; - } - c = b; - b++; - b = c; - a++; - } - } - } - - @Test - public void test() { - ClassNode cls = getClassNode(TestCls.class); - String code = cls.getCode().toString(); - - // TODO: remove unused variables from test - assertThat(code, containsOne("int c = b + 1")); - assertThat(code, containsOne("int c2 = b;")); - assertThat(code, containsOne("int c3 = b;")); - assertThat(code, containsOne("int b2 = b + 1;")); - assertThat(code, containsOne("b = c3")); - assertThat(code, containsOne("a++")); - } -} diff --git a/jadx-core/src/test/smali/conditions/TestConditions18.smali b/jadx-core/src/test/smali/conditions/TestConditions18.smali new file mode 100644 index 000000000..27e792611 --- /dev/null +++ b/jadx-core/src/test/smali/conditions/TestConditions18.smali @@ -0,0 +1,45 @@ +.class public final Lconditions/TestConditions18; +.super Ljava/lang/Object; + +.field private map:Ljava/util/Map; + +.method public test(Ljava/lang/Object;)Z + .locals 1 + + if-eq p0, p1, :cond_1 + + instance-of v0, p1, Lconditions/TestConditions18; + + if-eqz v0, :cond_0 + + check-cast p1, Lconditions/TestConditions18; + + iget-object v0, p0, Lconditions/TestConditions18;->map:Ljava/util/Map; + + iget-object p1, p1, Lconditions/TestConditions18;->map:Ljava/util/Map; + + invoke-static {v0, p1}, Lconditions/TestConditions18;->st(Ljava/lang/Object;Ljava/lang/Object;)Z + + move-result p1 + + if-eqz p1, :cond_0 + + goto :goto_0 + + :cond_0 + const/4 p1, 0x0 + + return p1 + + :cond_1 + :goto_0 + const/4 p1, 0x1 + + return p1 +.end method + +.method private static st(Ljava/lang/Object;Ljava/lang/Object;)Z + .locals 1 + const/4 v0, 0x0 + return v0 +.end method