提交 e4dde3f4 编写于 作者: S Skylot

core: fix class cast exception

上级 9c90699c
...@@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory; ...@@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory;
/** /**
* Jadx API usage example: * Jadx API usage example:
* <pre><code> * <pre><code>
* Decompiler jadx = new Decompiler(); * JadxDecompiler jadx = new JadxDecompiler();
* jadx.loadFile(new File("classes.dex")); * jadx.loadFile(new File("classes.dex"));
* jadx.setOutputDir(new File("out")); * jadx.setOutputDir(new File("out"));
* jadx.save(); * jadx.save();
......
...@@ -101,7 +101,7 @@ public class InsnGen { ...@@ -101,7 +101,7 @@ public class InsnGen {
if (f.isStatic()) { if (f.isStatic()) {
staticField(code, f.getField()); staticField(code, f.getField());
} else { } else {
instanceField(code, f.getField(), f.getRegisterArg()); instanceField(code, f.getField(), f.getInstanceArg());
} }
} else { } else {
throw new CodegenException("Unknown arg type " + arg); throw new CodegenException("Unknown arg type " + arg);
......
...@@ -6,12 +6,12 @@ import jadx.core.dex.info.FieldInfo; ...@@ -6,12 +6,12 @@ import jadx.core.dex.info.FieldInfo;
public final class FieldArg extends RegisterArg { public final class FieldArg extends RegisterArg {
private final FieldInfo field; private final FieldInfo field;
// regArg equal 'null' for static fields // instArg equal 'null' for static fields
private final RegisterArg regArg; private final InsnArg instArg;
public FieldArg(FieldInfo field, RegisterArg reg) { public FieldArg(FieldInfo field, InsnArg reg) {
super(-1); super(-1);
this.regArg = reg; this.instArg = reg;
this.field = field; this.field = field;
} }
...@@ -19,12 +19,12 @@ public final class FieldArg extends RegisterArg { ...@@ -19,12 +19,12 @@ public final class FieldArg extends RegisterArg {
return field; return field;
} }
public RegisterArg getRegisterArg() { public InsnArg getInstanceArg() {
return regArg; return instArg;
} }
public boolean isStatic() { public boolean isStatic() {
return regArg == null; return instArg == null;
} }
@Override @Override
...@@ -54,7 +54,7 @@ public final class FieldArg extends RegisterArg { ...@@ -54,7 +54,7 @@ public final class FieldArg extends RegisterArg {
if (!field.equals(fieldArg.field)) { if (!field.equals(fieldArg.field)) {
return false; return false;
} }
if (regArg != null ? !regArg.equals(fieldArg.regArg) : fieldArg.regArg != null) { if (instArg != null ? !instArg.equals(fieldArg.instArg) : fieldArg.instArg != null) {
return false; return false;
} }
return true; return true;
...@@ -64,7 +64,7 @@ public final class FieldArg extends RegisterArg { ...@@ -64,7 +64,7 @@ public final class FieldArg extends RegisterArg {
public int hashCode() { public int hashCode() {
int result = super.hashCode(); int result = super.hashCode();
result = 31 * result + field.hashCode(); result = 31 * result + field.hashCode();
result = 31 * result + (regArg != null ? regArg.hashCode() : 0); result = 31 * result + (instArg != null ? instArg.hashCode() : 0);
return result; return result;
} }
......
...@@ -14,7 +14,6 @@ import jadx.core.dex.instructions.args.FieldArg; ...@@ -14,7 +14,6 @@ import jadx.core.dex.instructions.args.FieldArg;
import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.InsnWrapArg; import jadx.core.dex.instructions.args.InsnWrapArg;
import jadx.core.dex.instructions.args.LiteralArg; 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.ConstructorInsn;
import jadx.core.dex.nodes.BlockNode; import jadx.core.dex.nodes.BlockNode;
import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.InsnNode;
...@@ -186,9 +185,9 @@ public class SimplifyVisitor extends AbstractVisitor { ...@@ -186,9 +185,9 @@ public class SimplifyVisitor extends AbstractVisitor {
return null; return null;
} }
try { try {
RegisterArg reg = null; InsnArg reg = null;
if (getType == InsnType.IGET) { if (getType == InsnType.IGET) {
reg = ((RegisterArg) get.getArg(0)); reg = get.getArg(0);
} }
FieldArg fArg = new FieldArg(field, reg); FieldArg fArg = new FieldArg(field, reg);
if (reg != null) { if (reg != null) {
......
...@@ -3,6 +3,7 @@ package jadx.core.utils; ...@@ -3,6 +3,7 @@ package jadx.core.utils;
import jadx.core.Consts; import jadx.core.Consts;
import jadx.core.dex.attributes.AFlag; import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.InsnWrapArg;
import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.instructions.args.SSAVar; import jadx.core.dex.instructions.args.SSAVar;
import jadx.core.dex.nodes.BlockNode; import jadx.core.dex.nodes.BlockNode;
...@@ -65,17 +66,24 @@ public class InstructionRemover { ...@@ -65,17 +66,24 @@ public class InstructionRemover {
mth.removeSVar(r.getSVar()); mth.removeSVar(r.getSVar());
} }
for (InsnArg arg : insn.getArguments()) { for (InsnArg arg : insn.getArguments()) {
if (arg instanceof RegisterArg) { unbindArgUsage(mth, arg);
RegisterArg reg = (RegisterArg) arg;
SSAVar sVar = reg.getSVar();
if (sVar != null) {
sVar.removeUse(reg);
}
}
} }
insn.add(AFlag.INCONSISTENT_CODE); insn.add(AFlag.INCONSISTENT_CODE);
} }
public static void unbindArgUsage(MethodNode mth, InsnArg arg) {
if (arg instanceof RegisterArg) {
RegisterArg reg = (RegisterArg) arg;
SSAVar sVar = reg.getSVar();
if (sVar != null) {
sVar.removeUse(reg);
}
} else if (arg instanceof InsnWrapArg) {
InsnWrapArg wrap = (InsnWrapArg) arg;
unbindInsn(mth, wrap.getWrapInsn());
}
}
// Don't use 'insns.removeAll(toRemove)' because it will remove instructions by content // Don't use 'insns.removeAll(toRemove)' because it will remove instructions by content
// and here can be several instructions with same content // and here can be several instructions with same content
private void removeAll(List<InsnNode> insns, List<InsnNode> toRemove) { private void removeAll(List<InsnNode> insns, List<InsnNode> toRemove) {
......
package jadx.tests.internal; package jadx.tests.internal.arith;
import jadx.api.InternalJadxTest; import jadx.api.InternalJadxTest;
import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.ClassNode;
......
package jadx.tests.internal.arith;
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 TestFieldIncrement2 extends InternalJadxTest {
class A {
int f = 5;
}
public static class TestCls {
public A a;
public void test1(int n) {
this.a.f = this.a.f + n;
}
public void test2(int n) {
this.a.f *= n;
}
}
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
System.out.println(code);
assertThat(code, containsString("this.a.f += n;"));
assertThat(code, containsString("a.f *= n;"));
// TODO
// assertThat(code, containsString("this.a.f *= n;"));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册