提交 39093130 编写于 作者: S Skylot

core: fix processing overriden methods in deobfuscator (#207)

上级 9e9270a8
......@@ -3,7 +3,7 @@ package jadx.core.deobf;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -142,87 +142,72 @@ public class Deobfuscator {
ovrdMap.clear();
}
@Nullable
private static ClassNode resolveOverridingInternal(DexNode dex, ClassNode cls, String signature,
Set<MethodInfo> overrideSet, ClassNode rootClass) {
ClassNode result = null;
for (MethodNode m : cls.getMethods()) {
if (m.getMethodInfo().getShortId().startsWith(signature)) {
result = cls;
overrideSet.add(m.getMethodInfo());
break;
private void resolveOverriding(MethodNode mth) {
Set<ClassNode> clsParents = new LinkedHashSet<>();
collectClassHierarchy(mth.getParentClass(), clsParents);
String mthSignature = mth.getMethodInfo().makeSignature(false);
Set<MethodInfo> overrideSet = new LinkedHashSet<>();
for (ClassNode classNode : clsParents) {
MethodInfo methodInfo = getMthOverride(classNode.getMethods(), mthSignature);
if (methodInfo != null) {
overrideSet.add(methodInfo);
}
}
if (overrideSet.isEmpty()) {
return;
}
OverridedMethodsNode overrideNode = getOverrideMethodsNode(overrideSet);
if (overrideNode == null) {
overrideNode = new OverridedMethodsNode(overrideSet);
ovrd.add(overrideNode);
}
for (MethodInfo overrideMth : overrideSet) {
if (!ovrdMap.containsKey(overrideMth)) {
ovrdMap.put(overrideMth, overrideNode);
overrideNode.add(overrideMth);
}
}
}
ArgType superClass = cls.getSuperClass();
if (superClass != null) {
ClassNode superNode = dex.resolveClass(superClass);
if (superNode != null) {
ClassNode clsWithMth = resolveOverridingInternal(dex, superNode, signature, overrideSet, rootClass);
if (clsWithMth != null) {
if ((result != null) && (result != cls)) {
if (clsWithMth != result) {
LOG.warn(String.format("Multiple overriding '%s' from '%s' and '%s' in '%s'",
signature,
result.getFullName(), clsWithMth.getFullName(),
rootClass.getFullName()));
}
} else {
result = clsWithMth;
}
}
private OverridedMethodsNode getOverrideMethodsNode(Set<MethodInfo> overrideSet) {
for (MethodInfo overrideMth : overrideSet) {
OverridedMethodsNode node = ovrdMap.get(overrideMth);
if (node != null) {
return node;
}
}
return null;
}
for (ArgType iFaceType : cls.getInterfaces()) {
ClassNode iFaceNode = dex.resolveClass(iFaceType);
if (iFaceNode != null) {
ClassNode clsWithMth = resolveOverridingInternal(dex, iFaceNode, signature, overrideSet, rootClass);
if (clsWithMth != null) {
if ((result != null) && (result != cls)) {
if (clsWithMth != result) {
LOG.warn(String.format("Multiple overriding '%s' from '%s' and '%s' in '%s'",
signature,
result.getFullName(), clsWithMth.getFullName(),
rootClass.getFullName()));
}
} else {
result = clsWithMth;
}
}
private MethodInfo getMthOverride(List<MethodNode> methods, String mthSignature) {
for (MethodNode m : methods) {
MethodInfo mthInfo = m.getMethodInfo();
if (mthInfo.getShortId().startsWith(mthSignature)) {
return mthInfo;
}
}
return result;
return null;
}
private void resolveOverriding(MethodNode mth) {
Set<MethodInfo> overrideSet = new HashSet<>();
String mthSignature = mth.getMethodInfo().makeSignature(false);
ClassNode cls = mth.getParentClass();
resolveOverridingInternal(mth.dex(), cls, mthSignature, overrideSet, cls);
if (overrideSet.size() > 1) {
OverridedMethodsNode overrideNode = null;
for (MethodInfo _mth : overrideSet) {
if (ovrdMap.containsKey(_mth)) {
overrideNode = ovrdMap.get(_mth);
break;
private void collectClassHierarchy(ClassNode cls, Set<ClassNode> collected) {
boolean added = collected.add(cls);
if (added) {
ArgType superClass = cls.getSuperClass();
if (superClass != null) {
ClassNode superNode = cls.dex().resolveClass(superClass);
if (superNode != null) {
collectClassHierarchy(superNode, collected);
}
}
if (overrideNode == null) {
overrideNode = new OverridedMethodsNode(overrideSet);
ovrd.add(overrideNode);
}
for (MethodInfo _mth : overrideSet) {
if (!ovrdMap.containsKey(_mth)) {
ovrdMap.put(_mth, overrideNode);
if (!overrideNode.contains(_mth)) {
overrideNode.add(_mth);
}
for (ArgType argType : cls.getInterfaces()) {
ClassNode interfaceNode = cls.dex().resolveClass(argType);
if (interfaceNode != null) {
collectClassHierarchy(interfaceNode, collected);
}
}
}
overrideSet.clear();
}
private void processClass(ClassNode cls) {
......
......@@ -4,7 +4,7 @@ import java.util.Set;
import jadx.core.dex.info.MethodInfo;
/* package */ class OverridedMethodsNode {
class OverridedMethodsNode {
private Set<MethodInfo> methods;
......
......@@ -30,10 +30,10 @@ public class TestMthRename extends IntegrationTest {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
assertThat(code, containsString("public abstract void m0a();"));
assertThat(code, containsString("public abstract void mo1a();"));
assertThat(code, not(containsString("public abstract void a();")));
assertThat(code, containsString(".m0a();"));
assertThat(code, containsString(".mo1a();"));
assertThat(code, not(containsString(".a();")));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册