See More

using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using Process.NET.Marshaling; using Process.NET.Native.Types; using Process.NET.Utilities; namespace Process.NET.Threads { ///

/// Class providing tools for manipulating threads. /// public class ThreadFactory : IThreadFactory { /// /// The reference of the object. /// protected readonly IProcess Process; /// /// Initializes a new instance of the class. /// /// The reference of the object. public ThreadFactory(IProcess process) { // Save the parameter Process = process; } /// /// Gets the main thread of the remote process. /// public IRemoteThread MainThread { get { return new RemoteThread(Process, NativeThreads.Aggregate((current, next) => next.StartTime < current.StartTime ? next : current)); } } /// /// Gets the native threads from the remote process. /// public IEnumerable NativeThreads { get { // Refresh the process info Process.Native.Refresh(); // Enumerates all threads return Process.Native.Threads.Cast(); } } /// /// Gets the threads from the remote process. /// public IEnumerable RemoteThreads { get { return NativeThreads.Select(t => new RemoteThread(Process, t)); } } /// /// Gets the thread corresponding to an id. /// /// The unique identifier of the thread to get. /// A new instance of a class. public IRemoteThread this[int threadId] { get { return new RemoteThread(Process, NativeThreads.First(t => t.Id == threadId)); } } /// /// Creates a thread that runs in the remote process. /// /// /// 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. /// /// A variable to be passed to the thread function. /// Sets if the thread must be started just after being created. /// A new instance of the class. public IRemoteThread Create(IntPtr address, dynamic parameter, bool isStarted = true) { // Marshal the parameter var marshalledParameter = MarshalValue.Marshal(Process, parameter); //Create the thread var ret = ThreadHelper.NtQueryInformationThread( ThreadHelper.CreateRemoteThread(Process.Handle, address, marshalledParameter.Reference, ThreadCreationFlags.Suspended)); // Find the managed object corresponding to this thread var result = new RemoteThread(Process, Process.ThreadFactory.NativeThreads.First(t => t.Id == ret.ThreadId), marshalledParameter); if (isStarted) result.Resume(); return result; } /// /// Creates a thread that runs in the remote process. /// /// /// 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. /// /// Sets if the thread must be started just after being created. /// A new instance of the class. public IRemoteThread Create(IntPtr address, bool isStarted = true) { //Create the thread var ret = ThreadHelper.NtQueryInformationThread( ThreadHelper.CreateRemoteThread(Process.Handle, address, IntPtr.Zero, ThreadCreationFlags.Suspended)); // Find the managed object corresponding to this thread var result = new RemoteThread(Process, Process.ThreadFactory.NativeThreads.First(t => t.Id == ret.ThreadId)); // If the thread must be started if (isStarted) result.Resume(); return result; } /// /// Creates a thread in the remote process and blocks the calling thread until the thread terminates. /// /// /// 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. /// /// A variable to be passed to the thread function. /// A new instance of the class. public IRemoteThread CreateAndJoin(IntPtr address, dynamic parameter) { // Create the thread var ret = Create(address, parameter); // Wait the end of the thread ret.Join(); // Return the thread return ret; } /// /// Creates a thread in the remote process and blocks the calling thread until the thread terminates. /// /// /// 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. /// /// A new instance of the class. public IRemoteThread CreateAndJoin(IntPtr address) { // Create the thread var ret = Create(address); // Wait the end of the thread ret.Join(); // Return the thread return ret; } /// /// Releases all resources used by the object. /// public void Dispose() { // Nothing to dispose... yet } /// /// Gets a thread by its id in the remote process. /// /// The id of the thread. /// A new instance of the class. public IRemoteThread GetThreadById(int id) { return new RemoteThread(Process, NativeThreads.First(t => t.Id == id)); } /// /// Resumes all threads. /// public void ResumeAll() { foreach (var thread in RemoteThreads) thread.Resume(); } /// /// Suspends all threads. /// public void SuspendAll() { foreach (var thread in RemoteThreads) thread.Suspend(); } } }