Commit f9e7a29c authored by Skylot's avatar Skylot

core: fix sythetic constructor replacement (#334)

parent 6cb14a1c
...@@ -396,14 +396,14 @@ public class ModVisitor extends AbstractVisitor { ...@@ -396,14 +396,14 @@ public class ModVisitor extends AbstractVisitor {
return filledArr; return filledArr;
} }
private static boolean allArgsNull(InsnNode insn) { private static boolean allArgsNull(ConstructorInsn insn) {
for (InsnArg insnArg : insn.getArguments()) { for (InsnArg insnArg : insn.getArguments()) {
if (insnArg.isLiteral()) { if (insnArg.isLiteral()) {
LiteralArg lit = (LiteralArg) insnArg; LiteralArg lit = (LiteralArg) insnArg;
if (lit.getLiteral() != 0) { if (lit.getLiteral() != 0) {
return false; return false;
} }
} else if (!insnArg.isThis()) { } else {
return false; return false;
} }
} }
......
...@@ -25,6 +25,7 @@ import jadx.core.dex.visitors.IDexTreeVisitor; ...@@ -25,6 +25,7 @@ import jadx.core.dex.visitors.IDexTreeVisitor;
import jadx.core.utils.exceptions.JadxRuntimeException; import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.tests.api.IntegrationTest; import jadx.tests.api.IntegrationTest;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
...@@ -58,7 +59,7 @@ public abstract class BaseExternalTest extends IntegrationTest { ...@@ -58,7 +59,7 @@ public abstract class BaseExternalTest extends IntegrationTest {
} else { } else {
Pattern clsPtrn = Pattern.compile(clsPatternStr); Pattern clsPtrn = Pattern.compile(clsPatternStr);
Pattern mthPtrn = mthPatternStr == null ? null : Pattern.compile(mthPatternStr); Pattern mthPtrn = mthPatternStr == null ? null : Pattern.compile(mthPatternStr);
processMthByPatterns(jadx, clsPtrn, mthPtrn); processByPatterns(jadx, clsPtrn, mthPtrn);
} }
printErrorReport(jadx); printErrorReport(jadx);
} }
...@@ -69,44 +70,53 @@ public abstract class BaseExternalTest extends IntegrationTest { ...@@ -69,44 +70,53 @@ public abstract class BaseExternalTest extends IntegrationTest {
} }
} }
private void processMthByPatterns(JadxDecompiler jadx, Pattern clsPattern, @Nullable Pattern mthPattern) { private void processByPatterns(JadxDecompiler jadx, Pattern clsPattern, @Nullable Pattern mthPattern) {
List<IDexTreeVisitor> passes = Jadx.getPassesList(jadx.getArgs()); List<IDexTreeVisitor> passes = Jadx.getPassesList(jadx.getArgs());
RootNode root = JadxInternalAccess.getRoot(jadx); RootNode root = JadxInternalAccess.getRoot(jadx);
int processed = 0;
for (ClassNode classNode : root.getClasses(true)) { for (ClassNode classNode : root.getClasses(true)) {
String clsFullName = classNode.getClassInfo().getFullName(); String clsFullName = classNode.getClassInfo().getFullName();
if (clsPattern.matcher(clsFullName).matches()) { if (clsPattern.matcher(clsFullName).matches()) {
classNode.load(); if (processCls(mthPattern, passes, classNode)) {
boolean decompile = false; processed++;
if (mthPattern == null) {
decompile = true;
} else {
for (MethodNode mth : classNode.getMethods()) {
if (mthPattern.matcher(mth.getName()).matches()) {
decompile = true;
break;
}
}
} }
if (decompile) { }
for (IDexTreeVisitor visitor : passes) { }
DepthTraversal.visit(visitor, classNode); assertThat("No classes processed", processed, greaterThan(0));
} }
try {
new CodeGen().visit(classNode); private boolean processCls(@Nullable Pattern mthPattern, List<IDexTreeVisitor> passes, ClassNode classNode) {
} catch (Exception e) { classNode.load();
throw new JadxRuntimeException("Codegen failed", e); boolean decompile = false;
} if (mthPattern == null) {
LOG.warn("\n Print class: {}, {}", classNode.getFullName(), classNode.dex()); decompile = true;
if (mthPattern != null) { } else {
printMethods(classNode, mthPattern); for (MethodNode mth : classNode.getMethods()) {
} else { if (mthPattern.matcher(mth.getName()).matches()) {
LOG.info("Code: \n{}", classNode.getCode()); decompile = true;
} break;
checkCode(classNode);
// SaveCode.save(jadx.getArgs().getOutDirSrc(), jadx.getArgs(), classNode);
} }
} }
} }
if (!decompile) {
return false;
}
for (IDexTreeVisitor visitor : passes) {
DepthTraversal.visit(visitor, classNode);
}
try {
new CodeGen().visit(classNode);
} catch (Exception e) {
throw new JadxRuntimeException("Codegen failed", e);
}
LOG.warn("\n Print class: {}, {}", classNode.getFullName(), classNode.dex());
if (mthPattern != null) {
printMethods(classNode, mthPattern);
} else {
LOG.info("Code: \n{}", classNode.getCode());
}
checkCode(classNode);
return true;
} }
private void printMethods(ClassNode classNode, @NotNull Pattern mthPattern) { private void printMethods(ClassNode classNode, @NotNull Pattern mthPattern) {
......
package jadx.tests.integration.inner;
import org.junit.Test;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
public class TestOuterConstructorCall extends IntegrationTest {
public static class TestCls {
private TestCls(Inner inner) {
System.out.println(inner);
}
private class Inner {
private TestCls test() {
return new TestCls(this);
}
}
}
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
assertThat(code, containsString("private class Inner {"));
assertThat(code, containsString("return new TestOuterConstructorCall$TestCls(this);"));
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