From 4d00fede56a85ba37daa5c2d231c754393dfeb32 Mon Sep 17 00:00:00 2001 From: Skylot Date: Thu, 2 Feb 2023 19:04:23 +0000 Subject: [PATCH] fix: resolve JavaNode caching issues (#1775) --- .../main/java/jadx/api/JadxDecompiler.java | 63 ++++++++----------- .../java/jadx/core/dex/nodes/ClassNode.java | 11 ++++ .../java/jadx/core/dex/nodes/FieldNode.java | 11 ++++ .../java/jadx/core/dex/nodes/MethodNode.java | 11 ++++ .../jadx/gui/ui/codearea/FridaAction.java | 4 ++ 5 files changed, 63 insertions(+), 37 deletions(-) diff --git a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java index 0caf7ded..d7f903b8 100644 --- a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java +++ b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java @@ -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 classesMap = new ConcurrentHashMap<>(); - private final Map methodsMap = new ConcurrentHashMap<>(); - private final Map fieldsMap = new ConcurrentHashMap<>(); - private final IDecompileScheduler decompileScheduler = new DecompilerScheduler(); private final List 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 diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java index c0465e96..6a981dde 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java @@ -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 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; diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java index bb877c76..be106bef 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java @@ -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 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; diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java index 5cd90d1a..0512dd46 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java @@ -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 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; diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/FridaAction.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/FridaAction.java index 111994f8..8658687d 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/FridaAction.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/FridaAction.java @@ -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; } -- GitLab