未验证 提交 c61cb80a 编写于 作者: L LBJ-the-GOAT 提交者: GitHub

feat(gui): rename local variables (#1023) (#1084) (PR #1098)

Co-authored-by: tobias <tobias.hotmail.com>
上级 4217aab9
......@@ -30,10 +30,7 @@ import jadx.api.plugins.input.data.ILoadResult;
import jadx.core.Jadx;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.nodes.LineAttrNode;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.FieldNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.RootNode;
import jadx.core.dex.nodes.*;
import jadx.core.dex.visitors.SaveCode;
import jadx.core.export.ExportGradleProject;
import jadx.core.utils.Utils;
......@@ -449,6 +446,10 @@ public final class JadxDecompiler implements Closeable {
if (obj instanceof FieldNode) {
return getJavaFieldByNode((FieldNode) obj);
}
if (obj instanceof VariableNode) {
VariableNode varNode = (VariableNode) obj;
return new JavaVariable(getJavaClassByNode(varNode.getClassNode()), varNode);
}
throw new JadxRuntimeException("Unexpected node type: " + obj);
}
......
package jadx.api;
import java.util.Collections;
import java.util.List;
import jadx.core.dex.nodes.VariableNode;
public class JavaVariable implements JavaNode {
JavaClass cls;
VariableNode node;
public JavaVariable(JavaClass cls, VariableNode node) {
this.cls = cls;
this.node = node;
}
public VariableNode getVariableNode() {
return node;
}
@Override
public String getName() {
return node.getName();
}
@Override
public String getFullName() {
return node.getName();
}
@Override
public JavaClass getDeclaringClass() {
return cls;
}
@Override
public JavaClass getTopParentClass() {
return cls.getTopParentClass();
}
@Override
public int getDecompiledLine() {
return node.getDecompiledLine();
}
@Override
public List<JavaNode> getUseIn() {
return Collections.emptyList();
}
@Override
public int hashCode() {
return node.hashCode();
}
@Override
public boolean equals(Object obj) {
return node.equals(obj);
}
}
......@@ -35,25 +35,16 @@ import jadx.core.dex.instructions.InvokeNode;
import jadx.core.dex.instructions.InvokeType;
import jadx.core.dex.instructions.NewArrayNode;
import jadx.core.dex.instructions.SwitchInsn;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.CodeVar;
import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.InsnWrapArg;
import jadx.core.dex.instructions.args.LiteralArg;
import jadx.core.dex.instructions.args.Named;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.instructions.args.SSAVar;
import jadx.core.dex.instructions.args.*;
import jadx.core.dex.instructions.mods.ConstructorInsn;
import jadx.core.dex.instructions.mods.TernaryInsn;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.FieldNode;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.RootNode;
import jadx.core.dex.nodes.*;
import jadx.core.utils.CodeGenUtils;
import jadx.core.utils.RegionUtils;
import jadx.core.utils.exceptions.CodegenException;
import jadx.core.utils.exceptions.JadxRuntimeException;
import static jadx.core.dex.nodes.VariableNode.*;
import static jadx.core.utils.android.AndroidResourcesUtils.handleAppResField;
public class InsnGen {
......@@ -97,12 +88,26 @@ public class InsnGen {
public void addArg(CodeWriter code, InsnArg arg, boolean wrap) throws CodegenException {
if (arg.isRegister()) {
CodeVar codeVar = CodeGenUtils.getCodeVar((RegisterArg) arg);
if (codeVar != null) {
VariableNode node = mth.getVariable(codeVar.getIndex());
if (node != null) {
node.useVar(code, codeVar);
code.attachAnnotation(node);
}
}
code.add(mgen.getNameGen().useArg((RegisterArg) arg));
} else if (arg.isLiteral()) {
code.add(lit((LiteralArg) arg));
} else if (arg.isInsnWrap()) {
addWrappedArg(code, (InsnWrapArg) arg, wrap);
} else if (arg.isNamed()) {
if (arg instanceof NamedArg) {
VariableNode node = mth.getVariable(((NamedArg) arg).getIndex());
if (node != null) {
code.attachAnnotation(node);
}
}
code.add(((Named) arg).getName());
} else {
throw new CodegenException("Unknown arg type " + arg);
......@@ -140,7 +145,16 @@ public class InsnGen {
}
useType(code, codeVar.getType());
code.add(' ');
code.add(mgen.getNameGen().assignArg(codeVar));
VariableNode node = mth.declareVar(codeVar, mgen.getNameGen(), VarKind.VAR);
String name;
if (node != null) {
code.attachDefinition(node);
name = node.getName();
codeVar.setName(name);
} else {
name = mgen.getNameGen().assignArg(codeVar);
}
code.add(name);
}
private String lit(LiteralArg arg) {
......@@ -639,6 +653,7 @@ public class InsnGen {
if (insn.isSuper()) {
code.add("super");
} else if (insn.isThis()) {
code.attachAnnotation(mth.getParentClass());
code.add("this");
} else {
code.add("new ");
......
......@@ -29,6 +29,7 @@ import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.instructions.args.SSAVar;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.VariableNode;
import jadx.core.dex.trycatch.CatchAttr;
import jadx.core.dex.visitors.DepthTraversal;
import jadx.core.dex.visitors.IDexTreeVisitor;
......@@ -42,6 +43,7 @@ import jadx.core.utils.exceptions.JadxOverflowException;
import static jadx.core.codegen.MethodGen.FallbackOption.BLOCK_DUMP;
import static jadx.core.codegen.MethodGen.FallbackOption.COMMENTED_DUMP;
import static jadx.core.codegen.MethodGen.FallbackOption.FALLBACK_MODE;
import static jadx.core.dex.nodes.VariableNode.*;
public class MethodGen {
private static final Logger LOG = LoggerFactory.getLogger(MethodGen.class);
......@@ -220,7 +222,19 @@ public class MethodGen {
classGen.useType(code, argType);
}
code.add(' ');
code.add(nameGen.assignArg(var));
VariableNode node = mth.declareVar(var, nameGen, VarKind.ARG);
String name;
if (node != null) {
code.attachDefinition(node);
name = node.getName();
var.setName(name);
} else {
name = nameGen.assignArg(var);
}
if (var.isThis()) {
code.attachDefinition(mth.getParentClass());
}
code.add(name);
i++;
if (it.hasNext()) {
......
......@@ -21,12 +21,7 @@ import jadx.core.dex.instructions.args.CodeVar;
import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.NamedArg;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.BlockNode;
import jadx.core.dex.nodes.FieldNode;
import jadx.core.dex.nodes.IBlock;
import jadx.core.dex.nodes.IContainer;
import jadx.core.dex.nodes.IRegion;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.*;
import jadx.core.dex.regions.Region;
import jadx.core.dex.regions.SwitchRegion;
import jadx.core.dex.regions.SwitchRegion.CaseInfo;
......@@ -40,10 +35,13 @@ import jadx.core.dex.regions.loops.LoopRegion;
import jadx.core.dex.regions.loops.LoopType;
import jadx.core.dex.trycatch.ExceptionHandler;
import jadx.core.utils.BlockUtils;
import jadx.core.utils.CodeGenUtils;
import jadx.core.utils.RegionUtils;
import jadx.core.utils.exceptions.CodegenException;
import jadx.core.utils.exceptions.JadxRuntimeException;
import static jadx.core.dex.nodes.VariableNode.*;
public class RegionGen extends InsnGen {
private static final Logger LOG = LoggerFactory.getLogger(RegionGen.class);
......@@ -351,10 +349,29 @@ public class RegionGen extends InsnGen {
if (arg == null) {
code.add("unknown"); // throwing exception is too late at this point
} else if (arg instanceof RegisterArg) {
RegisterArg reg = (RegisterArg) arg;
code.add(mgen.getNameGen().assignArg(reg.getSVar().getCodeVar()));
String name;
CodeVar codeVar = CodeGenUtils.getCodeVar((RegisterArg) arg);
if (codeVar != null) {
VariableNode node = mth.declareVar(codeVar, mgen.getNameGen(), VarKind.CATCH_ARG);
if (node != null) {
code.attachDefinition(node);
name = node.getName();
codeVar.setName(name);
} else {
name = mgen.getNameGen().assignArg(codeVar);
}
} else {
RegisterArg reg = (RegisterArg) arg;
name = mgen.getNameGen().assignArg(reg.getSVar().getCodeVar());
}
code.add(name);
} else if (arg instanceof NamedArg) {
code.add(mgen.getNameGen().assignNamedArg((NamedArg) arg));
VariableNode node = mth.declareVar((NamedArg) arg, mgen.getNameGen(), VarKind.CATCH_ARG);
if (node != null) {
code.add(node.getName());
} else {
code.add(mgen.getNameGen().assignNamedArg((NamedArg) arg));
}
} else {
throw new JadxRuntimeException("Unexpected arg type in catch block: " + arg + ", class: " + arg.getClass().getSimpleName());
}
......
......@@ -6,11 +6,7 @@ import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
......@@ -20,6 +16,7 @@ import jadx.core.dex.info.ClassInfo;
import jadx.core.dex.info.FieldInfo;
import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.nodes.RootNode;
import jadx.core.dex.nodes.VariableNode;
import jadx.core.utils.files.FileUtils;
import static java.nio.charset.StandardCharsets.UTF_8;
......@@ -35,6 +32,7 @@ public class DeobfPresets {
private final Map<String, String> clsPresetMap = new HashMap<>();
private final Map<String, String> fldPresetMap = new HashMap<>();
private final Map<String, String> mthPresetMap = new HashMap<>();
private final Map<String, Set<String>> varPresetMap = new HashMap<>();
@Nullable
public static DeobfPresets build(RootNode root) {
......@@ -94,6 +92,13 @@ public class DeobfPresets {
case 'm':
mthPresetMap.put(origName, alias);
break;
case 'v':
String[] mthIDAndVarIndex = origName.split(VariableNode.VAR_SEPARATOR);
if (mthIDAndVarIndex.length == 2) {
Set<String> nameList = varPresetMap.computeIfAbsent(mthIDAndVarIndex[0], k -> new HashSet<>());
nameList.add(makeVarSecIndex(mthIDAndVarIndex[1], alias));
}
break;
}
}
} catch (Exception e) {
......@@ -101,6 +106,10 @@ public class DeobfPresets {
}
}
public static String makeVarSecIndex(String indexes, String name) {
return indexes + VariableNode.VAR_SEPARATOR + name;
}
private static String[] splitAndTrim(String str) {
String[] v = str.substring(2).split("=");
for (int i = 0; i < v.length; i++) {
......@@ -123,6 +132,15 @@ public class DeobfPresets {
for (Map.Entry<String, String> mthEntry : mthPresetMap.entrySet()) {
list.add(String.format("m %s = %s", mthEntry.getKey(), mthEntry.getValue()));
}
for (Map.Entry<String, Set<String>> varEntry : varPresetMap.entrySet()) {
for (String val : varEntry.getValue()) {
String[] indexAndName = val.split(VariableNode.VAR_SEPARATOR);
if (indexAndName.length == 2) {
list.add(String.format("v %s%s%s = %s",
varEntry.getKey(), VariableNode.VAR_SEPARATOR, indexAndName[0], indexAndName[1]));
}
}
}
Collections.sort(list);
Files.write(deobfMapFile, list, MAP_FILE_CHARSET,
StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
......@@ -147,6 +165,7 @@ public class DeobfPresets {
clsPresetMap.clear();
fldPresetMap.clear();
mthPresetMap.clear();
varPresetMap.clear();
}
public Path getDeobfMapFile() {
......@@ -168,4 +187,18 @@ public class DeobfPresets {
public Map<String, String> getMthPresetMap() {
return mthPresetMap;
}
public Map<String, Set<String>> getVarPresetMap() {
return varPresetMap;
}
public void updateVariableName(VariableNode node, String name) {
String key = node.getRenameKey();
key = key.substring(0, key.indexOf(VariableNode.VAR_SEPARATOR));
String newIndex = makeVarSecIndex(node.makeVarIndex(), name);
String oldIndex = makeVarSecIndex(node.makeVarIndex(), node.getName());
Set<String> indexSet = varPresetMap.computeIfAbsent(key, k -> new HashSet<>());
indexSet.remove(oldIndex);
indexSet.add(newIndex);
}
}
......@@ -2,13 +2,7 @@ package jadx.core.deobf;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.*;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
......@@ -209,6 +203,10 @@ public class Deobfuscator {
}
private void renameMethod(MethodNode mth) {
Set<String> names = deobfPresets.getVarPresetMap().get(mth.getMethodInfo().getRawFullId());
if (names != null) {
mth.getMethodInfo().setVarNameMap(names);
}
String alias = getMethodAlias(mth);
if (alias != null) {
applyMethodAlias(mth, alias);
......
package jadx.core.dex.info;
import java.util.List;
import java.util.Objects;
import java.util.*;
import org.jetbrains.annotations.Nullable;
......@@ -10,6 +9,7 @@ import jadx.api.plugins.input.data.IMethodRef;
import jadx.core.codegen.TypeGen;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.nodes.RootNode;
import jadx.core.dex.nodes.VariableNode;
import jadx.core.utils.Utils;
public final class MethodInfo implements Comparable<MethodInfo> {
......@@ -20,6 +20,7 @@ public final class MethodInfo implements Comparable<MethodInfo> {
private final ClassInfo declClass;
private final String shortId;
private String alias;
private Map<String, String> varNameMap;
private MethodInfo(ClassInfo declClass, String name, List<ArgType> args, ArgType retType) {
this.name = name;
......@@ -148,6 +149,29 @@ public final class MethodInfo implements Comparable<MethodInfo> {
return !name.equals(alias);
}
public synchronized void setVarNameMap(Set<String> names) {
if (varNameMap == null) {
varNameMap = new HashMap<>();
}
for (String name : names) {
String[] indexesAndName = name.split(VariableNode.VAR_SEPARATOR);
if (indexesAndName.length == 2) {
varNameMap.put(indexesAndName[0], indexesAndName[1]);
}
}
}
public String getVariableName(String indexes) {
if (varNameMap != null) {
return varNameMap.get(indexes);
}
return null;
}
public boolean hasVarNameMap() {
return varNameMap != null && varNameMap.size() > 0;
}
@Override
public int hashCode() {
return shortId.hashCode() + 31 * declClass.hashCode();
......
......@@ -4,7 +4,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CodeVar {
public class CodeVar implements VisibleVar {
private String name;
private ArgType type; // before type inference can be null and set only for immutable types
private List<SSAVar> ssaVars = Collections.emptyList();
......@@ -13,6 +13,18 @@ public class CodeVar {
private boolean isThis;
private boolean isDeclared;
private int index = -1;
@Override
public int getIndex() {
return index;
}
@Override
public void setIndex(int index) {
this.index = index;
}
public static CodeVar fromMthArg(RegisterArg mthArg, boolean linkRegister) {
CodeVar var = new CodeVar();
var.setType(mthArg.getInitType());
......@@ -26,14 +38,17 @@ public class CodeVar {
return var;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public ArgType getType() {
return type;
}
......
......@@ -2,16 +2,28 @@ package jadx.core.dex.instructions.args;
import org.jetbrains.annotations.NotNull;
public final class NamedArg extends InsnArg implements Named {
public final class NamedArg extends InsnArg implements Named, VisibleVar {
@NotNull
private String name;
private int index = -1;
public NamedArg(@NotNull String name, @NotNull ArgType type) {
this.name = name;
this.type = type;
}
@Override
public int getIndex() {
return index;
}
@Override
public void setIndex(int index) {
this.index = index;
}
@NotNull
public String getName() {
return name;
......@@ -22,6 +34,7 @@ public final class NamedArg extends InsnArg implements Named {
return true;
}
@Override
public void setName(@NotNull String name) {
this.name = name;
}
......
package jadx.core.dex.instructions.args;
public interface VisibleVar {
int getIndex();
void setIndex(int index);
String getName();
void setName(String name);
ArgType getType();
}
package jadx.core.dex.nodes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
......@@ -16,6 +13,7 @@ import jadx.api.plugins.input.data.IMethodData;
import jadx.api.plugins.input.data.annotations.EncodedValue;
import jadx.api.plugins.input.data.annotations.IAnnotation;
import jadx.core.Consts;
import jadx.core.codegen.NameGen;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.annotations.AnnotationsList;
import jadx.core.dex.attributes.annotations.MethodParameters;
......@@ -26,10 +24,8 @@ import jadx.core.dex.info.AccessInfo.AFType;
import jadx.core.dex.info.ClassInfo;
import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.instructions.InsnDecoder;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.instructions.args.SSAVar;
import jadx.core.dex.instructions.args.*;
import jadx.core.dex.nodes.VariableNode.VarKind;
import jadx.core.dex.nodes.utils.TypeUtils;
import jadx.core.dex.regions.Region;
import jadx.core.dex.trycatch.ExceptionHandler;
......@@ -73,6 +69,7 @@ public class MethodNode extends NotificationAttrNode implements IMethodDetails,
private Region region;
private List<MethodNode> useIn = Collections.emptyList();
private List<VariableNode> variables = new ArrayList<>();
public static MethodNode build(ClassNode classNode, IMethodData methodData) {
MethodNode methodNode = new MethodNode(classNode, methodData);
......@@ -102,6 +99,59 @@ public class MethodNode extends NotificationAttrNode implements IMethodDetails,
unload();
}
public List<VariableNode> getVars() {
return new ArrayList<>(variables);
}
public VariableNode getVariable(int index) {
if (index >= 0 && index < variables.size()) {
return variables.get(index);
}
return null;
}
public VariableNode getVariable(int index, VarKind varType) {
for (VariableNode variable : variables) {
if (variable.getVarKind() == varType && variable.getIndex() == index) {
return variable;
}
}
return null;
}
public VariableNode declareVar(VisibleVar var, NameGen nameGen, VarKind varKind) {
if (var instanceof CodeVar) {
if (((CodeVar) var).isThis()) {
return null;
}
}
VariableNode varNode;
int index = var.getIndex();
if (index == -1) {
index = variables.size();
var.setIndex(index);
varNode = null;
} else {
varNode = getVariable(var.getIndex());
}
if (varNode == null) {
String name = mthInfo.getVariableName(VariableNode.makeVarIndex(index, varKind));
if (name != null) {
var.setName(name); // set name with user renamed previously.
}
if (var instanceof CodeVar) { // let NameGen record this name or gen an valid name.
name = nameGen.assignArg((CodeVar) var);
} else if (var instanceof NamedArg) {
name = nameGen.assignNamedArg((NamedArg) var);
} else {
throw new JadxRuntimeException("Unexpected var type: " + var);
}
varNode = new VariableNode(this, name, var.getType(), varKind, index);
this.variables.add(varNode);
}
return varNode;
}
@Override
public void unload() {
loaded = false;
......
package jadx.core.dex.nodes;
import jadx.core.codegen.CodeWriter;
import jadx.core.dex.attributes.nodes.LineAttrNode;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.CodeVar;
import jadx.core.utils.exceptions.JadxRuntimeException;
public class VariableNode extends LineAttrNode {
public enum VarKind {
// note: better not change the order of these fields,
// they are also used for variable renaming
VAR, ARG, CATCH_ARG
}
public static final String VAR_SEPARATOR = "--->>"; // do not contain '='
private VarKind varKind = VarKind.VAR;
private ArgType type;
private String name;
private int index;
MethodNode mth;
public VariableNode(MethodNode mth, String name, ArgType type, VarKind varKind, int index) {
this.mth = mth;
this.name = name;
this.type = type;
this.index = index;
this.varKind = varKind;
}
public MethodNode getMethodNode() {
return mth;
}
public ClassNode getClassNode() {
return mth.getParentClass();
}
public VarKind getVarKind() {
return this.varKind;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public ArgType getType() {
return type;
}
public int getIndex() {
return index;
}
public void addUsage(int line, int offset, int codeOffset) {
}
public void useVar(CodeWriter code, CodeVar codeVar) {
if (!codeVar.isThis()) { // TODO: add usage
// IdentifierVisitor.VariableNode node = codeVar.getVariableNode();
// node.addUsage(code.getLine(), code.getOffset(), code.bufLength());
// code.attachAnnotation(node);
}
}
public String getRenameKey() {
return mth.getMethodInfo().getRawFullId() + VAR_SEPARATOR + makeVarIndex(index, varKind);
}
public String makeVarIndex() {
return makeVarIndex(index, varKind);
}
public static String makeVarIndex(int index, VarKind kind) {
return kindToStr(kind) + "@" + kind.ordinal() + "_" + index;
}
private static String kindToStr(VarKind varKind) {
String kind;
switch (varKind) {
case VAR:
kind = "var";
break;
case ARG:
kind = "param";
break;
case CATCH_ARG:
kind = "catch";
break;
default:
throw new JadxRuntimeException("Unexpected variable type " + varKind);
}
return kind;
}
@Override
public int hashCode() {
return mth.hashCode() + 31 * getDefPosition() + 31 * makeVarIndex().hashCode();
}
@Override
public boolean equals(Object obj) {
return this == obj;
}
}
......@@ -7,6 +7,9 @@ import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.AttrNode;
import jadx.core.dex.attributes.nodes.RenameReasonAttr;
import jadx.core.dex.attributes.nodes.SourceFileAttr;
import jadx.core.dex.instructions.args.CodeVar;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.instructions.args.SSAVar;
import jadx.core.dex.nodes.ClassNode;
public class CodeGenUtils {
......@@ -36,6 +39,14 @@ public class CodeGenUtils {
}
}
public static CodeVar getCodeVar(RegisterArg arg) {
SSAVar svar = arg.getSVar();
if (svar != null) {
return svar.getCodeVar();
}
return null;
}
private CodeGenUtils() {
}
}
package jadx.gui.treemodel;
import javax.swing.*;
import jadx.api.JavaNode;
import jadx.api.JavaVariable;
public class JVariable extends JNode {
JClass cls;
JavaVariable var;
public JVariable(JavaVariable var, JClass cls) {
this.cls = cls;
this.var = var;
}
public JavaVariable getJavaVarNode() {
return (JavaVariable) getJavaNode();
}
@Override
public JClass getRootClass() {
return cls;
}
@Override
public JavaNode getJavaNode() {
return var;
}
@Override
public JClass getJParent() {
return cls;
}
@Override
public Icon getIcon() {
return null;
}
@Override
public String makeString() {
return var.getName();
}
@Override
public boolean canRename() {
return true;
}
}
......@@ -4,11 +4,7 @@ import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import javax.swing.BorderFactory;
......@@ -27,26 +23,20 @@ import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.api.JavaClass;
import jadx.api.JavaField;
import jadx.api.JavaMethod;
import jadx.api.JavaNode;
import jadx.api.*;
import jadx.core.codegen.CodeWriter;
import jadx.core.deobf.DeobfPresets;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.nodes.MethodOverrideAttr;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.RootNode;
import jadx.core.dex.nodes.VariableNode;
import jadx.core.dex.visitors.RenameVisitor;
import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.gui.jobs.IndexJob;
import jadx.gui.settings.JadxSettings;
import jadx.gui.treemodel.JClass;
import jadx.gui.treemodel.JField;
import jadx.gui.treemodel.JMethod;
import jadx.gui.treemodel.JNode;
import jadx.gui.treemodel.JPackage;
import jadx.gui.treemodel.*;
import jadx.gui.ui.codearea.ClassCodeContentPanel;
import jadx.gui.ui.codearea.CodePanel;
import jadx.gui.utils.*;
......@@ -126,6 +116,9 @@ public class RenameDialog extends JDialog {
deobfPresets.getClsPresetMap().put(javaClass.getRawName(), renameText);
} else if (node instanceof JPackage) {
deobfPresets.getPkgPresetMap().put(((JPackage) node).getFullName(), renameText);
} else if (node instanceof JVariable) {
VariableNode varNode = ((JVariable) node).getJavaVarNode().getVariableNode();
deobfPresets.updateVariableName(varNode, renameText);
}
}
......
......@@ -3,15 +3,9 @@ package jadx.gui.utils;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import jadx.api.JavaClass;
import jadx.api.JavaField;
import jadx.api.JavaMethod;
import jadx.api.JavaNode;
import jadx.api.*;
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.treemodel.*;
public class JNodeCache {
......@@ -45,6 +39,10 @@ public class JNodeCache {
JavaField fld = (JavaField) node;
return new JField(fld, (JClass) makeFrom(fld.getDeclaringClass()));
}
if (node instanceof JavaVariable) {
JavaVariable var = (JavaVariable) node;
return new JVariable(var, (JClass) makeFrom(var.getDeclaringClass()));
}
throw new JadxRuntimeException("Unknown type for JavaNode: " + node.getClass());
}
}
package jadx.gui.utils;
import jadx.api.JavaClass;
import jadx.api.JavaField;
import jadx.api.JavaMethod;
import jadx.api.JavaNode;
import jadx.api.*;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.gui.treemodel.*;
......@@ -55,6 +52,9 @@ public class JumpPosition {
if (node instanceof JField) {
return ((JField) node).getJavaField().getFieldNode().getDefPosition();
}
if (node instanceof JVariable) {
return ((JVariable) node).getJavaVarNode().getVariableNode().getDefPosition();
}
throw new JadxRuntimeException("Unexpected node " + node);
}
......@@ -68,6 +68,9 @@ public class JumpPosition {
if (node instanceof JavaField) {
return ((JavaField) node).getFieldNode().getDefPosition();
}
if (node instanceof JavaVariable) {
return ((JavaVariable) node).getVariableNode().getDefPosition();
}
throw new JadxRuntimeException("Unexpected node " + node);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册