string MethodToString(Method method) { var proto = _dex.GetPrototype(method.PrototypeIndex); var parameters = new List <string>(); int paramCounter = 0; foreach (var param in proto.Parameters) { parameters.Add(string.Format("{0} {1}{2}", _dex.GetTypeName(param), 'a', paramCounter++)); } return(string.Format("{0} {1} {2} ({3})", _helper.AccessFlagsToString(((AccessFlag)method.AccessFlags)), _dex.GetTypeName(proto.ReturnTypeIndex), method.Name, string.Join(",", parameters))); }
public void WriteOutMethod(Class dexClass, Method method, TextWriter output, Indentation indent, bool renderOpcodes = false) { var stringIndent = indent.ToString(); var proto = _dex.GetPrototype(method.PrototypeIndex); output.WriteLine(string.Format("{0}.METHOD {1} : {2}", stringIndent, method.Name, _dex.GetTypeName(proto.ReturnTypeIndex))); indent++; var paramCount = 0; foreach (var param in proto.Parameters) { output.WriteLine(string.Format("{0}.PARAM {1}", indent.ToString(), _dex.GetTypeName(param))); if (method.ParameterAnnotations.Count > paramCount) { indent++; WriteOutAnnotation(output, method.ParameterAnnotations[paramCount].Values, dexClass, indent); indent--; } paramCount++; } indent--; output.WriteLine(string.Format("{0}.MODIFIERS {1}", stringIndent, _helper.AccessFlagsToString(((AccessFlag)method.AccessFlags)))); output.WriteLine(string.Format("{0}.REGISTERS {1}", stringIndent, method.GetRegisterCount())); foreach (var annotation in method.Annotations) { WriteOutAnnotation(output, annotation.Values, dexClass, indent); } if (renderOpcodes) { output.WriteLine(string.Format("{0}.CODE", stringIndent)); indent++; stringIndent = indent.ToString(); long offset = 0; var lastTryBlockId = 0; var activeTryBlocks = new List <TryCatchBlock> (); TryCatchBlock currentTryBlock = null; foreach (var opcode in method.GetInstructions()) { offset = opcode.OpCodeOffset; // Test for the end of the current try block if (currentTryBlock != null && !currentTryBlock.IsInBlock(offset)) { WriteOutCatchStatements(output, indent, currentTryBlock); activeTryBlocks.Remove(currentTryBlock); if (activeTryBlocks.Count > 0) { currentTryBlock = activeTryBlocks [activeTryBlocks.Count - 1]; } else { currentTryBlock = null; } } // Should open a new try block? if (method.TryCatchBlocks != null && method.TryCatchBlocks.Length > lastTryBlockId) { var tryBlock = method.TryCatchBlocks [lastTryBlockId]; if (tryBlock.IsInBlock(offset)) { output.WriteLine(string.Format("{0}{1} {2} #{3}", stringIndent, "".PadLeft(12, ' '), ".TRY", lastTryBlockId)); activeTryBlocks.Add(tryBlock); currentTryBlock = tryBlock; lastTryBlockId++; } } if (opcode.Instruction != Instructions.Nop) { output.WriteLine(string.Format("{0}{1} {2}", stringIndent, offset.ToString().PadLeft(12, ' '), opcode.ToString())); } } if (currentTryBlock != null) { WriteOutCatchStatements(output, indent, currentTryBlock); } indent--; } }