fix: check synthetic methods before remove/inline (#1560)
This commit is contained in:
@@ -225,7 +225,7 @@ public class ClassModifier extends AbstractVisitor {
|
||||
}
|
||||
|
||||
private static boolean removeBridgeMethod(ClassNode cls, MethodNode mth) {
|
||||
if (cls.root().getArgs().isRenameValid()) {
|
||||
if (cls.root().getArgs().isInlineMethods()) { // simple wrapper remove is same as inline
|
||||
List<InsnNode> allInsns = BlockUtils.collectAllInsns(mth.getBasicBlocks());
|
||||
if (allInsns.size() == 1) {
|
||||
InsnNode wrappedInsn = allInsns.get(0);
|
||||
@@ -235,12 +235,10 @@ public class ClassModifier extends AbstractVisitor {
|
||||
wrappedInsn = ((InsnWrapArg) arg).getWrapInsn();
|
||||
}
|
||||
}
|
||||
if (checkSyntheticWrapper(mth, wrappedInsn)) {
|
||||
return true;
|
||||
}
|
||||
return checkSyntheticWrapper(mth, wrappedInsn);
|
||||
}
|
||||
}
|
||||
return !isMethodUnique(cls, mth);
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean checkSyntheticWrapper(MethodNode mth, InsnNode insn) {
|
||||
@@ -299,20 +297,6 @@ public class ClassModifier extends AbstractVisitor {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isMethodUnique(ClassNode cls, MethodNode mth) {
|
||||
MethodInfo mi = mth.getMethodInfo();
|
||||
for (MethodNode otherMth : cls.getMethods()) {
|
||||
if (otherMth != mth) {
|
||||
MethodInfo omi = otherMth.getMethodInfo();
|
||||
if (omi.getName().equals(mi.getName())
|
||||
&& Objects.equals(omi.getArgumentsTypes(), mi.getArgumentsTypes())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove public empty constructors (static or default)
|
||||
*/
|
||||
|
||||
@@ -14,9 +14,7 @@ import jadx.core.Consts;
|
||||
import jadx.core.codegen.json.JsonMappingGen;
|
||||
import jadx.core.deobf.Deobfuscator;
|
||||
import jadx.core.deobf.NameMapper;
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.attributes.nodes.RenameReasonAttr;
|
||||
import jadx.core.dex.info.AccessInfo;
|
||||
import jadx.core.dex.info.ClassInfo;
|
||||
import jadx.core.dex.info.FieldInfo;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
@@ -196,11 +194,6 @@ public class RenameVisitor extends AbstractVisitor {
|
||||
if (args.isRenameValid()) {
|
||||
Set<String> names = new HashSet<>(methods.size());
|
||||
for (MethodNode mth : methods) {
|
||||
AccessInfo accessFlags = mth.getAccessFlags();
|
||||
if (accessFlags.isBridge() || accessFlags.isSynthetic()
|
||||
|| mth.contains(AFlag.DONT_GENERATE) /* this flag not set yet */) {
|
||||
continue;
|
||||
}
|
||||
String signature = mth.getMethodInfo().makeSignature(true, false);
|
||||
if (!names.add(signature)) {
|
||||
deobfuscator.forceRenameMethod(mth);
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package jadx.tests.integration.inline;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.tests.api.SmaliTest;
|
||||
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
|
||||
@SuppressWarnings("CommentedOutCode")
|
||||
public class TestOverlapSyntheticMethods extends SmaliTest {
|
||||
// @formatter:off
|
||||
/*
|
||||
public String test(int i) {
|
||||
return a(i) + "|" + a(i);
|
||||
}
|
||||
|
||||
public int a(int i) {
|
||||
return i;
|
||||
}
|
||||
|
||||
public String a(int i) {
|
||||
return "i:" + i;
|
||||
}
|
||||
*/
|
||||
// @formatter:on
|
||||
|
||||
@Test
|
||||
public void testSmali() {
|
||||
assertThat(getClassNodeFromSmali())
|
||||
.code()
|
||||
.containsOne("int a(int i) {")
|
||||
.containsOne("String m0a(int i) {");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSmaliNoRename() {
|
||||
getArgs().setRenameFlags(Collections.emptySet());
|
||||
disableCompilation();
|
||||
assertThat(getClassNodeFromSmali())
|
||||
.code()
|
||||
.containsOne("int a(int i) {")
|
||||
.containsOne("String a(int i) {")
|
||||
.containsOne("return a(i) + \"|\" + a(i);");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
.class public Linline/TestOverlapSyntheticMethods;
|
||||
.super Ljava/lang/Object;
|
||||
|
||||
.method public synthetic a(I)I
|
||||
.registers 2
|
||||
return p1
|
||||
.end method
|
||||
|
||||
.method public synthetic a(I)Ljava/lang/String;
|
||||
.registers 4
|
||||
new-instance v0, Ljava/lang/StringBuilder;
|
||||
invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
|
||||
const-string v1, "i:"
|
||||
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||
move-result-object v0
|
||||
invoke-virtual {v0, p1}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
|
||||
move-result-object v0
|
||||
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||
move-result-object v0
|
||||
return-object v0
|
||||
.end method
|
||||
|
||||
.method public test(I)Ljava/lang/String;
|
||||
.registers 4
|
||||
new-instance v0, Ljava/lang/StringBuilder;
|
||||
invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
|
||||
invoke-virtual {p0, p1}, Linline/TestOverlapSyntheticMethods;->a(I)I
|
||||
move-result v1
|
||||
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
|
||||
move-result-object v0
|
||||
const-string v1, "|"
|
||||
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||
move-result-object v0
|
||||
invoke-virtual {p0, p1}, Linline/TestOverlapSyntheticMethods;->a(I)Ljava/lang/String;
|
||||
move-result-object v1
|
||||
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||
move-result-object v0
|
||||
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||
move-result-object v0
|
||||
return-object v0
|
||||
.end method
|
||||
Reference in New Issue
Block a user