Пример #1
0
        private ColorString FormatRGB(uint numColumns, bool withAlpha)
        {
            var   bytes        = Memory.Bytes;
            bool  is32Bit      = Debugger.TargetIs32Bit;
            ulong startAddress = Memory.StartAddress;

            if (0 == numColumns)
            {
                numColumns = 64;
            }

            ColorString cs = new ColorString();

            var bytesPerCharacter = withAlpha ? 4 : 3;
            int bytesPerRow       = (int)numColumns * bytesPerCharacter + 3 & ~(3); //round up

            for (int rowStart = 0; rowStart + bytesPerCharacter < bytes.Count; rowStart += bytesPerRow)
            {
                if (rowStart != 0)
                {
                    cs.AppendLine();
                }
                cs.Append(DbgProvider.FormatAddress(startAddress + (uint)rowStart, is32Bit, true, true)).Append("  ");

                var rowLen = Math.Min(bytes.Count - rowStart, bytesPerRow);

                for (int colOffset = 0; colOffset + bytesPerCharacter < rowLen; colOffset += bytesPerCharacter)
                {
                    byte   b  = bytes[rowStart + colOffset + 0];
                    byte   g  = bytes[rowStart + colOffset + 1];
                    byte   r  = bytes[rowStart + colOffset + 2];
                    string ch = "█";
                    if (withAlpha)
                    {
                        ch = AlphaChars[bytes[rowStart + colOffset + 3] >> 6];
                    }
                    cs.AppendFgRgb(r, g, b, ch);
                }
            }

            return(cs.MakeReadOnly());
        }
Пример #2
0
        // Throws a DbgProviderException if the disassembly represents a bad memory access.
        internal static DbgDisassembly _ParseDisassembly(ulong address,
                                                         string s,
                                                         ColorString blockId,
                                                         bool hasCodeBytes)
        {
            // Example inputs:
            //
            //    0113162e 55              push    ebp
            //    0113162f 8bec            mov     ebp,esp
            //    01131631 51              push    ecx
            //    01131632 894dfc          mov     dword ptr [ebp-4],ecx
            //    01131635 8b45fc          mov     eax,dword ptr [ebp-4]
            //    01131638 c70068c81301    mov     dword ptr [eax],offset TestNativeConsoleApp!VirtualBase1::`vftable' (0113c868)
            //    0113163e 8b4508          mov     eax,dword ptr [ebp+8]
            //    01131641 83e001          and     eax,1
            //    01131644 740a            je      TestNativeConsoleApp!VirtualBase1::`scalar deleting destructor'+0x22 (01131650)
            //    01131646 ff75fc          push    dword ptr [ebp-4]
            //    01131649 ff1578c01301    call    dword ptr [TestNativeConsoleApp!_imp_??3YAXPAXZ (0113c078)]
            //    0113164f 59              pop     ecx
            //    01131650 8b45fc          mov     eax,dword ptr [ebp-4]
            //    01131653 c9              leave
            //    01131654 c20400          ret     4
            //
            // Here's what it looks like if the address is bad:
            //
            //    00007ff6`ece87d60 ??              ???
            //

            ColorString cs = new ColorString();

            byte[] codeBytes   = null;
            string instruction = null;
            string arguments   = null;

            Regex goodRegex;
            Regex badRegex;

            if (hasCodeBytes)
            {
                goodRegex = sm_asmRegex;
                badRegex  = sm_badAsmRegex;
            }
            else
            {
                goodRegex = sm_asmRegex_noCodeBytes;
                badRegex  = sm_badAsmRegex_noCodeBytes;
            }

            int matchCount = 0;

            foreach (Match match in goodRegex.Matches(s))
            {
                if (0 == address)
                {
                    // Then we need to parse it out. (this is for -WholeFunction.
                    if (!DbgProvider.TryParseHexOrDecimalNumber(match.Groups["addr"].Value, out address))
                    {
                        throw new Exception(Util.Sprintf("Couldn't convert to address: {0}", match.Groups["addr"].Value));
                    }
                }
#if DEBUG
                else
                {
                    ulong parsedAddress;
                    if (!DbgProvider.TryParseHexOrDecimalNumber(match.Groups["addr"].Value, out parsedAddress))
                    {
                        throw new Exception(Util.Sprintf("Couldn't convert to address: {0}", match.Groups["addr"].Value));
                    }

                    // Nope: these are routinely different on ARM/THUMB2, where the low
                    // bit of the program counter is used as some sort of flag.
                    //Util.Assert( address == parsedAddress );
                }
#endif

                if (hasCodeBytes)
                {
                    codeBytes = Util.ConvertToBytes(match.Groups["codebytes"].Value);
                }

                instruction = match.Groups["instr"].Value;
                arguments   = match.Groups["args"].Value;

                matchCount++;
                cs.AppendPushPopFg(ConsoleColor.DarkCyan, match.Groups["addr"].Value)
                .Append(match.Groups["space1"].Value);

                if (hasCodeBytes)
                {
                    cs.AppendPushPopFg(ConsoleColor.DarkGray, match.Groups["codebytes"].Value)
                    .Append(match.Groups["space2"].Value);
                }

                var instr = match.Groups["instr"].Value;
                cs.Append(DbgProvider.ColorizeInstruction(instr));

                cs.Append(match.Groups["space3"].Value);
                cs.Append(match.Groups["args"].Value);
            }

            if (0 == matchCount)
            {
                var match = badRegex.Match(s);
                if ((null != match) && match.Success)
                {
                    string addrString = match.Groups["addr"].Value;
                    if (0 == address)
                    {
                        if (!DbgProvider.TryParseHexOrDecimalNumber(addrString, out address))
                        {
                            Util.Fail(Util.Sprintf("Couldn't convert to address: {0}", addrString));
                        }
                    }

                    throw new DbgMemoryAccessException(address,
                                                       Util.Sprintf("No code found at {0}.",
                                                                    addrString));
                }
                else
                {
                    throw new Exception(Util.Sprintf("TODO: Need to handle disassembly format: {0}", s));
                }
            }
            else
            {
                Util.Assert(1 == matchCount);
            }

            return(new DbgDisassembly(address,
                                      codeBytes,
                                      instruction,
                                      arguments,
                                      blockId,
                                      cs.MakeReadOnly()));
        } // end _ParseDisassembly()