fix(gui): improve code and method search (#2033)
This commit is contained in:
@@ -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) {
|
||||
|
||||
+4
-3
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user