@@ -7,9 +7,10 @@ import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import jadx.core.dex.instructions.ArithNode;
|
||||
import jadx.core.dex.instructions.ArithOp;
|
||||
import jadx.core.dex.instructions.IfNode;
|
||||
import jadx.core.dex.instructions.IfOp;
|
||||
import jadx.core.dex.instructions.InsnType;
|
||||
import jadx.core.dex.instructions.args.InsnWrapArg;
|
||||
import jadx.core.dex.instructions.args.LiteralArg;
|
||||
import jadx.core.dex.instructions.args.RegisterArg;
|
||||
@@ -142,7 +143,10 @@ public final class IfCondition {
|
||||
public static IfCondition simplify(IfCondition cond) {
|
||||
if (cond.isCompare()) {
|
||||
Compare c = cond.getCompare();
|
||||
simplifyCmpOp(c);
|
||||
IfCondition i = simplifyCmpOp(c);
|
||||
if (i != null) {
|
||||
return i;
|
||||
}
|
||||
if (c.getOp() == IfOp.EQ && c.getB().isLiteral() && c.getB().equals(LiteralArg.FALSE)) {
|
||||
cond = not(new IfCondition(c.invert()));
|
||||
} else {
|
||||
@@ -190,20 +194,53 @@ public final class IfCondition {
|
||||
return cond;
|
||||
}
|
||||
|
||||
private static void simplifyCmpOp(Compare c) {
|
||||
private static IfCondition simplifyCmpOp(Compare c) {
|
||||
if (!c.getA().isInsnWrap()) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
if (!c.getB().isLiteral() || ((LiteralArg) c.getB()).getLiteral() != 0) {
|
||||
return;
|
||||
if (!c.getB().isLiteral()) {
|
||||
return null;
|
||||
}
|
||||
long lit = ((LiteralArg) c.getB()).getLiteral();
|
||||
if (lit != 0 && lit != 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
InsnNode wrapInsn = ((InsnWrapArg) c.getA()).getWrapInsn();
|
||||
InsnType type = wrapInsn.getType();
|
||||
if (type != InsnType.CMP_L && type != InsnType.CMP_G) {
|
||||
return;
|
||||
switch (wrapInsn.getType()) {
|
||||
case CMP_L:
|
||||
case CMP_G:
|
||||
if (lit == 0) {
|
||||
IfNode insn = c.getInsn();
|
||||
insn.changeCondition(insn.getOp(), wrapInsn.getArg(0), wrapInsn.getArg(1));
|
||||
}
|
||||
break;
|
||||
|
||||
case ARITH:
|
||||
ArithOp arithOp = ((ArithNode) wrapInsn).getOp();
|
||||
if (arithOp == ArithOp.OR || arithOp == ArithOp.AND) {
|
||||
IfOp ifOp = c.getInsn().getOp();
|
||||
boolean isTrue = ifOp == IfOp.NE && lit == 0
|
||||
|| ifOp == IfOp.EQ && lit == 1;
|
||||
|
||||
IfOp op = isTrue ? IfOp.NE : IfOp.EQ;
|
||||
Mode mode = isTrue && arithOp == ArithOp.OR ||
|
||||
!isTrue && arithOp == ArithOp.AND ? Mode.OR : Mode.AND;
|
||||
|
||||
IfNode if1 = new IfNode(op, -1, wrapInsn.getArg(0), LiteralArg.FALSE);
|
||||
IfNode if2 = new IfNode(op, -1, wrapInsn.getArg(1), LiteralArg.FALSE);
|
||||
return new IfCondition(mode,
|
||||
Arrays.asList(new IfCondition(new Compare(if1)),
|
||||
new IfCondition(new Compare(if2))));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
IfNode insn = c.getInsn();
|
||||
insn.changeCondition(insn.getOp(), wrapInsn.getArg(0), wrapInsn.getArg(1));
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<RegisterArg> getRegisterArgs() {
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package jadx.tests.integration.conditions;
|
||||
|
||||
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 TestBitwiseAnd extends IntegrationTest {
|
||||
|
||||
public static class TestCls {
|
||||
private boolean a;
|
||||
private boolean b;
|
||||
|
||||
public void test() {
|
||||
if ((a & b) != false) {
|
||||
test();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
noDebugInfo();
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("if (this.a && this.b) {"));
|
||||
}
|
||||
|
||||
public static class TestCls2 {
|
||||
private boolean a;
|
||||
private boolean b;
|
||||
|
||||
public void test() {
|
||||
if ((a & b) != true) {
|
||||
test();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
noDebugInfo();
|
||||
ClassNode cls = getClassNode(TestCls2.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("if (!this.a || !this.b) {"));
|
||||
}
|
||||
|
||||
public static class TestCls3 {
|
||||
private boolean a;
|
||||
private boolean b;
|
||||
|
||||
public void test() {
|
||||
if ((a & b) == false) {
|
||||
test();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3() {
|
||||
noDebugInfo();
|
||||
ClassNode cls = getClassNode(TestCls3.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("if (!this.a || !this.b) {"));
|
||||
}
|
||||
|
||||
public static class TestCls4 {
|
||||
private boolean a;
|
||||
private boolean b;
|
||||
|
||||
public void test() {
|
||||
if ((a & b) == true) {
|
||||
test();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test4() {
|
||||
noDebugInfo();
|
||||
ClassNode cls = getClassNode(TestCls4.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("if (this.a && this.b) {"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package jadx.tests.integration.conditions;
|
||||
|
||||
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 TestBitwiseOr extends IntegrationTest {
|
||||
|
||||
public static class TestCls {
|
||||
private boolean a;
|
||||
private boolean b;
|
||||
|
||||
public void test() {
|
||||
if ((a | b) != false) {
|
||||
test();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
noDebugInfo();
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("if (this.a || this.b) {"));
|
||||
}
|
||||
|
||||
public static class TestCls2 {
|
||||
private boolean a;
|
||||
private boolean b;
|
||||
|
||||
public void test() {
|
||||
if ((a | b) != true) {
|
||||
test();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
noDebugInfo();
|
||||
ClassNode cls = getClassNode(TestCls2.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("if (!this.a && !this.b) {"));
|
||||
}
|
||||
|
||||
public static class TestCls3 {
|
||||
private boolean a;
|
||||
private boolean b;
|
||||
|
||||
public void test() {
|
||||
if ((a | b) == false) {
|
||||
test();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3() {
|
||||
noDebugInfo();
|
||||
ClassNode cls = getClassNode(TestCls3.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("if (!this.a && !this.b) {"));
|
||||
}
|
||||
|
||||
public static class TestCls4 {
|
||||
private boolean a;
|
||||
private boolean b;
|
||||
|
||||
public void test() {
|
||||
if ((a | b) == true) {
|
||||
test();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test4() {
|
||||
noDebugInfo();
|
||||
ClassNode cls = getClassNode(TestCls4.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("if (this.a || this.b) {"));
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package jadx.tests.integration.conditions;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.NotYetImplemented;
|
||||
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 TestConditions17 extends IntegrationTest {
|
||||
|
||||
public static class TestCls {
|
||||
private boolean a;
|
||||
private boolean b;
|
||||
|
||||
public void test() {
|
||||
if ((a | b) != false) {
|
||||
test();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@NotYetImplemented
|
||||
public void test202() {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("a || b"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user