diff --git a/jadx-core/src/main/java/jadx/core/ProcessClass.java b/jadx-core/src/main/java/jadx/core/ProcessClass.java index c62816230..671d529da 100644 --- a/jadx-core/src/main/java/jadx/core/ProcessClass.java +++ b/jadx-core/src/main/java/jadx/core/ProcessClass.java @@ -1,15 +1,15 @@ package jadx.core; +import java.util.List; + +import org.jetbrains.annotations.Nullable; + import jadx.core.codegen.CodeGen; import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.visitors.DepthTraversal; import jadx.core.dex.visitors.IDexTreeVisitor; import jadx.core.utils.ErrorsCounter; -import java.util.List; - -import org.jetbrains.annotations.Nullable; - import static jadx.core.dex.nodes.ProcessState.GENERATED; import static jadx.core.dex.nodes.ProcessState.NOT_LOADED; import static jadx.core.dex.nodes.ProcessState.PROCESSED; @@ -25,7 +25,7 @@ public final class ProcessClass { if (codeGen == null && cls.getState() == PROCESSED) { return; } - synchronized (cls.getClassInfo()) { + synchronized (getSyncObj(cls)) { try { if (cls.getState() == NOT_LOADED) { cls.load(); @@ -51,6 +51,10 @@ public final class ProcessClass { } } + public static Object getSyncObj(ClassNode cls) { + return cls.getClassInfo(); + } + private static void processDependencies(ClassNode cls, List passes) { for (ClassNode depCls : cls.getDependencies()) { process(depCls, passes, null); diff --git a/jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java b/jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java index 9041a5edf..6d6778c92 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java +++ b/jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java @@ -254,8 +254,9 @@ public class CodeWriter { } private void removeFirstEmptyLine() { - if (buf.indexOf(NL) == 0) { - buf.delete(0, NL.length()); + int len = NL.length(); + if (buf.substring(0, len).equals(NL)) { + buf.delete(0, len); } } diff --git a/jadx-core/src/main/java/jadx/core/codegen/NameGen.java b/jadx-core/src/main/java/jadx/core/codegen/NameGen.java index 535d9007c..e8a6987ae 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/NameGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/NameGen.java @@ -19,6 +19,7 @@ import jadx.core.utils.StringUtils; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; @@ -26,7 +27,7 @@ public class NameGen { private static final Map OBJ_ALIAS; - private final Set varNames = new HashSet<>(); + private final Set varNames = new LinkedHashSet<>(); private final MethodNode mth; private final boolean fallback; diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/PhiInsn.java b/jadx-core/src/main/java/jadx/core/dex/instructions/PhiInsn.java index 6a930d75c..e476fad7e 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/PhiInsn.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/PhiInsn.java @@ -11,6 +11,7 @@ import jadx.core.utils.Utils; import jadx.core.utils.exceptions.JadxRuntimeException; import java.util.IdentityHashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.jetbrains.annotations.NotNull; @@ -21,7 +22,7 @@ public final class PhiInsn extends InsnNode { public PhiInsn(int regNum, int predecessors) { super(InsnType.PHI, predecessors); - this.blockBinds = new IdentityHashMap<>(predecessors); + this.blockBinds = new LinkedHashMap<>(predecessors); setResult(InsnArg.reg(regNum, ArgType.UNKNOWN)); add(AFlag.DONT_INLINE); } diff --git a/jadx-core/src/main/java/jadx/core/dex/regions/conditions/IfInfo.java b/jadx-core/src/main/java/jadx/core/dex/regions/conditions/IfInfo.java index 1d53b2bd3..ed3f8d725 100644 --- a/jadx-core/src/main/java/jadx/core/dex/regions/conditions/IfInfo.java +++ b/jadx-core/src/main/java/jadx/core/dex/regions/conditions/IfInfo.java @@ -16,7 +16,7 @@ public final class IfInfo { private BlockNode ifBlock; public IfInfo(IfCondition condition, BlockNode thenBlock, BlockNode elseBlock) { - this(condition, thenBlock, elseBlock, new HashSet(), new HashSet()); + this(condition, thenBlock, elseBlock, new HashSet<>(), new HashSet<>()); } public IfInfo(IfInfo info, BlockNode thenBlock, BlockNode elseBlock) { diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ReSugarCode.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ReSugarCode.java index b79d781ec..eabebe155 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ReSugarCode.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ReSugarCode.java @@ -1,5 +1,6 @@ package jadx.core.dex.visitors; +import jadx.core.ProcessClass; import jadx.core.dex.attributes.AFlag; import jadx.core.dex.attributes.AType; import jadx.core.dex.attributes.nodes.EnumMapAttr; @@ -141,7 +142,6 @@ public class ReSugarCode extends AbstractVisitor { } enumMapField.add(AFlag.DONT_GENERATE); checkAndHideClass(enumMapField.getParentClass()); - return; } private static EnumMapAttr.KeyValueMap getEnumMap(MethodNode mth, FieldNode field) { @@ -150,33 +150,35 @@ public class ReSugarCode extends AbstractVisitor { if (mapAttr != null) { return mapAttr.getMap(field); } - mapAttr = new EnumMapAttr(); - syntheticClass.addAttr(mapAttr); + synchronized (ProcessClass.getSyncObj(syntheticClass)) { + mapAttr = new EnumMapAttr(); + syntheticClass.addAttr(mapAttr); - MethodNode clsInitMth = syntheticClass.searchMethodByName("()V"); - if (clsInitMth == null || clsInitMth.isNoCode()) { - return null; - } - if (clsInitMth.getBasicBlocks() == null) { - try { - clsInitMth.load(); - } catch (DecodeException e) { - LOG.error("Load failed", e); + MethodNode clsInitMth = syntheticClass.searchMethodByName("()V"); + if (clsInitMth == null || clsInitMth.isNoCode()) { return null; } if (clsInitMth.getBasicBlocks() == null) { - // TODO: - return null; - } - } - for (BlockNode block : clsInitMth.getBasicBlocks()) { - for (InsnNode insn : block.getInstructions()) { - if (insn.getType() == InsnType.APUT) { - addToEnumMap(mth, mapAttr, insn); + try { + clsInitMth.load(); + } catch (DecodeException e) { + LOG.error("Load failed", e); + return null; + } + if (clsInitMth.getBasicBlocks() == null) { + // TODO: + return null; } } + for (BlockNode block : clsInitMth.getBasicBlocks()) { + for (InsnNode insn : block.getInstructions()) { + if (insn.getType() == InsnType.APUT) { + addToEnumMap(mth, mapAttr, insn); + } + } + } + return mapAttr.getMap(field); } - return mapAttr.getMap(field); } private static void addToEnumMap(MethodNode mth, EnumMapAttr mapAttr, InsnNode aputInsn) { diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java b/jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java index abbab0d15..5368a10b6 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java @@ -4,6 +4,7 @@ import java.io.File; import jadx.api.JadxArgs; import jadx.core.codegen.CodeWriter; +import jadx.core.dex.attributes.AFlag; import jadx.core.dex.nodes.ClassNode; public class SaveCode { @@ -11,6 +12,9 @@ public class SaveCode { private SaveCode() {} public static void save(File dir, JadxArgs args, ClassNode cls) { + if (cls.contains(AFlag.DONT_GENERATE)) { + return; + } CodeWriter clsCode = cls.getCode(); String fileName = cls.getClassInfo().getFullPath() + ".java"; if (args.isFallbackMode()) { diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessVariables.java b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessVariables.java index b8541b4d0..aaf814828 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessVariables.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessVariables.java @@ -25,6 +25,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -72,8 +73,8 @@ public class ProcessVariables extends AbstractVisitor { private RegisterArg arg; private VarName varName; private IRegion argRegion; - private final Set usage = new HashSet<>(2); - private final Set assigns = new HashSet<>(2); + private final Set usage = new LinkedHashSet<>(2); + private final Set assigns = new LinkedHashSet<>(2); public void setArg(RegisterArg arg) { this.arg = arg;