Commit 8da0ba82 authored by Skylot's avatar Skylot

Save source file name, move constant strings

parent 35ee0a25
...@@ -15,5 +15,11 @@ public class Consts { ...@@ -15,5 +15,11 @@ public class Consts {
public static final String CLASS_STRING_BUILDER = "java.lang.StringBuilder"; public static final String CLASS_STRING_BUILDER = "java.lang.StringBuilder";
public static final String DALVIK_ANNOTATION_PKG = "dalvik.annotation.";
public static final String DALVIK_SIGNATURE = "dalvik.annotation.Signature"; public static final String DALVIK_SIGNATURE = "dalvik.annotation.Signature";
public static final String DALVIK_INNER_CLASS = "dalvik.annotation.InnerClass";
public static final String DALVIK_THROWS = "dalvik.annotation.Throws";
public static final String DALVIK_ANNOTATION_DEFAULT = "dalvik.annotation.AnnotationDefault";
public static final String DEFAULT_PACKAGE_NAME = "defpackage";
} }
...@@ -59,7 +59,7 @@ public class AnnotationGen { ...@@ -59,7 +59,7 @@ public class AnnotationGen {
for (Annotation a : aList.getAll()) { for (Annotation a : aList.getAll()) {
String aCls = a.getAnnotationClass(); String aCls = a.getAnnotationClass();
if (aCls.startsWith("dalvik.annotation.")) { if (aCls.startsWith(Consts.DALVIK_ANNOTATION_PKG)) {
// skip // skip
if (Consts.DEBUG) { if (Consts.DEBUG) {
code.startLine("// " + a); code.startLine("// " + a);
...@@ -97,7 +97,7 @@ public class AnnotationGen { ...@@ -97,7 +97,7 @@ public class AnnotationGen {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void addThrows(MethodNode mth, CodeWriter code) { public void addThrows(MethodNode mth, CodeWriter code) {
Annotation an = mth.getAttributes().getAnnotation("dalvik.annotation.Throws"); Annotation an = mth.getAttributes().getAnnotation(Consts.DALVIK_THROWS);
if (an != null) { if (an != null) {
Object exs = an.getDefaultValue(); Object exs = an.getDefaultValue();
code.add(" throws "); code.add(" throws ");
...@@ -111,7 +111,7 @@ public class AnnotationGen { ...@@ -111,7 +111,7 @@ public class AnnotationGen {
} }
public Object getAnnotationDefaultValue(String name) { public Object getAnnotationDefaultValue(String name) {
Annotation an = cls.getAttributes().getAnnotation("dalvik.annotation.AnnotationDefault"); Annotation an = cls.getAttributes().getAnnotation(Consts.DALVIK_ANNOTATION_DEFAULT);
if (an != null) { if (an != null) {
Annotation defAnnotation = (Annotation) an.getDefaultValue(); Annotation defAnnotation = (Annotation) an.getDefaultValue();
return defAnnotation.getValues().get(name); return defAnnotation.getValues().get(name);
......
package jadx.codegen; package jadx.codegen;
import jadx.Consts; import jadx.Consts;
import jadx.dex.attributes.AttrNode;
import jadx.dex.attributes.AttributeFlag; import jadx.dex.attributes.AttributeFlag;
import jadx.dex.attributes.AttributeType; import jadx.dex.attributes.AttributeType;
import jadx.dex.attributes.EnumClassAttr; import jadx.dex.attributes.EnumClassAttr;
import jadx.dex.attributes.EnumClassAttr.EnumField; import jadx.dex.attributes.EnumClassAttr.EnumField;
import jadx.dex.attributes.IAttribute;
import jadx.dex.attributes.SourceFileAttr;
import jadx.dex.info.AccessInfo; import jadx.dex.info.AccessInfo;
import jadx.dex.info.ClassInfo; import jadx.dex.info.ClassInfo;
import jadx.dex.instructions.args.ArgType; import jadx.dex.instructions.args.ArgType;
...@@ -169,6 +172,8 @@ public class ClassGen { ...@@ -169,6 +172,8 @@ public class ClassGen {
public void makeClassBody(CodeWriter clsCode) throws CodegenException { public void makeClassBody(CodeWriter clsCode) throws CodegenException {
clsCode.add('{'); clsCode.add('{');
insertSourceFileInfo(clsCode, cls);
CodeWriter mthsCode = makeMethods(clsCode, cls.getMethods()); CodeWriter mthsCode = makeMethods(clsCode, cls.getMethods());
CodeWriter fieldsCode = makeFields(clsCode, cls, cls.getFields()); CodeWriter fieldsCode = makeFields(clsCode, cls, cls.getFields());
clsCode.add(fieldsCode); clsCode.add(fieldsCode);
...@@ -224,6 +229,7 @@ public class ClassGen { ...@@ -224,6 +229,7 @@ public class ClassGen {
MethodGen mthGen = new MethodGen(this, mth); MethodGen mthGen = new MethodGen(this, mth);
mthGen.addDefinition(code); mthGen.addDefinition(code);
code.add(" {"); code.add(" {");
insertSourceFileInfo(code, mth);
code.add(mthGen.makeInstructions(code.getIndent())); code.add(mthGen.makeInstructions(code.getIndent()));
code.startLine('}'); code.startLine('}');
} }
...@@ -363,6 +369,14 @@ public class ClassGen { ...@@ -363,6 +369,14 @@ public class ClassGen {
return false; return false;
} }
private void insertSourceFileInfo(CodeWriter code, AttrNode node) {
IAttribute sourceFileAttr = node.getAttributes().get(AttributeType.SOURCE_FILE);
if(sourceFileAttr != null) {
code.startLine(1, "// compiled from: ");
code.add(((SourceFileAttr)sourceFileAttr).getFileName());
}
}
public Set<ClassInfo> getImports() { public Set<ClassInfo> getImports() {
return imports; return imports;
} }
......
...@@ -78,7 +78,7 @@ public class CodeWriter { ...@@ -78,7 +78,7 @@ public class CodeWriter {
return this; return this;
} }
private static final String[] indentCache = new String[] { private static final String[] INDENT_CACHE = new String[] {
"", "",
INDENT, INDENT,
INDENT + INDENT, INDENT + INDENT,
...@@ -88,11 +88,12 @@ public class CodeWriter { ...@@ -88,11 +88,12 @@ public class CodeWriter {
}; };
private void updateIndent() { private void updateIndent() {
if (indent < 6) { int curIndent = indent;
this.indentStr = indentCache[indent]; if (curIndent < 6) {
this.indentStr = INDENT_CACHE[curIndent];
} else { } else {
StringBuilder s = new StringBuilder(indent * INDENT.length()); StringBuilder s = new StringBuilder(curIndent * INDENT.length());
for (int i = 0; i < indent; i++) { for (int i = 0; i < curIndent; i++) {
s.append(INDENT); s.append(INDENT);
} }
this.indentStr = s.toString(); this.indentStr = s.toString();
......
package jadx.dex.attributes; package jadx.dex.attributes;
public enum AttributeType { public enum AttributeType {
// TODO? add attribute target (insn, block, method, field, class)
// instructions /* Multi attributes */
JUMP(false), JUMP(false),
// blocks
LOOP(false), LOOP(false),
CATCH_BLOCK(false), CATCH_BLOCK(false),
/* Uniq attributes */
EXC_HANDLER(true), EXC_HANDLER(true),
SPLITTER_BLOCK(true), SPLITTER_BLOCK(true),
FORCE_RETURN(true), FORCE_RETURN(true),
// fields
FIELD_VALUE(true), FIELD_VALUE(true),
// methods
JADX_ERROR(true), JADX_ERROR(true),
METHOD_INLINE(true), METHOD_INLINE(true),
// classes
ENUM_CLASS(true), ENUM_CLASS(true),
// any
ANNOTATION_LIST(true), ANNOTATION_LIST(true),
ANNOTATION_MTH_PARAMETERS(true), ANNOTATION_MTH_PARAMETERS(true),
SOURCE_FILE(true),
DECLARE_VARIABLE(true); DECLARE_VARIABLE(true);
private static final int notUniqCount; private static final int notUniqCount;
......
...@@ -20,7 +20,7 @@ import java.util.Set; ...@@ -20,7 +20,7 @@ import java.util.Set;
* 2. attribute - class instance associated for attribute type, * 2. attribute - class instance associated for attribute type,
* only one attached to node for unique attributes, multiple for others * only one attached to node for unique attributes, multiple for others
*/ */
public class AttributesList { public final class AttributesList {
private final Set<AttributeFlag> flags; private final Set<AttributeFlag> flags;
private final Map<AttributeType, IAttribute> uniqAttr; private final Map<AttributeType, IAttribute> uniqAttr;
......
...@@ -4,7 +4,7 @@ import jadx.dex.instructions.args.RegisterArg; ...@@ -4,7 +4,7 @@ import jadx.dex.instructions.args.RegisterArg;
import jadx.dex.instructions.args.TypedVar; import jadx.dex.instructions.args.TypedVar;
import jadx.dex.nodes.MethodNode; import jadx.dex.nodes.MethodNode;
public class BlockRegState { public final class BlockRegState {
private final RegisterArg[] regs; private final RegisterArg[] regs;
......
package jadx.dex.attributes;
public class SourceFileAttr implements IAttribute {
private final String fileName;
public SourceFileAttr(String fileName) {
this.fileName = fileName;
}
public String getFileName() {
return fileName;
}
@Override
public AttributeType getType() {
return AttributeType.SOURCE_FILE;
}
@Override
public String toString() {
return "SOURCE:" + fileName;
}
}
package jadx.dex.info; package jadx.dex.info;
import jadx.Consts;
import jadx.deobf.NameMapper; import jadx.deobf.NameMapper;
import jadx.dex.instructions.args.ArgType; import jadx.dex.instructions.args.ArgType;
import jadx.dex.nodes.DexNode; import jadx.dex.nodes.DexNode;
...@@ -11,7 +12,6 @@ import java.util.WeakHashMap; ...@@ -11,7 +12,6 @@ import java.util.WeakHashMap;
public final class ClassInfo { public final class ClassInfo {
private static final Map<ArgType, ClassInfo> CLASSINFO_CACHE = new WeakHashMap<ArgType, ClassInfo>(); private static final Map<ArgType, ClassInfo> CLASSINFO_CACHE = new WeakHashMap<ArgType, ClassInfo>();
private static final String DEFAULT_PACKAGE_NAME = "defpackage";
public static ClassInfo fromDex(DexNode dex, int clsIndex) { public static ClassInfo fromDex(DexNode dex, int clsIndex) {
if (clsIndex == DexNode.NO_INDEX) if (clsIndex == DexNode.NO_INDEX)
...@@ -62,7 +62,7 @@ public final class ClassInfo { ...@@ -62,7 +62,7 @@ public final class ClassInfo {
int dot = fullObjectName.lastIndexOf('.'); int dot = fullObjectName.lastIndexOf('.');
if (dot == -1) { if (dot == -1) {
// rename default package if it used from class with package (often for obfuscated apps), // rename default package if it used from class with package (often for obfuscated apps),
pkg = DEFAULT_PACKAGE_NAME; pkg = Consts.DEFAULT_PACKAGE_NAME;
name = fullObjectName; name = fullObjectName;
} else { } else {
pkg = fullObjectName.substring(0, dot); pkg = fullObjectName.substring(0, dot);
...@@ -110,7 +110,7 @@ public final class ClassInfo { ...@@ -110,7 +110,7 @@ public final class ClassInfo {
} }
public boolean isPackageDefault() { public boolean isPackageDefault() {
return pkg.isEmpty() || pkg.equals(DEFAULT_PACKAGE_NAME); return pkg.isEmpty() || pkg.equals(Consts.DEFAULT_PACKAGE_NAME);
} }
public String getNameWithoutPackage() { public String getNameWithoutPackage() {
......
...@@ -3,6 +3,7 @@ package jadx.dex.nodes; ...@@ -3,6 +3,7 @@ package jadx.dex.nodes;
import jadx.Consts; import jadx.Consts;
import jadx.dex.attributes.AttrNode; import jadx.dex.attributes.AttrNode;
import jadx.dex.attributes.AttributeType; import jadx.dex.attributes.AttributeType;
import jadx.dex.attributes.SourceFileAttr;
import jadx.dex.attributes.annotations.Annotation; import jadx.dex.attributes.annotations.Annotation;
import jadx.dex.info.AccessInfo; import jadx.dex.info.AccessInfo;
import jadx.dex.info.AccessInfo.AFType; import jadx.dex.info.AccessInfo.AFType;
...@@ -85,8 +86,17 @@ public class ClassNode extends AttrNode implements ILoadable { ...@@ -85,8 +86,17 @@ public class ClassNode extends AttrNode implements ILoadable {
parseClassSignature(); parseClassSignature();
setFieldsTypesFromSignature(); setFieldsTypesFromSignature();
int sfIdx = cls.getSourceFileIndex();
if(sfIdx != DexNode.NO_INDEX) {
String fileName = dex.getString(sfIdx);
if(!this.getFullName().contains(fileName.replace(".java", ""))) {
this.getAttributes().add(new SourceFileAttr(fileName));
LOG.info("TODO: move class {} to {} file", this, fileName);
}
}
int accFlagsValue; int accFlagsValue;
Annotation a = getAttributes().getAnnotation("dalvik.annotation.InnerClass"); Annotation a = getAttributes().getAnnotation(Consts.DALVIK_INNER_CLASS);
if (a != null) if (a != null)
accFlagsValue = (Integer) a.getValues().get("accessFlags"); accFlagsValue = (Integer) a.getValues().get("accessFlags");
else else
......
package jadx.dex.nodes.parser; package jadx.dex.nodes.parser;
import jadx.dex.attributes.SourceFileAttr;
import jadx.dex.info.LocalVarInfo; import jadx.dex.info.LocalVarInfo;
import jadx.dex.instructions.args.InsnArg; import jadx.dex.instructions.args.InsnArg;
import jadx.dex.instructions.args.RegisterArg; import jadx.dex.instructions.args.RegisterArg;
...@@ -50,7 +51,6 @@ public class DebugInfoParser { ...@@ -50,7 +51,6 @@ public class DebugInfoParser {
public void process() throws DecodeException { public void process() throws DecodeException {
int addr = 0; int addr = 0;
int line; int line;
// String source_file;
line = section.readUleb128(); line = section.readUleb128();
int param_size = section.readUleb128(); // exclude 'this' int param_size = section.readUleb128(); // exclude 'this'
...@@ -124,14 +124,18 @@ public class DebugInfoParser { ...@@ -124,14 +124,18 @@ public class DebugInfoParser {
} }
case DBG_SET_PROLOGUE_END: case DBG_SET_PROLOGUE_END:
break;
case DBG_SET_EPILOGUE_BEGIN: case DBG_SET_EPILOGUE_BEGIN:
// do nothing
break; break;
case DBG_SET_FILE: case DBG_SET_FILE: {
section.readUleb128(); int idx = section.readUleb128() - 1;
// source_file = dex.getString(idx); if (idx != DexNode.NO_INDEX) {
String sourceFile = dex.getString(idx);
mth.getAttributes().add(new SourceFileAttr(sourceFile));
}
break; break;
}
default: { default: {
if (c >= DBG_FIRST_SPECIAL) { if (c >= DBG_FIRST_SPECIAL) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment