Commit 662ebb64 authored by Skylot's avatar Skylot

core: don't add super call without args

parent 4a63f522
package jadx.core.dex.visitors; package jadx.core.dex.visitors;
import jadx.core.deobf.NameMapper; import jadx.core.deobf.NameMapper;
import jadx.core.dex.attributes.AttributeFlag;
import jadx.core.dex.attributes.AttributeType; import jadx.core.dex.attributes.AttributeType;
import jadx.core.dex.info.MethodInfo; import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.instructions.*; import jadx.core.dex.instructions.ConstClassNode;
import jadx.core.dex.instructions.args.*; import jadx.core.dex.instructions.ConstStringNode;
import jadx.core.dex.instructions.FillArrayNode;
import jadx.core.dex.instructions.IndexInsnNode;
import jadx.core.dex.instructions.InsnType;
import jadx.core.dex.instructions.InvokeNode;
import jadx.core.dex.instructions.SwitchNode;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.InsnArg;
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.*; import jadx.core.dex.nodes.BlockNode;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.FieldNode;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.trycatch.ExcHandlerAttr; import jadx.core.dex.trycatch.ExcHandlerAttr;
import jadx.core.dex.trycatch.ExceptionHandler; import jadx.core.dex.trycatch.ExceptionHandler;
import jadx.core.utils.BlockUtils;
import jadx.core.utils.exceptions.JadxRuntimeException; import jadx.core.utils.exceptions.JadxRuntimeException;
import java.util.List; import java.util.List;
...@@ -26,9 +39,9 @@ public class ModVisitor extends AbstractVisitor { ...@@ -26,9 +39,9 @@ public class ModVisitor extends AbstractVisitor {
@Override @Override
public void visit(MethodNode mth) { public void visit(MethodNode mth) {
if (mth.isNoCode()) if (mth.isNoCode()) {
return; return;
}
removeStep(mth); removeStep(mth);
replaceStep(mth); replaceStep(mth);
...@@ -40,6 +53,7 @@ public class ModVisitor extends AbstractVisitor { ...@@ -40,6 +53,7 @@ public class ModVisitor extends AbstractVisitor {
} }
private void replaceStep(MethodNode mth) { private void replaceStep(MethodNode mth) {
ClassNode parentClass = mth.getParentClass();
ConstructorInsn superCall = null; ConstructorInsn superCall = null;
for (BlockNode block : mth.getBasicBlocks()) { for (BlockNode block : mth.getBasicBlocks()) {
InstructionRemover remover = new InstructionRemover(block.getInstructions()); InstructionRemover remover = new InstructionRemover(block.getInstructions());
...@@ -47,9 +61,6 @@ public class ModVisitor extends AbstractVisitor { ...@@ -47,9 +61,6 @@ public class ModVisitor extends AbstractVisitor {
int size = block.getInstructions().size(); int size = block.getInstructions().size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
InsnNode insn = block.getInstructions().get(i); InsnNode insn = block.getInstructions().get(i);
ClassNode parentClass = mth.getParentClass();
FieldNode f = null;
switch (insn.getType()) { switch (insn.getType()) {
case INVOKE: case INVOKE:
InvokeNode inv = (InvokeNode) insn; InvokeNode inv = (InvokeNode) insn;
...@@ -58,18 +69,17 @@ public class ModVisitor extends AbstractVisitor { ...@@ -58,18 +69,17 @@ public class ModVisitor extends AbstractVisitor {
ConstructorInsn co = new ConstructorInsn(mth, inv); ConstructorInsn co = new ConstructorInsn(mth, inv);
if (co.isSuper()) { if (co.isSuper()) {
try { try {
if (co.getArgsCount() != 0) { // inline super call args
// inline super call args for (int j = 0; j < co.getArgsCount(); j++) {
for (int j = 0; j < co.getArgsCount(); j++) { InsnArg arg = co.getArg(j);
InsnArg arg = co.getArg(j); if (arg.isRegister()) {
if (arg.isRegister()) { CodeShrinker.inlineArgument(mth, (RegisterArg) arg);
CodeShrinker.inlineArgument(mth, (RegisterArg) arg);
}
} }
} }
} catch (JadxRuntimeException e) { } catch (JadxRuntimeException e) {
// inline args into super fail // inline args into super fail
LOG.warn("Can't inline args into super call: " + inv + ", mth: " + mth); LOG.warn("Can't inline args into super call: " + inv + ", mth: " + mth);
mth.getAttributes().add(AttributeFlag.INCONSISTENT_CODE);
} finally { } finally {
superCall = co; superCall = co;
remover.add(insn); remover.add(insn);
...@@ -91,7 +101,7 @@ public class ModVisitor extends AbstractVisitor { ...@@ -91,7 +101,7 @@ public class ModVisitor extends AbstractVisitor {
for (int j = 0; j < inv.getArgsCount(); j++) { for (int j = 0; j < inv.getArgsCount(); j++) {
InsnArg arg = inv.getArg(j); InsnArg arg = inv.getArg(j);
if (arg.isLiteral()) { if (arg.isLiteral()) {
f = parentClass.getConstFieldByLiteralArg((LiteralArg) arg); FieldNode f = parentClass.getConstFieldByLiteralArg((LiteralArg) arg);
if (f != null) { if (f != null) {
arg.wrapInstruction(new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0)); arg.wrapInstruction(new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0));
} }
...@@ -103,7 +113,8 @@ public class ModVisitor extends AbstractVisitor { ...@@ -103,7 +113,8 @@ public class ModVisitor extends AbstractVisitor {
case CONST: case CONST:
case CONST_STR: case CONST_STR:
case CONST_CLASS: case CONST_CLASS: {
FieldNode f;
if (insn.getType() == InsnType.CONST_STR) { if (insn.getType() == InsnType.CONST_STR) {
String s = ((ConstStringNode) insn).getString(); String s = ((ConstStringNode) insn).getString();
f = parentClass.getConstField(s); f = parentClass.getConstField(s);
...@@ -119,11 +130,12 @@ public class ModVisitor extends AbstractVisitor { ...@@ -119,11 +130,12 @@ public class ModVisitor extends AbstractVisitor {
replaceInsn(block, i, inode); replaceInsn(block, i, inode);
} }
break; break;
}
case SWITCH: case SWITCH:
SwitchNode sn = (SwitchNode) insn; SwitchNode sn = (SwitchNode) insn;
for (int k = 0; k < sn.getCasesCount(); k++) { for (int k = 0; k < sn.getCasesCount(); k++) {
f = parentClass.getConstField(sn.getKeys()[k]); FieldNode f = parentClass.getConstField(sn.getKeys()[k]);
if (f != null) { if (f != null) {
sn.getKeys()[k] = new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0); sn.getKeys()[k] = new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0);
} }
...@@ -131,10 +143,9 @@ public class ModVisitor extends AbstractVisitor { ...@@ -131,10 +143,9 @@ public class ModVisitor extends AbstractVisitor {
break; break;
case RETURN: case RETURN:
if (insn.getArgsCount() > 0 if (insn.getArgsCount() > 0 && insn.getArg(0).isLiteral()) {
&& insn.getArg(0).isLiteral()) {
LiteralArg arg = (LiteralArg) insn.getArg(0); LiteralArg arg = (LiteralArg) insn.getArg(0);
f = parentClass.getConstFieldByLiteralArg(arg); FieldNode f = parentClass.getConstFieldByLiteralArg(arg);
if (f != null) { if (f != null) {
arg.wrapInstruction(new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0)); arg.wrapInstruction(new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0));
} }
...@@ -147,7 +158,7 @@ public class ModVisitor extends AbstractVisitor { ...@@ -147,7 +158,7 @@ public class ModVisitor extends AbstractVisitor {
} }
remover.perform(); remover.perform();
} }
if (superCall != null && !mth.getParentClass().isEnum()) { if (superCall != null && !parentClass.isEnum() && superCall.getArgsCount() != 0) {
List<InsnNode> insns = mth.getEnterBlock().getInstructions(); List<InsnNode> insns = mth.getEnterBlock().getInstructions();
insns.add(0, superCall); insns.add(0, superCall);
} }
...@@ -204,9 +215,9 @@ public class ModVisitor extends AbstractVisitor { ...@@ -204,9 +215,9 @@ public class ModVisitor extends AbstractVisitor {
private void processExceptionHander(MethodNode mth, BlockNode block) { private void processExceptionHander(MethodNode mth, BlockNode block) {
ExcHandlerAttr handlerAttr = (ExcHandlerAttr) block.getAttributes().get(AttributeType.EXC_HANDLER); ExcHandlerAttr handlerAttr = (ExcHandlerAttr) block.getAttributes().get(AttributeType.EXC_HANDLER);
if (handlerAttr == null) if (handlerAttr == null) {
return; return;
}
ExceptionHandler excHandler = handlerAttr.getHandler(); ExceptionHandler excHandler = handlerAttr.getHandler();
boolean noExitNode = true; // check if handler has exit edge to block not from this handler boolean noExitNode = true; // check if handler has exit edge to block not from this handler
for (BlockNode excBlock : excHandler.getBlocks()) { for (BlockNode excBlock : excHandler.getBlocks()) {
...@@ -261,18 +272,6 @@ public class ModVisitor extends AbstractVisitor { ...@@ -261,18 +272,6 @@ public class ModVisitor extends AbstractVisitor {
block.getInstructions().set(i, insn); block.getInstructions().set(i, insn);
} }
/**
* Replace oldInsn in block by newInsn,
*/
public static boolean replaceInsn(BlockNode block, InsnNode oldInsn, InsnNode newInsn) {
int pos = BlockUtils.insnIndex(block, oldInsn);
if (pos == -1)
return false;
replaceInsn(block, pos, newInsn);
return true;
}
private void checkArgsNames(MethodNode mth) { private void checkArgsNames(MethodNode mth) {
for (RegisterArg arg : mth.getArguments(false)) { for (RegisterArg arg : mth.getArguments(false)) {
String name = arg.getTypedVar().getName(); String name = arg.getTypedVar().getName();
......
...@@ -6,13 +6,14 @@ import jadx.core.dex.nodes.ClassNode; ...@@ -6,13 +6,14 @@ import jadx.core.dex.nodes.ClassNode;
import org.junit.Test; import org.junit.Test;
import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
public class TestInnerClass extends InternalJadxTest { public class TestInnerClass extends InternalJadxTest {
public static class TestCls { public static class TestCls {
public class Inner { public class Inner {
public class Inner2 { public class Inner2 extends Thread {
} }
} }
} }
...@@ -23,10 +24,10 @@ public class TestInnerClass extends InternalJadxTest { ...@@ -23,10 +24,10 @@ public class TestInnerClass extends InternalJadxTest {
String code = cls.getCode().toString(); String code = cls.getCode().toString();
System.out.println(code); System.out.println(code);
assertThat(code, containsString("Inner")); assertThat(code, containsString("Inner {"));
assertThat(code, containsString("Inner2")); assertThat(code, containsString("Inner2 extends Thread {"));
assertThat(code, not(containsString("super();")));
// assertThat(code, not(containsString("this$0"))); // assertThat(code, not(containsString("this$0")));
// assertThat(code, not(containsString("super()")));
// assertThat(code, not(containsString("/* synthetic */"))); // assertThat(code, not(containsString("/* synthetic */")));
} }
} }
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