fix(gui): improve code and method search (#2033)

This commit is contained in:
Skylot
2023-10-18 21:52:22 +01:00
parent 1bd4526e4c
commit 15d464d620
10 changed files with 49 additions and 16 deletions
@@ -9,6 +9,7 @@ public class Consts {
public static final boolean DEBUG_EXC_HANDLERS = false;
public static final boolean DEBUG_FINALLY = false;
public static final boolean DEBUG_ATTRIBUTES = false;
public static final boolean DEBUG_RESTRUCTURE = false;
public static final boolean DEBUG_EVENTS = true;
public static final String CLASS_OBJECT = "java.lang.Object";
@@ -9,6 +9,7 @@ import org.slf4j.LoggerFactory;
import jadx.api.ICodeInfo;
import jadx.api.JadxArgs;
import jadx.api.impl.SimpleCodeInfo;
import jadx.core.codegen.CodeGen;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.nodes.ClassNode;
@@ -27,6 +28,8 @@ import static jadx.core.dex.nodes.ProcessState.PROCESS_STARTED;
public class ProcessClass {
private static final Logger LOG = LoggerFactory.getLogger(ProcessClass.class);
private static final ICodeInfo NOT_GENERATED = new SimpleCodeInfo("");
private final List<IDexTreeVisitor> passes;
public ProcessClass(JadxArgs args) {
@@ -101,7 +104,8 @@ public class ProcessClass {
try {
if (cls.contains(AFlag.DONT_GENERATE)) {
process(cls, false);
return ICodeInfo.EMPTY;
LOG.warn("Requested code for class with DONT_GENERATE flag: {}", cls);
return NOT_GENERATED;
}
for (ClassNode depCls : cls.getDependencies()) {
process(depCls, false);
@@ -106,6 +106,10 @@ public final class MethodInfo implements Comparable<MethodInfo> {
return declClass.getFullName() + '.' + name;
}
public String getAliasFullName() {
return declClass.getAliasFullName() + '.' + alias;
}
public String getFullId() {
return declClass.getFullName() + '.' + shortId;
}
@@ -13,6 +13,8 @@ import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.api.DecompilationMode;
import jadx.api.ICodeCache;
@@ -56,6 +58,8 @@ import static jadx.core.dex.nodes.ProcessState.NOT_LOADED;
public class ClassNode extends NotificationAttrNode
implements ILoadable, ICodeNode, IPackageUpdate, Comparable<ClassNode> {
private static final Logger LOG = LoggerFactory.getLogger(ClassNode.class);
private final RootNode root;
private final IClassData clsData;
@@ -381,6 +385,9 @@ public class ClassNode extends NotificationAttrNode
}
ICodeInfo codeInfo;
try {
if (Consts.DEBUG) {
LOG.debug("Decompiling class: {}", this);
}
codeInfo = root.getProcessClasses().generateCode(this);
} catch (Throwable e) {
addError("Code generation failed", e);
@@ -8,6 +8,7 @@ import org.slf4j.LoggerFactory;
import jadx.api.ICodeWriter;
import jadx.api.impl.SimpleCodeWriter;
import jadx.core.Consts;
import jadx.core.codegen.InsnGen;
import jadx.core.codegen.MethodGen;
import jadx.core.dex.attributes.AFlag;
@@ -46,7 +47,8 @@ public class CheckRegions extends AbstractVisitor {
if (blocksInRegions.add(block)) {
return;
}
if (LOG.isDebugEnabled()
if (Consts.DEBUG_RESTRUCTURE
&& LOG.isDebugEnabled()
&& !block.contains(AFlag.RETURN)
&& !block.contains(AFlag.REMOVE)
&& !block.contains(AFlag.SYNTHETIC)
@@ -9,6 +9,7 @@ import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.core.Consts;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.nodes.LoopInfo;
@@ -74,7 +75,9 @@ public class IfMakerHelper {
boolean badThen = isBadBranchBlock(info, thenBlock);
boolean badElse = isBadBranchBlock(info, elseBlock);
if (badThen && badElse) {
LOG.debug("Stop processing blocks after 'if': {}, method: {}", info.getMergedBlocks(), mth);
if (Consts.DEBUG_RESTRUCTURE) {
LOG.debug("Stop processing blocks after 'if': {}, method: {}", info.getMergedBlocks(), mth);
}
return null;
}
if (badElse) {
@@ -182,7 +182,7 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
} catch (JadxOverflowException e) {
throw e;
} catch (Exception e) {
LOG.error("Failed to set immutable type for var: {}", ssaVar, e);
mth.addWarnComment("Failed to set immutable type for var: " + ssaVar, e);
}
}
@@ -192,7 +192,7 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
} catch (JadxOverflowException e) {
throw e;
} catch (Exception e) {
LOG.error("Failed to calculate best type for var: {}", ssaVar, e);
mth.addWarnComment("Failed to calculate best type for var: " + ssaVar, e);
return false;
}
}
@@ -201,7 +201,7 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
TypeInfo typeInfo = ssaVar.getTypeInfo();
Set<ITypeBound> bounds = typeInfo.getBounds();
Optional<ArgType> bestTypeOpt = selectBestTypeFromBounds(bounds);
if (!bestTypeOpt.isPresent()) {
if (bestTypeOpt.isEmpty()) {
if (Consts.DEBUG_TYPE_INFERENCE) {
LOG.warn("Failed to select best type from bounds, count={} : ", bounds.size());
for (ITypeBound bound : bounds) {
@@ -456,6 +456,7 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
return fixed;
}
@SuppressWarnings("RedundantIfStatement")
private boolean deduceType(MethodNode mth, SSAVar var) {
if (var.isTypeImmutable()) {
return false;
@@ -309,7 +309,7 @@ public class BackgroundExecutor {
return "TaskWorker{status=" + status
+ ", jobsCount=" + jobsCount
+ ", jobsComplete=" + jobsComplete
+ ", time=" + time + '}';
+ ", time=" + time + "ms}";
}
}
}
@@ -1,6 +1,7 @@
package jadx.gui.search.providers;
import java.util.List;
import java.util.stream.Collectors;
import org.jetbrains.annotations.Nullable;
@@ -16,7 +17,16 @@ public final class ClassSearchProvider extends BaseSearchProvider {
private int clsNum = 0;
public ClassSearchProvider(MainWindow mw, SearchSettings searchSettings, List<JavaClass> classes) {
super(mw, searchSettings, classes);
super(mw, searchSettings, filterClasses(classes));
}
/**
* Collect top class with code
*/
private static List<JavaClass> filterClasses(List<JavaClass> classes) {
return classes.stream()
.filter(cls -> !cls.isInner() && !cls.isNoCode())
.collect(Collectors.toList());
}
@Override
@@ -5,8 +5,8 @@ import java.util.List;
import org.jetbrains.annotations.Nullable;
import jadx.api.JavaClass;
import jadx.api.JavaMethod;
import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.nodes.MethodNode;
import jadx.gui.jobs.Cancelable;
import jadx.gui.search.SearchSettings;
import jadx.gui.treemodel.JNode;
@@ -28,11 +28,11 @@ public final class MethodSearchProvider extends BaseSearchProvider {
return null;
}
JavaClass cls = classes.get(clsNum);
List<JavaMethod> methods = cls.getMethods();
List<MethodNode> methods = cls.getClassNode().getMethods();
if (mthNum < methods.size()) {
JavaMethod mth = methods.get(mthNum++);
if (checkMth(mth)) {
return convert(mth);
MethodNode mth = methods.get(mthNum++);
if (checkMth(mth.getMethodInfo())) {
return convert(mth.getJavaNode());
}
} else {
clsNum++;
@@ -44,10 +44,11 @@ public final class MethodSearchProvider extends BaseSearchProvider {
}
}
private boolean checkMth(JavaMethod mth) {
MethodInfo mthInfo = mth.getMethodNode().getMethodInfo();
private boolean checkMth(MethodInfo mthInfo) {
return isMatch(mthInfo.getShortId())
|| isMatch(mthInfo.getAlias());
|| isMatch(mthInfo.getAlias())
|| isMatch(mthInfo.getFullId())
|| isMatch(mthInfo.getAliasFullName());
}
@Override