提交 dc578f98 编写于 作者: D Donlon

Fix deobfuscation issue

上级 cb135997
...@@ -42,7 +42,7 @@ import jadx.core.xmlgen.ResourcesSaver; ...@@ -42,7 +42,7 @@ import jadx.core.xmlgen.ResourcesSaver;
* jadx.load(); * jadx.load();
* jadx.save(); * jadx.save();
* </code></pre> * </code></pre>
* <p/> *
* Instead of 'save()' you can iterate over decompiled classes: * Instead of 'save()' you can iterate over decompiled classes:
* <pre><code> * <pre><code>
* for(JavaClass cls : jadx.getClasses()) { * for(JavaClass cls : jadx.getClasses()) {
......
...@@ -137,13 +137,7 @@ public class InsnGen { ...@@ -137,13 +137,7 @@ public class InsnGen {
private void instanceField(CodeWriter code, FieldInfo field, InsnArg arg) throws CodegenException { private void instanceField(CodeWriter code, FieldInfo field, InsnArg arg) throws CodegenException {
ClassNode pCls = mth.getParentClass(); ClassNode pCls = mth.getParentClass();
FieldNode fieldNode = pCls.searchField(field); FieldNode fieldNode = pCls.dex().root().deepResolveField(field);
while (fieldNode == null
&& pCls.getParentClass() != pCls
&& pCls.getParentClass() != null) {
pCls = pCls.getParentClass();
fieldNode = pCls.searchField(field);
}
if (fieldNode != null) { if (fieldNode != null) {
FieldReplaceAttr replace = fieldNode.get(AType.FIELD_REPLACE); FieldReplaceAttr replace = fieldNode.get(AType.FIELD_REPLACE);
if (replace != null) { if (replace != null) {
...@@ -163,7 +157,11 @@ public class InsnGen { ...@@ -163,7 +157,11 @@ public class InsnGen {
if (fieldNode != null) { if (fieldNode != null) {
code.attachAnnotation(fieldNode); code.attachAnnotation(fieldNode);
} }
code.add(field.getAlias()); if (fieldNode == null) {
code.add(field.getAlias());
} else {
code.add(fieldNode.getAlias());
}
} }
public static void makeStaticFieldAccess(CodeWriter code, FieldInfo field, ClassGen clsGen) { public static void makeStaticFieldAccess(CodeWriter code, FieldInfo field, ClassGen clsGen) {
...@@ -176,11 +174,15 @@ public class InsnGen { ...@@ -176,11 +174,15 @@ public class InsnGen {
} }
code.add('.'); code.add('.');
} }
FieldNode fieldNode = clsGen.getClassNode().dex().resolveField(field); FieldNode fieldNode = clsGen.getClassNode().dex().root().deepResolveField(field);
if (fieldNode != null) { if (fieldNode != null) {
code.attachAnnotation(fieldNode); code.attachAnnotation(fieldNode);
} }
code.add(field.getAlias()); if (fieldNode == null) {
code.add(field.getAlias());
} else {
code.add(fieldNode.getAlias());
}
} }
protected void staticField(CodeWriter code, FieldInfo field) { protected void staticField(CodeWriter code, FieldInfo field) {
......
...@@ -201,17 +201,13 @@ public class Deobfuscator { ...@@ -201,17 +201,13 @@ public class Deobfuscator {
private void collectClassHierarchy(ClassNode cls, Set<ClassNode> collected) { private void collectClassHierarchy(ClassNode cls, Set<ClassNode> collected) {
boolean added = collected.add(cls); boolean added = collected.add(cls);
if (added) { if (added) {
ArgType superClass = cls.getSuperClass(); ClassNode superClass = cls.getSuperClassNode();
if (superClass != null) { if (superClass != null) {
ClassNode superNode = cls.dex().resolveClass(superClass); collectClassHierarchy(superClass, collected);
if (superNode != null) {
collectClassHierarchy(superNode, collected);
}
} }
for (ArgType argType : cls.getInterfaces()) { for (ClassNode interfaceNode : cls.getInterfaceNodes()) {
ClassNode interfaceNode = cls.dex().resolveClass(argType); if(interfaceNode != null) {
if (interfaceNode != null) {
collectClassHierarchy(interfaceNode, collected); collectClassHierarchy(interfaceNode, collected);
} }
} }
......
...@@ -2,9 +2,13 @@ package jadx.core.dex.info; ...@@ -2,9 +2,13 @@ package jadx.core.dex.info;
import com.android.dex.FieldId; import com.android.dex.FieldId;
import com.android.dx.io.instructions.DecodedInstruction;
import jadx.core.codegen.TypeGen; import jadx.core.codegen.TypeGen;
import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.DexNode; import jadx.core.dex.nodes.DexNode;
import jadx.core.dex.nodes.FieldNode;
import jadx.core.dex.nodes.MethodNode;
public final class FieldInfo { public final class FieldInfo {
......
...@@ -2,7 +2,9 @@ package jadx.core.dex.instructions; ...@@ -2,7 +2,9 @@ package jadx.core.dex.instructions;
import java.io.EOFException; import java.io.EOFException;
import com.android.dex.ClassData;
import com.android.dex.Code; import com.android.dex.Code;
import com.android.dex.FieldId;
import com.android.dx.io.OpcodeInfo; import com.android.dx.io.OpcodeInfo;
import com.android.dx.io.Opcodes; import com.android.dx.io.Opcodes;
import com.android.dx.io.instructions.DecodedInstruction; import com.android.dx.io.instructions.DecodedInstruction;
...@@ -10,6 +12,9 @@ import com.android.dx.io.instructions.FillArrayDataPayloadDecodedInstruction; ...@@ -10,6 +12,9 @@ import com.android.dx.io.instructions.FillArrayDataPayloadDecodedInstruction;
import com.android.dx.io.instructions.PackedSwitchPayloadDecodedInstruction; import com.android.dx.io.instructions.PackedSwitchPayloadDecodedInstruction;
import com.android.dx.io.instructions.ShortArrayCodeInput; import com.android.dx.io.instructions.ShortArrayCodeInput;
import com.android.dx.io.instructions.SparseSwitchPayloadDecodedInstruction; import com.android.dx.io.instructions.SparseSwitchPayloadDecodedInstruction;
import jadx.core.dex.info.ClassInfo;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.FieldNode;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
......
...@@ -48,7 +48,9 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode { ...@@ -48,7 +48,9 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
private final ClassInfo clsInfo; private final ClassInfo clsInfo;
private final AccessInfo accessFlags; private final AccessInfo accessFlags;
private ArgType superClass; private ArgType superClass;
private ClassNode superClassNode;
private List<ArgType> interfaces; private List<ArgType> interfaces;
private List<ClassNode> interfaceNodes; //some element is null whose declaration is out of the dex files
private Map<ArgType, List<ArgType>> genericMap; private Map<ArgType, List<ArgType>> genericMap;
private final List<MethodNode> methods; private final List<MethodNode> methods;
...@@ -72,12 +74,17 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode { ...@@ -72,12 +74,17 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
try { try {
if (cls.getSupertypeIndex() == DexNode.NO_INDEX) { if (cls.getSupertypeIndex() == DexNode.NO_INDEX) {
this.superClass = null; this.superClass = null;
this.superClassNode = null;
} else { } else {
this.superClass = dex.getType(cls.getSupertypeIndex()); this.superClass = dex.getType(cls.getSupertypeIndex());
this.superClassNode = dex.resolveClass(ClassInfo.fromType(dex.root(), superClass));
} }
this.interfaces = new ArrayList<>(cls.getInterfaces().length); this.interfaces = new ArrayList<>(cls.getInterfaces().length);
this.interfaceNodes = new ArrayList<>(cls.getInterfaces().length);
for (short interfaceIdx : cls.getInterfaces()) { for (short interfaceIdx : cls.getInterfaces()) {
this.interfaces.add(dex.getType(interfaceIdx)); ArgType intf = dex.getType(interfaceIdx);
this.interfaces.add(intf);
this.interfaceNodes.add(dex.resolveClass(intf));
} }
if (cls.getClassDataOffset() != 0) { if (cls.getClassDataOffset() != 0) {
ClassData clsData = dex.readClassData(cls); ClassData clsData = dex.readClassData(cls);
...@@ -138,6 +145,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode { ...@@ -138,6 +145,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
this.dex = dex; this.dex = dex;
this.clsInfo = clsInfo; this.clsInfo = clsInfo;
this.interfaces = Collections.emptyList(); this.interfaces = Collections.emptyList();
this.interfaceNodes = Collections.emptyList();
this.methods = Collections.emptyList(); this.methods = Collections.emptyList();
this.fields = Collections.emptyList(); this.fields = Collections.emptyList();
this.accessFlags = new AccessInfo(AccessFlags.ACC_PUBLIC | AccessFlags.ACC_SYNTHETIC, AFType.CLASS); this.accessFlags = new AccessInfo(AccessFlags.ACC_PUBLIC | AccessFlags.ACC_SYNTHETIC, AFType.CLASS);
...@@ -280,10 +288,19 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode { ...@@ -280,10 +288,19 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
return superClass; return superClass;
} }
@Nullable
public ClassNode getSuperClassNode() {
return superClassNode;
}
public List<ArgType> getInterfaces() { public List<ArgType> getInterfaces() {
return interfaces; return interfaces;
} }
public List<ClassNode> getInterfaceNodes() {
return interfaceNodes;
}
public Map<ArgType, List<ArgType>> getGenericMap() { public Map<ArgType, List<ArgType>> getGenericMap() {
return genericMap; return genericMap;
} }
...@@ -323,7 +340,6 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode { ...@@ -323,7 +340,6 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
return null; return null;
} }
@TestOnly
public FieldNode searchFieldByName(String name) { public FieldNode searchFieldByName(String name) {
for (FieldNode f : fields) { for (FieldNode f : fields) {
if (f.getName().equals(name)) { if (f.getName().equals(name)) {
......
...@@ -95,6 +95,7 @@ public class DexNode implements IDexNode { ...@@ -95,6 +95,7 @@ public class DexNode implements IDexNode {
return resolveClass(ClassInfo.fromType(root, type)); return resolveClass(ClassInfo.fromType(root, type));
} }
@Deprecated
@Nullable @Nullable
public MethodNode resolveMethod(@NotNull MethodInfo mth) { public MethodNode resolveMethod(@NotNull MethodInfo mth) {
ClassNode cls = resolveClass(mth.getDeclClass()); ClassNode cls = resolveClass(mth.getDeclClass());
...@@ -105,27 +106,23 @@ public class DexNode implements IDexNode { ...@@ -105,27 +106,23 @@ public class DexNode implements IDexNode {
} }
@Nullable @Nullable
MethodNode deepResolveMethod(@NotNull ClassNode cls, String signature) { MethodNode deepResolveMethod(@NotNull ClassNode cls, MethodInfo methodInfo) {
for (MethodNode m : cls.getMethods()) { MethodNode field = cls.searchMethodByName(methodInfo.getShortId());
if (m.getMethodInfo().getShortId().startsWith(signature)) { if (field != null) {
return m; return field;
}
} }
MethodNode found; MethodNode found;
ArgType superClass = cls.getSuperClass(); ClassNode superNode = cls.getSuperClassNode();
if (superClass != null) { if (superNode != null) {
ClassNode superNode = resolveClass(superClass); found = deepResolveMethod(superNode, methodInfo);
if (superNode != null) { if (found != null) {
found = deepResolveMethod(superNode, signature); return found;
if (found != null) {
return found;
}
} }
} }
for (ArgType iFaceType : cls.getInterfaces()) { for (ClassNode interfaceNode : cls.getInterfaceNodes()) {
ClassNode iFaceNode = resolveClass(iFaceType); if(interfaceNode != null) {
if (iFaceNode != null) { found = deepResolveMethod(interfaceNode, methodInfo);
found = deepResolveMethod(iFaceNode, signature);
if (found != null) { if (found != null) {
return found; return found;
} }
...@@ -134,6 +131,7 @@ public class DexNode implements IDexNode { ...@@ -134,6 +131,7 @@ public class DexNode implements IDexNode {
return null; return null;
} }
@Deprecated
@Nullable @Nullable
public FieldNode resolveField(FieldInfo field) { public FieldNode resolveField(FieldInfo field) {
ClassNode cls = resolveClass(field.getDeclClass()); ClassNode cls = resolveClass(field.getDeclClass());
...@@ -143,6 +141,32 @@ public class DexNode implements IDexNode { ...@@ -143,6 +141,32 @@ public class DexNode implements IDexNode {
return null; return null;
} }
@Nullable
FieldNode deepResolveField(@NotNull ClassNode cls, FieldInfo fieldInfo) {
FieldNode field = cls.searchFieldByName(fieldInfo.getName());
if (field != null) {
return field;
}
FieldNode found;
ClassNode superNode = cls.getSuperClassNode();
if (superNode != null) {
found = deepResolveField(superNode, fieldInfo);
if (found != null) {
return found;
}
}
for (ClassNode interfaceNode : cls.getInterfaceNodes()) {
if(interfaceNode != null) {
found = deepResolveField(interfaceNode, fieldInfo);
if (found != null) {
return found;
}
}
}
return null;
}
public DexFile getDexFile() { public DexFile getDexFile() {
return file; return file;
} }
......
...@@ -5,6 +5,8 @@ import java.io.InputStream; ...@@ -5,6 +5,8 @@ import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.android.dex.Dex;
import jadx.core.dex.info.FieldInfo;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -181,7 +183,50 @@ public class RootNode { ...@@ -181,7 +183,50 @@ public class RootNode {
if (cls == null) { if (cls == null) {
return null; return null;
} }
return cls.dex().deepResolveMethod(cls, mth.makeSignature(false)); MethodNode resolved;
//most of the time, the method node could be found in current dex.
DexNode declDex = cls.dex();
resolved = declDex.deepResolveMethod(cls, mth);
if (resolved != null){
return resolved;
}
for (DexNode dexNode : dexNodes) {
if(dexNodes == declDex) {
continue;
}
resolved = dexNode.deepResolveMethod(cls, mth);
if (resolved != null){
return resolved;
}
}
return null;
}
@Nullable
public FieldNode deepResolveField(@NotNull FieldInfo field) {
ClassNode cls = resolveClass(field.getDeclClass());
if (cls == null) {
return null;
}
FieldNode resolved;
//most of the time, the field node could be found in current dex.
DexNode declDex = cls.dex();
resolved = declDex.deepResolveField(cls, field);
if (resolved != null){
return resolved;
}
for (DexNode dexNode : dexNodes) {
if(dexNodes == declDex) {
continue;
}
resolved = dexNode.deepResolveField(cls, field);
if (resolved != null){
return resolved;
}
}
return null;
} }
public List<DexNode> getDexNodes() { public List<DexNode> getDexNodes() {
......
...@@ -78,7 +78,7 @@ public class InsnUtils { ...@@ -78,7 +78,7 @@ public class InsnUtils {
return ((ConstClassNode) insn).getClsType(); return ((ConstClassNode) insn).getClsType();
case SGET: case SGET:
FieldInfo f = (FieldInfo) ((IndexInsnNode) insn).getIndex(); FieldInfo f = (FieldInfo) ((IndexInsnNode) insn).getIndex();
FieldNode fieldNode = dex.resolveField(f); FieldNode fieldNode = dex.root().deepResolveField(f);
if (fieldNode == null) { if (fieldNode == null) {
LOG.warn("Field {} not found in dex {}", f, dex); LOG.warn("Field {} not found in dex {}", f, dex);
return null; return null;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册