diff --git a/jadx-core/src/main/java/jadx/api/ICodeCache.java b/jadx-core/src/main/java/jadx/api/ICodeCache.java index bc121067b..a078f79cf 100644 --- a/jadx-core/src/main/java/jadx/api/ICodeCache.java +++ b/jadx-core/src/main/java/jadx/api/ICodeCache.java @@ -8,6 +8,4 @@ public interface ICodeCache { @Nullable ICodeInfo get(String clsFullName); - - void remove(String clsFullName); } diff --git a/jadx-core/src/main/java/jadx/api/JavaClass.java b/jadx-core/src/main/java/jadx/api/JavaClass.java index 67d4aba53..8227771da 100644 --- a/jadx-core/src/main/java/jadx/api/JavaClass.java +++ b/jadx-core/src/main/java/jadx/api/JavaClass.java @@ -57,8 +57,9 @@ public final class JavaClass implements JavaNode { cls.decompile(); } - public void refresh() { - cls.refresh(); + public synchronized void refresh() { + listsLoaded = false; + cls.reloadCode(); } public synchronized String getSmali() { diff --git a/jadx-core/src/main/java/jadx/api/impl/InMemoryCodeCache.java b/jadx-core/src/main/java/jadx/api/impl/InMemoryCodeCache.java index 8f36b4c0e..04d80fef8 100644 --- a/jadx-core/src/main/java/jadx/api/impl/InMemoryCodeCache.java +++ b/jadx-core/src/main/java/jadx/api/impl/InMemoryCodeCache.java @@ -21,9 +21,4 @@ public class InMemoryCodeCache implements ICodeCache { public @Nullable ICodeInfo get(String clsFullName) { return storage.get(clsFullName); } - - @Override - public void remove(String clsFullName) { - storage.remove(clsFullName); - } } diff --git a/jadx-core/src/main/java/jadx/api/impl/NoOpCodeCache.java b/jadx-core/src/main/java/jadx/api/impl/NoOpCodeCache.java index cf738372c..f764cde4e 100644 --- a/jadx-core/src/main/java/jadx/api/impl/NoOpCodeCache.java +++ b/jadx-core/src/main/java/jadx/api/impl/NoOpCodeCache.java @@ -16,8 +16,4 @@ public class NoOpCodeCache implements ICodeCache { public @Nullable ICodeInfo get(String clsFullName) { return null; } - - @Override - public void remove(String clsFullName) { - } } diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/AType.java b/jadx-core/src/main/java/jadx/core/dex/attributes/AType.java index 5fb276d45..2cdab5b73 100644 --- a/jadx-core/src/main/java/jadx/core/dex/attributes/AType.java +++ b/jadx-core/src/main/java/jadx/core/dex/attributes/AType.java @@ -86,11 +86,5 @@ public class AType { public static final Set> SKIP_ON_UNLOAD = new HashSet<>(Arrays.asList( FIELD_REPLACE, METHOD_INLINE, - COMMENTS, - RENAME_REASON, - JADX_WARN, - JADX_ERROR, - FIELD_INIT, - SOURCE_FILE, SKIP_MTH_ARGS)); } diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/RenameReasonAttr.java b/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/RenameReasonAttr.java index b56dd409c..028182295 100644 --- a/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/RenameReasonAttr.java +++ b/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/RenameReasonAttr.java @@ -46,7 +46,7 @@ public class RenameReasonAttr implements IAttribute { public RenameReasonAttr append(String reason) { if (description.isEmpty()) { description += reason; - } else if (!description.contains(reason)) { + } else { description += " and " + reason; } return this; diff --git a/jadx-core/src/main/java/jadx/core/dex/info/ConstStorage.java b/jadx-core/src/main/java/jadx/core/dex/info/ConstStorage.java index 5e19520d3..fbd706150 100644 --- a/jadx-core/src/main/java/jadx/core/dex/info/ConstStorage.java +++ b/jadx-core/src/main/java/jadx/core/dex/info/ConstStorage.java @@ -64,7 +64,7 @@ public class ConstStorage { this.replaceEnabled = args.isReplaceConsts(); } - public void processConstFields(ClassNode cls, List staticFields, boolean isRefresh) { + public void processConstFields(ClassNode cls, List staticFields) { if (!replaceEnabled || staticFields.isEmpty()) { return; } @@ -76,9 +76,7 @@ public class ConstStorage { && fv.getValue() != null && fv.getValueType() == FieldInitAttr.InitType.CONST && fv != FieldInitAttr.NULL_VALUE) { - if (!isRefresh) { - addConstField(cls, f, fv.getValue(), accFlags.isPublic()); - } + addConstField(cls, f, fv.getValue(), accFlags.isPublic()); } } } diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java index 7968f7a04..00f3b0390 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java @@ -54,8 +54,8 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode { private List interfaces; private List generics = Collections.emptyList(); - private final List methods; - private final List fields; + private List methods; + private List fields; private List innerClasses = Collections.emptyList(); // store smali @@ -74,6 +74,10 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode { this.cls = cls; this.clsDefOffset = cls.getOffset(); this.clsInfo = ClassInfo.fromDex(dex, cls.getTypeIndex()); + initialLoad(); + } + + private void initialLoad() { try { if (cls.getSupertypeIndex() == DexNode.NO_INDEX) { this.superClass = null; @@ -102,7 +106,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode { for (Field f : clsData.getStaticFields()) { fields.add(new FieldNode(this, f)); } - loadStaticValues(cls, fields, false); + loadStaticValues(cls, fields); for (Field f : clsData.getInstanceFields()) { fields.add(new FieldNode(this, f)); } @@ -169,7 +173,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode { } } - private void loadStaticValues(ClassDef cls, List staticFields, boolean isRefresh) throws DecodeException { + private void loadStaticValues(ClassDef cls, List staticFields) throws DecodeException { for (FieldNode f : staticFields) { AccessInfo flags = f.getAccessFlags(); if (flags.isStatic() && flags.isFinal()) { @@ -186,7 +190,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode { parser.processFields(staticFields); // process const fields - root().getConstValues().processConstFields(this, staticFields, isRefresh); + root().getConstValues().processConstFields(this, staticFields); } private void parseClassSignature() { @@ -275,7 +279,11 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode { return decompile(true); } - public ICodeInfo reloadCode() { + public synchronized ICodeInfo reloadCode() { + unload(); + clearAttributes(); + initialLoad(); + load(); return decompile(false); } @@ -294,36 +302,6 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode { return codeInfo; } - public synchronized ICodeInfo refresh() { - reloadRecursive(); - return decompile(false); - } - - private void reloadRecursive() { - load(); - int sfIdx = cls.getSourceFileIndex(); - if (sfIdx != DexNode.NO_INDEX) { - String fileName = dex.getString(sfIdx); - addSourceFilenameAttr(fileName); - } - for (ClassNode innerCls : getInnerClasses()) { - innerCls.reloadRecursive(); - } - loadStaticInfo(); - loadAnnotations(cls); - } - - private void loadStaticInfo() { - try { - if (cls != null) { - loadStaticValues(cls, fields, true); - } - } catch (DecodeException e) { - LOG.error("Got DecodeException in loadStaticValues() for class {}", getRawName()); - e.printStackTrace(); - } - } - @Override public void load() { for (MethodNode mth : getMethods()) { @@ -346,6 +324,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode { fields.forEach(FieldNode::unloadAttributes); unloadAttributes(); setState(NOT_LOADED); + this.smali = null; } private void buildCache() { diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java index 889f2ff2c..5006bb30e 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java @@ -154,10 +154,6 @@ public class MethodNode extends LineAttrNode implements ILoadable, ICodeNode { public void checkInstructions() { List list = new ArrayList<>(); - if (instructions == null) { - LOG.debug("instructions == null, reloading method {}.{}", getClass().getName(), getName()); - reload(); - } for (InsnNode insnNode : instructions) { if (insnNode == null) { continue; diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ClassModifier.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ClassModifier.java index 5518f4e82..508adb3e3 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ClassModifier.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ClassModifier.java @@ -105,7 +105,7 @@ public class ClassModifier extends AbstractVisitor { return false; } List args = mth.getArgRegs(); - if (args.isEmpty()) { + if (args.isEmpty() || mth.contains(AFlag.SKIP_FIRST_ARG)) { return false; } RegisterArg arg = args.get(0); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/EnumVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/EnumVisitor.java index 88868f35e..d016a37c9 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/EnumVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/EnumVisitor.java @@ -5,6 +5,8 @@ import java.util.List; import org.jetbrains.annotations.Nullable; +import com.android.dx.rop.code.AccessFlags; + import jadx.core.codegen.TypeGen; import jadx.core.deobf.NameMapper; import jadx.core.dex.attributes.AFlag; @@ -45,7 +47,8 @@ public class EnumVisitor extends AbstractVisitor { if (!convertToEnum(cls)) { AccessInfo accessFlags = cls.getAccessFlags(); if (accessFlags.isEnum()) { - cls.addAttr(AType.COMMENTS, "'enum' modifier should be removed"); + cls.setAccessFlags(accessFlags.remove(AccessFlags.ACC_ENUM)); + cls.addAttr(AType.COMMENTS, "'enum' modifier removed"); } } return true; diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/debuginfo/DebugInfoParseVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/debuginfo/DebugInfoParseVisitor.java index e21b5734d..3bc4368ae 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/debuginfo/DebugInfoParseVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/debuginfo/DebugInfoParseVisitor.java @@ -48,15 +48,6 @@ public class DebugInfoParseVisitor extends AbstractVisitor { private void processDebugInfo(MethodNode mth, int debugOffset) { InsnNode[] insnArr = mth.getInstructions(); - if (insnArr == null) { - LOG.debug("insnArr == null, reloading method {}.{}", getClass().getName(), mth.getName()); - mth.reload(); - insnArr = mth.getInstructions(); - } - if (insnArr == null) { - LOG.error("insnArr == null even after reloading method {}.{} - bailing", getClass().getName(), mth.getName()); - return; - } DebugInfoParser debugInfoParser = new DebugInfoParser(mth, debugOffset, insnArr); List localVars = debugInfoParser.process(); attachDebugInfo(mth, localVars, insnArr);