private void BeginObject() { _builder.Append("{"); if (_formatOptions.HasFlag(FormatOptions.MultiLine)) { _builder.AppendLine(); if (_formatOptions.HasFlag(FormatOptions.Indented)) { ++_indent; _builder.Append('\t', _indent); } } }
public static string FormatOperands(Instruction ins, MethodBody body, FormatOptions options = FormatOptions.Default) { StringBuilder ops = new StringBuilder(); bool fullTypeNames = options.HasFlag(FormatOptions.FullTypeNames); foreach (var r in ins.Registers) { if (ops.Length > 0) { ops.Append(","); Align(ops, 4); } ops.Append(FormatRegister(r, body)); } if (ops.Length == 0) { ops.Append(" "); } if (ins.Operand != null) { Align(ops, 12); if (ins.Operand is string) { ops.Append("\""); ops.Append(ins.Operand); ops.Append("\""); } else if (ins.Operand is sbyte) { FormatOperand_Integer(ops, (int)(byte)(sbyte)ins.Operand, "X2"); } else if (ins.Operand is short) { FormatOperand_Integer(ops, (int)(short)ins.Operand); } else if (ins.Operand is int) { FormatOperand_Integer(ops, (int)ins.Operand); } else if (ins.Operand is long) { var l = (long)ins.Operand; ops.Append(l); ops.Append(" (0x"); ops.Append(l.ToString("X8")); ops.Append(")"); } else if (ins.Operand is Instruction) { var target = (Instruction)ins.Operand; FormatOperand_Instruction(ops, ins, body, target, false); } else if (ins.Operand is ClassReference) { var m = (ClassReference)ins.Operand; ops.Append(fullTypeNames ? m.ToString() : m.Name); } else if (ins.Operand is MethodReference) { var m = (MethodReference)ins.Operand; var owner = fullTypeNames || !(m.Owner is ClassReference) ? m.ToString() : ((ClassReference)m.Owner).Name; ops.Append(owner + "::" + m.Name + m.Prototype); } else if (ins.Operand is FieldReference) { var m = (FieldReference)ins.Operand; ops.Append(fullTypeNames ? m.ToString() : m.Owner.Name + "::" + m.Name + " : " + m.Type); } else if (ins.Operand is PackedSwitchData) { var d = (PackedSwitchData)ins.Operand; FormatOperand_Integer(ops, d.FirstKey); ops.Append(":"); foreach (var target in d.Targets) { ops.Append(" "); FormatOperand_Instruction(ops, ins, body, target, true); } } else if (ins.Operand is SparseSwitchData) { var d = (SparseSwitchData)ins.Operand; bool isFirst = true; foreach (var target in d.Targets) { if (!isFirst) { ops.Append(" "); } ops.Append(target.Key); ops.Append(": "); FormatOperand_Instruction(ops, ins, body, target.Value, true); isFirst = false; } } else { ops.Append(ins.Operand); } if (options.HasFlag(FormatOptions.DebugOperandTypes)) { ops.AppendFormat(" [{0}]", ins.Operand.GetType().Name); } } var bstrOperands = ops.ToString(); return(bstrOperands); }
public string Format(FormatOptions options) { var nl = Environment.NewLine; var sb = new StringBuilder(); var body = _methodDef.Body; var cfg = new ControlFlowGraph(body); SourceCodePosition lastSource = null; _dissassembly.Format = options; var embedSource = options.HasFlag(FormatOptions.EmbedSourceCode) || options.HasFlag(FormatOptions.EmbedSourcePositions); if (embedSource && _dissassembly.MethodEntry != null) { var pos = _mapFile.GetSourceCodePositions(_dissassembly.MethodEntry).FirstOrDefault(); if (pos != null) { sb.Append(" // ----- Source Code: "); sb.Append(pos.Document.Path); sb.Append(nl); } } foreach (var block in cfg) { if (options.HasFlag(FormatOptions.ShowControlFlow)) { sb.AppendFormat(" // ----- Entry [{0}] Exit [{1}]{2}", string.Join(", ", block.EntryBlocks.Select(x => _dissassembly.FormatAddress(x.Entry).Trim())), string.Join(", ", block.ExitBlocks.Select(x => _dissassembly.FormatAddress(x.Entry).Trim())), nl); } foreach (var i in block.Instructions) { if (embedSource) { var source = _dissassembly.FindSourceCode(i.Offset, false); if (source != null && lastSource != null && source.Document.Path != lastSource.Document.Path) { // print document name. sb.Append(" // ----- "); sb.Append(source.Document.Path); sb.Append(nl); lastSource = null; } if (source == null && lastSource != null) { sb.AppendLine(" // ----- (no source)"); } else if (source != null && (lastSource == null || !source.Position.EqualExceptOffset(lastSource.Position))) { if (options.HasFlag(FormatOptions.EmbedSourcePositions)) sb.AppendFormat(" // ----- Position: {0} - {1}{2}", source.Position.Start, source.Position.End, nl); if (options.HasFlag(FormatOptions.EmbedSourceCode)) { string[] lines = GetSourceCodeLines(source); if (lines != null) sb.AppendLine(" // " + string.Join(nl + " // ", lines)); } } lastSource = source; } sb.AppendLine(_dissassembly.FormatInstruction(i)); } } sb.AppendLine(); if (body.Exceptions.Any()) { sb.AppendLine("Exception handlers:"); foreach (var handler in body.Exceptions) { sb.AppendFormat("\t{0} - {1}{2}", _dissassembly.FormatAddress(handler.TryStart), _dissassembly.FormatAddress(handler.TryEnd), nl); foreach (var c in handler.Catches) { sb.AppendFormat("\t\t{0} => {1}{2}", c.Type, _dissassembly.FormatAddress(c.Instruction), nl); } if (handler.CatchAll != null) { sb.AppendFormat("\t\t{0} => {1}{2}", "<any>", _dissassembly.FormatAddress(handler.CatchAll), nl); } } sb.AppendLine(); } if (_mapFile != null) { var typeEntry = _mapFile.GetTypeByNewName(_methodDef.Owner.Fullname); if (typeEntry != null) { var methodEntry = typeEntry.FindDexMethod(_methodDef.Name, _methodDef.Prototype.ToSignature()); if (methodEntry != null) { _registersToVariableNames = new Dictionary<string, string>(); var validParameters = methodEntry.Parameters.Where(x => !string.IsNullOrEmpty(x.Name)).ToList(); if (validParameters.Any()) { sb.AppendLine("Parameters:"); foreach (var p in validParameters) { var registerName = _dissassembly.FormatRegister(p.Register); sb.AppendFormat("\t{0} (r{1}) -> {2}{3}", registerName, p.Register, p.Name, nl); if(!string.IsNullOrEmpty(p.Name)) _registersToVariableNames.Add(registerName, p.Name); } sb.AppendLine(); } var validVariables = methodEntry.Variables.Where(x => !string.IsNullOrEmpty(x.Name)).ToList(); if (validVariables.Any()) { sb.AppendLine("Variables:"); foreach (var p in validVariables) { var registerName = _dissassembly.FormatRegister(p.Register); sb.AppendFormat("\t{0} -> {1}{2}", registerName, p.Name, nl); if (!string.IsNullOrEmpty(p.Name)) _registersToVariableNames.Add(registerName, p.Name); } sb.AppendLine(); } sb.AppendLine("Source code positions:"); Document lastDocument = null; foreach (var row in _mapFile.GetSourceCodePositions(methodEntry)) { if (row.Document != lastDocument) { sb.AppendFormat("\t{0}{1}", row.Document.Path, nl); lastDocument = row.Document; } var pos = row.Position; sb.AppendFormat("\t{0}\t({1},{2}) - ({3},{4}){5}", MethodDisassembly.FormatOffset(pos.MethodOffset), pos.Start.Line, pos.Start.Column, pos.End.Line, pos.End.Column, nl); } } } } return sb.ToString(); }
public static string FormatOperands(Instruction ins, MethodBody body, FormatOptions options = FormatOptions.Default) { StringBuilder ops = new StringBuilder(); bool fullTypeNames = options.HasFlag(FormatOptions.FullTypeNames); foreach (var r in ins.Registers) { if (ops.Length > 0) { ops.Append(","); Align(ops, 4); } ops.Append(FormatRegister(r, body)); } if (ops.Length == 0) ops.Append(" "); if (ins.Operand != null) { Align(ops, 12); if (ins.Operand is string) { ops.Append("\""); ops.Append(ins.Operand); ops.Append("\""); } else if (ins.Operand is sbyte) { FormatOperand_Integer(ops, (int)(byte)(sbyte)ins.Operand, "X2"); } else if (ins.Operand is short) { FormatOperand_Integer(ops, (int) (short) ins.Operand); } else if (ins.Operand is int) { FormatOperand_Integer(ops, (int) ins.Operand); } else if (ins.Operand is long) { var l = (long) ins.Operand; ops.Append(l); ops.Append(" (0x"); ops.Append(l.ToString("X8")); ops.Append(")"); } else if (ins.Operand is Instruction) { var target = (Instruction) ins.Operand; FormatOperand_Instruction(ops, ins, body, target, false); } else if (ins.Operand is ClassReference) { var m = (ClassReference) ins.Operand; ops.Append(fullTypeNames ? m.ToString() : m.Name); } else if (ins.Operand is MethodReference) { var m = (MethodReference) ins.Operand; var owner = fullTypeNames || !(m.Owner is ClassReference) ? m.ToString() : ((ClassReference) m.Owner).Name; ops.Append(owner + "::" + m.Name + m.Prototype); } else if (ins.Operand is FieldReference) { var m = (FieldReference) ins.Operand; ops.Append(fullTypeNames ? m.ToString() : m.Owner.Name + "::" + m.Name + " : " + m.Type); } else if (ins.Operand is PackedSwitchData) { var d = (PackedSwitchData) ins.Operand; FormatOperand_Integer(ops, d.FirstKey); ops.Append(":"); foreach (var target in d.Targets) { ops.Append(" "); FormatOperand_Instruction(ops, ins, body, target, true); } } else if (ins.Operand is SparseSwitchData) { var d = (SparseSwitchData) ins.Operand; bool isFirst = true; foreach (var target in d.Targets) { if (!isFirst) ops.Append(" "); ops.Append(target.Key); ops.Append(": "); FormatOperand_Instruction(ops, ins, body, target.Value, true); isFirst = false; } } else { ops.Append(ins.Operand); } if (options.HasFlag(FormatOptions.DebugOperandTypes)) ops.AppendFormat(" [{0}]", ins.Operand.GetType().Name); } var bstrOperands = ops.ToString(); return bstrOperands; }
public string Format(FormatOptions options) { var nl = Environment.NewLine; var sb = new StringBuilder(); var body = _methodDef.Body; var cfg = new ControlFlowGraph(body); SourceCodePosition lastSource = null; _dissassembly.Format = options; var embedSource = options.HasFlag(FormatOptions.EmbedSourceCode) || options.HasFlag(FormatOptions.EmbedSourcePositions); if (embedSource && _dissassembly.MethodEntry != null) { var pos = _mapFile.GetSourceCodePositions(_dissassembly.MethodEntry).FirstOrDefault(); if (pos != null) { sb.Append(" // ----- Source Code: "); sb.Append(pos.Document.Path); sb.Append(nl); } } foreach (var block in cfg) { if (options.HasFlag(FormatOptions.ShowControlFlow)) { sb.AppendFormat(" // ----- Entry [{0}] Exit [{1}]{2}", string.Join(", ", block.EntryBlocks.Select(x => _dissassembly.FormatAddress(x.Entry).Trim())), string.Join(", ", block.ExitBlocks.Select(x => _dissassembly.FormatAddress(x.Entry).Trim())), nl); } foreach (var i in block.Instructions) { if (embedSource) { var source = _dissassembly.FindSourceCode(i.Offset, false); if (source != null && lastSource != null && source.Document.Path != lastSource.Document.Path) { // print document name. sb.Append(" // ----- "); sb.Append(source.Document.Path); sb.Append(nl); lastSource = null; } if (source == null && lastSource != null) { sb.AppendLine(" // ----- (no source)"); } else if (source != null && (lastSource == null || !source.Position.EqualExceptOffset(lastSource.Position))) { if (options.HasFlag(FormatOptions.EmbedSourcePositions)) { sb.AppendFormat(" // ----- Position: {0} - {1}{2}", source.Position.Start, source.Position.End, nl); } if (options.HasFlag(FormatOptions.EmbedSourceCode)) { string[] lines = GetSourceCodeLines(source); if (lines != null) { sb.AppendLine(" // " + string.Join(nl + " // ", lines)); } } } lastSource = source; } sb.AppendLine(_dissassembly.FormatInstruction(i)); } } sb.AppendLine(); if (body.Exceptions.Any()) { sb.AppendLine("Exception handlers:"); foreach (var handler in body.Exceptions) { sb.AppendFormat("\t{0} - {1}{2}", _dissassembly.FormatAddress(handler.TryStart), _dissassembly.FormatAddress(handler.TryEnd), nl); foreach (var c in handler.Catches) { sb.AppendFormat("\t\t{0} => {1}{2}", c.Type, _dissassembly.FormatAddress(c.Instruction), nl); } if (handler.CatchAll != null) { sb.AppendFormat("\t\t{0} => {1}{2}", "<any>", _dissassembly.FormatAddress(handler.CatchAll), nl); } } sb.AppendLine(); } if (_mapFile != null) { var typeEntry = _mapFile.GetTypeByNewName(_methodDef.Owner.Fullname); if (typeEntry != null) { var methodEntry = typeEntry.FindDexMethod(_methodDef.Name, _methodDef.Prototype.ToSignature()); if (methodEntry != null) { _registersToVariableNames = new Dictionary <string, string>(); var validParameters = methodEntry.Parameters.Where(x => !string.IsNullOrEmpty(x.Name)).ToList(); if (validParameters.Any()) { sb.AppendLine("Parameters:"); foreach (var p in validParameters) { var registerName = _dissassembly.FormatRegister(p.Register); sb.AppendFormat("\t{0} (r{1}) -> {2}{3}", registerName, p.Register, p.Name, nl); if (!string.IsNullOrEmpty(p.Name)) { _registersToVariableNames.Add(registerName, p.Name); } } sb.AppendLine(); } var validVariables = methodEntry.Variables.Where(x => !string.IsNullOrEmpty(x.Name)).ToList(); if (validVariables.Any()) { sb.AppendLine("Variables:"); foreach (var p in validVariables) { var registerName = _dissassembly.FormatRegister(p.Register); sb.AppendFormat("\t{0} -> {1}{2}", registerName, p.Name, nl); if (!string.IsNullOrEmpty(p.Name)) { _registersToVariableNames.Add(registerName, p.Name); } } sb.AppendLine(); } sb.AppendLine("Source code positions:"); Document lastDocument = null; foreach (var row in _mapFile.GetSourceCodePositions(methodEntry)) { if (row.Document != lastDocument) { sb.AppendFormat("\t{0}{1}", row.Document.Path, nl); lastDocument = row.Document; } var pos = row.Position; sb.AppendFormat("\t{0}\t({1},{2}) - ({3},{4}){5}", MethodDisassembly.FormatOffset(pos.MethodOffset), pos.Start.Line, pos.Start.Column, pos.End.Line, pos.End.Column, nl); } } } } return(sb.ToString()); }