private T WaitHijackedThreadSignal <T>(ExecutionContext executingContext) { AutoResetEvent ev = new AutoResetEvent(false); bool OnSignaled(byte[] newVal) { ev.Set(); return(true); } using (var ptr = Process[executingContext.SignalAddr]) { ptr.RegisterValueChangedEventHandler(OnSignaled, MarshalType <T> .Size); executingContext.Thread.Resume(); // TODO: Pass timeout by parameter bool success = ev.WaitOne(ExecutionTimeout); return(success ? Process.Memory.Read <T>(executingContext.RetAddr) : throw new InvalidOperationException("Hijacked thread method call timed out")); } }
/// <summary>Executes the assembly code located in the remote process at the specified address.</summary> /// <param name="address">The address where the assembly code is located.</param> /// <param name="executionContext">Execution context.</param> /// <returns>The return value is the exit code of the thread created to execute the assembly code.</returns> private T Execute <T>(IntPtr address, ExecutionContext executionContext) { if (executionContext.Thread == null) { // Execute and join the code in a new thread var executingThread = Process.ThreadFactory.CreateAndJoin(address); // Return the exit code of the thread return(executingThread.GetExitCode <T>()); } else { return(WaitHijackedThreadSignal <T>(executionContext)); } }