diff --git a/jadx-core/src/main/java/jadx/core/dex/regions/Compare.java b/jadx-core/src/main/java/jadx/core/dex/regions/Compare.java index 5716f4ecaf9a66db7d82941e2130122d314f88e9..d070f5fcafc708b7c78c7c0b5a56d61a6a84a352 100644 --- a/jadx-core/src/main/java/jadx/core/dex/regions/Compare.java +++ b/jadx-core/src/main/java/jadx/core/dex/regions/Compare.java @@ -24,6 +24,10 @@ public final class Compare { return insn.getArg(1); } + public IfNode getInsn() { + return insn; + } + public Compare invert() { insn.invertCondition(); return this; diff --git a/jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java b/jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java index fb85b489e53b881bcdb5b164b848b33c9a2c46f0..c0452c141d8267ad5e91d3e8fd8454f54b381d4f 100644 --- a/jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java +++ b/jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java @@ -2,10 +2,13 @@ package jadx.core.dex.regions; import jadx.core.dex.instructions.IfNode; import jadx.core.dex.instructions.IfOp; +import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.args.InsnArg; +import jadx.core.dex.instructions.args.InsnWrapArg; import jadx.core.dex.instructions.args.LiteralArg; import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.nodes.BlockNode; +import jadx.core.dex.nodes.InsnNode; import jadx.core.utils.exceptions.JadxRuntimeException; import java.util.ArrayList; @@ -132,6 +135,7 @@ public final class IfCondition { public static IfCondition simplify(IfCondition cond) { if (cond.isCompare()) { Compare c = cond.getCompare(); + simplifyCmpOp(c); if (c.getOp() == IfOp.EQ && c.getB().isLiteral() && c.getB().equals(LiteralArg.FALSE)) { return not(new IfCondition(c.invert())); } else { @@ -177,6 +181,22 @@ public final class IfCondition { return cond; } + private static void simplifyCmpOp(Compare c) { + if (!c.getA().isInsnWrap()) { + return; + } + if (!c.getB().isLiteral() || ((LiteralArg) c.getB()).getLiteral() != 0) { + return; + } + InsnNode wrapInsn = ((InsnWrapArg) c.getA()).getWrapInsn(); + InsnType type = wrapInsn.getType(); + if (type != InsnType.CMP_L && type != InsnType.CMP_G) { + return; + } + IfNode insn = c.getInsn(); + insn.changeCondition(insn.getOp(), wrapInsn.getArg(0), wrapInsn.getArg(1)); + } + public List getRegisterArgs() { List list = new LinkedList(); if (mode == Mode.COMPARE) { diff --git a/jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp.java b/jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp.java new file mode 100644 index 0000000000000000000000000000000000000000..9253bdc1b5619b33972631d6381685a46eb3618d --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp.java @@ -0,0 +1,67 @@ +package jadx.tests.internal.conditions; + +import jadx.api.InternalJadxTest; +import jadx.core.dex.nodes.ClassNode; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; + +public class TestCmpOp extends InternalJadxTest { + + public static class TestCls { + public boolean testGT(float a) { + return a > 3.0f; + } + + public boolean testLT(float b) { + return b < 2.0f; + } + + public boolean testEQ(float c) { + return c == 1.0f; + } + + public boolean testNE(float d) { + return d != 0.0f; + } + + public boolean testGE(float e) { + return e >= -1.0f; + } + + public boolean testLE(float f) { + return f <= -2.0f; + } + + public boolean testGT2(float g) { + return 4.0f > g; + } + + public boolean testLT2(long h) { + return 5 < h; + } + + public boolean testGE2(double i) { + return 6.5d < i; + } + } + + @Test + public void test() { + ClassNode cls = getClassNode(TestCls.class); + String code = cls.getCode().toString(); + System.out.println(code); + + assertThat(code, containsString("return a > 3.0f;")); + assertThat(code, containsString("return b < 2.0f;")); + assertThat(code, containsString("return c == 1.0f;")); + assertThat(code, containsString("return d != 0.0f;")); + assertThat(code, containsString("return e >= -1.0f;")); + assertThat(code, containsString("return f <= -2.0f;")); + assertThat(code, containsString("return 4.0f > g;")); + assertThat(code, containsString("return 5 < h;")); + assertThat(code, containsString("return 6.5d < i;")); + } +} diff --git a/jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp2.java b/jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp2.java new file mode 100644 index 0000000000000000000000000000000000000000..674bc5c2a7deacdd66041720b1a4374844567093 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp2.java @@ -0,0 +1,32 @@ +package jadx.tests.internal.conditions; + +import jadx.api.InternalJadxTest; +import jadx.core.dex.nodes.ClassNode; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; + +public class TestCmpOp2 extends InternalJadxTest { + + public static class TestCls { + public boolean testGT(float a, float b) { + return a > b; + } + + public boolean testLT(float c, double d) { + return c < d; + } + } + + @Test + public void test() { + ClassNode cls = getClassNode(TestCls.class); + String code = cls.getCode().toString(); + System.out.println(code); + + assertThat(code, containsString("return a > b;")); + assertThat(code, containsString("return ((double) c) < d;")); + } +}