Save source file name, move constant strings
This commit is contained in:
@@ -15,5 +15,11 @@ public class Consts {
|
||||
|
||||
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_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 {
|
||||
|
||||
for (Annotation a : aList.getAll()) {
|
||||
String aCls = a.getAnnotationClass();
|
||||
if (aCls.startsWith("dalvik.annotation.")) {
|
||||
if (aCls.startsWith(Consts.DALVIK_ANNOTATION_PKG)) {
|
||||
// skip
|
||||
if (Consts.DEBUG) {
|
||||
code.startLine("// " + a);
|
||||
@@ -97,7 +97,7 @@ public class AnnotationGen {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
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) {
|
||||
Object exs = an.getDefaultValue();
|
||||
code.add(" throws ");
|
||||
@@ -111,7 +111,7 @@ public class AnnotationGen {
|
||||
}
|
||||
|
||||
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) {
|
||||
Annotation defAnnotation = (Annotation) an.getDefaultValue();
|
||||
return defAnnotation.getValues().get(name);
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package jadx.codegen;
|
||||
|
||||
import jadx.Consts;
|
||||
import jadx.dex.attributes.AttrNode;
|
||||
import jadx.dex.attributes.AttributeFlag;
|
||||
import jadx.dex.attributes.AttributeType;
|
||||
import jadx.dex.attributes.EnumClassAttr;
|
||||
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.ClassInfo;
|
||||
import jadx.dex.instructions.args.ArgType;
|
||||
@@ -169,6 +172,8 @@ public class ClassGen {
|
||||
|
||||
public void makeClassBody(CodeWriter clsCode) throws CodegenException {
|
||||
clsCode.add('{');
|
||||
insertSourceFileInfo(clsCode, cls);
|
||||
|
||||
CodeWriter mthsCode = makeMethods(clsCode, cls.getMethods());
|
||||
CodeWriter fieldsCode = makeFields(clsCode, cls, cls.getFields());
|
||||
clsCode.add(fieldsCode);
|
||||
@@ -224,6 +229,7 @@ public class ClassGen {
|
||||
MethodGen mthGen = new MethodGen(this, mth);
|
||||
mthGen.addDefinition(code);
|
||||
code.add(" {");
|
||||
insertSourceFileInfo(code, mth);
|
||||
code.add(mthGen.makeInstructions(code.getIndent()));
|
||||
code.startLine('}');
|
||||
}
|
||||
@@ -363,6 +369,14 @@ public class ClassGen {
|
||||
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() {
|
||||
return imports;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public class CodeWriter {
|
||||
return this;
|
||||
}
|
||||
|
||||
private static final String[] indentCache = new String[] {
|
||||
private static final String[] INDENT_CACHE = new String[] {
|
||||
"",
|
||||
INDENT,
|
||||
INDENT + INDENT,
|
||||
@@ -88,11 +88,12 @@ public class CodeWriter {
|
||||
};
|
||||
|
||||
private void updateIndent() {
|
||||
if (indent < 6) {
|
||||
this.indentStr = indentCache[indent];
|
||||
int curIndent = indent;
|
||||
if (curIndent < 6) {
|
||||
this.indentStr = INDENT_CACHE[curIndent];
|
||||
} else {
|
||||
StringBuilder s = new StringBuilder(indent * INDENT.length());
|
||||
for (int i = 0; i < indent; i++) {
|
||||
StringBuilder s = new StringBuilder(curIndent * INDENT.length());
|
||||
for (int i = 0; i < curIndent; i++) {
|
||||
s.append(INDENT);
|
||||
}
|
||||
this.indentStr = s.toString();
|
||||
|
||||
@@ -1,33 +1,32 @@
|
||||
package jadx.dex.attributes;
|
||||
|
||||
public enum AttributeType {
|
||||
// TODO? add attribute target (insn, block, method, field, class)
|
||||
|
||||
// instructions
|
||||
/* Multi attributes */
|
||||
|
||||
JUMP(false),
|
||||
|
||||
// blocks
|
||||
LOOP(false),
|
||||
CATCH_BLOCK(false),
|
||||
|
||||
/* Uniq attributes */
|
||||
|
||||
EXC_HANDLER(true),
|
||||
SPLITTER_BLOCK(true),
|
||||
FORCE_RETURN(true),
|
||||
|
||||
// fields
|
||||
FIELD_VALUE(true),
|
||||
|
||||
// methods
|
||||
JADX_ERROR(true),
|
||||
METHOD_INLINE(true),
|
||||
|
||||
// classes
|
||||
ENUM_CLASS(true),
|
||||
|
||||
// any
|
||||
ANNOTATION_LIST(true),
|
||||
ANNOTATION_MTH_PARAMETERS(true),
|
||||
|
||||
SOURCE_FILE(true),
|
||||
|
||||
DECLARE_VARIABLE(true);
|
||||
|
||||
private static final int notUniqCount;
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.Set;
|
||||
* 2. attribute - class instance associated for attribute type,
|
||||
* 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 Map<AttributeType, IAttribute> uniqAttr;
|
||||
|
||||
@@ -4,7 +4,7 @@ import jadx.dex.instructions.args.RegisterArg;
|
||||
import jadx.dex.instructions.args.TypedVar;
|
||||
import jadx.dex.nodes.MethodNode;
|
||||
|
||||
public class BlockRegState {
|
||||
public final class BlockRegState {
|
||||
|
||||
private final RegisterArg[] regs;
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package jadx.dex.info;
|
||||
|
||||
import jadx.Consts;
|
||||
import jadx.deobf.NameMapper;
|
||||
import jadx.dex.instructions.args.ArgType;
|
||||
import jadx.dex.nodes.DexNode;
|
||||
@@ -11,7 +12,6 @@ import java.util.WeakHashMap;
|
||||
public final class 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) {
|
||||
if (clsIndex == DexNode.NO_INDEX)
|
||||
@@ -62,7 +62,7 @@ public final class ClassInfo {
|
||||
int dot = fullObjectName.lastIndexOf('.');
|
||||
if (dot == -1) {
|
||||
// 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;
|
||||
} else {
|
||||
pkg = fullObjectName.substring(0, dot);
|
||||
@@ -110,7 +110,7 @@ public final class ClassInfo {
|
||||
}
|
||||
|
||||
public boolean isPackageDefault() {
|
||||
return pkg.isEmpty() || pkg.equals(DEFAULT_PACKAGE_NAME);
|
||||
return pkg.isEmpty() || pkg.equals(Consts.DEFAULT_PACKAGE_NAME);
|
||||
}
|
||||
|
||||
public String getNameWithoutPackage() {
|
||||
|
||||
@@ -3,6 +3,7 @@ package jadx.dex.nodes;
|
||||
import jadx.Consts;
|
||||
import jadx.dex.attributes.AttrNode;
|
||||
import jadx.dex.attributes.AttributeType;
|
||||
import jadx.dex.attributes.SourceFileAttr;
|
||||
import jadx.dex.attributes.annotations.Annotation;
|
||||
import jadx.dex.info.AccessInfo;
|
||||
import jadx.dex.info.AccessInfo.AFType;
|
||||
@@ -85,8 +86,17 @@ public class ClassNode extends AttrNode implements ILoadable {
|
||||
parseClassSignature();
|
||||
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;
|
||||
Annotation a = getAttributes().getAnnotation("dalvik.annotation.InnerClass");
|
||||
Annotation a = getAttributes().getAnnotation(Consts.DALVIK_INNER_CLASS);
|
||||
if (a != null)
|
||||
accFlagsValue = (Integer) a.getValues().get("accessFlags");
|
||||
else
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package jadx.dex.nodes.parser;
|
||||
|
||||
import jadx.dex.attributes.SourceFileAttr;
|
||||
import jadx.dex.info.LocalVarInfo;
|
||||
import jadx.dex.instructions.args.InsnArg;
|
||||
import jadx.dex.instructions.args.RegisterArg;
|
||||
@@ -50,7 +51,6 @@ public class DebugInfoParser {
|
||||
public void process() throws DecodeException {
|
||||
int addr = 0;
|
||||
int line;
|
||||
// String source_file;
|
||||
|
||||
line = section.readUleb128();
|
||||
int param_size = section.readUleb128(); // exclude 'this'
|
||||
@@ -124,14 +124,18 @@ public class DebugInfoParser {
|
||||
}
|
||||
|
||||
case DBG_SET_PROLOGUE_END:
|
||||
break;
|
||||
case DBG_SET_EPILOGUE_BEGIN:
|
||||
// do nothing
|
||||
break;
|
||||
|
||||
case DBG_SET_FILE:
|
||||
section.readUleb128();
|
||||
// source_file = dex.getString(idx);
|
||||
case DBG_SET_FILE: {
|
||||
int idx = section.readUleb128() - 1;
|
||||
if (idx != DexNode.NO_INDEX) {
|
||||
String sourceFile = dex.getString(idx);
|
||||
mth.getAttributes().add(new SourceFileAttr(sourceFile));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
if (c >= DBG_FIRST_SPECIAL) {
|
||||
|
||||
Reference in New Issue
Block a user