Beispiel #1
0
        private string GetUnwindCode(ref int i)
        {
            StringBuilder sb   = new StringBuilder();
            string        tab2 = new string(' ', 8);

            sb.AppendLine($"{tab2}CodeOffset: 0x{UnwindCode[i].CodeOffset:X2}");
            sb.AppendLine($"{tab2}UnwindOp: {UnwindCode[i].UnwindOp}({(byte)UnwindCode[i].UnwindOp})");

            switch (UnwindCode[i].UnwindOp)
            {
            case UnwindOpCodes.UWOP_PUSH_NONVOL:
                sb.AppendLine($"{tab2}OpInfo: {(Amd64Registers)UnwindCode[i].OpInfo}({UnwindCode[i].OpInfo})");
                break;

            case UnwindOpCodes.UWOP_ALLOC_LARGE:
                sb.Append($"{tab2}OpInfo: {UnwindCode[i].OpInfo} - ");
                if (UnwindCode[i].OpInfo == 0)
                {
                    i++;
                    sb.AppendLine("Scaled small");
                    uint frameOffset = UnwindCode[i].FrameOffset * 8;
                    sb.AppendLine($"{tab2}FrameOffset: {UnwindCode[i].FrameOffset} * 8 = {frameOffset} = 0x{frameOffset:X5})");
                }
                else if (UnwindCode[i].OpInfo == 1)
                {
                    i++;
                    sb.AppendLine("Unscaled large");
                    uint offset = UnwindCode[i].FrameOffset;
                    i++;
                    offset = ((UnwindCode[i].FrameOffset << 16) | offset);
                    sb.AppendLine($"{tab2}FrameOffset: 0x{offset:X8})");
                }
                else
                {
                    sb.AppendLine("Unknown");
                }
                break;

            case UnwindOpCodes.UWOP_ALLOC_SMALL:
                int opInfo = UnwindCode[i].OpInfo * 8 + 8;
                sb.AppendLine($"{tab2}OpInfo: {UnwindCode[i].OpInfo} * 8 + 8 = {opInfo} = 0x{opInfo:X2}");
                break;

            case UnwindOpCodes.UWOP_SET_FPREG:
                sb.AppendLine($"{tab2}OpInfo: Unused({UnwindCode[i].OpInfo})");
                break;

            case UnwindOpCodes.UWOP_SET_FPREG_LARGE:
            {
                sb.AppendLine($"{tab2}OpInfo: Unused({UnwindCode[i].OpInfo})");
                i++;
                uint offset = UnwindCode[i].FrameOffset;
                i++;
                offset = ((UnwindCode[i].FrameOffset << 16) | offset);
                sb.AppendLine($"{tab2}Scaled Offset: {offset} * 16 = {offset * 16} = 0x{(offset * 16):X8}");
                if ((UnwindCode[i].FrameOffset & 0xF0000000) != 0)
                {
                    R2RDump.WriteWarning("Illegal unwindInfo unscaled offset: too large");
                }
            }
            break;

            case UnwindOpCodes.UWOP_SAVE_NONVOL:
            {
                sb.AppendLine($"{tab2}OpInfo: {(Amd64Registers)UnwindCode[i].OpInfo}({UnwindCode[i].OpInfo})");
                i++;
                uint offset = UnwindCode[i].FrameOffset * 8;
                sb.AppendLine($"{tab2}Scaled Offset: {UnwindCode[i].FrameOffset} * 8 = {offset} = 0x{offset:X5}");
            }
            break;

            case UnwindOpCodes.UWOP_SAVE_NONVOL_FAR:
            {
                sb.AppendLine($"{tab2}OpInfo: {(Amd64Registers)UnwindCode[i].OpInfo}({UnwindCode[i].OpInfo})");
                i++;
                uint offset = UnwindCode[i].FrameOffset;
                i++;
                offset = ((UnwindCode[i].FrameOffset << 16) | offset);
                sb.AppendLine($"{tab2}Unscaled Large Offset: 0x{offset:X8}");
            }
            break;

            case UnwindOpCodes.UWOP_SAVE_XMM128:
            {
                sb.AppendLine($"{tab2}OpInfo: XMM{UnwindCode[i].OpInfo}({UnwindCode[i].OpInfo})");
                i++;
                uint offset = UnwindCode[i].FrameOffset * 16;
                sb.AppendLine($"{tab2}Scaled Offset: {UnwindCode[i].FrameOffset} * 16 = {offset} = 0x{offset:X5}");
            }
            break;

            case UnwindOpCodes.UWOP_SAVE_XMM128_FAR:
            {
                sb.AppendLine($"{tab2}OpInfo: XMM{UnwindCode[i].OpInfo}({UnwindCode[i].OpInfo})");
                i++;
                uint offset = UnwindCode[i].FrameOffset;
                i++;
                offset = ((UnwindCode[i].FrameOffset << 16) | offset);
                sb.AppendLine($"{tab2}Unscaled Large Offset: 0x{offset:X8}");
            }
            break;

            case UnwindOpCodes.UWOP_EPILOG:
            case UnwindOpCodes.UWOP_SPARE_CODE:
            case UnwindOpCodes.UWOP_PUSH_MACHFRAME:
            default:
                sb.AppendLine($"{tab2}OpInfo: {UnwindCode[i].OpInfo}");
                sb.AppendLine();
                sb.AppendLine($"{tab2}OffsetLow: {UnwindCode[i].OffsetLow}");
                sb.AppendLine($"{tab2}OffsetHigh: {UnwindCode[i].OffsetHigh}");
                sb.AppendLine();
                sb.AppendLine($"{tab2}FrameOffset: {FrameOffset}");
                break;
            }
            return(sb.ToString());
        }
Beispiel #2
0
        /// <summary>
        /// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/jit/unwindamd64.cpp">src\jit\unwindamd64.cpp</a> DumpUnwindInfo
        /// </summary>
        private void ParseUnwindCode(ref int i)
        {
            UnwindCode code = UnwindCodeArray[i];

            code.IsOpInfo = true;
            switch (code.UnwindOp)
            {
            case UnwindOpCodes.UWOP_PUSH_NONVOL:
                code.OpInfoStr = $"{(Registers)code.OpInfo}({code.OpInfo})";
                break;

            case UnwindOpCodes.UWOP_ALLOC_LARGE:
                code.OpInfoStr = $"{code.OpInfo} - ";
                if (code.OpInfo == 0)
                {
                    i++;
                    UnwindCodeArray[i].OpInfoStr += "Scaled small";
                    code.NextFrameOffset          = (int)UnwindCodeArray[i].FrameOffset * 8;
                }
                else if (code.OpInfo == 1)
                {
                    i++;
                    UnwindCodeArray[i].OpInfoStr += "Unscaled large";
                    uint offset = UnwindCodeArray[i].FrameOffset;
                    i++;
                    offset = ((UnwindCodeArray[i].FrameOffset << 16) | offset);
                    code.NextFrameOffset = (int)offset;
                }
                else
                {
                    code.OpInfoStr += "Unknown";
                }
                break;

            case UnwindOpCodes.UWOP_ALLOC_SMALL:
                int opInfo = code.OpInfo * 8 + 8;
                code.OpInfoStr = $"{opInfo}";
                break;

            case UnwindOpCodes.UWOP_SET_FPREG:
                code.OpInfoStr = $"Unused({code.OpInfo})";
                break;

            case UnwindOpCodes.UWOP_SET_FPREG_LARGE:
            {
                code.OpInfoStr = $"Unused({code.OpInfo})";
                i++;
                uint offset = UnwindCodeArray[i].FrameOffset;
                i++;
                offset = ((UnwindCodeArray[i].FrameOffset << 16) | offset);
                code.NextFrameOffset = (int)offset * 16;
                if ((UnwindCodeArray[i].FrameOffset & 0xF0000000) != 0)
                {
                    R2RDump.WriteWarning("Illegal unwindInfo unscaled offset: too large");
                }
            }
            break;

            case UnwindOpCodes.UWOP_SAVE_NONVOL:
            {
                code.OpInfoStr = $"{(Registers)code.OpInfo}({code.OpInfo})";
                i++;
                uint offset = UnwindCodeArray[i].FrameOffset * 8;
                code.NextFrameOffset = (int)offset;
            }
            break;

            case UnwindOpCodes.UWOP_SAVE_NONVOL_FAR:
            {
                code.OpInfoStr = $"{(Registers)code.OpInfo}({code.OpInfo})";
                i++;
                uint offset = UnwindCodeArray[i].FrameOffset;
                i++;
                offset = ((UnwindCodeArray[i].FrameOffset << 16) | offset);
                code.NextFrameOffset = (int)offset;
            }
            break;

            case UnwindOpCodes.UWOP_SAVE_XMM128:
            {
                code.OpInfoStr = $"XMM{code.OpInfo}({code.OpInfo})";
                i++;
                uint offset = UnwindCodeArray[i].FrameOffset * 16;
                code.NextFrameOffset = (int)offset;
            }
            break;

            case UnwindOpCodes.UWOP_SAVE_XMM128_FAR:
            {
                code.OpInfoStr = $"XMM{code.OpInfo}({code.OpInfo})";
                i++;
                uint offset = UnwindCodeArray[i].FrameOffset;
                i++;
                offset = ((UnwindCodeArray[i].FrameOffset << 16) | offset);
                code.NextFrameOffset = (int)offset;
            }
            break;
            }
        }