提交 d2acaa03 编写于 作者: S Skylot

core: guess variable name from assign instruction

上级 f2aa4cd1
...@@ -3,20 +3,46 @@ package jadx.core.codegen; ...@@ -3,20 +3,46 @@ package jadx.core.codegen;
import jadx.core.Consts; import jadx.core.Consts;
import jadx.core.deobf.NameMapper; import jadx.core.deobf.NameMapper;
import jadx.core.dex.info.ClassInfo; import jadx.core.dex.info.ClassInfo;
import jadx.core.dex.instructions.InvokeNode;
import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.InsnWrapArg;
import jadx.core.dex.instructions.args.NamedArg; import jadx.core.dex.instructions.args.NamedArg;
import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.instructions.args.SSAVar; import jadx.core.dex.instructions.args.SSAVar;
import jadx.core.dex.instructions.mods.ConstructorInsn;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.utils.Utils; import jadx.core.utils.Utils;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
public class NameGen { public class NameGen {
private static final Map<String, String> OBJ_ALIAS;
private final Set<String> varNames = new HashSet<String>(); private final Set<String> varNames = new HashSet<String>();
private final boolean fallback; private final boolean fallback;
static {
OBJ_ALIAS = new HashMap<String, String>();
OBJ_ALIAS.put(Consts.CLASS_STRING, "str");
OBJ_ALIAS.put(Consts.CLASS_CLASS, "cls");
OBJ_ALIAS.put(Consts.CLASS_THROWABLE, "th");
OBJ_ALIAS.put(Consts.CLASS_OBJECT, "obj");
OBJ_ALIAS.put("java.util.Iterator", "it");
OBJ_ALIAS.put("java.lang.Boolean", "bool");
OBJ_ALIAS.put("java.lang.Short", "sh");
OBJ_ALIAS.put("java.lang.Integer", "num");
OBJ_ALIAS.put("java.lang.Character", "ch");
OBJ_ALIAS.put("java.lang.Byte", "b");
OBJ_ALIAS.put("java.lang.Float", "f");
OBJ_ALIAS.put("java.lang.Long", "l");
OBJ_ALIAS.put("java.lang.Double", "d");
}
public NameGen(boolean fallback) { public NameGen(boolean fallback) {
this.fallback = fallback; this.fallback = fallback;
} }
...@@ -72,7 +98,7 @@ public class NameGen { ...@@ -72,7 +98,7 @@ public class NameGen {
} }
String varName; String varName;
if (name != null) { if (name != null) {
if (name.equals("this")) { if ("this".equals(name)) {
return name; return name;
} }
varName = name; varName = name;
...@@ -101,34 +127,92 @@ public class NameGen { ...@@ -101,34 +127,92 @@ public class NameGen {
private static String makeNameForObject(ArgType type) { private static String makeNameForObject(ArgType type) {
if (type.isObject()) { if (type.isObject()) {
String obj = type.getObject(); String alias = getAliasForObject(type.getObject());
if (obj.startsWith("java.lang.")) { if (alias != null) {
if (obj.equals(Consts.CLASS_STRING)) { return alias;
return "str";
}
if (obj.equals(Consts.CLASS_OBJECT)) {
return "obj";
}
if (obj.equals(Consts.CLASS_CLASS)) {
return "cls";
}
if (obj.equals(Consts.CLASS_THROWABLE)) {
return "th";
}
} }
ClassInfo clsInfo = ClassInfo.fromType(type); ClassInfo clsInfo = ClassInfo.fromType(type);
String shortName = clsInfo.getShortName(); String shortName = clsInfo.getShortName();
if (shortName.toUpperCase().equals(shortName)) { String vName = fromName(shortName);
// all characters are upper case if (vName != null) {
return shortName.toLowerCase(); return vName;
}
if (!shortName.isEmpty()) {
String v1 = Character.toLowerCase(shortName.charAt(0)) + shortName.substring(1);
if (!v1.equals(shortName)) {
return v1;
}
} }
} }
return Utils.escape(type.toString()); return Utils.escape(type.toString());
} }
private static String fromName(String name) {
if (name == null || name.isEmpty()) {
return null;
}
if (name.toUpperCase().equals(name)) {
// all characters are upper case
return name.toLowerCase();
}
String v1 = Character.toLowerCase(name.charAt(0)) + name.substring(1);
if (!v1.equals(name)) {
return v1;
}
if (name.length() < 3) {
return name + "Var";
}
return null;
}
public static void guessName(RegisterArg arg) {
SSAVar sVar = arg.getSVar();
if (sVar == null || sVar.getName() != null) {
return;
}
RegisterArg assignArg = sVar.getAssign();
InsnNode assignInsn = assignArg.getParentInsn();
String name = makeNameFromInsn(assignInsn);
if (name != null && !NameMapper.isReserved(name)) {
assignArg.setName(name);
}
}
public static String getAliasForObject(String name) {
return OBJ_ALIAS.get(name);
}
private static String makeNameFromInsn(InsnNode insn) {
switch (insn.getType()) {
case INVOKE:
InvokeNode inv = (InvokeNode) insn;
String name = inv.getCallMth().getName();
if (name.startsWith("get") || name.startsWith("set")) {
return fromName(name.substring(3));
}
if ("iterator".equals(name)) {
return "it";
}
return name;
case CONSTRUCTOR:
ConstructorInsn co = (ConstructorInsn) insn;
return makeNameForObject(co.getClassType().getType());
case ARRAY_LENGTH:
return "length";
case ARITH:
case TERNARY:
case CAST:
for (InsnArg arg : insn.getArguments()) {
if (arg.isInsnWrap()) {
InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
String wName = makeNameFromInsn(wrapInsn);
if (wName != null) {
return wName;
}
}
}
break;
default:
break;
}
return null;
}
} }
...@@ -41,4 +41,24 @@ public class MthParameterArg extends RegisterArg { ...@@ -41,4 +41,24 @@ public class MthParameterArg extends RegisterArg {
} }
super.setSVar(sVar); super.setSVar(sVar);
} }
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof MthParameterArg)) {
return false;
}
if (!super.equals(obj)) {
return false;
}
MthParameterArg that = (MthParameterArg) obj;
return isThis == that.isThis;
}
@Override
public int hashCode() {
return 31 * super.hashCode() + (isThis ? 1 : 0);
}
} }
package jadx.core.dex.visitors.regions; package jadx.core.dex.visitors.regions;
import jadx.core.codegen.NameGen;
import jadx.core.dex.attributes.AFlag; import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.AType; import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.nodes.DeclareVariablesAttr; import jadx.core.dex.attributes.nodes.DeclareVariablesAttr;
...@@ -179,6 +180,7 @@ public class ProcessVariables extends AbstractVisitor { ...@@ -179,6 +180,7 @@ public class ProcessVariables extends AbstractVisitor {
if (u.getArgRegion() == assignRegion if (u.getArgRegion() == assignRegion
&& canDeclareInRegion(u, assignRegion, regionsOrder)) { && canDeclareInRegion(u, assignRegion, regionsOrder)) {
u.getArg().getParentInsn().add(AFlag.DECLARE_VAR); u.getArg().getParentInsn().add(AFlag.DECLARE_VAR);
processVar(u.getArg());
it.remove(); it.remove();
break; break;
} }
...@@ -248,6 +250,11 @@ public class ProcessVariables extends AbstractVisitor { ...@@ -248,6 +250,11 @@ public class ProcessVariables extends AbstractVisitor {
region.addAttr(dv); region.addAttr(dv);
} }
dv.addVar(arg); dv.addVar(arg);
processVar(arg);
}
private static void processVar(RegisterArg arg) {
NameGen.guessName(arg);
} }
private static int calculateOrder(IContainer container, Map<IContainer, Integer> regionsOrder, private static int calculateOrder(IContainer container, Map<IContainer, Integer> regionsOrder,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册