public string EncodedValueToString(EncodedValue value, Class currentClass) { switch (value.EncodedType) { case EncodedValueType.VALUE_BYTE: return(((EncodedNumber)value).AsByte().ToString()); case EncodedValueType.VALUE_NULL: return("null"); case EncodedValueType.VALUE_BOOLEAN: return(((EncodedNumber)value).AsBoolean().ToString().ToLower()); case EncodedValueType.VALUE_SHORT: return(((EncodedNumber)value).AsShort().ToString()); case EncodedValueType.VALUE_CHAR: return(((EncodedNumber)value).AsChar().ToString()); case EncodedValueType.VALUE_INT: return(((EncodedNumber)value).AsInt().ToString()); case EncodedValueType.VALUE_LONG: return(((EncodedNumber)value).AsLong().ToString()); case EncodedValueType.VALUE_FLOAT: return(((EncodedNumber)value).AsFloat().ToString()); case EncodedValueType.VALUE_DOUBLE: return(((EncodedNumber)value).AsDouble().ToString()); case EncodedValueType.VALUE_STRING: return(String.Format("\"{0}\"", _dex.GetString(((EncodedNumber)value).AsId()).Replace("\n", "\\n"))); case EncodedValueType.VALUE_TYPE: return(_dex.GetTypeName(((EncodedNumber)value).AsId())); case EncodedValueType.VALUE_FIELD: case EncodedValueType.VALUE_ENUM: return(_getFieldName(((EncodedNumber)value).AsId(), currentClass, true)); case EncodedValueType.VALUE_METHOD: var method = _dex.GetMethod(((EncodedNumber)value).AsId()); return(string.Format("{0}.{1}", _dex.GetTypeName(method.ClassIndex), method.Name)); case EncodedValueType.VALUE_ARRAY: var encodedArray = (EncodedArray)value; var array = new List <string> ((int)encodedArray.Count); foreach (var arrayValue in encodedArray.GetValues()) { array.Add(EncodedValueToString(arrayValue, currentClass)); } return(string.Format("[{0}]", string.Join(",", array))); case EncodedValueType.VALUE_ANNOTATION: var stringAnnotation = new StringWriter(); _annToString(stringAnnotation, (EncodedAnnotation)value, currentClass, new Indentation()); return(stringAnnotation.ToString()); } return("Unknown"); }
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--; } }
private void WriteOutCatchStatements(TextWriter output, Indentation indent, TryCatchBlock currentTryBlock, JumpTable jumpTable) { indent--; foreach (var catchBlock in currentTryBlock.Handlers) { output.WriteLine(string.Format("{0}catch({1}) :{2}", indent.ToString(), catchBlock.TypeIndex == 0 ? "ALL" : _dex.GetTypeName(catchBlock.TypeIndex), jumpTable.GetHandlerLabel(catchBlock))); } }
public override string ToString() { return(string.Format("Field: Class={0} Type={1} Name={2} Id={3}", Dex.GetTypeName(ClassIndex), Dex.GetTypeName(TypeIndex), Name, Id)); }