[PlatformSpecific(~PlatformID.OSX)] // OSX throws PNSE from StartTime public async Task TestStartTimeProperty() { TimeSpan allowedWindow = TimeSpan.FromSeconds(1); using (Process p = Process.GetCurrentProcess()) { // Get the process' start time DateTime startTime = p.StartTime.ToUniversalTime(); // Get the process' threads ProcessThreadCollection threads = p.Threads; Assert.NotNull(threads); Assert.NotEmpty(threads); // Get the current time DateTime curTime = DateTime.UtcNow; // Make sure each thread's start time is at least the process' // start time and not beyond the current time. Assert.All( threads.Cast <ProcessThread>(), t => Assert.InRange(t.StartTime.ToUniversalTime(), startTime - allowedWindow, curTime + allowedWindow)); // Now add a thread, and from that thread, while it's still alive, verify // that there's at least one thread greater than the current time we previously grabbed. await Task.Factory.StartNew(() => { p.Refresh(); Assert.Contains( p.Threads.Cast <ProcessThread>(), t => t.StartTime.ToUniversalTime() >= curTime - allowedWindow); }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); } }
public async Task TestStartTimeProperty() { TimeSpan allowedWindow = TimeSpan.FromSeconds(2); using (Process p = Process.GetCurrentProcess()) { // Get the process' start time DateTime startTime = p.StartTime.ToUniversalTime(); // Get the process' threads ProcessThreadCollection threads = p.Threads; Assert.NotNull(threads); Assert.NotEmpty(threads); // Get the current time DateTime curTime = DateTime.UtcNow; // Make sure each thread's start time is at least the process' // start time and not beyond the current time. int passed = 0; foreach (ProcessThread t in threads.Cast <ProcessThread>()) { try { Assert.InRange(t.StartTime.ToUniversalTime(), startTime - allowedWindow, curTime + allowedWindow); passed++; } catch (InvalidOperationException) { // The thread may have gone away between our getting its info and attempting to access its StartTime } } Assert.InRange(passed, 1, int.MaxValue); // Now add a thread, and from that thread, while it's still alive, verify // that there's at least one thread greater than the current time we previously grabbed. await Task.Factory.StartNew(() => { p.Refresh(); try { var newest = p.Threads.Cast <ProcessThread>().OrderBy(t => t.StartTime.ToUniversalTime()).Last(); Assert.InRange(newest.StartTime.ToUniversalTime(), curTime - allowedWindow, DateTime.Now.ToUniversalTime() + allowedWindow); } catch (InvalidOperationException) { // A thread may have gone away between our getting its info and attempting to access its StartTime } }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); } }
public void TestThreadCollectionBehavior() { ProcessThread[] tArray = _process.Threads.Cast<ProcessThread>().ToArray(); int countOfTArray = tArray.Count(); // constructor ProcessThreadCollection threadCollection = new ProcessThreadCollection(tArray); // Count Assert.Equal(countOfTArray, threadCollection.Count); // get_item, Contains, IndexOf for (int i = 0; i < countOfTArray; i++) { Assert.Equal(tArray[i], threadCollection[i]); Assert.True(threadCollection.Contains(tArray[i])); Assert.Equal(i, threadCollection.IndexOf(tArray[i])); } // CopyTo ProcessThread[] threadArray = new ProcessThread[threadCollection.Count + 1]; threadCollection.CopyTo(threadArray, 1); for (int i = 0; i < countOfTArray; i++) { Assert.Equal(tArray[i], threadArray[i + 1]); } Assert.Throws<ArgumentOutOfRangeException>(() => threadCollection.CopyTo(threadArray, -1)); // Remove threadCollection.Remove(tArray[0]); Assert.Equal(-1, threadCollection.IndexOf(tArray[0])); Assert.False(threadCollection.Contains(tArray[0])); // Try remove non existent member threadCollection.Remove(tArray[0]); // Cleanup after remove threadCollection.Insert(0, tArray[0]); // Add threadCollection.Add(default(ProcessThread)); Assert.Equal(threadCollection.Count - 1, threadCollection.IndexOf(default(ProcessThread))); // Add same member again threadCollection.Add(default(ProcessThread)); Assert.Equal(threadCollection.Count - 2, threadCollection.IndexOf(default(ProcessThread))); Assert.Equal(default(ProcessThread), threadCollection[threadCollection.Count - 1]); // Cleanup after Add. threadCollection.Remove(default(ProcessThread)); threadCollection.Remove(default(ProcessThread)); Assert.False(threadCollection.Contains(default(ProcessThread))); // Insert int index = threadCollection.Count / 2; int initialCount = threadCollection.Count; threadCollection.Insert(index, null); Assert.Equal(index, threadCollection.IndexOf(null)); Assert.Equal(initialCount + 1, threadCollection.Count); // Insert at invalid index Assert.Throws<ArgumentOutOfRangeException>(() => threadCollection.Insert(-1, tArray[0])); // Explicit interface implementations Assert.False(((ICollection)threadCollection).IsSynchronized); Assert.NotNull(((ICollection)threadCollection).SyncRoot); threadArray = new ProcessThread[threadCollection.Count]; ((ICollection)threadCollection).CopyTo(threadArray, 0); Assert.Equal(threadCollection.Cast<ProcessThread>().ToArray(), threadArray); // GetEnumerator IEnumerator enumerator = threadCollection.GetEnumerator(); Assert.Throws<InvalidOperationException>(() => enumerator.Current); for (int i = 0; i < threadCollection.Count; i++) { enumerator.MoveNext(); Assert.Equal(threadCollection[i], enumerator.Current); } }
public void TestThreadCollectionBehavior() { ProcessThread[] tArray = _process.Threads.Cast <ProcessThread>().ToArray(); int countOfTArray = tArray.Count(); // constructor ProcessThreadCollection threadCollection = new ProcessThreadCollection(tArray); // Count Assert.Equal(countOfTArray, threadCollection.Count); // get_item, Contains, IndexOf for (int i = 0; i < countOfTArray; i++) { Assert.Equal(tArray[i], threadCollection[i]); Assert.True(threadCollection.Contains(tArray[i])); Assert.Equal(i, threadCollection.IndexOf(tArray[i])); } // CopyTo ProcessThread[] threadArray = new ProcessThread[threadCollection.Count + 1]; threadCollection.CopyTo(threadArray, 1); for (int i = 0; i < countOfTArray; i++) { Assert.Equal(tArray[i], threadArray[i + 1]); } Assert.Throws <ArgumentOutOfRangeException>(() => threadCollection.CopyTo(threadArray, -1)); // Remove threadCollection.Remove(tArray[0]); Assert.Equal(-1, threadCollection.IndexOf(tArray[0])); Assert.False(threadCollection.Contains(tArray[0])); // Try remove non existent member threadCollection.Remove(tArray[0]); // Cleanup after remove threadCollection.Insert(0, tArray[0]); // Add threadCollection.Add(default(ProcessThread)); Assert.Equal(threadCollection.Count - 1, threadCollection.IndexOf(default(ProcessThread))); // Add same member again threadCollection.Add(default(ProcessThread)); Assert.Equal(threadCollection.Count - 2, threadCollection.IndexOf(default(ProcessThread))); Assert.Equal(default(ProcessThread), threadCollection[threadCollection.Count - 1]); // Cleanup after Add. threadCollection.Remove(default(ProcessThread)); threadCollection.Remove(default(ProcessThread)); Assert.False(threadCollection.Contains(default(ProcessThread))); // Insert int index = threadCollection.Count / 2; int initialCount = threadCollection.Count; threadCollection.Insert(index, null); Assert.Equal(index, threadCollection.IndexOf(null)); Assert.Equal(initialCount + 1, threadCollection.Count); // Insert at invalid index Assert.Throws <ArgumentOutOfRangeException>(() => threadCollection.Insert(-1, tArray[0])); // Explicit interface implementations Assert.False(((ICollection)threadCollection).IsSynchronized); Assert.NotNull(((ICollection)threadCollection).SyncRoot); threadArray = new ProcessThread[threadCollection.Count]; ((ICollection)threadCollection).CopyTo(threadArray, 0); Assert.Equal(threadCollection.Cast <ProcessThread>().ToArray(), threadArray); // GetEnumerator IEnumerator enumerator = threadCollection.GetEnumerator(); Assert.Throws <InvalidOperationException>(() => enumerator.Current); for (int i = 0; i < threadCollection.Count; i++) { enumerator.MoveNext(); Assert.Equal(threadCollection[i], enumerator.Current); } }
internal bool Inject() { // Get the address of the LoadLibraryW method from kernel32.dll var loadLibraryAddress = Tools.GetRemoteProcAddress(_properties, "kernel32.dll", "LoadLibraryW"); if (loadLibraryAddress == IntPtr.Zero) { ExceptionHandler.ThrowWin32Exception("Failed to find the address of the LoadLibraryW method in kernel32.dll"); } // Allocate memory for the dll path in the process var dllPathAddress = IntPtr.Zero; try { dllPathAddress = _properties.MemoryModule.AllocateMemory(_properties.ProcessId, _properties.DllPath.Length); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the dll path in the process"); } // Write the dll path into the process var dllPathBytes = Encoding.Unicode.GetBytes(_properties.DllPath + "\0"); try { _properties.MemoryModule.WriteMemory(_properties.ProcessId, dllPathAddress, dllPathBytes); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write the dll path into the memory of the process"); } foreach (var thread in _processThreads.Cast <ProcessThread>()) { // Open a handle to the thread var threadHandle = Native.OpenThread(Native.ThreadAccess.SetContext, false, thread.Id); if (threadHandle is null) { ExceptionHandler.ThrowWin32Exception("Failed to open a handle to a thread in the process"); } // Add a user-mode APC to the APC queue of the thread if (!Native.QueueUserAPC(loadLibraryAddress, threadHandle, dllPathAddress)) { ExceptionHandler.ThrowWin32Exception("Failed to queue a user-mode apc to the apc queue of a thread in the process"); } threadHandle?.Close(); } // Free the memory previously allocated for the dll path try { _properties.MemoryModule.FreeMemory(_properties.ProcessId, dllPathAddress); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the dll path in the process"); } return(true); }