use of org.jf.util.IndentingWriter in project atlas by alibaba.
the class BakSmali method disassembleClass.
public static boolean disassembleClass(ClassDef classDef, ClassFileNameHandler fileNameHandler, baksmaliOptions options) {
/**
* The path for the disassembly file is based on the package name
* The class descriptor will look something like:
* Ljava/lang/Object;
* Where the there is leading 'L' and a trailing ';', and the parts of the
* package name are separated by '/'
*/
String classDescriptor = classDef.getType();
//validate that the descriptor is formatted like we expect
if (classDescriptor.charAt(0) != 'L' || classDescriptor.charAt(classDescriptor.length() - 1) != ';') {
System.err.println("Unrecognized class descriptor - " + classDescriptor + " - skipping class");
return false;
}
File smaliFile = fileNameHandler.getUniqueFilenameForClass(classDescriptor);
//create and initialize the top level string template
ClassDefinition classDefinition = new ClassDefinition(options, classDef);
//write the disassembly
Writer writer = null;
try {
File smaliParent = smaliFile.getParentFile();
if (!smaliParent.exists()) {
if (!smaliParent.mkdirs()) {
// check again, it's likely it was created in a different thread
if (!smaliParent.exists()) {
System.err.println("Unable to create directory " + smaliParent.toString() + " - skipping class");
return false;
}
}
}
if (!smaliFile.exists()) {
if (!smaliFile.createNewFile()) {
System.err.println("Unable to create file " + smaliFile.toString() + " - skipping class");
return false;
}
}
BufferedWriter bufWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(smaliFile), "UTF8"));
writer = new IndentingWriter(bufWriter);
classDefinition.writeTo((IndentingWriter) writer);
} catch (Exception ex) {
System.err.println("\n\nError occurred while disassembling class " + classDescriptor.replace('/', '.') + " - skipping class");
ex.printStackTrace();
// noinspection ResultOfMethodCallIgnored
smaliFile.delete();
return false;
} finally {
if (writer != null) {
try {
writer.close();
} catch (Throwable ex) {
System.err.println("\n\nError occurred while closing file " + smaliFile.toString());
ex.printStackTrace();
}
}
}
return true;
}
use of org.jf.util.IndentingWriter in project smali by JesusFreke.
the class ClassDefinition method writeDirectMethods.
private Set<String> writeDirectMethods(IndentingWriter writer) throws IOException {
boolean wroteHeader = false;
Set<String> writtenMethods = new HashSet<String>();
Iterable<? extends Method> directMethods;
if (classDef instanceof DexBackedClassDef) {
directMethods = ((DexBackedClassDef) classDef).getDirectMethods(false);
} else {
directMethods = classDef.getDirectMethods();
}
for (Method method : directMethods) {
if (!wroteHeader) {
writer.write("\n\n");
writer.write("# direct methods");
wroteHeader = true;
}
writer.write('\n');
// TODO: check for method validation errors
String methodString = ReferenceUtil.getMethodDescriptor(method, true);
IndentingWriter methodWriter = writer;
if (!writtenMethods.add(methodString)) {
writer.write("# duplicate method ignored\n");
methodWriter = new CommentingIndentingWriter(writer);
}
MethodImplementation methodImpl = method.getImplementation();
if (methodImpl == null) {
MethodDefinition.writeEmptyMethodTo(methodWriter, method, options);
} else {
MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
methodDefinition.writeTo(methodWriter);
}
}
return writtenMethods;
}
use of org.jf.util.IndentingWriter in project smali by JesusFreke.
the class ClassDefinition method writeInstanceFields.
private void writeInstanceFields(IndentingWriter writer, Set<String> staticFields) throws IOException {
boolean wroteHeader = false;
Set<String> writtenFields = new HashSet<String>();
Iterable<? extends Field> instanceFields;
if (classDef instanceof DexBackedClassDef) {
instanceFields = ((DexBackedClassDef) classDef).getInstanceFields(false);
} else {
instanceFields = classDef.getInstanceFields();
}
for (Field field : instanceFields) {
if (!wroteHeader) {
writer.write("\n\n");
writer.write("# instance fields");
wroteHeader = true;
}
writer.write('\n');
IndentingWriter fieldWriter = writer;
String fieldString = ReferenceUtil.getShortFieldDescriptor(field);
if (!writtenFields.add(fieldString)) {
writer.write("# duplicate field ignored\n");
fieldWriter = new CommentingIndentingWriter(writer);
System.err.println(String.format("Ignoring duplicate field: %s->%s", classDef.getType(), fieldString));
} else if (staticFields.contains(fieldString)) {
System.err.println(String.format("Duplicate static+instance field found: %s->%s", classDef.getType(), fieldString));
System.err.println("You will need to rename one of these fields, including all references.");
writer.write("# There is both a static and instance field with this signature.\n" + "# You will need to rename one of these fields, including all references.\n");
}
FieldDefinition.writeTo(options, fieldWriter, field, false);
}
}
use of org.jf.util.IndentingWriter in project smali by JesusFreke.
the class ClassDefinition method writeVirtualMethods.
private void writeVirtualMethods(IndentingWriter writer, Set<String> directMethods) throws IOException {
boolean wroteHeader = false;
Set<String> writtenMethods = new HashSet<String>();
Iterable<? extends Method> virtualMethods;
if (classDef instanceof DexBackedClassDef) {
virtualMethods = ((DexBackedClassDef) classDef).getVirtualMethods(false);
} else {
virtualMethods = classDef.getVirtualMethods();
}
for (Method method : virtualMethods) {
if (!wroteHeader) {
writer.write("\n\n");
writer.write("# virtual methods");
wroteHeader = true;
}
writer.write('\n');
// TODO: check for method validation errors
String methodString = ReferenceUtil.getMethodDescriptor(method, true);
IndentingWriter methodWriter = writer;
if (!writtenMethods.add(methodString)) {
writer.write("# duplicate method ignored\n");
methodWriter = new CommentingIndentingWriter(writer);
} else if (directMethods.contains(methodString)) {
writer.write("# There is both a direct and virtual method with this signature.\n" + "# You will need to rename one of these methods, including all references.\n");
System.err.println(String.format("Duplicate direct+virtual method found: %s->%s", classDef.getType(), methodString));
System.err.println("You will need to rename one of these methods, including all references.");
}
MethodImplementation methodImpl = method.getImplementation();
if (methodImpl == null) {
MethodDefinition.writeEmptyMethodTo(methodWriter, method, options);
} else {
MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
methodDefinition.writeTo(methodWriter);
}
}
}
use of org.jf.util.IndentingWriter in project dex2jar by pxb1988.
the class SmaliTest method baksmali.
private static String baksmali(DexBackedClassDef def) throws IOException {
baksmaliOptions opts = new baksmaliOptions();
opts.outputDebugInfo = false;
opts.syntheticAccessorResolver = new SyntheticAccessorResolver(Collections.EMPTY_LIST);
ClassDefinition classDefinition = new ClassDefinition(opts, def);
StringWriter bufWriter = new StringWriter();
IndentingWriter writer = new IndentingWriter(bufWriter);
classDefinition.writeTo((IndentingWriter) writer);
writer.flush();
return bufWriter.toString();
}
Aggregations