Skip to content

Commit

Permalink
fix(gui): improve code and method search (#2033)
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Oct 18, 2023
1 parent 1bd4526 commit 15d464d
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 16 deletions.
1 change: 1 addition & 0 deletions jadx-core/src/main/java/jadx/core/Consts.java
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
6 changes: 5 additions & 1 deletion jadx-core/src/main/java/jadx/core/ProcessClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

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;
Expand All @@ -27,6 +28,8 @@
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) {
Expand Down Expand Up @@ -101,7 +104,8 @@ public ICodeInfo generateCode(ClassNode cls) {
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);
Expand Down
4 changes: 4 additions & 0 deletions jadx-core/src/main/java/jadx/core/dex/info/MethodInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ public String getFullName() {
return declClass.getFullName() + '.' + name;
}

public String getAliasFullName() {
return declClass.getAliasFullName() + '.' + alias;
}

public String getFullId() {
return declClass.getFullName() + '.' + shortId;
}
Expand Down
7 changes: 7 additions & 0 deletions jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

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;
Expand Down Expand Up @@ -56,6 +58,8 @@

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;

Expand Down Expand Up @@ -381,6 +385,9 @@ private synchronized ICodeInfo decompile(boolean searchInCache) {
}
ICodeInfo codeInfo;
try {
if (Consts.DEBUG) {
LOG.debug("Decompiling class: {}", this);
}
codeInfo = root.getProcessClasses().generateCode(this);
} catch (Throwable e) {
addError("Code generation failed", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

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;
Expand Down Expand Up @@ -46,7 +47,8 @@ public void processBlock(MethodNode mth, IBlock container) {
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
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;
Expand Down Expand Up @@ -74,7 +75,9 @@ static IfInfo restructureIf(MethodNode mth, BlockNode block, IfInfo info) {
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ private void setImmutableType(MethodNode mth, SSAVar ssaVar) {
} 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);
}
}

Expand All @@ -192,7 +192,7 @@ private boolean setBestType(MethodNode mth, SSAVar ssaVar) {
} 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;
}
}
Expand All @@ -201,7 +201,7 @@ private boolean calculateFromBounds(MethodNode mth, SSAVar ssaVar) {
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) {
Expand Down Expand Up @@ -456,6 +456,7 @@ private boolean tryDeduceTypes(MethodNode mth) {
return fixed;
}

@SuppressWarnings("RedundantIfStatement")
private boolean deduceType(MethodNode mth, SSAVar var) {
if (var.isTypeImmutable()) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ public String toString() {
return "TaskWorker{status=" + status
+ ", jobsCount=" + jobsCount
+ ", jobsComplete=" + jobsComplete
+ ", time=" + time + '}';
+ ", time=" + time + "ms}";
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jadx.gui.search.providers;

import java.util.List;
import java.util.stream.Collectors;

import org.jetbrains.annotations.Nullable;

Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
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;
Expand All @@ -28,11 +28,11 @@ public MethodSearchProvider(MainWindow mw, SearchSettings searchSettings, List<J
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++;
Expand All @@ -44,10 +44,11 @@ public MethodSearchProvider(MainWindow mw, SearchSettings searchSettings, List<J
}
}

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
Expand Down

0 comments on commit 15d464d

Please sign in to comment.