Exemple #1
0
        public void GetInfoAddress()
        {
            var contextInfo = new CONTEXT_INFO[1];

            Assert.AreEqual(VSConstants.S_OK,
                            memoryContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfo));
            Assert.AreEqual(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfo[0].dwFields);
            Assert.AreEqual(TEST_PC_STR, contextInfo[0].bstrAddress);
        }
Exemple #2
0
        public int WriteAt(IDebugMemoryContext2 startMemoryContext, uint count, byte[] buffer)
        {
            CONTEXT_INFO[] contextInfos = new CONTEXT_INFO[1];
            startMemoryContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfos);
            ulong address;

            if (!DebugEngineUtil.GetAddressFromString(contextInfos[0].bstrAddress, out address))
            {
                Trace.WriteLine($"Failed to convert {contextInfos[0].bstrAddress} to address");
                return(VSConstants.E_FAIL);
            }
            SbError error;
            var     bytesWrote = _lldbProcess.WriteMemory(address, buffer, count, out error);

            if (error.Fail())
            {
                Trace.WriteLine($"Error: {error.GetCString()}");
                return(VSConstants.E_FAIL);
            }
            if (bytesWrote != count)
            {
                Trace.WriteLine(
                    $"Warning: only written {bytesWrote} out of {count} bytes to memory.");
                return(VSConstants.S_FALSE);
            }
            return(VSConstants.S_OK);
        }
Exemple #3
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int ReadAt(IDebugMemoryContext2 pStartContext, uint dwCount, byte [] rgbMemory, out uint pdwRead, ref uint pdwUnreadable)
        {
            //
            // Reads a sequence of bytes, starting at a given location.
            //

            LoggingUtils.PrintFunction();

            try
            {
                CONTEXT_INFO [] contextInfoArray = new CONTEXT_INFO [1];

                LoggingUtils.RequireOk(pStartContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE, contextInfoArray));

                string command = string.Format("-data-read-memory-bytes {0} {1}", contextInfoArray [0].bstrAddressAbsolute, dwCount);

                MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand(command);

                MiResultRecord.RequireOk(resultRecord, command);

                MiResultValueList memoryStreamList = (MiResultValueList)resultRecord ["memory"] [0];

                for (int s = 0; s < memoryStreamList.Values.Count; ++s)
                {
                    if (!memoryStreamList [s].HasField("contents"))
                    {
                        throw new InvalidOperationException("-data-read-memory-bytes result missing 'contents' field");
                    }

                    string hexValue = memoryStreamList [s] ["contents"] [0].GetString();

                    if ((hexValue.Length / 2) != dwCount)
                    {
                        throw new InvalidOperationException();
                    }

                    for (int i = 0; i < dwCount; ++i)
                    {
                        rgbMemory [i] = byte.Parse(hexValue.Substring(i * 2, 2), NumberStyles.HexNumber);
                    }
                }

                pdwRead = dwCount;

                pdwUnreadable = 0;

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                pdwRead = 0;

                pdwUnreadable = dwCount;

                return(Constants.E_FAIL);
            }
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int ReadAt (IDebugMemoryContext2 pStartContext, uint dwCount, byte [] rgbMemory, out uint pdwRead, ref uint pdwUnreadable)
    {
      // 
      // Reads a sequence of bytes, starting at a given location.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        CONTEXT_INFO [] contextInfoArray = new CONTEXT_INFO [1];

        LoggingUtils.RequireOk (pStartContext.GetInfo (enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE, contextInfoArray));

        string command = string.Format ("-data-read-memory-bytes {0} {1}", contextInfoArray [0].bstrAddressAbsolute, dwCount);

        MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand (command);

        MiResultRecord.RequireOk (resultRecord, command);

        MiResultValueList memoryStreamList = (MiResultValueList) resultRecord ["memory"] [0];

        for (int s = 0; s < memoryStreamList.Values.Count; ++s)
        {
          if (!memoryStreamList [s].HasField ("contents"))
          {
            throw new InvalidOperationException ("-data-read-memory-bytes result missing 'contents' field");
          }

          string hexValue = memoryStreamList [s] ["contents"] [0].GetString ();

          if ((hexValue.Length / 2) != dwCount)
          {
            throw new InvalidOperationException ();
          }

          for (int i = 0; i < dwCount; ++i)
          {
            rgbMemory [i] = byte.Parse (hexValue.Substring (i * 2, 2), NumberStyles.HexNumber);
          }
        }

        pdwRead = dwCount;

        pdwUnreadable = 0;

        return Constants.S_OK;
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);

        pdwRead = 0;

        pdwUnreadable = dwCount;

        return Constants.E_FAIL;
      }
    }
Exemple #5
0
        public static ulong GetAddress(this IDebugMemoryContext2 context)
        {
            var contextInfo = new CONTEXT_INFO[1];
            int res         = context.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfo);

            Debug.Assert(res == VSConstants.S_OK);
            return(System.Convert.ToUInt64(contextInfo[0].bstrAddress, 16));
        }
Exemple #6
0
        public int ReadAt(IDebugMemoryContext2 startMemoryContext, uint countToRead, byte[] memory,
                          out uint countRead, ref uint countUnreadable)
        {
            // |countUnreadable| can be null when calling from C++ according to Microsoft's doc.
            // However, countUnreadable == null will always return false in C# as an uint can never
            // be null. Accessing |countUnreadable| here might cause a NullReferenceException.
            // According to Microsoft's doc, |countUnreadable| is useful when there are
            // non -consecutive blocks of memory that are readable. For example, if we want to read
            // 100 bytes at a certain address and only the first 50 bytes and the last 20 bytes are
            // readable.  |countRead| would be 50 and |countUnreadable| should be 30. However,
            // LLDB's ReadMemory() doesn't provide this kind of output, so this is not
            // straightforward to implement.

            // TODO We should estimate |countUnreadable| from page boundaries.
            // Otherwise, the memory view might be missing some valid contents in the beginnings
            // of mapped regions.

            // Note: We need to make sure we never return S_OK while setting countRead and
            // countUnreadable to zero. That can send the memory view into an infinite loop
            // and freeze Visual Studio ((internal)).
            CONTEXT_INFO[] contextInfo = new CONTEXT_INFO[1];
            startMemoryContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfo);
            ulong address;

            if (DebugEngineUtil.GetAddressFromString(contextInfo[0].bstrAddress, out address))
            {
                SbError error;
                try
                {
                    countRead = Convert.ToUInt32(_lldbProcess.ReadMemory(address, memory,
                                                                         countToRead, out error));
                    if (error.Fail() || countRead == 0)
                    {
                        countRead = 0;
                        return(VSConstants.E_FAIL);
                    }
                    return(VSConstants.S_OK);
                }
                catch (OverflowException e)
                {
                    Trace.WriteLine($"Warning: Failed to read memory.{Environment.NewLine}" +
                                    $"{e.ToString()}");
                    countRead = 0;
                    return(VSConstants.E_FAIL);
                }
            }
            countRead = 0;
            return(VSConstants.E_FAIL);
        }
Exemple #7
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int WriteAt(IDebugMemoryContext2 pStartContext, uint dwCount, byte [] rgbMemory)
        {
            //
            // Writes the specified number of bytes of memory, starting at the specified address.
            //

            LoggingUtils.PrintFunction();

            try
            {
                CONTEXT_INFO [] contextInfoArray = new CONTEXT_INFO [1];

                LoggingUtils.RequireOk(pStartContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE, contextInfoArray));

                StringBuilder stringBuilder = new StringBuilder((int)dwCount * 2);

                for (uint i = 0; i < dwCount; ++i)
                {
                    stringBuilder.Append(rgbMemory [i].ToString("x"));
                }

                string command = string.Format("-data-write-memory-bytes {0} {1} {2}", contextInfoArray [0].bstrAddressAbsolute, stringBuilder.ToString(), dwCount);

                MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand(command);

                MiResultRecord.RequireOk(resultRecord, command);

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
Exemple #8
0
 int IDebugCodeContext2.GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
 {
     return(IDebugMemoryContext2.GetInfo(dwFields, pinfo));
 }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int WriteAt (IDebugMemoryContext2 pStartContext, uint dwCount, byte [] rgbMemory)
    {
      // 
      // Writes the specified number of bytes of memory, starting at the specified address.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        CONTEXT_INFO [] contextInfoArray = new CONTEXT_INFO [1];

        LoggingUtils.RequireOk (pStartContext.GetInfo (enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE, contextInfoArray));

        StringBuilder stringBuilder = new StringBuilder ((int)dwCount * 2);

        for (uint i = 0; i < dwCount; ++i)
        {
          stringBuilder.Append (rgbMemory [i].ToString ("x"));
        }

        string command = string.Format ("-data-write-memory-bytes {0} {1} {2}", contextInfoArray [0].bstrAddressAbsolute, stringBuilder.ToString (), dwCount);

        MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand (command);

        MiResultRecord.RequireOk (resultRecord, command);

        return Constants.S_OK;
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);

        return Constants.E_FAIL;
      }
    }