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

fix: resolve JavaNode caching issues (#1775)

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