提交 eb2a1734 编写于 作者: A Ahmed Ashour 提交者: skylot

fix: xor with boolean (#409) (PR #516)

上级 aa8a7c03
......@@ -277,7 +277,8 @@ public class InsnGen {
break;
case NOT:
oneArgInsn(code, insn, state, '~');
char op = insn.getArg(0).getType() == ArgType.BOOLEAN ? '!' : '~';
oneArgInsn(code, insn, state, op);
break;
case RETURN:
......
......@@ -4,18 +4,26 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import jadx.core.dex.instructions.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.core.Consts;
import jadx.core.dex.info.FieldInfo;
import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.instructions.ArithNode;
import jadx.core.dex.instructions.ArithOp;
import jadx.core.dex.instructions.CallMthInterface;
import jadx.core.dex.instructions.ConstStringNode;
import jadx.core.dex.instructions.IfNode;
import jadx.core.dex.instructions.IndexInsnNode;
import jadx.core.dex.instructions.InsnType;
import jadx.core.dex.instructions.InvokeNode;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.FieldArg;
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.instructions.mods.ConstructorInsn;
import jadx.core.dex.instructions.mods.TernaryInsn;
import jadx.core.dex.nodes.BlockNode;
......@@ -54,7 +62,7 @@ public class SimplifyVisitor extends AbstractVisitor {
}
switch (insn.getType()) {
case ARITH:
return simplifyArith(insn);
return simplifyArith((ArithNode) insn);
case IF:
simplifyIf((IfNode) insn);
......@@ -64,7 +72,7 @@ public class SimplifyVisitor extends AbstractVisitor {
break;
case INVOKE:
return convertInvoke(mth, insn);
return convertInvoke(mth, (InvokeNode) insn);
case IPUT:
case SPUT:
......@@ -151,8 +159,8 @@ public class SimplifyVisitor extends AbstractVisitor {
* @param insn
* @return
*/
private static InsnNode convertInvoke(MethodNode mth, InsnNode insn) {
MethodInfo callMth = ((InvokeNode) insn).getCallMth();
private static InsnNode convertInvoke(MethodNode mth, InvokeNode insn) {
MethodInfo callMth = insn.getCallMth();
// If this is a 'new StringBuilder(xxx).append(yyy).append(zzz).toString(),
// convert it to STRING_CONCAT pseudo instruction.
......@@ -225,8 +233,7 @@ public class SimplifyVisitor extends AbstractVisitor {
return null;
}
private static InsnNode simplifyArith(InsnNode insn) {
ArithNode arith = (ArithNode) insn;
private static InsnNode simplifyArith(ArithNode arith) {
if (arith.getArgsCount() != 2) {
return null;
}
......@@ -245,9 +252,17 @@ public class SimplifyVisitor extends AbstractVisitor {
// fix 'c + (-1)' => 'c - (1)'
if (arith.getOp() == ArithOp.ADD && lit < 0) {
return new ArithNode(ArithOp.SUB,
arith.getResult(), insn.getArg(0),
arith.getResult(), arith.getArg(0),
InsnArg.lit(-lit, litArg.getType()));
}
InsnArg firstArg = arith.getArg(0);
if (arith.getOp() == ArithOp.XOR && firstArg.getType() == ArgType.BOOLEAN
&& (lit == 0 || lit == 1)) {
InsnNode node = new InsnNode(lit == 0 ? InsnType.MOVE : InsnType.NOT, 1);
node.setResult(arith.getResult());
node.addArg(firstArg);
return node;
}
}
return null;
}
......
package jadx.tests.integration.conditions;
import static jadx.tests.api.utils.JadxMatchers.containsOne;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.jupiter.api.Test;
import jadx.NotYetImplemented;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest;
import jadx.tests.api.SmaliTest;
public class TestXor extends IntegrationTest {
public class TestXor extends SmaliTest {
public static class TestCls {
public boolean test() {
return test2() ^ true;
public boolean test1() {
return test() ^ true;
}
public boolean test2(boolean v) {
return v ^ true;
}
public boolean test2() {
public boolean test() {
return true;
}
}
@Test
@NotYetImplemented
public void test409() {
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
assertThat(code, not(containsOne("1")));
assertThat(code, containsOne("return !test();"));
assertThat(code, containsOne("return !v;"));
}
@Test
public void smali() {
/*
public boolean test1() {
return test() ^ true;
}
public boolean test2() {
return test() ^ false;
}
public boolean test() {
return true;
}
*/
ClassNode cls = getClassNodeFromSmaliWithPath("conditions", "TestXor");
String code = cls.getCode().toString();
assertThat(code, containsOne("return !test();"));
assertThat(code, containsOne("return test();"));
}
}
.class public LTestXor;
.super Ljava/lang/Object;
# direct methods
.method public constructor <init>()V
.locals 0
.line 9
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
# virtual methods
.method public test()Z
.locals 1
.line 20
const/4 v0, 0x1
return v0
.end method
.method public test1()Z
.locals 1
.line 12
invoke-virtual {p0}, Lcom/example/myapplication/MainActivity;->test()Z
move-result v0
xor-int/lit8 v0, v0, 0x1
return v0
.end method
.method public test2()Z
.locals 1
.line 16
invoke-virtual {p0}, Lcom/example/myapplication/MainActivity;->test()Z
move-result v0
xor-int/lit8 v0, v0, 0x0
return v0
.end method
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册