예제 #1
0
        public void ReadDataArray <T>(ref DEBUG_PROPERTY_INFO propertyInfo, string typeAsString)
        {
            byte[] xData;

            // Get handle
            xData = mProcess.mDbgConnector.GetStackData(OFFSET, 4);
            // Get actual pointer
            xData = mProcess.mDbgConnector.GetMemoryData(BitConverter.ToUInt32(xData, 0), 4);
            if (xData == null)
            {
                propertyInfo.bstrValue = String.Format("Error! Stack data received was null!");
            }
            else
            {
                uint xPointer = BitConverter.ToUInt32(xData, 0);
                if (xPointer == 0)
                {
                    propertyInfo.bstrValue = NULL;
                }
                else
                {
                    xData = mProcess.mDbgConnector.GetMemoryData(xPointer + mArrayLengthOffset, 4, 4);
                    if (xData == null)
                    {
                        propertyInfo.bstrValue = String.Format("Error! Memory data received was null!");
                    }
                    else
                    {
                        uint xDataLength = BitConverter.ToUInt32(xData, 0);
                        bool xIsTooLong  = xDataLength > 512;
                        if (xIsTooLong)
                        {
                            xDataLength = 512;
                        }
                        if (xDataLength > 0)
                        {
                            if (m_variableInformation.Children.Count == 0)
                            {
                                for (int i = 0; i < xDataLength; i++)
                                {
                                    var inf = new DebugLocalInfo();
                                    inf.IsReference = true;
                                    inf.Type        = typeof(T).FullName;
                                    inf.Offset      = (int)(mArrayFirstElementOffset + (System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)) * i));
                                    inf.Pointer     = (uint)(xPointer + mArrayFirstElementOffset + (System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)) * i));
                                    inf.Name        = "[" + i.ToString() + "]";
                                    m_variableInformation.Children.Add(new AD7Property(inf, mProcess, mStackFrame));
                                }
                            }
                        }
                        propertyInfo.bstrValue = String.Format(typeAsString + "[{0}] at 0x{1} ", xDataLength, xPointer.ToString("X"));
                    }
                }
            }
        }
예제 #2
0
 public AD7Property(DebugLocalInfo localInfo, AD7Process process, AD7StackFrame stackFrame)
 {
     m_variableInformation = localInfo;
     mProcess    = process;
     mStackFrame = stackFrame;
     if (localInfo.IsLocal)
     {
         mDebugInfo = mStackFrame.mLocalInfos[m_variableInformation.Index];
     }
     else if (localInfo.IsReference)
     {
         mDebugInfo = new LOCAL_ARGUMENT_INFO()
         {
             TYPENAME = localInfo.Type,
             NAME     = localInfo.Name,
             OFFSET   = localInfo.Offset
         };
     }
     else
     {
         mDebugInfo = mStackFrame.mArgumentInfos[m_variableInformation.Index];
     }
 }
예제 #3
0
        public AD7StackFrame(AD7Engine aEngine, AD7Thread aThread, AD7Process aProcess)
        {
            mEngine  = aEngine;
            mThread  = aThread;
            mProcess = aProcess;
            var xProcess = mEngine.mProcess;

            if (mHasSource = xProcess.mCurrentAddress.HasValue)
            {
                var xAddress     = xProcess.mCurrentAddress.Value;
                var xSourceInfos = xProcess.mDebugInfoDb.GetSourceInfos(xAddress);
                if (!xSourceInfos.ContainsKey(xAddress))
                {
                    //Attempt to find the ASM address of the first ASM line of the C# line that contains
                    //the current ASM address line

                    // Because of Asm breakpoints the address we have might be in the middle of a C# line.
                    // So we find the closest address to ours that is less or equal to ours.
                    var xQry = from x in xSourceInfos
                               where x.Key <= xAddress
                               orderby x.Key descending
                               select x.Key;
                    if (xQry.Count() > 0)
                    {
                        xAddress = xQry.First();
                    }
                }
                if (mHasSource = xSourceInfos.ContainsKey(xAddress))
                {
                    var xSourceInfo = xSourceInfos[xAddress];
                    mDocName      = xSourceInfo.SourceFile;
                    mFunctionName = xSourceInfo.MethodName;
                    mLineNum      = (uint)xSourceInfo.LineStart;

                    // Multiple labels that point to a single address can happen because of exception handling exits etc.
                    // Because of this given an address, we might find more than one label that matches the address.
                    // Currently, the label we are looking for will always be the first one so we choose that one.
                    // In the future this might "break", so be careful about this. In the future we may need to classify
                    // labels in the output and mark them somehow.
                    var xLabelsForAddr = xProcess.mDebugInfoDb.GetLabels(xAddress);
                    if (xLabelsForAddr.Length > 0)
                    {
                        MethodIlOp xSymbolInfo;
                        string     xLabel = xLabelsForAddr[0]; // Necessary for LINQ
                        xSymbolInfo = aProcess.mDebugInfoDb.TryGetFirstMethodIlOpByLabelName(xLabel);
                        if (xSymbolInfo != null)
                        {
                            var xMethod   = mProcess.mDebugInfoDb.GetMethod(xSymbolInfo.MethodID.Value);
                            var xAllInfos = aProcess.mDebugInfoDb.GetAllLocalsAndArgumentsInfosByMethodLabelName(xMethod.LabelCall);
                            mLocalInfos    = xAllInfos.Where(q => !q.IsArgument).ToArray();
                            mArgumentInfos = xAllInfos.Where(q => q.IsArgument).ToArray();
                            if (mArgumentInfos.Length > 0)
                            {
                                mParams = new DebugLocalInfo[mArgumentInfos.Length];
                                for (int i = 0; i < mArgumentInfos.Length; i++)
                                {
                                    mParams[i] = new DebugLocalInfo
                                    {
                                        Name    = mArgumentInfos[i].NAME,
                                        Index   = i,
                                        IsLocal = false
                                    };
                                }
                                mParams = mParams.OrderBy(i => i.Name, StringComparer.OrdinalIgnoreCase).ToArray();
                            }

                            if (mLocalInfos.Length > 0)
                            {
                                mLocals = new DebugLocalInfo[mLocalInfos.Length];
                                for (int i = 0; i < mLocalInfos.Length; i++)
                                {
                                    mLocals[i] = new DebugLocalInfo
                                    {
                                        Name    = mLocalInfos[i].NAME,
                                        Index   = i,
                                        IsLocal = true
                                    };
                                }
                                mLocals = mLocals.OrderBy(i => i.Name, StringComparer.OrdinalIgnoreCase).ToArray();
                            }
                        }
                    }
                    else
                    {
                        AD7Util.ShowError("No Symbol found for address 0x" + xAddress.ToString("X8").ToUpper());
                    }
                    xProcess.DebugMsg(String.Format("StackFrame: Returning: {0}#{1}[{2}]", mDocName, mFunctionName, mLineNum));
                }
            }
            if (!mHasSource)
            {
                xProcess.DebugMsg("StackFrame: No Source available");
            }

            // If source information is available, create the collections of locals and parameters and populate them with
            // values from the debuggee.
            //if (m_hasSource) {
            //if (mArgumentInfos.Length > 0) {
            //m_parameters = new VariableInformation[m_numParameters];
            //m_engine.DebuggedProcess.GetFunctionArgumentsByIP(m_threadContext.eip, m_threadContext.ebp, m_parameters);
            //}

            //if (mLocalInfos.Length > 0) {
            //m_locals = new VariableInformation[m_numLocals];
            //m_engine.DebuggedProcess.GetFunctionLocalsByIP(m_threadContext.eip, m_threadContext.ebp, m_locals);
            //}
            //}
        }
예제 #4
0
 public AD7Expression(DebugLocalInfo pVar, AD7Process pProcess, AD7StackFrame pStackFrame)
 {
     m_var      = pVar;
     Process    = pProcess;
     StackFrame = pStackFrame;
 }
예제 #5
0
        // Construct a DEBUG_PROPERTY_INFO representing this local or parameter.
        public DEBUG_PROPERTY_INFO ConstructDebugPropertyInfo(enum_DEBUGPROP_INFO_FLAGS dwFields)
        {
            var propertyInfo = new DEBUG_PROPERTY_INFO();

            try
            {
                if (dwFields.HasFlag(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_FULLNAME))
                {
                    propertyInfo.bstrFullName = m_variableInformation.Name;
                    propertyInfo.dwFields    |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_FULLNAME;
                }

                if (dwFields.HasFlag(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_NAME))
                {
                    propertyInfo.bstrName  = m_variableInformation.Name;
                    propertyInfo.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_NAME;
                }

                if (dwFields.HasFlag(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_TYPE))
                {
                    propertyInfo.bstrType  = mDebugInfo.TYPENAME;
                    propertyInfo.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_TYPE;
                }

                if (dwFields.HasFlag(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE))
                {
                    byte[] xData;

                    #region string
                    if (mDebugInfo.TYPENAME == typeof(string).FullName)
                    {
                        const uint xStringLengthOffset    = 12;
                        const uint xStringFirstCharOffset = 16;
                        // Get handle
                        xData = mProcess.mDbgConnector.GetStackData(OFFSET, 4);
                        // Get actual pointer
                        xData = mProcess.mDbgConnector.GetMemoryData(BitConverter.ToUInt32(xData, 0), 4);
                        if (xData == null)
                        {
                            propertyInfo.bstrValue = String.Format("Error! Stack data received was null!");
                        }
                        else
                        {
                            uint xStrPointer = BitConverter.ToUInt32(xData, 0);
                            if (xStrPointer == 0)
                            {
                                propertyInfo.bstrValue = NULL;
                            }
                            else
                            {
                                xData = mProcess.mDbgConnector.GetMemoryData(xStrPointer + xStringLengthOffset, 4, 4);
                                if (xData == null)
                                {
                                    propertyInfo.bstrValue = String.Format("Error! Memory data received was null!");
                                }
                                else
                                {
                                    uint xStringLength = BitConverter.ToUInt32(xData, 0);
                                    propertyInfo.bstrValue = "String of length: " + xStringLength;
                                    if (xStringLength > 100)
                                    {
                                        propertyInfo.bstrValue = "For now, strings larger than 100 chars are not supported..";
                                    }
                                    else if (xStringLength == 0)
                                    {
                                        propertyInfo.bstrValue = "\"\"";
                                    }
                                    else
                                    {
                                        xData = mProcess.mDbgConnector.GetMemoryData(xStrPointer + xStringFirstCharOffset, xStringLength * 2, 2);
                                        if (xData == null)
                                        {
                                            propertyInfo.bstrValue = String.Format("Error! Memory data received was null!");
                                        }
                                        else
                                        {
                                            propertyInfo.bstrValue = "\"" + Encoding.Unicode.GetString(xData) + "\"";
                                        }
                                    }
                                }
                            }
                        }
                    }
                    #endregion

#warning TODO: String[]

                    #region byte
                    // Byte
                    else if (mDebugInfo.TYPENAME == typeof(byte).FullName)
                    {
                        ReadData <byte>(ref propertyInfo, new Func <byte[], int, byte>(delegate(byte[] barr, int ind) { return(barr[ind]); }));
                    }
                    else if (mDebugInfo.TYPENAME == typeof(byte[]).FullName)
                    {
                        ReadDataArray <byte>(ref propertyInfo, "byte");
                    }
                    #endregion

                    #region sbyte
                    // SByte
                    else if (mDebugInfo.TYPENAME == typeof(sbyte).FullName)
                    {
                        ReadData <sbyte>(ref propertyInfo, new Func <byte[], int, sbyte>(delegate(byte[] barr, int ind) { return(unchecked ((sbyte)barr[ind])); }));
                    }
                    else if (mDebugInfo.TYPENAME == typeof(sbyte[]).FullName)
                    {
                        ReadDataArray <sbyte>(ref propertyInfo, "sbyte");
                    }
                    #endregion

                    #region char
                    else if (mDebugInfo.TYPENAME == typeof(char).FullName)
                    {
                        xData = mProcess.mDbgConnector.GetStackData(OFFSET, 2);
                        if (xData == null)
                        {
                            propertyInfo.bstrValue = String.Format("Error! Stack data received was null!");
                        }
                        else
                        {
                            var xTypedCharValue = BitConverter.ToChar(xData, 0);
                            propertyInfo.bstrValue = String.Format("{0} '{1}'", (ushort)xTypedCharValue, xTypedCharValue);
                        }
                    }
                    else if (mDebugInfo.TYPENAME == typeof(char[]).FullName)
                    {
                        // Get handle
                        xData = mProcess.mDbgConnector.GetStackData(OFFSET, 4);
                        // Get actual pointer
                        xData = mProcess.mDbgConnector.GetMemoryData(BitConverter.ToUInt32(xData, 0), 4);

                        if (xData == null)
                        {
                            propertyInfo.bstrValue = String.Format("Error! Stack data received was null!");
                        }
                        else
                        {
                            uint xArrayPointer = BitConverter.ToUInt32(xData, 0);
                            if (xArrayPointer == 0)
                            {
                                propertyInfo.bstrValue = NULL;
                            }
                            else
                            {
                                xData = mProcess.mDbgConnector.GetMemoryData(xArrayPointer + mArrayLengthOffset, 4, 4);
                                if (xData == null)
                                {
                                    propertyInfo.bstrValue = String.Format("Error! Memory data received was null!");
                                }
                                else
                                {
                                    uint xDataLength = BitConverter.ToUInt32(xData, 0);
                                    bool xIsTooLong  = xDataLength > 512;
                                    var  xSB         = new StringBuilder();
                                    xSB.AppendFormat("Char[{0}] at 0x{1} {{ ", xDataLength, xArrayPointer.ToString("X"));
                                    if (xIsTooLong)
                                    {
                                        xDataLength = 512;
                                    }
                                    if (xDataLength > 0)
                                    {
                                        xData = mProcess.mDbgConnector.GetMemoryData(xArrayPointer + mArrayFirstElementOffset, xDataLength * 2);
                                        if (xData == null)
                                        {
                                            xSB.Append(String.Format("Error! Memory data received was null!"));
                                        }
                                        else
                                        {
                                            bool first = true;
                                            for (int i = 0; (i / 2) < xDataLength; i += 2)
                                            {
                                                if (!first)
                                                {
                                                    xSB.Append(", ");
                                                }

                                                char c = BitConverter.ToChar(xData, i);
                                                xSB.Append('\'');

                                                if (c == '\0')
                                                {
                                                    xSB.Append("\\0");
                                                }
                                                else
                                                {
                                                    xSB.Append(c);
                                                }

                                                xSB.Append('\'');

                                                first = false;
                                            }
                                        }
                                    }
                                    if (xIsTooLong)
                                    {
                                        xSB.Append(", ..");
                                    }

                                    xSB.Append(" }");
                                    propertyInfo.bstrValue = xSB.ToString();
                                }
                            }
                        }
                    }
                    #endregion

                    #region short
                    // Short
                    else if (mDebugInfo.TYPENAME == typeof(short).FullName)
                    {
                        ReadData <short>(ref propertyInfo, new Func <byte[], int, short>(BitConverter.ToInt16));
                    }
                    else if (mDebugInfo.TYPENAME == typeof(short[]).FullName)
                    {
                        ReadDataArray <short>(ref propertyInfo, "short");
                    }
                    #endregion

                    #region ushort
                    // UShort
                    else if (mDebugInfo.TYPENAME == typeof(ushort).FullName)
                    {
                        ReadData <ushort>(ref propertyInfo, new Func <byte[], int, ushort>(BitConverter.ToUInt16));
                    }
                    else if (mDebugInfo.TYPENAME == typeof(ushort[]).FullName)
                    {
                        ReadDataArray <ushort>(ref propertyInfo, "ushort");
                    }
                    #endregion

                    #region int
                    // Int32
                    else if (mDebugInfo.TYPENAME == typeof(int).FullName)
                    {
                        ReadData <int>(ref propertyInfo, new Func <byte[], int, int>(BitConverter.ToInt32));
                    }
                    else if (mDebugInfo.TYPENAME == typeof(int[]).FullName)
                    {
                        ReadDataArray <int>(ref propertyInfo, "int");
                    }
                    #endregion

                    #region uint
                    // UInt32
                    else if (mDebugInfo.TYPENAME == typeof(uint).FullName)
                    {
                        ReadData <uint>(ref propertyInfo, new Func <byte[], int, uint>(BitConverter.ToUInt32));
                    }
                    else if (mDebugInfo.TYPENAME == typeof(uint[]).FullName)
                    {
                        ReadDataArray <uint>(ref propertyInfo, "uint");
                    }
                    #endregion

                    #region long
                    // Long
                    else if (mDebugInfo.TYPENAME == typeof(long).FullName)
                    {
                        ReadData <long>(ref propertyInfo, new Func <byte[], int, long>(BitConverter.ToInt64));
                    }
                    else if (mDebugInfo.TYPENAME == typeof(long[]).FullName)
                    {
                        ReadDataArray <long>(ref propertyInfo, "long");
                    }
                    #endregion

                    #region ulong
                    // ULong
                    else if (mDebugInfo.TYPENAME == typeof(ulong).FullName)
                    {
                        ReadData <ulong>(ref propertyInfo, new Func <byte[], int, ulong>(BitConverter.ToUInt64));
                    }
                    else if (mDebugInfo.TYPENAME == typeof(ulong[]).FullName)
                    {
                        ReadDataArray <ulong>(ref propertyInfo, "ulong");
                    }
                    #endregion

                    #region float
                    // Float
                    else if (mDebugInfo.TYPENAME == typeof(float).FullName)
                    {
                        ReadData <float>(ref propertyInfo, new Func <byte[], int, float>(BitConverter.ToSingle));
                    }
                    else if (mDebugInfo.TYPENAME == typeof(float[]).FullName)
                    {
                        ReadDataArray <float>(ref propertyInfo, "float");
                    }
                    #endregion

                    #region double
                    // Double
                    else if (mDebugInfo.TYPENAME == typeof(double).FullName)
                    {
                        ReadData <double>(ref propertyInfo, new Func <byte[], int, double>(BitConverter.ToDouble));
                    }
                    else if (mDebugInfo.TYPENAME == typeof(double[]).FullName)
                    {
                        ReadDataArray <double>(ref propertyInfo, "double");
                    }
                    #endregion

                    #region bool
                    // Bool
                    else if (mDebugInfo.TYPENAME == typeof(bool).FullName)
                    {
                        ReadData <bool>(ref propertyInfo, new Func <byte[], int, bool>(BitConverter.ToBoolean));
                    }
                    else if (mDebugInfo.TYPENAME == typeof(bool[]).FullName)
                    {
                        ReadDataArray <bool>(ref propertyInfo, "bool");
                    }
                    #endregion

                    else
                    {
                        if (m_variableInformation.IsReference)
                        {
                            xData = mProcess.mDbgConnector.GetMemoryData(m_variableInformation.Pointer, 4, 4);
                        }
                        else
                        {
                            xData = mProcess.mDbgConnector.GetStackData(OFFSET, 4);
                        }
                        if (xData == null)
                        {
                            propertyInfo.bstrValue = String.Format("Error! Stack data received was null!");
                        }
                        else
                        {
                            var xPointer = BitConverter.ToUInt32(xData, 0);
                            if (xPointer == 0)
                            {
                                propertyInfo.bstrValue = NULL;
                            }
                            else
                            {
                                try
                                {
                                    var mp = mProcess.mDebugInfoDb.GetFieldMap(mDebugInfo.TYPENAME);
                                    foreach (string str in mp.FieldNames)
                                    {
                                        FIELD_INFO xFieldInfo;
                                        xFieldInfo = mProcess.mDebugInfoDb.GetFieldInfoByName(str);
                                        var inf = new DebugLocalInfo();
                                        inf.IsReference = true;
                                        inf.Type        = xFieldInfo.TYPE;
                                        inf.Offset      = xFieldInfo.OFFSET;
                                        inf.Pointer     = (uint)(xPointer + xFieldInfo.OFFSET + 12);
                                        inf.Name        = GetFieldName(xFieldInfo);
                                        m_variableInformation.Children.Add(new AD7Property(inf, mProcess, mStackFrame));
                                    }
                                    propertyInfo.bstrValue = String.Format("{0} (0x{1})", xPointer, xPointer.ToString("X").ToUpper());
                                }
                                catch (Exception ex)
                                {
                                    if (ex.GetType().Name == "SQLiteException")
                                    {
                                        //Ignore but warn user
                                        propertyInfo.bstrValue = "SQLiteException. Could not get type information for " + mDebugInfo.TYPENAME;
                                    }
                                    else
                                    {
                                        throw new Exception("Unexpected error in AD7Property.cs:459", ex);
                                    }
                                }
                            }
                        }
                    }
                    propertyInfo.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE;
                }

                if (dwFields.HasFlag(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_ATTRIB))
                {
                    // The sample does not support writing of values displayed in the debugger, so mark them all as read-only.
                    propertyInfo.dwAttrib = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_VALUE_READONLY;

                    if (m_variableInformation.Children.Count > 0)
                    {
                        propertyInfo.dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_OBJ_IS_EXPANDABLE;
                    }
                }

                propertyInfo.pProperty = (IDebugProperty2)this;
                propertyInfo.dwFields |= (enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_PROP);
                // If the debugger has asked for the property, or the property has children (meaning it is a pointer in the sample)
                // then set the pProperty field so the debugger can call back when the children are enumerated.
                //if (((dwFields & (uint)enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_PROP) != 0)
                //|| (this.m_variableInformation.child != null))
                //{
                //    propertyInfo.pProperty = (IDebugProperty2)this;
                //    propertyInfo.dwFields |= (enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_PROP);
                //}
            }
            catch
            {
            }

            return(propertyInfo);
        }