提交 2b300341 编写于 作者: S Skylot

core: improve error reporting for inconsistent code

上级 01fabca3
...@@ -6,7 +6,6 @@ import jadx.core.dex.attributes.AttributeFlag; ...@@ -6,7 +6,6 @@ import jadx.core.dex.attributes.AttributeFlag;
import jadx.core.dex.attributes.AttributeType; import jadx.core.dex.attributes.AttributeType;
import jadx.core.dex.attributes.EnumClassAttr; import jadx.core.dex.attributes.EnumClassAttr;
import jadx.core.dex.attributes.EnumClassAttr.EnumField; import jadx.core.dex.attributes.EnumClassAttr.EnumField;
import jadx.core.dex.attributes.IAttribute;
import jadx.core.dex.attributes.SourceFileAttr; import jadx.core.dex.attributes.SourceFileAttr;
import jadx.core.dex.info.AccessInfo; import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.info.ClassInfo; import jadx.core.dex.info.ClassInfo;
...@@ -236,17 +235,20 @@ public class ClassGen { ...@@ -236,17 +235,20 @@ public class ClassGen {
code.add(';'); code.add(';');
} else { } else {
MethodGen mthGen = new MethodGen(this, mth); MethodGen mthGen = new MethodGen(this, mth);
if (mth.getAttributes().contains(AttributeFlag.INCONSISTENT_CODE)) { boolean badCode = mth.getAttributes().contains(AttributeFlag.INCONSISTENT_CODE);
code.startLine("/* JADX WARNING: inconsistent code */"); if (badCode) {
code.startLine("/* JADX WARNING: inconsistent code. */");
code.startLine("/* Code decompiled incorrectly, please refer to instructions dump. */");
LOG.error(ErrorsCounter.formatErrorMsg(mth, " Inconsistent code")); LOG.error(ErrorsCounter.formatErrorMsg(mth, " Inconsistent code"));
mthGen.makeMethodDump(code);
} }
if (mthGen.addDefinition(code)) { if (mthGen.addDefinition(code)) {
code.add(' '); code.add(' ');
} }
code.add('{'); code.add('{');
code.incIndent();
insertSourceFileInfo(code, mth); insertSourceFileInfo(code, mth);
code.add(mthGen.makeInstructions(code.getIndent())); mthGen.addInstructions(code);
code.decIndent();
code.startLine('}'); code.startLine('}');
} }
} catch (Throwable e) { } catch (Throwable e) {
...@@ -263,6 +265,33 @@ public class ClassGen { ...@@ -263,6 +265,33 @@ public class ClassGen {
private CodeWriter makeFields(CodeWriter clsCode, ClassNode cls, List<FieldNode> fields) throws CodegenException { private CodeWriter makeFields(CodeWriter clsCode, ClassNode cls, List<FieldNode> fields) throws CodegenException {
CodeWriter code = new CodeWriter(clsCode.getIndent() + 1); CodeWriter code = new CodeWriter(clsCode.getIndent() + 1);
addEnumFields(cls, code);
for (FieldNode f : fields) {
if (f.getAttributes().contains(AttributeFlag.DONT_GENERATE)) {
continue;
}
annotationGen.addForField(code, f);
code.startLine(f.getAccessFlags().makeString());
code.add(TypeGen.translate(this, f.getType()));
code.add(' ');
code.add(f.getName());
FieldValueAttr fv = (FieldValueAttr) f.getAttributes().get(AttributeType.FIELD_VALUE);
if (fv != null) {
code.add(" = ");
if (fv.getValue() == null) {
code.add(TypeGen.literalToString(0, f.getType()));
} else {
code.add(annotationGen.encValueToString(fv.getValue()));
}
}
code.add(';');
code.attachAnnotation(f);
}
return code;
}
private void addEnumFields(ClassNode cls, CodeWriter code) throws CodegenException {
EnumClassAttr enumFields = (EnumClassAttr) cls.getAttributes().get(AttributeType.ENUM_CLASS); EnumClassAttr enumFields = (EnumClassAttr) cls.getAttributes().get(AttributeType.ENUM_CLASS);
if (enumFields != null) { if (enumFields != null) {
InsnGen igen = null; InsnGen igen = null;
...@@ -278,7 +307,7 @@ public class ClassGen { ...@@ -278,7 +307,7 @@ public class ClassGen {
MethodGen mthGen = new MethodGen(this, enumFields.getStaticMethod()); MethodGen mthGen = new MethodGen(this, enumFields.getStaticMethod());
igen = new InsnGen(mthGen, enumFields.getStaticMethod(), false); igen = new InsnGen(mthGen, enumFields.getStaticMethod(), false);
} }
code.add(igen.arg(arg)); igen.addArg(code, arg);
if (aIt.hasNext()) { if (aIt.hasNext()) {
code.add(", "); code.add(", ");
} }
...@@ -298,29 +327,6 @@ public class ClassGen { ...@@ -298,29 +327,6 @@ public class ClassGen {
code.add(';'); code.add(';');
code.newLine(); code.newLine();
} }
for (FieldNode f : fields) {
if (f.getAttributes().contains(AttributeFlag.DONT_GENERATE)) {
continue;
}
annotationGen.addForField(code, f);
code.startLine(f.getAccessFlags().makeString());
code.add(TypeGen.translate(this, f.getType()));
code.add(' ');
code.add(f.getName());
FieldValueAttr fv = (FieldValueAttr) f.getAttributes().get(AttributeType.FIELD_VALUE);
if (fv != null) {
code.add(" = ");
if (fv.getValue() == null) {
code.add(TypeGen.literalToString(0, f.getType()));
} else {
code.add(annotationGen.encValueToString(fv.getValue()));
}
}
code.add(';');
code.attachAnnotation(f);
}
return code;
} }
public String useClass(ArgType clsType) { public String useClass(ArgType clsType) {
...@@ -357,9 +363,9 @@ public class ClassGen { ...@@ -357,9 +363,9 @@ public class ClassGen {
} }
private String useClassInternal(ClassInfo useCls, ClassInfo classInfo) { private String useClassInternal(ClassInfo useCls, ClassInfo classInfo) {
String clsStr = classInfo.getFullName(); String fullName = classInfo.getFullName();
if (fallback) { if (fallback) {
return clsStr; return fullName;
} }
String shortName = classInfo.getShortName(); String shortName = classInfo.getShortName();
if (classInfo.getPackage().equals("java.lang") && classInfo.getParentClass() == null) { if (classInfo.getPackage().equals("java.lang") && classInfo.getParentClass() == null) {
...@@ -374,15 +380,15 @@ public class ClassGen { ...@@ -374,15 +380,15 @@ public class ClassGen {
return shortName; return shortName;
} }
if (classInfo.getPackage().equals(useCls.getPackage())) { if (classInfo.getPackage().equals(useCls.getPackage())) {
clsStr = classInfo.getNameWithoutPackage(); fullName = classInfo.getNameWithoutPackage();
} }
if (searchCollision(cls.dex(), useCls, shortName)) { if (searchCollision(cls.dex(), useCls, shortName)) {
return clsStr; return fullName;
} }
for (ClassInfo importCls : imports) { for (ClassInfo importCls : imports) {
if (!importCls.equals(classInfo) if (!importCls.equals(classInfo)
&& importCls.getShortName().equals(shortName)) { && importCls.getShortName().equals(shortName)) {
return clsStr; return fullName;
} }
} }
addImport(classInfo); addImport(classInfo);
...@@ -425,10 +431,9 @@ public class ClassGen { ...@@ -425,10 +431,9 @@ public class ClassGen {
} }
private void insertSourceFileInfo(CodeWriter code, AttrNode node) { private void insertSourceFileInfo(CodeWriter code, AttrNode node) {
IAttribute sourceFileAttr = node.getAttributes().get(AttributeType.SOURCE_FILE); SourceFileAttr sourceFileAttr = (SourceFileAttr) node.getAttributes().get(AttributeType.SOURCE_FILE);
if (sourceFileAttr != null) { if (sourceFileAttr != null) {
code.startLine("// compiled from: "); code.startLine("// compiled from: ").add(sourceFileAttr.getFileName());
code.add(((SourceFileAttr) sourceFileAttr).getFileName());
} }
} }
......
...@@ -12,6 +12,7 @@ import jadx.core.dex.instructions.args.NamedArg; ...@@ -12,6 +12,7 @@ import jadx.core.dex.instructions.args.NamedArg;
import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.regions.Region;
import jadx.core.dex.trycatch.CatchAttr; import jadx.core.dex.trycatch.CatchAttr;
import jadx.core.dex.visitors.DepthTraverser; import jadx.core.dex.visitors.DepthTraverser;
import jadx.core.dex.visitors.FallbackModeVisitor; import jadx.core.dex.visitors.FallbackModeVisitor;
...@@ -227,16 +228,14 @@ public class MethodGen { ...@@ -227,16 +228,14 @@ public class MethodGen {
return r; return r;
} }
public CodeWriter makeInstructions(int mthIndent) throws CodegenException { public void addInstructions(CodeWriter code) throws CodegenException {
CodeWriter code = new CodeWriter(mthIndent + 1);
if (mth.getAttributes().contains(AttributeType.JADX_ERROR)) { if (mth.getAttributes().contains(AttributeType.JADX_ERROR)) {
code.startLine("throw new UnsupportedOperationException(\"Method not decompiled: "); code.startLine("throw new UnsupportedOperationException(\"Method not decompiled: ");
code.add(mth.toString()); code.add(mth.toString());
code.add("\");"); code.add("\");");
JadxErrorAttr err = (JadxErrorAttr) mth.getAttributes().get(AttributeType.JADX_ERROR); JadxErrorAttr err = (JadxErrorAttr) mth.getAttributes().get(AttributeType.JADX_ERROR);
code.startLine("// jadx: method processing error"); code.startLine("/* JADX: method processing error */");
Throwable cause = err.getCause(); Throwable cause = err.getCause();
if (cause != null) { if (cause != null) {
code.newLine(); code.newLine();
...@@ -245,32 +244,35 @@ public class MethodGen { ...@@ -245,32 +244,35 @@ public class MethodGen {
code.add("*/"); code.add("*/");
} }
makeMethodDump(code); makeMethodDump(code);
} else if (mth.getAttributes().contains(AttributeFlag.INCONSISTENT_CODE)) {
code.startLine("/*");
addFallbackMethodCode(code);
code.startLine("*/");
code.newLine();
} else { } else {
if (mth.getRegion() != null) { Region startRegion = mth.getRegion();
CodeWriter insns = new CodeWriter(mthIndent + 1); if (startRegion != null) {
(new RegionGen(this, mth)).makeRegion(insns, mth.getRegion()); (new RegionGen(this, mth)).makeRegion(code, startRegion);
code.add(insns);
} else { } else {
makeFallbackMethod(code, mth); addFallbackMethodCode(code);
} }
} }
return code;
} }
public void makeMethodDump(CodeWriter code) { private void makeMethodDump(CodeWriter code) {
code.startLine("/*"); code.startLine("/*");
getFallbackMethodGen(mth).addDefinition(code); getFallbackMethodGen(mth).addDefinition(code);
code.add(" {"); code.add(" {");
code.incIndent(); code.incIndent();
makeFallbackMethod(code, mth); addFallbackMethodCode(code);
code.decIndent(); code.decIndent();
code.startLine('}'); code.startLine('}');
code.startLine("*/"); code.startLine("*/");
} }
private static void makeFallbackMethod(CodeWriter code, MethodNode mth) { public void addFallbackMethodCode(CodeWriter code) {
if (mth.getInstructions() == null) { if (mth.getInstructions() == null) {
// loadFile original instructions // loadFile original instructions
try { try {
...@@ -285,10 +287,10 @@ public class MethodGen { ...@@ -285,10 +287,10 @@ public class MethodGen {
if (mth.getThisArg() != null) { if (mth.getThisArg() != null) {
code.startLine(getFallbackMethodGen(mth).makeArgName(mth.getThisArg())).add(" = this;"); code.startLine(getFallbackMethodGen(mth).makeArgName(mth.getThisArg())).add(" = this;");
} }
makeFallbackInsns(code, mth, mth.getInstructions(), true); addFallbackInsns(code, mth, mth.getInstructions(), true);
} }
public static void makeFallbackInsns(CodeWriter code, MethodNode mth, List<InsnNode> insns, boolean addLabels) { public static void addFallbackInsns(CodeWriter code, MethodNode mth, List<InsnNode> insns, boolean addLabels) {
InsnGen insnGen = new InsnGen(getFallbackMethodGen(mth), mth, true); InsnGen insnGen = new InsnGen(getFallbackMethodGen(mth), mth, true);
for (InsnNode insn : insns) { for (InsnNode insn : insns) {
AttributesList attrs = insn.getAttributes(); AttributesList attrs = insn.getAttributes();
......
...@@ -165,7 +165,7 @@ public class DotGraphVisitor extends AbstractVisitor { ...@@ -165,7 +165,7 @@ public class DotGraphVisitor extends AbstractVisitor {
return str.toString(); return str.toString();
} else { } else {
CodeWriter code = new CodeWriter(0); CodeWriter code = new CodeWriter(0);
MethodGen.makeFallbackInsns(code, mth, block.getInstructions(), false); MethodGen.addFallbackInsns(code, mth, block.getInstructions(), false);
String str = escape(code.newLine().toString()); String str = escape(code.newLine().toString());
if (str.startsWith(NL)) { if (str.startsWith(NL)) {
str = str.substring(NL.length()); str = str.substring(NL.length());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册