From e07332d49a77f0db16cc0eeeb230cde6b1021100 Mon Sep 17 00:00:00 2001 From: Skylot Date: Sat, 21 May 2022 21:33:58 +0100 Subject: [PATCH] fix(gui): resolve cast exception for variable reference (#1489) --- .../src/main/java/jadx/api/JadxDecompiler.java | 9 ++++++--- jadx-core/src/main/java/jadx/api/JavaClass.java | 16 +++++++++++++--- .../java/jadx/gui/ui/dialog/UsageDialog.java | 4 ---- .../gui/utils/codecache/disk/DiskCodeCache.java | 2 +- .../codecache/disk/adapters/VarRefAdapter.java | 8 ++++---- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java index 354e7596..8a88bcbe 100644 --- a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java +++ b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java @@ -683,10 +683,13 @@ public final class JadxDecompiler implements Closeable { throw new JadxRuntimeException("Missing code info for resolve VarRef: " + varRef); } ICodeAnnotation varNodeAnn = codeInfo.getCodeMetadata().getAt(varRef.getRefPos()); - if (varNodeAnn == null) { - return null; + if (varNodeAnn != null && varNodeAnn.getAnnType() == ICodeAnnotation.AnnType.DECLARATION) { + ICodeNodeRef nodeRef = ((NodeDeclareRef) varNodeAnn).getNode(); + if (nodeRef.getAnnType() == ICodeAnnotation.AnnType.VAR) { + return resolveVarNode((VarNode) nodeRef); + } } - return (JavaVariable) getJavaNodeByCodeAnnotation(codeInfo, varNodeAnn); + return null; } List convertNodes(Collection nodesList) { diff --git a/jadx-core/src/main/java/jadx/api/JavaClass.java b/jadx-core/src/main/java/jadx/api/JavaClass.java index 572b54ea..4032c87a 100644 --- a/jadx-core/src/main/java/jadx/api/JavaClass.java +++ b/jadx-core/src/main/java/jadx/api/JavaClass.java @@ -6,12 +6,16 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import jadx.api.metadata.ICodeAnnotation; +import jadx.api.metadata.ICodeAnnotation.AnnType; import jadx.api.metadata.ICodeNodeRef; import jadx.core.dex.attributes.AFlag; import jadx.core.dex.attributes.AType; @@ -22,6 +26,7 @@ import jadx.core.dex.nodes.FieldNode; import jadx.core.dex.nodes.MethodNode; public final class JavaClass implements JavaNode { + private static final Logger LOG = LoggerFactory.getLogger(JavaClass.class); private final JadxDecompiler decompiler; private final ClassNode cls; @@ -196,12 +201,17 @@ public final class JavaClass implements JavaNode { List result = new ArrayList<>(); for (Map.Entry entry : map.entrySet()) { ICodeAnnotation ann = entry.getValue(); - if (ann.getAnnType() == ICodeAnnotation.AnnType.DECLARATION) { - // ignore declarations + AnnType annType = ann.getAnnType(); + if (annType == AnnType.DECLARATION || annType == AnnType.OFFSET) { + // ignore declarations and offset annotations continue; } + // ignore declarations JavaNode annNode = rootDec.getJavaNodeByCodeAnnotation(codeInfo, ann); - if (javaNode.equals(annNode)) { + if (annNode == null && LOG.isDebugEnabled()) { + LOG.debug("Failed to resolve code annotation, cls: {}, pos: {}, ann: {}", this, entry.getKey(), ann); + } + if (Objects.equals(annNode, javaNode)) { result.add(entry.getKey()); } } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/dialog/UsageDialog.java b/jadx-gui/src/main/java/jadx/gui/ui/dialog/UsageDialog.java index fe91033a..defe5fa2 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/dialog/UsageDialog.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/dialog/UsageDialog.java @@ -100,10 +100,6 @@ public class UsageDialog extends CommonSearchDialog { JadxDecompiler decompiler = mainWindow.getWrapper().getDecompiler(); List usePositions = topUseClass.getUsePlacesFor(codeInfo, searchNode); for (int pos : usePositions) { - if (searchNode.getTopParentClass().equals(topUseClass) && pos == searchNode.getDefPos()) { - // skip declaration - continue; - } String line = CodeUtils.getLineForPos(code, pos); if (line.startsWith("import ")) { continue; diff --git a/jadx-gui/src/main/java/jadx/gui/utils/codecache/disk/DiskCodeCache.java b/jadx-gui/src/main/java/jadx/gui/utils/codecache/disk/DiskCodeCache.java index 700bf757..1fb9d0a5 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/codecache/disk/DiskCodeCache.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/codecache/disk/DiskCodeCache.java @@ -37,7 +37,7 @@ import jadx.core.utils.files.FileUtils; public class DiskCodeCache implements ICodeCache { private static final Logger LOG = LoggerFactory.getLogger(DiskCodeCache.class); - private static final int DATA_FORMAT_VERSION = 7; + private static final int DATA_FORMAT_VERSION = 8; private final Path srcDir; private final Path metaDir; diff --git a/jadx-gui/src/main/java/jadx/gui/utils/codecache/disk/adapters/VarRefAdapter.java b/jadx-gui/src/main/java/jadx/gui/utils/codecache/disk/adapters/VarRefAdapter.java index 8f5b20a7..e708ec5a 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/codecache/disk/adapters/VarRefAdapter.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/codecache/disk/adapters/VarRefAdapter.java @@ -13,14 +13,14 @@ public class VarRefAdapter extends BaseDataAdapter { @Override public void write(DataOutput out, VarRef value) throws IOException { int refPos = value.getRefPos(); - if (refPos == 0) { - throw new RuntimeException("Variable refPos is zero: " + value); + if (refPos <= 0) { + throw new RuntimeException("Variable refPos is invalid: " + value); } - out.writeShort(refPos); + out.writeInt(refPos); } @Override public VarRef read(DataInput in) throws IOException { - return VarRef.fromPos(in.readShort()); + return VarRef.fromPos(in.readInt()); } } -- GitLab