using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using DllUtils.Interop; using DllUtils.Process; namespace DllUtils.Threads { public class RemoteThread { private int _waitForSingleObjectResult; private bool _waitedForObject; public RemoteThread(ProcessHandle process, IntPtr startAddress, IntPtr param, IntPtr handle) { Handle = handle; if (handle != IntPtr.Zero) { IsOpened = true; } StartAddress = startAddress; Param = param; Handle = handle; Process = process; } public bool IsOpened { get; private set; } public IntPtr Handle { get; private set; } public IntPtr StartAddress { get; } public IntPtr Param { get; } public ProcessHandle Process { get; } public bool Create() { if (!IsOpened) { Process.Open(); Handle = Kernel32.CreateRemoteThread(Process.Handle, (IntPtr) null, IntPtr.Zero, StartAddress, Param, 0, (IntPtr) null); int error = Marshal.GetLastWin32Error(); if (Handle != IntPtr.Zero) { IsOpened = true; } } return Handle != IntPtr.Zero; } public int WaitForResult(int timeout = 100000) { _waitForSingleObjectResult = Kernel32.WaitForSingleObject(Handle, timeout); _waitedForObject = true; return _waitForSingleObjectResult; } public bool CheckResult() { if (!_waitedForObject) { WaitForResult(); } int result = _waitForSingleObjectResult; if (result == 0x00000080L || result == 0x00000102L || result == 0xFFFFFFF) { Close(); return false; } return true; } public IntPtr GetResult() { bool success = Kernel32.GetExitCodeThread(Handle, out IntPtr result); if (!success) { return IntPtr.Zero; } return result; } public void Close() { if (Handle != IntPtr.Zero) { Kernel32.CloseHandle(Handle); IsOpened = false; Handle = IntPtr.Zero; } } } }