Fix deobfuscation issue
This commit is contained in:
@@ -42,7 +42,7 @@ import jadx.core.xmlgen.ResourcesSaver;
|
||||
* jadx.load();
|
||||
* jadx.save();
|
||||
* </code></pre>
|
||||
* <p/>
|
||||
*
|
||||
* Instead of 'save()' you can iterate over decompiled classes:
|
||||
* <pre><code>
|
||||
* for(JavaClass cls : jadx.getClasses()) {
|
||||
|
||||
@@ -137,13 +137,7 @@ public class InsnGen {
|
||||
|
||||
private void instanceField(CodeWriter code, FieldInfo field, InsnArg arg) throws CodegenException {
|
||||
ClassNode pCls = mth.getParentClass();
|
||||
FieldNode fieldNode = pCls.searchField(field);
|
||||
while (fieldNode == null
|
||||
&& pCls.getParentClass() != pCls
|
||||
&& pCls.getParentClass() != null) {
|
||||
pCls = pCls.getParentClass();
|
||||
fieldNode = pCls.searchField(field);
|
||||
}
|
||||
FieldNode fieldNode = pCls.dex().root().deepResolveField(field);
|
||||
if (fieldNode != null) {
|
||||
FieldReplaceAttr replace = fieldNode.get(AType.FIELD_REPLACE);
|
||||
if (replace != null) {
|
||||
@@ -163,7 +157,11 @@ public class InsnGen {
|
||||
if (fieldNode != null) {
|
||||
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) {
|
||||
@@ -176,11 +174,15 @@ public class InsnGen {
|
||||
}
|
||||
code.add('.');
|
||||
}
|
||||
FieldNode fieldNode = clsGen.getClassNode().dex().resolveField(field);
|
||||
FieldNode fieldNode = clsGen.getClassNode().dex().root().deepResolveField(field);
|
||||
if (fieldNode != null) {
|
||||
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) {
|
||||
|
||||
@@ -201,17 +201,13 @@ public class Deobfuscator {
|
||||
private void collectClassHierarchy(ClassNode cls, Set<ClassNode> collected) {
|
||||
boolean added = collected.add(cls);
|
||||
if (added) {
|
||||
ArgType superClass = cls.getSuperClass();
|
||||
ClassNode superClass = cls.getSuperClassNode();
|
||||
if (superClass != null) {
|
||||
ClassNode superNode = cls.dex().resolveClass(superClass);
|
||||
if (superNode != null) {
|
||||
collectClassHierarchy(superNode, collected);
|
||||
}
|
||||
collectClassHierarchy(superClass, collected);
|
||||
}
|
||||
|
||||
for (ArgType argType : cls.getInterfaces()) {
|
||||
ClassNode interfaceNode = cls.dex().resolveClass(argType);
|
||||
if (interfaceNode != null) {
|
||||
for (ClassNode interfaceNode : cls.getInterfaceNodes()) {
|
||||
if(interfaceNode != null) {
|
||||
collectClassHierarchy(interfaceNode, collected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,13 @@ package jadx.core.dex.info;
|
||||
|
||||
import com.android.dex.FieldId;
|
||||
|
||||
import com.android.dx.io.instructions.DecodedInstruction;
|
||||
import jadx.core.codegen.TypeGen;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.core.dex.nodes.DexNode;
|
||||
import jadx.core.dex.nodes.FieldNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
|
||||
public final class FieldInfo {
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ package jadx.core.dex.instructions;
|
||||
|
||||
import java.io.EOFException;
|
||||
|
||||
import com.android.dex.ClassData;
|
||||
import com.android.dex.Code;
|
||||
import com.android.dex.FieldId;
|
||||
import com.android.dx.io.OpcodeInfo;
|
||||
import com.android.dx.io.Opcodes;
|
||||
import com.android.dx.io.instructions.DecodedInstruction;
|
||||
@@ -10,6 +12,9 @@ import com.android.dx.io.instructions.FillArrayDataPayloadDecodedInstruction;
|
||||
import com.android.dx.io.instructions.PackedSwitchPayloadDecodedInstruction;
|
||||
import com.android.dx.io.instructions.ShortArrayCodeInput;
|
||||
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.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -48,7 +48,9 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
private final ClassInfo clsInfo;
|
||||
private final AccessInfo accessFlags;
|
||||
private ArgType superClass;
|
||||
private ClassNode superClassNode;
|
||||
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 final List<MethodNode> methods;
|
||||
@@ -72,12 +74,17 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
try {
|
||||
if (cls.getSupertypeIndex() == DexNode.NO_INDEX) {
|
||||
this.superClass = null;
|
||||
this.superClassNode = null;
|
||||
} else {
|
||||
this.superClass = dex.getType(cls.getSupertypeIndex());
|
||||
this.superClassNode = dex.resolveClass(ClassInfo.fromType(dex.root(), superClass));
|
||||
}
|
||||
this.interfaces = new ArrayList<>(cls.getInterfaces().length);
|
||||
this.interfaceNodes = new ArrayList<>(cls.getInterfaces().length);
|
||||
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) {
|
||||
ClassData clsData = dex.readClassData(cls);
|
||||
@@ -138,6 +145,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
this.dex = dex;
|
||||
this.clsInfo = clsInfo;
|
||||
this.interfaces = Collections.emptyList();
|
||||
this.interfaceNodes = Collections.emptyList();
|
||||
this.methods = Collections.emptyList();
|
||||
this.fields = Collections.emptyList();
|
||||
this.accessFlags = new AccessInfo(AccessFlags.ACC_PUBLIC | AccessFlags.ACC_SYNTHETIC, AFType.CLASS);
|
||||
@@ -280,10 +288,19 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
return superClass;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ClassNode getSuperClassNode() {
|
||||
return superClassNode;
|
||||
}
|
||||
|
||||
public List<ArgType> getInterfaces() {
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
public List<ClassNode> getInterfaceNodes() {
|
||||
return interfaceNodes;
|
||||
}
|
||||
|
||||
public Map<ArgType, List<ArgType>> getGenericMap() {
|
||||
return genericMap;
|
||||
}
|
||||
@@ -323,7 +340,6 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
return null;
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public FieldNode searchFieldByName(String name) {
|
||||
for (FieldNode f : fields) {
|
||||
if (f.getName().equals(name)) {
|
||||
|
||||
@@ -95,6 +95,7 @@ public class DexNode implements IDexNode {
|
||||
return resolveClass(ClassInfo.fromType(root, type));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public MethodNode resolveMethod(@NotNull MethodInfo mth) {
|
||||
ClassNode cls = resolveClass(mth.getDeclClass());
|
||||
@@ -105,27 +106,23 @@ public class DexNode implements IDexNode {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
MethodNode deepResolveMethod(@NotNull ClassNode cls, String signature) {
|
||||
for (MethodNode m : cls.getMethods()) {
|
||||
if (m.getMethodInfo().getShortId().startsWith(signature)) {
|
||||
return m;
|
||||
}
|
||||
MethodNode deepResolveMethod(@NotNull ClassNode cls, MethodInfo methodInfo) {
|
||||
MethodNode field = cls.searchMethodByName(methodInfo.getShortId());
|
||||
if (field != null) {
|
||||
return field;
|
||||
}
|
||||
|
||||
MethodNode found;
|
||||
ArgType superClass = cls.getSuperClass();
|
||||
if (superClass != null) {
|
||||
ClassNode superNode = resolveClass(superClass);
|
||||
if (superNode != null) {
|
||||
found = deepResolveMethod(superNode, signature);
|
||||
if (found != null) {
|
||||
return found;
|
||||
}
|
||||
ClassNode superNode = cls.getSuperClassNode();
|
||||
if (superNode != null) {
|
||||
found = deepResolveMethod(superNode, methodInfo);
|
||||
if (found != null) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
for (ArgType iFaceType : cls.getInterfaces()) {
|
||||
ClassNode iFaceNode = resolveClass(iFaceType);
|
||||
if (iFaceNode != null) {
|
||||
found = deepResolveMethod(iFaceNode, signature);
|
||||
for (ClassNode interfaceNode : cls.getInterfaceNodes()) {
|
||||
if(interfaceNode != null) {
|
||||
found = deepResolveMethod(interfaceNode, methodInfo);
|
||||
if (found != null) {
|
||||
return found;
|
||||
}
|
||||
@@ -134,6 +131,7 @@ public class DexNode implements IDexNode {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public FieldNode resolveField(FieldInfo field) {
|
||||
ClassNode cls = resolveClass(field.getDeclClass());
|
||||
@@ -143,6 +141,32 @@ public class DexNode implements IDexNode {
|
||||
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() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.android.dex.Dex;
|
||||
import jadx.core.dex.info.FieldInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
@@ -181,7 +183,50 @@ public class RootNode {
|
||||
if (cls == 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() {
|
||||
|
||||
@@ -78,7 +78,7 @@ public class InsnUtils {
|
||||
return ((ConstClassNode) insn).getClsType();
|
||||
case SGET:
|
||||
FieldInfo f = (FieldInfo) ((IndexInsnNode) insn).getIndex();
|
||||
FieldNode fieldNode = dex.resolveField(f);
|
||||
FieldNode fieldNode = dex.root().deepResolveField(f);
|
||||
if (fieldNode == null) {
|
||||
LOG.warn("Field {} not found in dex {}", f, dex);
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user