Commit 90fb95e7 authored by Skylot's avatar Skylot

core: check arguments for field arithmetic operations (fix #40)

parent 0f97f074
...@@ -2,14 +2,17 @@ package jadx.core.dex.instructions.args; ...@@ -2,14 +2,17 @@ package jadx.core.dex.instructions.args;
import jadx.core.dex.info.FieldInfo; import jadx.core.dex.info.FieldInfo;
import org.jetbrains.annotations.Nullable;
// TODO: don't extend RegisterArg (now used as a result of instruction) // TODO: don't extend RegisterArg (now used as a result of instruction)
public final class FieldArg extends RegisterArg { public final class FieldArg extends RegisterArg {
private final FieldInfo field; private final FieldInfo field;
// instArg equal 'null' for static fields // instArg equal 'null' for static fields
@Nullable
private final InsnArg instArg; private final InsnArg instArg;
public FieldArg(FieldInfo field, InsnArg reg) { public FieldArg(FieldInfo field, @Nullable InsnArg reg) {
super(-1); super(-1);
this.instArg = reg; this.instArg = reg;
this.field = field; this.field = field;
......
...@@ -2,11 +2,13 @@ package jadx.core.dex.instructions.args; ...@@ -2,11 +2,13 @@ package jadx.core.dex.instructions.args;
import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.InsnNode;
import org.jetbrains.annotations.NotNull;
public final class InsnWrapArg extends InsnArg { public final class InsnWrapArg extends InsnArg {
private final InsnNode wrappedInsn; private final InsnNode wrappedInsn;
public InsnWrapArg(InsnNode insn) { public InsnWrapArg(@NotNull InsnNode insn) {
RegisterArg result = insn.getResult(); RegisterArg result = insn.getResult();
this.type = result != null ? result.getType() : ArgType.VOID; this.type = result != null ? result.getType() : ArgType.VOID;
this.wrappedInsn = insn; this.wrappedInsn = insn;
...@@ -28,6 +30,34 @@ public final class InsnWrapArg extends InsnArg { ...@@ -28,6 +30,34 @@ public final class InsnWrapArg extends InsnArg {
} }
@Override @Override
public int hashCode() {
return wrappedInsn.hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof InsnWrapArg)) {
return false;
}
InsnWrapArg that = (InsnWrapArg) o;
InsnNode thisInsn = wrappedInsn;
InsnNode thatInsn = that.wrappedInsn;
if (!thisInsn.isSame(thatInsn)) {
return false;
}
int count = thisInsn.getArgsCount();
for (int i = 0; i < count; i++) {
if (!thisInsn.getArg(i).equals(thatInsn.getArg(i))) {
return false;
}
}
return true;
}
@Override
public String toString() { public String toString() {
return "(wrap: " + type + "\n " + wrappedInsn + ")"; return "(wrap: " + type + "\n " + wrappedInsn + ")";
} }
......
package jadx.core.dex.instructions.args; package jadx.core.dex.instructions.args;
import org.jetbrains.annotations.NotNull;
public final class NamedArg extends InsnArg implements Named { public final class NamedArg extends InsnArg implements Named {
@NotNull
private String name; private String name;
public NamedArg(String name, ArgType type) { public NamedArg(@NotNull String name, @NotNull ArgType type) {
this.name = name; this.name = name;
this.type = type; this.type = type;
} }
@NotNull
public String getName() { public String getName() {
return name; return name;
} }
...@@ -18,11 +22,28 @@ public final class NamedArg extends InsnArg implements Named { ...@@ -18,11 +22,28 @@ public final class NamedArg extends InsnArg implements Named {
return true; return true;
} }
public void setName(String name) { public void setName(@NotNull String name) {
this.name = name; this.name = name;
} }
@Override @Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof NamedArg)) {
return false;
}
return name.equals(((NamedArg) o).name);
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public String toString() { public String toString() {
return "(" + name + " " + type + ")"; return "(" + name + " " + type + ")";
} }
......
...@@ -55,8 +55,7 @@ public class TypeImmutableArg extends RegisterArg { ...@@ -55,8 +55,7 @@ public class TypeImmutableArg extends RegisterArg {
if (!super.equals(obj)) { if (!super.equals(obj)) {
return false; return false;
} }
TypeImmutableArg that = (TypeImmutableArg) obj; return isThis == ((TypeImmutableArg) obj).isThis;
return isThis == that.isThis;
} }
@Override @Override
......
...@@ -252,6 +252,10 @@ public class SimplifyVisitor extends AbstractVisitor { ...@@ -252,6 +252,10 @@ public class SimplifyVisitor extends AbstractVisitor {
InsnArg reg = null; InsnArg reg = null;
if (getType == InsnType.IGET) { if (getType == InsnType.IGET) {
reg = get.getArg(0); reg = get.getArg(0);
InsnArg putReg = insn.getArg(1);
if (!reg.equals(putReg)) {
return null;
}
} }
FieldArg fArg = new FieldArg(field, reg); FieldArg fArg = new FieldArg(field, reg);
if (reg != null) { if (reg != null) {
...@@ -268,7 +272,7 @@ public class SimplifyVisitor extends AbstractVisitor { ...@@ -268,7 +272,7 @@ public class SimplifyVisitor extends AbstractVisitor {
} }
return new ArithNode(ArithOp.ADD, fArg, InsnArg.wrapArg(concat)); return new ArithNode(ArithOp.ADD, fArg, InsnArg.wrapArg(concat));
} }
} catch (Throwable e) { } catch (Exception e) {
LOG.debug("Can't convert field arith insn: {}, mth: {}", insn, mth, e); LOG.debug("Can't convert field arith insn: {}, mth: {}", insn, mth, e);
} }
return null; return null;
......
package jadx.tests.integration.arith;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest;
import java.util.Random;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertThat;
public class TestFieldIncrement3 extends IntegrationTest {
public static class TestCls {
static int tileX;
static int tileY;
static Vector2 targetPos = new Vector2();
static Vector2 directVect = new Vector2();
static Vector2 newPos = new Vector2();
private static void test() {
Random rd = new Random();
int direction = rd.nextInt(7);
switch (direction) {
case 0:
targetPos.x = (float) (((tileX + 1) * 55) + 55);
targetPos.y = (float) (((tileY + 1) * 35) + 35);
break;
case 2:
targetPos.x = (float) (((tileX + 1) * 55) + 55);
targetPos.y = (float) (((tileY - 1) * 35) + 35);
break;
case 4:
targetPos.x = (float) (((tileX - 1) * 55) + 55);
targetPos.y = (float) (((tileY - 1) * 35) + 35);
break;
case 6:
targetPos.x = (float) (((tileX - 1) * 55) + 55);
targetPos.y = (float) (((tileY + 1) * 35) + 35);
break;
default:
break;
}
directVect.x = targetPos.x - newPos.x;
directVect.y = targetPos.y - newPos.y;
float hPos = (float) Math.sqrt((double) ((directVect.x * directVect.x) + (directVect.y * directVect.y)));
directVect.x /= hPos;
directVect.y /= hPos;
}
static class Vector2 {
public float x;
public float y;
public Vector2() {
this.x = 0.0f;
this.y = 0.0f;
}
public boolean equals(Vector2 other) {
return (this.x == other.x && this.y == other.y);
}
}
}
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
assertThat(code, containsString("directVect.x = targetPos.x - newPos.x;"));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment