Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using System.Threading.Tasks;
using System.Threading;
using ApolloInterop.Classes.Events;
using System.Text;
using Microsoft.Win32.SafeHandles;

namespace ExecutePE.Helpers
{
Expand All @@ -19,6 +21,11 @@ class StdHandleRedirector : IDisposable

private IntPtr _oldStdout;
private IntPtr _oldStderr;
private int _osfHandle;
private int _oldOsfOut;
private int _oldOsfErr;
IntPtr _stdoutClientHandle;
private Encoding _oldEncoding;

private event EventHandler<StringDataEventArgs> _stdoutHandler;

Expand All @@ -43,22 +50,76 @@ public StdHandleRedirector(EventHandler<StringDataEventArgs> stdoutHandler)

private void Initialize()
{
SetupNamePipes();
DuplicateHandlesAndEncoding();
SetupRedirection();
}

private void DuplicateHandlesAndEncoding() {
_oldEncoding = (Encoding)Console.OutputEncoding.Clone();
DuplicateHandle(
GetCurrentProcess(),
GetStdHandle(StdHandle.Stdout),
GetCurrentProcess(),
out _oldStdout,
0,
false,
DuplicateOptions.DuplicateSameAccess
);
DuplicateHandle(
GetCurrentProcess(),
GetStdHandle(StdHandle.Stderr),
GetCurrentProcess(),
out _oldStderr,
0,
false,
DuplicateOptions.DuplicateSameAccess
);

IntPtr pipeWriteHandle = stdoutClientStream.SafePipeHandle.DangerousGetHandle();
DuplicateHandle(
GetCurrentProcess(),
pipeWriteHandle,
GetCurrentProcess(),
out _stdoutClientHandle,
0,
false,
DuplicateOptions.DuplicateSameAccess
);

_oldOsfOut = _dup(1);
_oldOsfErr = _dup(2);
}

private void SetupNamePipes() {
string stdoutGuid = Guid.NewGuid().ToString();

stdoutServerStream = new NamedPipeServerStream(stdoutGuid, PipeDirection.InOut, 100, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
stdoutServerStream.BeginWaitForConnection(new AsyncCallback(stdoutServerStream.EndWaitForConnection), stdoutServerStream);

stdoutClientStream = new NamedPipeClientStream("127.0.0.1", stdoutGuid, PipeDirection.InOut, PipeOptions.Asynchronous);
stdoutClientStream.Connect();
}

private void SetupRedirection()
{
var stdoutServerFileHandle = new SafeFileHandle(
stdoutServerStream.SafePipeHandle.DangerousGetHandle(),
ownsHandle: false
);
stdoutReader = new FileStream(stdoutServerFileHandle, FileAccess.Read);

SetStdHandle(StdHandle.Stdout, _stdoutClientHandle);
SetStdHandle(StdHandle.Stderr, _stdoutClientHandle);

stdoutReader = new FileStream(stdoutServerStream.SafePipeHandle.DangerousGetHandle(), FileAccess.Read);
_osfHandle = _open_osfhandle(_stdoutClientHandle.ToInt32(), _O_TEXT);
if (_osfHandle == 0)
throw new Exception("_open_osfhandle failed");

_oldStdout = GetStdHandle(StdHandles.Stdout);
_oldStderr = GetStdHandle(StdHandles.Stderr);
if (_dup2(_osfHandle, 1) != 0)
throw new Exception("_dup2 stdout failed");

SetStdHandle(StdHandles.Stdout, stdoutClientStream.SafePipeHandle.DangerousGetHandle());
SetStdHandle(StdHandles.Stderr, stdoutClientStream.SafePipeHandle.DangerousGetHandle());
if (_dup2(_osfHandle, 2) != 0)
throw new Exception("_dup2 stderr failed");
}

private void ReadFileStreamAsync(FileStream stream, EventHandler<StringDataEventArgs> eventhandler)
Expand Down Expand Up @@ -96,23 +157,23 @@ private void ReadFileStreamAsync(FileStream stream, EventHandler<StringDataEvent
{
eventhandler?.Invoke(this, new StringDataEventArgs(t.Result));
}
} while (!_cts.IsCancellationRequested);

do
{
tmp = new byte[szBuf];
n = stream.Read(tmp, 0, szBuf);
if (n > 0)
{
newstr = new byte[n];
Array.Copy(tmp, newstr, n);
eventhandler?.Invoke(this, new StringDataEventArgs(Console.OutputEncoding.GetString(newstr)));
}
else
{
break;
}
} while (n > 0);
} while (!_cts.IsCancellationRequested || n > 0);
//do
//{
// tmp = new byte[szBuf];
// n = stream.Read(tmp, 0, szBuf);
// if (n > 0)
// {
// newstr = new byte[n];
// Array.Copy(tmp, newstr, n);
// eventhandler?.Invoke(this, new StringDataEventArgs(Console.OutputEncoding.GetString(newstr)));
// }
// else
// {
// break;
// }
//} while (n > 0);
}

private void ReadStdoutAsync()
Expand All @@ -122,20 +183,38 @@ private void ReadStdoutAsync()

public void Dispose()
{
SetStdHandle(StdHandles.Stderr, _oldStderr);
SetStdHandle(StdHandles.Stdout, _oldStdout);

Console.Out.Flush();
Console.Error.Flush();
fflush(IntPtr.Zero);
stdoutClientStream.Flush();
stdoutServerStream.Flush();

stdoutClientStream.Close();
if (_dup2(_oldOsfOut, 1) != 0)
throw new Exception("_dup2 stdout failed");

_cts.Cancel();
if (_dup2(_oldOsfErr, 2) != 0)
throw new Exception("_dup2 stderr failed");

SetStdHandle(StdHandle.Stderr, _oldStderr);
SetStdHandle(StdHandle.Stdout, _oldStdout);
Console.SetOut(new StreamWriter(Console.OpenStandardOutput(), _oldEncoding)
{
AutoFlush = true
});

Console.SetError(new StreamWriter(Console.OpenStandardError(), _oldEncoding)
{
AutoFlush = true
});
_close(_oldOsfOut);
_close(_oldOsfErr);
_close(_osfHandle);
stdoutClientStream.Close();
_cts.Cancel();
Task.WaitAll(new Task[]
{
_stdoutReadTask
});

stdoutServerStream.Close();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Runtime.InteropServices;
using ExecutePE.Internals;

namespace ExecutePE.Helpers
{
Expand All @@ -14,7 +15,7 @@ internal static class Utils
Marshal.Copy(pFunc, originalBytes, 0, patchBytes.Length);

var result = NativeDeclarations.VirtualProtect(pFunc, (UIntPtr)patchBytes.Length,
NativeDeclarations.PAGE_EXECUTE_READWRITE, out var oldProtect);
NativeDeclarations.MemoryProtectionConstant.PAGE_EXECUTE_READWRITE, out var oldProtect);
if (!result)
{
return null;
Expand All @@ -31,7 +32,7 @@ internal static class Utils
internal static bool PatchAddress(IntPtr pAddress, IntPtr newValue)
{
var result = NativeDeclarations.VirtualProtect(pAddress, (UIntPtr)IntPtr.Size,
NativeDeclarations.PAGE_EXECUTE_READWRITE, out var oldProtect);
NativeDeclarations.MemoryProtectionConstant.PAGE_EXECUTE_READWRITE, out var oldProtect);
if (!result)
{
return false;
Expand All @@ -48,7 +49,7 @@ internal static bool PatchAddress(IntPtr pAddress, IntPtr newValue)

internal static bool ZeroOutMemory(IntPtr start, int length)
{
var result = NativeDeclarations.VirtualProtect(start, (UIntPtr)length, NativeDeclarations.PAGE_READWRITE,
var result = NativeDeclarations.VirtualProtect(start, (UIntPtr)length, NativeDeclarations.MemoryProtectionConstant.PAGE_READWRITE,
out var oldProtect);
if (!result)
{
Expand Down
Loading