Skip to content

Commit

Permalink
fix: change resource fields generations in R class (#308)
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Sep 8, 2018
1 parent 5de4d07 commit f6f883b
Show file tree
Hide file tree
Showing 13 changed files with 145 additions and 92 deletions.
14 changes: 8 additions & 6 deletions jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.parser.FieldInitAttr;
import jadx.core.dex.nodes.parser.FieldInitAttr.InitType;
import jadx.core.utils.CodegenUtils;
import jadx.core.utils.ErrorsCounter;
import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.CodegenException;
Expand Down Expand Up @@ -105,9 +106,8 @@ public void addClassCode(CodeWriter code) throws CodegenException {
if (cls.contains(AFlag.DONT_GENERATE)) {
return;
}
if (cls.contains(AFlag.INCONSISTENT_CODE)) {
code.startLine("// jadx: inconsistent code");
}
CodegenUtils.addComments(code, cls);
insertDecompilationProblems(code, cls);
addClassDeclaration(code);
addClassBody(code);
}
Expand Down Expand Up @@ -296,6 +296,7 @@ private void addMethod(CodeWriter code, MethodNode mth) throws CodegenException
}
code.add(';');
} else {
CodegenUtils.addComments(code, mth);
insertDecompilationProblems(code, mth);
boolean badCode = mth.contains(AFlag.INCONSISTENT_CODE);
if (badCode && showInconsistentCode) {
Expand Down Expand Up @@ -325,9 +326,9 @@ private void addMethod(CodeWriter code, MethodNode mth) throws CodegenException
}
}

private void insertDecompilationProblems(CodeWriter code, MethodNode mth) {
List<JadxError> errors = mth.getAll(AType.JADX_ERROR);
List<JadxWarn> warns = mth.getAll(AType.JADX_WARN);
private void insertDecompilationProblems(CodeWriter code, AttrNode node) {
List<JadxError> errors = node.getAll(AType.JADX_ERROR);
List<JadxWarn> warns = node.getAll(AType.JADX_WARN);
if (!errors.isEmpty()) {
errors.forEach(err -> {
code.startLine("/* JADX ERROR: ").add(err.getError());
Expand All @@ -351,6 +352,7 @@ private void addFields(CodeWriter code) throws CodegenException {
if (f.contains(AFlag.DONT_GENERATE)) {
continue;
}
CodegenUtils.addComments(code, f);
annotationGen.addForField(code, f);

if (f.getFieldInfo().isRenamed()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class AType<T extends IAttribute> {

public static final AType<AttrList<JadxError>> JADX_ERROR = new AType<>();
public static final AType<AttrList<JadxWarn>> JADX_WARN = new AType<>();
public static final AType<AttrList<String>> COMMENTS = new AType<>();

public static final AType<ExcHandlerAttr> EXC_HANDLER = new AType<>();
public static final AType<CatchAttr> CATCH_BLOCK = new AType<>();
Expand Down
39 changes: 32 additions & 7 deletions jadx-core/src/main/java/jadx/core/dex/info/ConstStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.DexNode;
import jadx.core.dex.nodes.FieldNode;
import jadx.core.dex.nodes.ResRefField;
import jadx.core.dex.nodes.parser.FieldInitAttr;
import jadx.core.utils.ErrorsCounter;

public class ConstStorage {

Expand Down Expand Up @@ -101,16 +101,16 @@ private ValueStorage getClsValues(ClassNode cls) {

@Nullable
public FieldNode getConstField(ClassNode cls, Object value, boolean searchGlobal) {
if (!replaceEnabled) {
return null;
}
DexNode dex = cls.dex();
if (value instanceof Integer) {
String str = resourcesNames.get(value);
if (str != null) {
return new ResRefField(dex, str.replace('/', '.'));
FieldNode rField = getResourceField((Integer) value, dex);
if (rField != null) {
return rField;
}
}
if (!replaceEnabled) {
return null;
}
boolean foundInGlobal = globalValues.contains(value);
if (foundInGlobal && !searchGlobal) {
return null;
Expand Down Expand Up @@ -139,6 +139,31 @@ public FieldNode getConstField(ClassNode cls, Object value, boolean searchGlobal
return null;
}

@Nullable
private FieldNode getResourceField(Integer value, DexNode dex) {
String str = resourcesNames.get(value);
if (str == null) {
return null;
}
ClassNode appResClass = dex.root().getAppResClass();
if (appResClass == null) {
return null;
}
String[] parts = str.split("/", 2);
if (parts.length != 2) {
return null;
}
String typeName = parts[0];
String fieldName = parts[1];
for (ClassNode innerClass : appResClass.getInnerClasses()) {
if (innerClass.getShortName().equals(typeName)) {
return innerClass.searchFieldByName(fieldName);
}
}
ErrorsCounter.classWarn(appResClass, "Not found resource field with id: " + value + ", name: " + str.replace('/', '.'));
return null;
}

@Nullable
public FieldNode getConstFieldByLiteralArg(ClassNode cls, LiteralArg arg) {
PrimitiveType type = arg.getType().getPrimitiveType();
Expand Down
21 changes: 10 additions & 11 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,7 +13,6 @@
import com.android.dex.ClassData.Method;
import com.android.dex.ClassDef;
import com.android.dex.Dex;
import com.android.dx.rop.code.AccessFlags;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -51,7 +50,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {

private final List<MethodNode> methods;
private final List<FieldNode> fields;
private List<ClassNode> innerClasses = Collections.emptyList();
private List<ClassNode> innerClasses = new ArrayList<>();

// store decompiled code
private CodeWriter code;
Expand Down Expand Up @@ -132,14 +131,16 @@ public ClassNode(DexNode dex, ClassDef cls) {
}

// empty synthetic class
public ClassNode(DexNode dex, ClassInfo clsInfo) {
public ClassNode(DexNode dex, String name, int accessFlags) {
this.dex = dex;
this.clsInfo = clsInfo;
this.interfaces = Collections.emptyList();
this.methods = Collections.emptyList();
this.fields = Collections.emptyList();
this.accessFlags = new AccessInfo(AccessFlags.ACC_PUBLIC | AccessFlags.ACC_SYNTHETIC, AFType.CLASS);
this.clsInfo = ClassInfo.fromName(dex.root(), name);
this.interfaces = new ArrayList<>();
this.methods = new ArrayList<>();
this.fields = new ArrayList<>();
this.accessFlags = new AccessInfo(accessFlags, AFType.CLASS);
this.parentClass = this;

dex.addClassNode(this);
}

private void loadAnnotations(ClassDef cls) {
Expand Down Expand Up @@ -368,10 +369,8 @@ public List<ClassNode> getInnerClasses() {
}

public void addInnerClass(ClassNode cls) {
if (innerClasses.isEmpty()) {
innerClasses = new ArrayList<>(3);
}
innerClasses.add(cls);
cls.parentClass = this;
}

public boolean isEnum() {
Expand Down
9 changes: 6 additions & 3 deletions jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,15 @@ public DexNode(RootNode root, DexFile input, int dexId) {

public void loadClasses() {
for (ClassDef cls : dexBuf.classDefs()) {
ClassNode clsNode = new ClassNode(this, cls);
classes.add(clsNode);
clsMap.put(clsNode.getClassInfo(), clsNode);
addClassNode(new ClassNode(this, cls));
}
}

public void addClassNode(ClassNode clsNode) {
classes.add(clsNode);
clsMap.put(clsNode.getClassInfo(), clsNode);
}

void initInnerClasses() {
// move inner classes
List<ClassNode> inner = new ArrayList<>();
Expand Down
15 changes: 0 additions & 15 deletions jadx-core/src/main/java/jadx/core/dex/nodes/ResRefField.java

This file was deleted.

7 changes: 5 additions & 2 deletions jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@ public class RootNode {
private final ConstStorage constValues;
private final InfoStorage infoStorage = new InfoStorage();

private ClspGraph clsp;
private List<DexNode> dexNodes;
@Nullable
private String appPackage;
@Nullable
private ClassNode appResClass;
private ClspGraph clsp;

public RootNode(JadxArgs args) {
this.args = args;
Expand Down Expand Up @@ -90,8 +91,10 @@ public void loadResources(List<ResourceFile> resources) {
LOG.error("Failed to parse '.arsc' file", e);
return;
}
processResources(parser.getResStorage());
}

ResourceStorage resStorage = parser.getResStorage();
public void processResources(ResourceStorage resStorage) {
constValues.setResourcesNames(resStorage.getResourcesNames());
appPackage = resStorage.getAppPackage();
appResClass = AndroidResourcesUtils.searchAppResClass(this, resStorage);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public boolean visit(ClassNode cls) throws JadxException {
}
}
if (staticMethod == null) {
ErrorsCounter.classError(cls, "Enum class init method not found");
ErrorsCounter.classWarn(cls, "Enum class init method not found");
return true;
}

Expand Down
14 changes: 14 additions & 0 deletions jadx-core/src/main/java/jadx/core/utils/CodegenUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package jadx.core.utils;

import jadx.core.codegen.CodeWriter;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.AttrNode;

public class CodegenUtils {

public static void addComments(CodeWriter code, AttrNode node) {
for (String comment : node.getAll(AType.COMMENTS)) {
code.startLine("/* ").add(comment).add(" */");
}
}
}
4 changes: 2 additions & 2 deletions jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ public static String classError(ClassNode cls, String errorMsg, Throwable e) {
return cls.dex().root().getErrorsCounter().addError(cls, errorMsg, e);
}

public static String classError(ClassNode cls, String errorMsg) {
return classError(cls, errorMsg, null);
public static String classWarn(ClassNode cls, String warnMsg) {
return cls.dex().root().getErrorsCounter().addWarning(cls, warnMsg);
}

public static String methodError(MethodNode mth, String errorMsg, Throwable e) {
Expand Down
Loading

0 comments on commit f6f883b

Please sign in to comment.