core: fix enum processing order, remove synchronization (#257)
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
package jadx.core.dex.attributes.nodes;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.core.dex.attributes.AType;
|
||||
import jadx.core.dex.attributes.IAttribute;
|
||||
import jadx.core.dex.nodes.FieldNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class EnumMapAttr implements IAttribute {
|
||||
|
||||
public static class KeyValueMap {
|
||||
@@ -21,9 +23,14 @@ public class EnumMapAttr implements IAttribute {
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<FieldNode, KeyValueMap> fieldsMap = new HashMap<>();
|
||||
@Nullable
|
||||
private Map<FieldNode, KeyValueMap> fieldsMap;
|
||||
|
||||
@Nullable
|
||||
public KeyValueMap getMap(FieldNode field) {
|
||||
if (fieldsMap == null) {
|
||||
return null;
|
||||
}
|
||||
return fieldsMap.get(field);
|
||||
}
|
||||
|
||||
@@ -31,11 +38,18 @@ public class EnumMapAttr implements IAttribute {
|
||||
KeyValueMap map = getMap(field);
|
||||
if (map == null) {
|
||||
map = new KeyValueMap();
|
||||
if (fieldsMap == null) {
|
||||
fieldsMap = new HashMap<>();
|
||||
}
|
||||
fieldsMap.put(field, map);
|
||||
}
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return fieldsMap == null || fieldsMap.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AType<EnumMapAttr> getType() {
|
||||
return AType.ENUM_MAP;
|
||||
@@ -45,5 +59,4 @@ public class EnumMapAttr implements IAttribute {
|
||||
public String toString() {
|
||||
return "Enum fields map: " + fieldsMap;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package jadx.core.dex.visitors;
|
||||
|
||||
import jadx.core.ProcessClass;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.attributes.AType;
|
||||
import jadx.core.dex.attributes.nodes.EnumMapAttr;
|
||||
@@ -18,18 +23,13 @@ import jadx.core.dex.instructions.args.InsnWrapArg;
|
||||
import jadx.core.dex.instructions.args.LiteralArg;
|
||||
import jadx.core.dex.nodes.BlockNode;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.core.dex.nodes.DexNode;
|
||||
import jadx.core.dex.nodes.FieldNode;
|
||||
import jadx.core.dex.nodes.InsnNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
import jadx.core.utils.InstructionRemover;
|
||||
import jadx.core.utils.exceptions.DecodeException;
|
||||
import jadx.core.utils.exceptions.JadxException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@JadxVisitor(
|
||||
name = "ReSugarCode",
|
||||
desc = "Simplify synthetic or verbose code",
|
||||
@@ -39,6 +39,12 @@ public class ReSugarCode extends AbstractVisitor {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ReSugarCode.class);
|
||||
|
||||
@Override
|
||||
public boolean visit(ClassNode cls) throws JadxException {
|
||||
initClsEnumMap(cls);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MethodNode mth) throws JadxException {
|
||||
if (mth.isNoCode()) {
|
||||
@@ -78,7 +84,7 @@ public class ReSugarCode extends AbstractVisitor {
|
||||
* Replace new array and sequence of array-put to new filled-array instruction.
|
||||
*/
|
||||
private static InsnNode processNewArray(MethodNode mth, List<InsnNode> instructions, int i,
|
||||
InstructionRemover remover) {
|
||||
InstructionRemover remover) {
|
||||
NewArrayNode newArrayInsn = (NewArrayNode) instructions.get(i);
|
||||
InsnArg arg = newArrayInsn.getArg(0);
|
||||
if (!arg.isLiteral()) {
|
||||
@@ -115,7 +121,7 @@ public class ReSugarCode extends AbstractVisitor {
|
||||
if (wrapInsn.getType() != InsnType.AGET) {
|
||||
return;
|
||||
}
|
||||
EnumMapInfo enumMapInfo = checkEnumMapAccess(mth, wrapInsn);
|
||||
EnumMapInfo enumMapInfo = checkEnumMapAccess(mth.dex(), wrapInsn);
|
||||
if (enumMapInfo == null) {
|
||||
return;
|
||||
}
|
||||
@@ -144,49 +150,40 @@ public class ReSugarCode extends AbstractVisitor {
|
||||
checkAndHideClass(enumMapField.getParentClass());
|
||||
}
|
||||
|
||||
private static EnumMapAttr.KeyValueMap getEnumMap(MethodNode mth, FieldNode field) {
|
||||
ClassNode syntheticClass = field.getParentClass();
|
||||
EnumMapAttr mapAttr = syntheticClass.get(AType.ENUM_MAP);
|
||||
if (mapAttr != null) {
|
||||
return mapAttr.getMap(field);
|
||||
private static void initClsEnumMap(ClassNode enumCls) {
|
||||
MethodNode clsInitMth = enumCls.getClassInitMth();
|
||||
if (clsInitMth == null || clsInitMth.isNoCode()) {
|
||||
return;
|
||||
}
|
||||
synchronized (ProcessClass.getSyncObj(syntheticClass)) {
|
||||
mapAttr = new EnumMapAttr();
|
||||
syntheticClass.addAttr(mapAttr);
|
||||
|
||||
MethodNode clsInitMth = syntheticClass.searchMethodByName("<clinit>()V");
|
||||
if (clsInitMth == null || clsInitMth.isNoCode()) {
|
||||
return null;
|
||||
}
|
||||
if (clsInitMth.getBasicBlocks() == null) {
|
||||
try {
|
||||
clsInitMth.load();
|
||||
} catch (DecodeException e) {
|
||||
LOG.error("Load failed", e);
|
||||
return null;
|
||||
}
|
||||
if (clsInitMth.getBasicBlocks() == null) {
|
||||
// TODO:
|
||||
return null;
|
||||
EnumMapAttr mapAttr = new EnumMapAttr();
|
||||
for (BlockNode block : clsInitMth.getBasicBlocks()) {
|
||||
for (InsnNode insn : block.getInstructions()) {
|
||||
if (insn.getType() == InsnType.APUT) {
|
||||
addToEnumMap(enumCls.dex(), mapAttr, insn);
|
||||
}
|
||||
}
|
||||
for (BlockNode block : clsInitMth.getBasicBlocks()) {
|
||||
for (InsnNode insn : block.getInstructions()) {
|
||||
if (insn.getType() == InsnType.APUT) {
|
||||
addToEnumMap(mth, mapAttr, insn);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mapAttr.getMap(field);
|
||||
}
|
||||
if (!mapAttr.isEmpty()) {
|
||||
enumCls.addAttr(mapAttr);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addToEnumMap(MethodNode mth, EnumMapAttr mapAttr, InsnNode aputInsn) {
|
||||
@Nullable
|
||||
private static EnumMapAttr.KeyValueMap getEnumMap(MethodNode mth, FieldNode field) {
|
||||
ClassNode syntheticClass = field.getParentClass();
|
||||
EnumMapAttr mapAttr = syntheticClass.get(AType.ENUM_MAP);
|
||||
if (mapAttr == null) {
|
||||
return null;
|
||||
}
|
||||
return mapAttr.getMap(field);
|
||||
}
|
||||
|
||||
private static void addToEnumMap(DexNode dex, EnumMapAttr mapAttr, InsnNode aputInsn) {
|
||||
InsnArg litArg = aputInsn.getArg(2);
|
||||
if (!litArg.isLiteral()) {
|
||||
return;
|
||||
}
|
||||
EnumMapInfo mapInfo = checkEnumMapAccess(mth, aputInsn);
|
||||
EnumMapInfo mapInfo = checkEnumMapAccess(dex, aputInsn);
|
||||
if (mapInfo == null) {
|
||||
return;
|
||||
}
|
||||
@@ -203,7 +200,7 @@ public class ReSugarCode extends AbstractVisitor {
|
||||
if (!(index instanceof FieldInfo)) {
|
||||
return;
|
||||
}
|
||||
FieldNode fieldNode = mth.dex().resolveField((FieldInfo) index);
|
||||
FieldNode fieldNode = dex.resolveField((FieldInfo) index);
|
||||
if (fieldNode == null) {
|
||||
return;
|
||||
}
|
||||
@@ -211,7 +208,7 @@ public class ReSugarCode extends AbstractVisitor {
|
||||
mapAttr.add(field, literal, fieldNode);
|
||||
}
|
||||
|
||||
public static EnumMapInfo checkEnumMapAccess(MethodNode mth, InsnNode checkInsn) {
|
||||
public static EnumMapInfo checkEnumMapAccess(DexNode dex, InsnNode checkInsn) {
|
||||
InsnArg sgetArg = checkInsn.getArg(0);
|
||||
InsnArg invArg = checkInsn.getArg(1);
|
||||
if (!sgetArg.isInsnWrap() || !invArg.isInsnWrap()) {
|
||||
@@ -226,7 +223,7 @@ public class ReSugarCode extends AbstractVisitor {
|
||||
if (!inv.getCallMth().getShortId().equals("ordinal()I")) {
|
||||
return null;
|
||||
}
|
||||
ClassNode enumCls = mth.dex().resolveClass(inv.getCallMth().getDeclClass());
|
||||
ClassNode enumCls = dex.resolveClass(inv.getCallMth().getDeclClass());
|
||||
if (enumCls == null || !enumCls.isEnum()) {
|
||||
return null;
|
||||
}
|
||||
@@ -234,7 +231,7 @@ public class ReSugarCode extends AbstractVisitor {
|
||||
if (!(index instanceof FieldInfo)) {
|
||||
return null;
|
||||
}
|
||||
FieldNode enumMapField = mth.dex().resolveField((FieldInfo) index);
|
||||
FieldNode enumMapField = dex.resolveField((FieldInfo) index);
|
||||
if (enumMapField == null || !enumMapField.getAccessFlags().isSynthetic()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user