use of org.jf.baksmali.formatter.BaksmaliWriter in project jadx by skylot.
the class SmaliUtils method getSmaliCode.
public static String getSmaliCode(byte[] dexBuf, int clsDefOffset) {
StringWriter stringWriter = new StringWriter();
try {
DexBackedDexFile dexFile = new DexBackedDexFile(null, dexBuf);
DexBackedClassDef dexBackedClassDef = new DexBackedClassDef(dexFile, clsDefOffset, 0);
ClassDefinition classDefinition = new ClassDefinition(new BaksmaliOptions(), dexBackedClassDef);
classDefinition.writeTo(new BaksmaliWriter(stringWriter));
} catch (Exception e) {
LOG.error("Error generating smali", e);
stringWriter.append("Error generating smali code: ");
stringWriter.append(e.getMessage());
stringWriter.append(System.lineSeparator());
e.printStackTrace(new PrintWriter(stringWriter, true));
}
return stringWriter.toString();
}
use of org.jf.baksmali.formatter.BaksmaliWriter in project smali by JesusFreke.
the class MethodDefinition method addAnalyzedInstructionMethodItems.
private void addAnalyzedInstructionMethodItems(List<MethodItem> methodItems) {
MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classDef.options.classPath, method, classDef.options.inlineResolver, classDef.options.normalizeVirtualMethods);
AnalysisException analysisException = methodAnalyzer.getAnalysisException();
if (analysisException != null) {
// TODO: need to keep track of whether any errors occurred, so we can exit with a non-zero result
methodItems.add(new CommentMethodItem(String.format("AnalysisException: %s", analysisException.getMessage()), analysisException.codeAddress, Integer.MIN_VALUE));
analysisException.printStackTrace(System.err);
}
List<AnalyzedInstruction> instructions = methodAnalyzer.getAnalyzedInstructions();
int currentCodeAddress = 0;
for (int i = 0; i < instructions.size(); i++) {
AnalyzedInstruction instruction = instructions.get(i);
MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, currentCodeAddress, instruction.getInstruction());
methodItems.add(methodItem);
if (instruction.getInstruction().getOpcode().format == Format.UnresolvedOdexInstruction) {
methodItems.add(new CommentedOutMethodItem(InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, currentCodeAddress, instruction.getOriginalInstruction())));
}
if (i != instructions.size() - 1) {
methodItems.add(new BlankMethodItem(currentCodeAddress));
}
if (classDef.options.codeOffsets) {
methodItems.add(new MethodItem(currentCodeAddress) {
@Override
public double getSortOrder() {
return -1000;
}
@Override
public boolean writeTo(BaksmaliWriter writer) throws IOException {
writer.write("#@");
writer.writeUnsignedLongAsHex(codeAddress & 0xFFFFFFFFL);
return true;
}
});
}
if (classDef.options.registerInfo != 0 && !instruction.getInstruction().getOpcode().format.isPayloadFormat) {
methodItems.add(new PreInstructionRegisterInfoMethodItem(classDef.options.registerInfo, methodAnalyzer, registerFormatter, instruction, currentCodeAddress));
methodItems.add(new PostInstructionRegisterInfoMethodItem(registerFormatter, instruction, currentCodeAddress));
}
currentCodeAddress += instruction.getInstruction().getCodeUnits();
}
}
use of org.jf.baksmali.formatter.BaksmaliWriter in project smali by JesusFreke.
the class Baksmali method disassembleClass.
private 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 = null;
try {
smaliFile = fileNameHandler.getUniqueFilenameForClass(classDescriptor);
} catch (IOException ex) {
System.err.println("\n\nError occurred while creating file for class " + classDescriptor);
ex.printStackTrace();
return false;
}
// create and initialize the top level string template
ClassDefinition classDefinition = new ClassDefinition(options, classDef);
// write the disassembly
BaksmaliWriter 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 BaksmaliWriter(bufWriter, options.implicitReferences ? classDef.getType() : null);
classDefinition.writeTo(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.baksmali.formatter.BaksmaliWriter in project smali by JesusFreke.
the class MethodDefinition method addInstructionMethodItems.
private void addInstructionMethodItems(List<MethodItem> methodItems) {
int currentCodeAddress = 0;
for (int i = 0; i < effectiveInstructions.size(); i++) {
Instruction instruction = effectiveInstructions.get(i);
MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, currentCodeAddress, instruction);
methodItems.add(methodItem);
if (i != effectiveInstructions.size() - 1) {
methodItems.add(new BlankMethodItem(currentCodeAddress));
}
if (classDef.options.codeOffsets) {
methodItems.add(new MethodItem(currentCodeAddress) {
@Override
public double getSortOrder() {
return -1000;
}
@Override
public boolean writeTo(BaksmaliWriter writer) throws IOException {
writer.write("#@");
writer.writeUnsignedLongAsHex(codeAddress & 0xFFFFFFFFL);
return true;
}
});
}
if (classDef.options.accessorComments && classDef.options.syntheticAccessorResolver != null && (instruction instanceof ReferenceInstruction)) {
Opcode opcode = instruction.getOpcode();
if (opcode.referenceType == ReferenceType.METHOD) {
MethodReference methodReference = (MethodReference) ((ReferenceInstruction) instruction).getReference();
try {
methodReference.validateReference();
if (SyntheticAccessorResolver.looksLikeSyntheticAccessor(methodReference.getName())) {
AccessedMember accessedMember = classDef.options.syntheticAccessorResolver.getAccessedMember(methodReference);
if (accessedMember != null) {
methodItems.add(new SyntheticAccessCommentMethodItem(classDef, accessedMember, currentCodeAddress));
}
}
} catch (Reference.InvalidReferenceException e) {
// Just ignore for now. We'll deal with it when processing the instruction
}
}
}
currentCodeAddress += instruction.getCodeUnits();
}
}
use of org.jf.baksmali.formatter.BaksmaliWriter in project smali by JesusFreke.
the class ClassDefinition method writeVirtualMethods.
private void writeVirtualMethods(BaksmaliWriter 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 = formatter.getShortMethodDescriptor(method);
BaksmaliWriter methodWriter = writer;
if (!writtenMethods.add(methodString)) {
writer.write("# duplicate method ignored\n");
methodWriter = getCommentingWriter(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, this);
} else {
MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
methodDefinition.writeTo(methodWriter);
}
}
}
Aggregations