fix: improve ClassNode reloading and revert some changes
This commit is contained in:
@@ -8,6 +8,4 @@ public interface ICodeCache {
|
||||
|
||||
@Nullable
|
||||
ICodeInfo get(String clsFullName);
|
||||
|
||||
void remove(String clsFullName);
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,4 @@ public class NoOpCodeCache implements ICodeCache {
|
||||
public @Nullable ICodeInfo get(String clsFullName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(String clsFullName) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,11 +86,5 @@ public class AType<T extends IAttribute> {
|
||||
public static final Set<AType<?>> 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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -64,7 +64,7 @@ public class ConstStorage {
|
||||
this.replaceEnabled = args.isReplaceConsts();
|
||||
}
|
||||
|
||||
public void processConstFields(ClassNode cls, List<FieldNode> staticFields, boolean isRefresh) {
|
||||
public void processConstFields(ClassNode cls, List<FieldNode> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,8 +54,8 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode {
|
||||
private List<ArgType> interfaces;
|
||||
private List<GenericInfo> generics = Collections.emptyList();
|
||||
|
||||
private final List<MethodNode> methods;
|
||||
private final List<FieldNode> fields;
|
||||
private List<MethodNode> methods;
|
||||
private List<FieldNode> fields;
|
||||
private List<ClassNode> 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<FieldNode> staticFields, boolean isRefresh) throws DecodeException {
|
||||
private void loadStaticValues(ClassDef cls, List<FieldNode> 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() {
|
||||
|
||||
@@ -154,10 +154,6 @@ public class MethodNode extends LineAttrNode implements ILoadable, ICodeNode {
|
||||
|
||||
public void checkInstructions() {
|
||||
List<RegisterArg> list = new ArrayList<>();
|
||||
if (instructions == null) {
|
||||
LOG.debug("instructions == null, reloading method {}.{}", getClass().getName(), getName());
|
||||
reload();
|
||||
}
|
||||
for (InsnNode insnNode : instructions) {
|
||||
if (insnNode == null) {
|
||||
continue;
|
||||
|
||||
@@ -105,7 +105,7 @@ public class ClassModifier extends AbstractVisitor {
|
||||
return false;
|
||||
}
|
||||
List<RegisterArg> args = mth.getArgRegs();
|
||||
if (args.isEmpty()) {
|
||||
if (args.isEmpty() || mth.contains(AFlag.SKIP_FIRST_ARG)) {
|
||||
return false;
|
||||
}
|
||||
RegisterArg arg = args.get(0);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<LocalVar> localVars = debugInfoParser.process();
|
||||
attachDebugInfo(mth, localVars, insnArr);
|
||||
|
||||
Reference in New Issue
Block a user