예제 #1
0
 private void BeginObject()
 {
     _builder.Append("{");
     if (_formatOptions.HasFlag(FormatOptions.MultiLine))
     {
         _builder.AppendLine();
         if (_formatOptions.HasFlag(FormatOptions.Indented))
         {
             ++_indent;
             _builder.Append('\t', _indent);
         }
     }
 }
예제 #2
0
        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();
        }
예제 #4
0
        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;
        }
예제 #5
0
        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());
        }