未验证 提交 4d00fede 编写于 作者: S Skylot

fix: resolve JavaNode caching issues (#1775)

上级 b1bc5c08
...@@ -12,7 +12,6 @@ import java.util.List; ...@@ -12,7 +12,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
...@@ -93,10 +92,6 @@ public final class JadxDecompiler implements Closeable { ...@@ -93,10 +92,6 @@ public final class JadxDecompiler implements Closeable {
private BinaryXMLParser binaryXmlParser; private BinaryXMLParser binaryXmlParser;
private ProtoXMLParser protoXmlParser; private ProtoXMLParser protoXmlParser;
private final Map<ClassNode, JavaClass> classesMap = new ConcurrentHashMap<>();
private final Map<MethodNode, JavaMethod> methodsMap = new ConcurrentHashMap<>();
private final Map<FieldNode, JavaField> fieldsMap = new ConcurrentHashMap<>();
private final IDecompileScheduler decompileScheduler = new DecompilerScheduler(); private final IDecompileScheduler decompileScheduler = new DecompilerScheduler();
private final List<ILoadResult> customLoads = new ArrayList<>(); private final List<ILoadResult> customLoads = new ArrayList<>();
...@@ -155,10 +150,6 @@ public final class JadxDecompiler implements Closeable { ...@@ -155,10 +150,6 @@ public final class JadxDecompiler implements Closeable {
resources = null; resources = null;
binaryXmlParser = null; binaryXmlParser = null;
protoXmlParser = null; protoXmlParser = null;
classesMap.clear();
methodsMap.clear();
fieldsMap.clear();
} }
@Override @Override
...@@ -471,33 +462,36 @@ public final class JadxDecompiler implements Closeable { ...@@ -471,33 +462,36 @@ public final class JadxDecompiler implements Closeable {
* Get JavaClass by ClassNode without loading and decompilation * Get JavaClass by ClassNode without loading and decompilation
*/ */
@ApiStatus.Internal @ApiStatus.Internal
JavaClass convertClassNode(ClassNode cls) { synchronized JavaClass convertClassNode(ClassNode cls) {
return classesMap.compute(cls, (node, prevJavaCls) -> { JavaClass javaClass = cls.getJavaNode();
if (prevJavaCls != null && prevJavaCls.getClassNode() == cls) { if (javaClass == null) {
// keep previous variable javaClass = cls.isInner()
return prevJavaCls; ? new JavaClass(cls, convertClassNode(cls.getParentClass()))
} : new JavaClass(cls, this);
if (cls.isInner()) { cls.setJavaNode(javaClass);
return new JavaClass(cls, convertClassNode(cls.getParentClass())); }
} return javaClass;
return new JavaClass(cls, this);
});
} }
@ApiStatus.Internal @ApiStatus.Internal
JavaField convertFieldNode(FieldNode field) { synchronized JavaField convertFieldNode(FieldNode fld) {
return fieldsMap.computeIfAbsent(field, fldNode -> { JavaField javaField = fld.getJavaNode();
JavaClass parentCls = convertClassNode(fldNode.getParentClass()); if (javaField == null) {
return new JavaField(parentCls, fldNode); JavaClass parentCls = convertClassNode(fld.getParentClass());
}); javaField = new JavaField(parentCls, fld);
fld.setJavaNode(javaField);
}
return javaField;
} }
@ApiStatus.Internal @ApiStatus.Internal
JavaMethod convertMethodNode(MethodNode method) { synchronized JavaMethod convertMethodNode(MethodNode mth) {
return methodsMap.computeIfAbsent(method, mthNode -> { JavaMethod javaMethod = mth.getJavaNode();
ClassNode parentCls = mthNode.getParentClass(); if (javaMethod == null) {
return new JavaMethod(convertClassNode(parentCls), mthNode); javaMethod = new JavaMethod(convertClassNode(mth.getParentClass()), mth);
}); mth.setJavaNode(javaMethod);
}
return javaMethod;
} }
@Nullable @Nullable
...@@ -574,14 +568,9 @@ public final class JadxDecompiler implements Closeable { ...@@ -574,14 +568,9 @@ public final class JadxDecompiler implements Closeable {
} }
} }
@Nullable
private JavaVariable resolveVarNode(VarNode varNode) { private JavaVariable resolveVarNode(VarNode varNode) {
MethodNode mthNode = varNode.getMth(); JavaMethod javaNode = convertMethodNode(varNode.getMth());
JavaMethod mth = convertMethodNode(mthNode); return new JavaVariable(javaNode, varNode);
if (mth == null) {
return null;
}
return new JavaVariable(mth, varNode);
} }
@Nullable @Nullable
......
...@@ -21,6 +21,7 @@ import jadx.api.ICodeCache; ...@@ -21,6 +21,7 @@ import jadx.api.ICodeCache;
import jadx.api.ICodeInfo; import jadx.api.ICodeInfo;
import jadx.api.ICodeWriter; import jadx.api.ICodeWriter;
import jadx.api.JadxArgs; import jadx.api.JadxArgs;
import jadx.api.JavaClass;
import jadx.api.impl.SimpleCodeInfo; import jadx.api.impl.SimpleCodeInfo;
import jadx.api.plugins.input.data.IClassData; import jadx.api.plugins.input.data.IClassData;
import jadx.api.plugins.input.data.IFieldData; import jadx.api.plugins.input.data.IFieldData;
...@@ -100,6 +101,8 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN ...@@ -100,6 +101,8 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
// cache maps // cache maps
private Map<MethodInfo, MethodNode> mthInfoMap = Collections.emptyMap(); private Map<MethodInfo, MethodNode> mthInfoMap = Collections.emptyMap();
private JavaClass javaNode;
public ClassNode(RootNode root, IClassData cls) { public ClassNode(RootNode root, IClassData cls) {
this.root = root; this.root = root;
this.clsInfo = ClassInfo.fromType(root, ArgType.object(cls.getType())); this.clsInfo = ClassInfo.fromType(root, ArgType.object(cls.getType()));
...@@ -835,6 +838,14 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN ...@@ -835,6 +838,14 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
return clsData == null ? "synthetic" : clsData.getInputFileName(); return clsData == null ? "synthetic" : clsData.getInputFileName();
} }
public JavaClass getJavaNode() {
return javaNode;
}
public void setJavaNode(JavaClass javaNode) {
this.javaNode = javaNode;
}
@Override @Override
public AnnType getAnnType() { public AnnType getAnnType() {
return AnnType.CLASS; return AnnType.CLASS;
......
...@@ -3,6 +3,7 @@ package jadx.core.dex.nodes; ...@@ -3,6 +3,7 @@ package jadx.core.dex.nodes;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import jadx.api.JavaField;
import jadx.api.plugins.input.data.IFieldData; import jadx.api.plugins.input.data.IFieldData;
import jadx.core.dex.attributes.nodes.NotificationAttrNode; import jadx.core.dex.attributes.nodes.NotificationAttrNode;
import jadx.core.dex.info.AccessInfo; import jadx.core.dex.info.AccessInfo;
...@@ -21,6 +22,8 @@ public class FieldNode extends NotificationAttrNode implements ICodeNode { ...@@ -21,6 +22,8 @@ public class FieldNode extends NotificationAttrNode implements ICodeNode {
private List<MethodNode> useIn = Collections.emptyList(); private List<MethodNode> useIn = Collections.emptyList();
private JavaField javaNode;
public static FieldNode build(ClassNode cls, IFieldData fieldData) { public static FieldNode build(ClassNode cls, IFieldData fieldData) {
FieldInfo fieldInfo = FieldInfo.fromRef(cls.root(), fieldData); FieldInfo fieldInfo = FieldInfo.fromRef(cls.root(), fieldData);
FieldNode fieldNode = new FieldNode(cls, fieldInfo, fieldData.getAccessFlags()); FieldNode fieldNode = new FieldNode(cls, fieldInfo, fieldData.getAccessFlags());
...@@ -112,6 +115,14 @@ public class FieldNode extends NotificationAttrNode implements ICodeNode { ...@@ -112,6 +115,14 @@ public class FieldNode extends NotificationAttrNode implements ICodeNode {
return parentClass.root(); return parentClass.root();
} }
public JavaField getJavaNode() {
return javaNode;
}
public void setJavaNode(JavaField javaNode) {
this.javaNode = javaNode;
}
@Override @Override
public AnnType getAnnType() { public AnnType getAnnType() {
return AnnType.FIELD; return AnnType.FIELD;
......
...@@ -10,6 +10,7 @@ import org.jetbrains.annotations.Nullable; ...@@ -10,6 +10,7 @@ import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import jadx.api.JavaMethod;
import jadx.api.plugins.input.data.ICodeReader; import jadx.api.plugins.input.data.ICodeReader;
import jadx.api.plugins.input.data.IDebugInfo; import jadx.api.plugins.input.data.IDebugInfo;
import jadx.api.plugins.input.data.IMethodData; import jadx.api.plugins.input.data.IMethodData;
...@@ -71,6 +72,8 @@ public class MethodNode extends NotificationAttrNode implements IMethodDetails, ...@@ -71,6 +72,8 @@ public class MethodNode extends NotificationAttrNode implements IMethodDetails,
private List<MethodNode> useIn = Collections.emptyList(); private List<MethodNode> useIn = Collections.emptyList();
private JavaMethod javaNode;
public static MethodNode build(ClassNode classNode, IMethodData methodData) { public static MethodNode build(ClassNode classNode, IMethodData methodData) {
MethodNode methodNode = new MethodNode(classNode, methodData); MethodNode methodNode = new MethodNode(classNode, methodData);
methodNode.addAttrs(methodData.getAttributes()); methodNode.addAttrs(methodData.getAttributes());
...@@ -610,6 +613,14 @@ public class MethodNode extends NotificationAttrNode implements IMethodDetails, ...@@ -610,6 +613,14 @@ public class MethodNode extends NotificationAttrNode implements IMethodDetails,
this.useIn = useIn; this.useIn = useIn;
} }
public JavaMethod getJavaNode() {
return javaNode;
}
public void setJavaNode(JavaMethod javaNode) {
this.javaNode = javaNode;
}
@Override @Override
public AnnType getAnnType() { public AnnType getAnnType() {
return AnnType.METHOD; return AnnType.METHOD;
......
...@@ -141,6 +141,10 @@ public final class FridaAction extends JNodeAction { ...@@ -141,6 +141,10 @@ public final class FridaAction extends JNodeAction {
} }
return null; return null;
}); });
int argsCount = javaMethod.getMethodNode().getMethodInfo().getArgsCount();
if (argNames.size() != argsCount) {
LOG.warn("Incorrect args count, expected: {}, got: {}", argsCount, argNames.size());
}
return argNames; return argNames;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册