Skip to content

Commit

Permalink
fix: make correct class members loading in jadx api (#742)
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Aug 25, 2019
1 parent 401d08e commit 1cbaad3
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 33 deletions.
88 changes: 66 additions & 22 deletions jadx-core/src/main/java/jadx/api/JadxDecompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -292,61 +292,105 @@ synchronized BinaryXMLParser getXmlParser() {
return xmlParser;
}

Map<ClassNode, JavaClass> getClassesMap() {
return classesMap;
private void loadJavaClass(JavaClass javaClass) {
javaClass.getMethods().forEach(mth -> methodsMap.put(mth.getMethodNode(), mth));
javaClass.getFields().forEach(fld -> fieldsMap.put(fld.getFieldNode(), fld));

for (JavaClass innerCls : javaClass.getInnerClasses()) {
classesMap.put(innerCls.getClassNode(), innerCls);
loadJavaClass(innerCls);
}
}

Map<MethodNode, JavaMethod> getMethodsMap() {
return methodsMap;
@Nullable("For not generated classes")
private JavaClass getJavaClassByNode(ClassNode cls) {
JavaClass javaClass = classesMap.get(cls);
if (javaClass != null) {
return javaClass;
}
// load parent class if inner
ClassNode parentClass = cls.getTopParentClass();
if (parentClass.contains(AFlag.DONT_GENERATE)) {
return null;
}
if (parentClass != cls) {
JavaClass parentJavaClass = classesMap.get(parentClass);
if (parentJavaClass == null) {
getClasses();
parentJavaClass = classesMap.get(parentClass);
}
loadJavaClass(parentJavaClass);
javaClass = classesMap.get(cls);
if (javaClass != null) {
return javaClass;
}
}
throw new JadxRuntimeException("JavaClass not found by ClassNode: " + cls);
}

JavaMethod getJavaMethodByNode(MethodNode mth) {
@Nullable
private JavaMethod getJavaMethodByNode(MethodNode mth) {
JavaMethod javaMethod = methodsMap.get(mth);
if (javaMethod != null) {
return javaMethod;
}
// parent class not loaded yet
JavaClass javaClass = classesMap.get(mth.getParentClass());
if (javaClass != null) {
javaClass.decompile();
return methodsMap.get(mth);
JavaClass javaClass = getJavaClassByNode(mth.getParentClass().getTopParentClass());
if (javaClass == null) {
return null;
}
return null;
}

Map<FieldNode, JavaField> getFieldsMap() {
return fieldsMap;
loadJavaClass(javaClass);
javaMethod = methodsMap.get(mth);
if (javaMethod != null) {
return javaMethod;
}
if (mth.getParentClass().hasNotGeneratedParent()) {
return null;
}
throw new JadxRuntimeException("JavaMethod not found by MethodNode: " + mth);
}

JavaField getJavaFieldByNode(FieldNode fld) {
@Nullable
private JavaField getJavaFieldByNode(FieldNode fld) {
JavaField javaField = fieldsMap.get(fld);
if (javaField != null) {
return javaField;
}
// parent class not loaded yet
JavaClass javaClass = classesMap.get(fld.getParentClass());
if (javaClass != null) {
javaClass.decompile();
return fieldsMap.get(fld);
JavaClass javaClass = getJavaClassByNode(fld.getParentClass().getTopParentClass());
if (javaClass == null) {
return null;
}
return null;
loadJavaClass(javaClass);
javaField = fieldsMap.get(fld);
if (javaField != null) {
return javaField;
}
if (fld.getParentClass().hasNotGeneratedParent()) {
return null;
}
throw new JadxRuntimeException("JavaField not found by FieldNode: " + fld);
}

@Nullable
JavaNode convertNode(Object obj) {
if (!(obj instanceof LineAttrNode)) {
return null;
}
LineAttrNode node = (LineAttrNode) obj;
if (node.contains(AFlag.DONT_GENERATE)) {
return null;
}
if (obj instanceof ClassNode) {
return getClassesMap().get(obj);
return getJavaClassByNode((ClassNode) obj);
}
if (obj instanceof MethodNode) {
return getJavaMethodByNode(((MethodNode) obj));
}
if (obj instanceof FieldNode) {
return getJavaFieldByNode((FieldNode) obj);
}
return null;
throw new JadxRuntimeException("Unexpected node type: " + obj);
}

@Nullable
Expand Down
13 changes: 3 additions & 10 deletions jadx-core/src/main/java/jadx/api/JavaClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.jetbrains.annotations.Nullable;

import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.nodes.LineAttrNode;
import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.FieldNode;
Expand Down Expand Up @@ -78,7 +77,6 @@ private void loadLists() {
listsLoaded = true;
decompile();

JadxDecompiler rootDecompiler = getRootDecompiler();
int inClsCount = cls.getInnerClasses().size();
if (inClsCount != 0) {
List<JavaClass> list = new ArrayList<>(inClsCount);
Expand All @@ -87,7 +85,6 @@ private void loadLists() {
JavaClass javaClass = new JavaClass(inner, this);
javaClass.loadLists();
list.add(javaClass);
rootDecompiler.getClassesMap().put(inner, javaClass);
}
}
this.innerClasses = Collections.unmodifiableList(list);
Expand All @@ -100,7 +97,6 @@ private void loadLists() {
if (!f.contains(AFlag.DONT_GENERATE)) {
JavaField javaField = new JavaField(f, this);
flds.add(javaField);
rootDecompiler.getFieldsMap().put(f, javaField);
}
}
this.fields = Collections.unmodifiableList(flds);
Expand All @@ -113,7 +109,6 @@ private void loadLists() {
if (!m.contains(AFlag.DONT_GENERATE)) {
JavaMethod javaMethod = new JavaMethod(this, m);
mths.add(javaMethod);
rootDecompiler.getMethodsMap().put(m, javaMethod);
}
}
mths.sort(Comparator.comparing(JavaMethod::getName));
Expand Down Expand Up @@ -145,11 +140,9 @@ public Map<CodePosition, JavaNode> getUsageMap() {
for (Map.Entry<CodePosition, Object> entry : map.entrySet()) {
CodePosition codePosition = entry.getKey();
Object obj = entry.getValue();
if (obj instanceof LineAttrNode) {
JavaNode node = getRootDecompiler().convertNode(obj);
if (node != null) {
resultMap.put(codePosition, node);
}
JavaNode node = getRootDecompiler().convertNode(obj);
if (node != null) {
resultMap.put(codePosition, node);
}
}
return resultMap;
Expand Down
4 changes: 4 additions & 0 deletions jadx-core/src/main/java/jadx/api/JavaField.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public int getDecompiledLine() {
return field.getDecompiledLine();
}

FieldNode getFieldNode() {
return field;
}

@Override
public int hashCode() {
return field.hashCode();
Expand Down
4 changes: 4 additions & 0 deletions jadx-core/src/main/java/jadx/api/JavaMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ public int getDecompiledLine() {
return mth.getDecompiledLine();
}

MethodNode getMethodNode() {
return mth;
}

@Override
public int hashCode() {
return mth.hashCode();
Expand Down
12 changes: 12 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 @@ -414,6 +414,17 @@ public ClassNode getTopParentClass() {
return parent == this ? this : parent.getTopParentClass();
}

public boolean hasNotGeneratedParent() {
if (contains(AFlag.DONT_GENERATE)) {
return true;
}
ClassNode parent = getParentClass();
if (parent == this) {
return false;
}
return parent.hasNotGeneratedParent();
}

public List<ClassNode> getInnerClasses() {
return innerClasses;
}
Expand Down Expand Up @@ -543,4 +554,5 @@ public boolean equals(Object o) {
public String toString() {
return clsInfo.getFullName();
}

}
2 changes: 2 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/JadxGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jadx.cli.LogHelper;
import jadx.gui.settings.JadxSettings;
import jadx.gui.settings.JadxSettingsAdapter;
import jadx.gui.ui.MainWindow;
Expand All @@ -18,6 +19,7 @@ public static void main(String[] args) {
try {
LogCollector.register();
final JadxSettings settings = JadxSettingsAdapter.load();
settings.setLogLevel(LogHelper.LogLevelEnum.INFO);
// overwrite loaded settings by command line arguments
if (!settings.overrideProvided(args)) {
return;
Expand Down
8 changes: 7 additions & 1 deletion jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import jadx.api.JadxArgs;
import jadx.cli.JadxCLIArgs;
import jadx.cli.LogHelper;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.codearea.EditorTheme;
import jadx.gui.utils.FontUtils;
Expand All @@ -40,7 +41,8 @@ public class JadxSettings extends JadxCLIArgs {

static final Set<String> SKIP_FIELDS = new HashSet<>(Arrays.asList(
"files", "input", "outDir", "outDirSrc", "outDirRes", "outputFormat",
"verbose", "printVersion", "printHelp"));
"verbose", "quiet", "logLevel",
"printVersion", "printHelp"));

private Path lastSaveProjectPath = USER_HOME;
private Path lastOpenFilePath = USER_HOME;
Expand Down Expand Up @@ -359,6 +361,10 @@ public void setFont(@Nullable Font font) {
}
}

public void setLogLevel(LogHelper.LogLevelEnum level) {
this.logLevel = level;
}

public String getEditorThemePath() {
return editorThemePath;
}
Expand Down

0 comments on commit 1cbaad3

Please sign in to comment.