From fa86d8f4593aad650959dff2e92c9d446ad20d24 Mon Sep 17 00:00:00 2001 From: klee <1046120015@qq.com> Date: Sun, 26 Nov 2023 00:26:59 +0800 Subject: [PATCH] Fix: Resolved an issue with incorrectly generated xposedMethodSnippet when the parameter type is generic. Add: Introduced xposedGenerateFieldSnippet. --- .../jadx/gui/ui/codearea/XposedAction.java | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/XposedAction.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/XposedAction.java index 54c4801d0cf..4d6c90c1ae7 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/XposedAction.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/XposedAction.java @@ -1,6 +1,7 @@ package jadx.gui.ui.codearea; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import javax.swing.JOptionPane; @@ -9,11 +10,13 @@ import org.slf4j.LoggerFactory; import jadx.api.JavaClass; +import jadx.api.JavaField; import jadx.api.JavaMethod; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.nodes.MethodNode; import jadx.core.utils.exceptions.JadxRuntimeException; import jadx.gui.treemodel.JClass; +import jadx.gui.treemodel.JField; import jadx.gui.treemodel.JMethod; import jadx.gui.treemodel.JNode; import jadx.gui.ui.action.ActionModel; @@ -23,6 +26,16 @@ public class XposedAction extends JNodeAction { private static final Logger LOG = LoggerFactory.getLogger(XposedAction.class); private static final long serialVersionUID = 2641585141624592578L; + private static final Map PRIMITIVE_TYPE_MAPPING = Map.of( + "int", "Int", + "byte", "Byte", + "short", "Short", + "long", "Long", + "float", "Float", + "double", "Double", + "char", "Char", + "boolean", "Boolean" + ); public XposedAction(CodeArea codeArea) { super(ActionModel.XPOSED_COPY, codeArea); @@ -43,7 +56,7 @@ public void runAction(JNode node) { @Override public boolean isActionEnabled(JNode node) { - return node instanceof JMethod || node instanceof JClass; + return node instanceof JMethod || node instanceof JClass || node instanceof JField; } private String generateXposedSnippet(JNode node) { @@ -53,6 +66,9 @@ private String generateXposedSnippet(JNode node) { if (node instanceof JClass) { return generateClassSnippet((JClass) node); } + if (node instanceof JField) { + return generateFieldSnippet((JField) node); + } throw new JadxRuntimeException("Unsupported node type: " + (node != null ? node.getClass() : "null")); } @@ -84,7 +100,7 @@ private String generateMethodSnippet(JMethod jMth) { if (mthArgs.isEmpty()) { return String.format(xposedFormatStr, xposedMethod, rawClassName, methodName); } - String params = mthArgs.stream().map(type -> type + ".class, ").collect(Collectors.joining()); + String params = mthArgs.stream().map(type -> (type.isGeneric() ? type.getObject() : type) + ".class, ").collect(Collectors.joining()); return String.format(xposedFormatStr, xposedMethod, rawClassName, methodName + params); } @@ -92,8 +108,18 @@ private String generateClassSnippet(JClass jc) { JavaClass javaClass = jc.getCls(); String rawClassName = javaClass.getRawName(); String shortClassName = javaClass.getName(); - return String.format("ClassLoader classLoader=lpparam.classLoader;\n" - + "Class %sClass=classLoader.loadClass(\"%s\");", + return String.format("ClassLoader classLoader = lpparam.classLoader;\n" + + "Class %sClass = classLoader.loadClass(\"%s\");", shortClassName, rawClassName); } + + private String generateFieldSnippet(JField jf) { + JavaField javaField = jf.getJavaField(); + String isStatic = javaField.getAccessFlags().isStatic() ? "Static" : ""; + String type = PRIMITIVE_TYPE_MAPPING.getOrDefault(javaField.getFieldNode().getType().toString(), "Object"); + String xposedMethod = "XposedHelpers.get" + isStatic + type + "Field"; + return String.format("%s(/*runtimeObject*/, \"%s\");", + xposedMethod, javaField.getName()); + + } }