예제 #1
0
        /// <summary>
        /// Creates a thread that runs in the remote process.
        /// </summary>
        /// <param name="address">
        /// A pointer to the application-defined function to be executed by the thread and represents 
        /// the starting address of the thread in the remote process.
        /// </param>
        /// <param name="parameter">A variable to be passed to the thread function.</param>
        /// <param name="isStarted">Sets if the thread must be started just after being created.</param>
        /// <returns>A new instance of the <see cref="RemoteThread"/> class.</returns>
        public RemoteThread Create(IntPtr address, dynamic parameter, bool isStarted = true)
        {
            // Marshal the parameter
            var marshalledParameter = MarshalValue.Marshal(MemorySharp, parameter);

            //Create the thread
            var ret = ThreadCore.NtQueryInformationThread(
                ThreadCore.CreateRemoteThread(MemorySharp.Handle, address, marshalledParameter.Reference, ThreadCreationFlags.Suspended));

            // Find the managed object corresponding to this thread
            var result = new RemoteThread(MemorySharp, MemorySharp.Threads.NativeThreads.First(t => t.Id == ret.ThreadId), marshalledParameter);

            // If the thread must be started
            if (isStarted)
                result.Resume();
            return result;
        }
예제 #2
0
        /// <summary>
        /// Creates a thread that runs in the remote process.
        /// </summary>
        /// <param name="address">
        /// A pointer to the application-defined function to be executed by the thread and represents 
        /// the starting address of the thread in the remote process.
        /// </param>
        /// <param name="isStarted">Sets if the thread must be started just after being created.</param>
        /// <returns>A new instance of the <see cref="RemoteThread"/> class.</returns>
        public RemoteThread Create(IntPtr address, bool isStarted = true)
        {
            //Create the thread
            var ret = ThreadCore.NtQueryInformationThread(
                ThreadCore.CreateRemoteThread(MemorySharp.Handle, address, IntPtr.Zero, ThreadCreationFlags.Suspended));

            // Find the managed object corresponding to this thread
            var result = new RemoteThread(MemorySharp, MemorySharp.Threads.NativeThreads.First(t => t.Id == ret.ThreadId));

            // If the thread must be started
            if (isStarted)
                result.Resume();
            return result;
        }
예제 #3
0
        /// <summary>
        /// Creates a thread that runs in the remote process.
        /// </summary>
        /// <param name="address">
        /// A pointer to the application-defined function to be executed by the thread and represents 
        /// the starting address of the thread in the remote process.
        /// </param>
        /// <param name="isStarted">Sets if the thread must be started just after being created.</param>
        /// <returns>A new instance of the <see cref="RemoteThread"/> class.</returns>
        public RemoteThread Create(IntPtr address, bool isStarted = true)
        {
            // Create the thread
            var ret = ThreadCore.NtQueryInformationThread(
                ThreadCore.CreateRemoteThread(MemorySharp.Handle, address, IntPtr.Zero, ThreadCreationFlags.Suspended));

            // Get the native thread previously created
            // Loop until the native thread is retrieved
            ProcessThread nativeThread;
            do
            {
                nativeThread = MemorySharp.Threads.NativeThreads.FirstOrDefault(t => t.Id == ret.ThreadId);
            } while (nativeThread == null);

            // Wrap the native thread in an object of the library
            var result = new RemoteThread(MemorySharp, nativeThread);

            // If the thread must be started
            if (isStarted)
                result.Resume();
            return result;
        }
예제 #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FrozenThread"/> class.
 /// </summary>
 /// <param name="thread">The frozen thread.</param>
 internal FrozenThread(RemoteThread thread)
 {
     // Save the parameter
     Thread = thread;
 }
예제 #5
0
        /// <summary>
        /// Creates a thread that runs in the remote process.
        /// </summary>
        /// <param name="address">
        /// A pointer to the application-defined function to be executed by the thread and represents 
        /// the starting address of the thread in the remote process.
        /// </param>
        /// <param name="parameter">A variable to be passed to the thread function.</param>
        /// <param name="isStarted">Sets if the thread must be started just after being created.</param>
        /// <returns>A new instance of the <see cref="RemoteThread"/> class.</returns>
        public RemoteThread Create(IntPtr address, dynamic parameter, bool isStarted = true)
        {
            // Marshal the parameter
            var marshalledParameter = MarshalValue.Marshal(MemorySharp, parameter);

            //Create the thread
            var ret = ThreadCore.NtQueryInformationThread(
                ThreadCore.CreateRemoteThread(MemorySharp.Handle, address, marshalledParameter.Reference, ThreadCreationFlags.Suspended));

            // Get the native thread previously created
            // Loop until the native thread is retrieved
            ProcessThread nativeThread;
            do
            {
                nativeThread = MemorySharp.Threads.NativeThreads.FirstOrDefault(t => t.Id == ret.ThreadId);
            } while (nativeThread == null);

            // Find the managed object corresponding to this thread
            var result = new RemoteThread(MemorySharp, nativeThread, marshalledParameter);

            // If the thread must be started
            if (isStarted)
                result.Resume();
            return result;
        }
예제 #6
0
 DebugThreadAsync(ITaskExecutor taskExecutor, FrameEnumFactory frameEnumFactory,
                  StackFramesProvider stackFramesProvider, RemoteThread lldbThread) : base(
         taskExecutor, frameEnumFactory, stackFramesProvider, lldbThread)
 {
 }
예제 #7
0
 /// <summary>
 /// Creator for unit tests.
 /// </summary>
 /// <param name="stackFramesProvider"></param>
 /// <param name="lldbThread"></param>
 /// <returns></returns>
 public virtual IDebugThreadAsync CreateForTesting(
     StackFramesProvider stackFramesProvider, RemoteThread lldbThread) =>
 new DebugThreadAsync(_taskExecutor, _frameEnumFactory, stackFramesProvider,
                      lldbThread);
예제 #8
0
        // Called when we receive a state changed LLDB event.
        void OnStateChangedEvent(SbEvent sbEvent)
        {
            if (sbEvent == null)
            {
                return;
            }

            var type = sbEvent.GetStateType();

            Debug.WriteLine("Received LLDB event: " + Enum.GetName(type.GetType(), type));
            switch (type)
            {
            case StateType.STOPPED:
                if (sbEvent.GetProcessRestarted())
                {
                    break;
                }

                var currentThread     = _lldbProcess.GetSelectedThread();
                var currentStopReason = StopReason.INVALID;
                if (currentThread != null)
                {
                    currentStopReason = currentThread.GetStopReason();
                }

                // When stopping pick the most relevant thread based on the stop reason.
                if (currentThread == null || currentStopReason == StopReason.INVALID ||
                    currentStopReason == StopReason.NONE)
                {
                    int          numThreads  = _lldbProcess.GetNumThreads();
                    RemoteThread planThread  = null;
                    RemoteThread otherThread = null;
                    for (int i = 0; i < numThreads; ++i)
                    {
                        RemoteThread thread = _lldbProcess.GetThreadAtIndex(i);
                        switch (thread.GetStopReason())
                        {
                        case StopReason.INVALID:
                        // fall-through
                        case StopReason.NONE:
                            break;

                        case StopReason.SIGNAL:
                            if (otherThread == null)
                            {
                                var signalNumber = thread.GetStopReasonDataAtIndex(0);
                                var unixSignals  = _lldbProcess.GetUnixSignals();
                                if (unixSignals != null &&
                                    unixSignals.GetShouldStop((int)signalNumber))
                                {
                                    otherThread = thread;
                                }
                            }
                            break;

                        case StopReason.TRACE:
                        // fall-through
                        case StopReason.BREAKPOINT:
                        // fall-through
                        case StopReason.WATCHPOINT:
                        // fall-through
                        case StopReason.EXCEPTION:
                        // fall-through
                        case StopReason.EXEC:
                        // fall-through
                        case StopReason.EXITING:
                        // fall-through
                        case StopReason.INSTRUMENTATION:
                            if (otherThread == null)
                            {
                                otherThread = thread;
                            }
                            break;

                        case StopReason.PLAN_COMPLETE:
                            if (planThread == null)
                            {
                                planThread = thread;
                            }
                            break;
                        }
                    }
                    if (planThread != null)
                    {
                        currentThread = planThread;
                    }
                    else if (otherThread != null)
                    {
                        currentThread = otherThread;
                    }
                    else if (currentThread == null)
                    {
                        currentThread = _lldbProcess.GetThreadAtIndex(0);
                    }
                    if (currentThread == null)
                    {
                        Trace.WriteLine("Error: Cannot handle event. No thread found.");
                        return;
                    }
                    _lldbProcess.SetSelectedThreadById(currentThread.GetThreadId());
                    currentStopReason = currentThread.GetStopReason();
                }

                // Log specific information about the stop event.
                string message = "Received stop event.  Reason: " + currentStopReason;

                var stopReasonDataCount = currentThread.GetStopReasonDataCount();
                if (stopReasonDataCount > 0)
                {
                    message += " Data:";
                    for (uint i = 0; i < stopReasonDataCount; i++)
                    {
                        message += " " + currentThread.GetStopReasonDataAtIndex(i);
                    }
                }
                Trace.WriteLine(message);

                _taskContext.Factory.Run(async() => {
                    // We run the event resolution on the main thread to make sure
                    // we do not race with concurrent modifications in the breakpoint
                    // manager class (we could just have hit breakpoint that is being
                    // added by the main thread!).
                    await _taskContext.Factory.SwitchToMainThreadAsync();
                    DebugEvent eventToSend = null;
                    switch (currentStopReason)
                    {
                    case StopReason.BREAKPOINT:
                        eventToSend = HandleBreakpointStop(currentThread);
                        break;

                    case StopReason.WATCHPOINT:
                        eventToSend = HandleWatchpointStop(currentThread);
                        break;

                    case StopReason.SIGNAL:
                        eventToSend = HandleSignalStop(currentThread);
                        break;

                    case StopReason.PLAN_COMPLETE:
                        eventToSend = new StepCompleteEvent();
                        break;

                    default:
                        break;
                    }
                    if (eventToSend == null)
                    {
                        eventToSend = new BreakEvent();
                    }
                    _debugEngineHandler.SendEvent(eventToSend,_program,currentThread);
                });
                break;

            case StateType.EXITED:
            {
                // There are two ways to exit a debug session without an error:
                //   - We call program.Terminate, which causes LLDB to send this event.
                //   - Program exits by itself, resulting in this event.
                // We distinguish these events by checking if we called Terminate.
                ExitReason exitReason = _program.TerminationRequested
                                                    ? ExitReason.DebuggerTerminated
                                                    : ExitReason.ProcessExited;
                _debugEngineHandler.Abort(_program,ExitInfo.Normal(exitReason));
            }
            break;

            case StateType.DETACHED:
            {
                // Normally the only way to detach the process is by program.Detach.
                // However, this check was retained to mirror the EXITED case and to
                // record unexpected instances of detaching through some other path.
                ExitReason exitReason = _program.DetachRequested
                                                    ? ExitReason.DebuggerDetached
                                                    : ExitReason.ProcessDetached;
                _debugEngineHandler.Abort(_program,ExitInfo.Normal(exitReason));
            }
            break;
            }
        }
예제 #9
0
 public int SendEvent(DebugEvent evnt, IGgpDebugProgram program,
                      RemoteThread thread) => SendEvent(evnt, program,
                                                        program.GetDebugThread(thread));