/// <summary> /// 等待进程退出 /// </summary> /// <param name="millisec">要等待的毫秒数,-1为无限等待</param> /// <param name="nativeWait">是否直接使用WaitForSingleObject等待</param> public int?WaitForExit(int millisec, bool nativeWait) { if (nativeWait) { int rslt = WaitForSingleObject(NativeProcessHandle.DangerousGetHandle(), millisec); ThrowExceptionByCode(rslt); if (GetExitCodeProcess(NativeProcessHandle.DangerousGetHandle(), out var exitCode)) { if (exitCode == 0) { OnExited?.Invoke(exitCode); } else { OnExitCodeNonZero?.Invoke(exitCode); } NativeProcessHandle = null; return(exitCode); } OnExited?.Invoke(null); NativeProcessHandle = null; return(null); } CurrentProcess.WaitForExit(millisec); NativeProcessHandle = null; return(CurrentProcess.ExitCode); }
public bool CloseHandle() { if (!IsHandleClosed) { using (SafeProcessHandle processHandle = NativeMethods.OpenProcess(ProcessAccessRights.PROCESS_ALL_ACCESS, false, SourceProcess)) { if (!processHandle.IsInvalid) { SafeObjectHandle objectHandle = null; if (NativeMethods.DuplicateHandle(processHandle.DangerousGetHandle(), SourceHandle, IntPtr.Zero, out objectHandle, 0, false, DuplicateHandleOptions.DUPLICATE_CLOSE_SOURCE)) { NativeMethods.CloseHandle(processHandle.DangerousGetHandle()); processHandle.Dispose(); IsHandleClosed = true; } } } } return(IsHandleClosed); }
public override void ReadMemory(ulong address, void *destination, int size) { if (destination is null && size != 0) { throw new ArgumentNullException(nameof(destination)); } if (size < 0) { throw new ArgumentOutOfRangeException(nameof(size)); } var dest = (byte *)destination; if (hProcess.IsClosed || (Bitness == 32 && address > uint.MaxValue)) { Clear(dest, size); return; } ulong endAddr = Bitness == 32 ? (ulong)uint.MaxValue + 1 : 0UL; uint count = (uint)size; var hProcessLocal = hProcess.DangerousGetHandle(); ulong pageSize = (ulong)Environment.SystemPageSize; while (count != 0) { int len = (int)Math.Min((uint)pageSize, count); ulong nextPage = (address + pageSize) & ~(pageSize - 1); ulong pageSizeLeft = nextPage - address; if ((ulong)len > pageSizeLeft) { len = (int)pageSizeLeft; } bool b = NativeMethods.ReadProcessMemory(hProcessLocal, (void *)address, dest, new IntPtr(len), out var sizeRead); int read = !b ? 0 : (int)sizeRead.ToInt64(); Debug.Assert(read <= len); Debug.Assert(read == 0 || read == len); if (read != len) { Clear(dest + read, len - read); } address += (ulong)len; count -= (uint)len; dest += len; if (address == endAddr) { Clear(dest, (int)count); break; } } }
private static bool GetFileNameFromHandle(IntPtr handle, int processId, out string fileName) { IntPtr currentProcess = GetCurrentProcess(); bool remote = processId != GetProcessId(currentProcess); SafeProcessHandle processHandle = null; SafeObjectHandle objectHandle = null; try { if (remote) { processHandle = OpenProcess(ProcessAccessRights.PROCESS_DUP_HANDLE, true, processId); if (DuplicateHandle(processHandle.DangerousGetHandle(), handle, currentProcess, out objectHandle, 0, false, DuplicateHandleOptions.DUPLICATE_SAME_ACCESS)) { handle = objectHandle.DangerousGetHandle(); } } return(GetFileNameFromHandle(handle, out fileName, 200)); } finally { if (remote) { if (processHandle != null) { processHandle.Close(); } if (objectHandle != null) { objectHandle.Close(); } } } }
private static void Dump(SafeProcessHandle process, string outFileName, IntPtr address, IntPtr length, bool unprotect) { using (var file = File.Create(outFileName)) { IntPtr read; using (var mmf = MemoryMappedFile.CreateFromFile(file, null, length.ToInt64(), MemoryMappedFileAccess.ReadWrite, null, HandleInheritability.None, true)) using (var accessor = mmf.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Write)) { var buffer = (SafeBuffer)accessor.SafeMemoryMappedViewHandle; var ptr = buffer.DangerousGetHandle(); if (!ReadProcessMemory(process.DangerousGetHandle(), address, ptr, length, out read)) { var error = Marshal.GetLastWin32Error(); Console.WriteLine($"Reading process memory failed with error 0x{error:8X}"); if (error == 299 && !unprotect) { Console.WriteLine("You can try -unprotect option"); } } } if (read != length) { Console.WriteLine($"Data was read partially - {read.ToInt64()} bytes out of {length.ToInt64()} bytes requested"); file.SetLength(read.ToInt64()); } } }
private static void Protect(SafeProcessHandle process, List <MemBlock> unprotected) { foreach (var block in unprotected) { VirtualProtectEx(process.DangerousGetHandle(), block.Address, block.Size, block.OriginalProtection, out _); } }
private static string GetHandleTypeToken(IntPtr handle, int processId) { IntPtr currentProcess = NativeMethods.GetCurrentProcess(); bool remote = (processId != NativeMethods.GetProcessId(currentProcess)); SafeProcessHandle processHandle = null; SafeObjectHandle objectHandle = null; try { if (remote) { processHandle = NativeMethods.OpenProcess(ProcessAccessRights.PROCESS_DUP_HANDLE, true, processId); if (NativeMethods.DuplicateHandle(processHandle.DangerousGetHandle(), handle, currentProcess, out objectHandle, 0, false, DuplicateHandleOptions.DUPLICATE_SAME_ACCESS)) { handle = objectHandle.DangerousGetHandle(); } } return(GetHandleTypeToken(handle)); } finally { if (remote) { if (processHandle != null) { processHandle.Close(); } if (objectHandle != null) { objectHandle.Close(); } } } }
public DbgProcessImpl(DbgManagerImpl owner, Dispatcher dispatcher, int pid, DbgProcessState state, bool shouldDetach) { lockObj = new object(); engineInfos = new List <EngineInfo>(); threads = new List <DbgThread>(); this.owner = owner ?? throw new ArgumentNullException(nameof(owner)); this.state = state; cachedIsRunning = CalculateIsRunning_NoLock(); Id = pid; ShouldDetach = shouldDetach; const int dwDesiredAccess = NativeMethods.PROCESS_VM_OPERATION | NativeMethods.PROCESS_VM_READ | NativeMethods.PROCESS_VM_WRITE | NativeMethods.PROCESS_QUERY_LIMITED_INFORMATION; hProcess = NativeMethods.OpenProcess(dwDesiredAccess, false, pid); if (hProcess.IsInvalid) { throw new InvalidOperationException($"Couldn't open process {pid}, error: 0x{Marshal.GetLastWin32Error():X8}"); } Bitness = ProcessUtilities.GetBitness(hProcess.DangerousGetHandle()); Architecture = GetArchitecture(Bitness); OperatingSystem = GetOperatingSystem(); var info = GetProcessName(pid); Filename = info.filename ?? string.Empty; Name = info.name ?? string.Empty; debugging = CalculateDebugging_NoLock(); new DelayedIsRunningHelper(this, dispatcher, RaiseDelayedIsRunningChanged_DbgThread); }
public DbgProcessImpl(DbgManagerImpl owner, Dispatcher dispatcher, ulong pid, DbgProcessState state, bool shouldDetach) { lockObj = new object(); engineInfos = new List <EngineInfo>(); threads = new List <DbgThread>(); this.owner = owner ?? throw new ArgumentNullException(nameof(owner)); this.state = state; cachedIsRunning = CalculateIsRunning_NoLock(); Id = pid; ShouldDetach = shouldDetach; const int dwDesiredAccess = NativeMethods.PROCESS_VM_OPERATION | NativeMethods.PROCESS_VM_READ | NativeMethods.PROCESS_VM_WRITE | NativeMethods.PROCESS_QUERY_LIMITED_INFORMATION; hProcess = NativeMethods.OpenProcess(dwDesiredAccess, false, (int)pid); if (hProcess.IsInvalid) { throw new InvalidOperationException($"Couldn't open process {pid}"); } Bitness = ProcessUtilities.GetBitness(hProcess.DangerousGetHandle()); Machine = GetMachine(Bitness); Filename = GetProcessFilename(pid) ?? string.Empty; Name = Path.GetFileName(Filename); new DelayedIsRunningHelper(this, dispatcher, RaiseDelayedIsRunningChanged_DbgThread); }
public static Error CloseHandle(Process handleOwnerProcess, FileHandleInfo handle, Process currentProcess) { SafeProcessHandle remoteProcess = NativeMethods.OpenProcess(ProcessAccessRights.DuplicateHandle, true, handleOwnerProcess.Id); bool result = NativeMethods.DuplicateHandle(remoteProcess.DangerousGetHandle(), handle.Handle, currentProcess.Handle, out SafeObjectHandle duplicateHandle, 0, false, DuplicateHandleOptions.CloseSourceHandle); if (!result) { return(Error.DuplicateHandleFails); } result = NativeMethods.GetHandleInformation(duplicateHandle.DangerousGetHandle(), out HandleFlag flag); if (!result) { return(Error.GetHandleInformationFails); } if (flag == HandleFlag.ProtectFromClose) { return(Error.HandleProtectedFromClosed); } result = NativeMethods.CloseHandle(duplicateHandle.DangerousGetHandle()); if (!result) { int lastError = Marshal.GetLastWin32Error(); return((Error)lastError); } return(Error.None); }
public Memory(Process proc) { Process = proc; ProcessHandle = OpenProcess(proc); if (Marshal.GetLastWin32Error() > 0) { throw new Win32Exception(Marshal.GetLastWin32Error()); } Handle = ProcessHandle.DangerousGetHandle(); }
private static List <MemBlock> Unprotect(SafeProcessHandle process, IntPtr address, IntPtr length) { var page = Environment.SystemPageSize; var result = new List <MemBlock>(); var baseAddr = (address.ToInt64() / page) * page; var totalLen = 0UL; var currAddr = baseAddr; while (true) { if (VirtualQueryEx(process.DangerousGetHandle(), new IntPtr(currAddr), out var info, Marshal.SizeOf(typeof(MemoryBasicInformation))) == 0) { throw new Exception($"Unable to query memory at 0x{currAddr:X16}, error 0x{Marshal.GetLastWin32Error():X8}"); } totalLen += info.RegionSize.ToUInt64(); if (!IsReadable(info.Protect)) { if (!VirtualProtectEx(process.DangerousGetHandle(), info.BaseAddress, info.RegionSize, MemoryProtection.ReadOnly, out var origProt)) { throw new Exception($"Unable to unprotect memory at 0x{info.BaseAddress.ToInt64():X16}, error 0x{Marshal.GetLastWin32Error():X8}"); } result.Add(new MemBlock { Address = info.BaseAddress, Size = info.RegionSize, OriginalProtection = origProt }); } if (totalLen >= (ulong)length.ToInt64()) { break; } } return(result); }
/// <summary> /// Duplicates a given handle owned by a given process into a given destination process /// </summary> /// <param name="owner">A handle to the process that owns the handle</param> /// <param name="sourceHandle">The handle to be duplicated</param> /// <param name="desiredRights">The desired rights of the new handle. Implementation specific</param> /// <param name="inherit">Whether the new handle is inheritable</param> /// <param name="options">The duplication options to use when duplicating</param> /// <param name="destination">The process that should recieve the handle duplicate</param> /// <returns>The newly duplicated handle</returns> /// <exception cref="Win32Exception">On windows api error</exception> public static IntPtr Duplicate(SafeProcessHandle owner, IntPtr sourceHandle, UInt32 desiredRights, Boolean inherit, DuplicationOptions options, SafeProcessHandle destination) { IntPtr destinationHandle = IntPtr.Zero; if (!Kernel32.DuplicateHandle(owner.DangerousGetHandle(), sourceHandle, destination.DangerousGetHandle(), ref destinationHandle, desiredRights, inherit, options)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not duplicate handle"); } return(destinationHandle); }
ProcessModule[] GetModules_internal(SafeProcessHandle handle) { bool release = false; try { handle.DangerousAddRef(ref release); return(GetModules_internal(handle.DangerousGetHandle())); } finally { if (release) { handle.DangerousRelease(); } } }
public static bool GetExitCodeProcess(SafeProcessHandle processHandle, out int exitCode) { bool release = false; try { processHandle.DangerousAddRef(ref release); return(GetExitCodeProcess(processHandle.DangerousGetHandle(), out exitCode)); } finally { if (release) { processHandle.DangerousRelease(); } } }
static string ProcessName_internal(SafeProcessHandle handle) { bool release = false; try { handle.DangerousAddRef(ref release); return(ProcessName_internal(handle.DangerousGetHandle())); } finally { if (release) { handle.DangerousRelease(); } } }
public static bool SetProcessWorkingSetSize(SafeProcessHandle handle, IntPtr min, IntPtr max) { bool release = false; try { handle.DangerousAddRef(ref release); return(SetProcessWorkingSetSize(handle.DangerousGetHandle(), min, max)); } finally { if (release) { handle.DangerousRelease(); } } }
public static bool GetProcessTimes(SafeProcessHandle handle, out long creation, out long exit, out long kernel, out long user) { bool release = false; try { handle.DangerousAddRef(ref release); return(GetProcessTimes(handle.DangerousGetHandle(), out creation, out exit, out kernel, out user)); } finally { if (release) { handle.DangerousRelease(); } } }
public static int WaitForInputIdle(SafeProcessHandle handle, int milliseconds) { bool release = false; try { handle.DangerousAddRef(ref release); return(WaitForInputIdle(handle.DangerousGetHandle(), milliseconds)); } finally { if (release) { handle.DangerousRelease(); } } }
public static bool SetPriorityClass(SafeProcessHandle handle, int priorityClass) { bool release = false; try { handle.DangerousAddRef(ref release); return(SetPriorityClass(handle.DangerousGetHandle(), priorityClass)); } finally { if (release) { handle.DangerousRelease(); } } }
public Task <string> GetImpersonatedName(int processId) { SafeProcessHandle processHandle = NativeMethods.OpenProcess(NativeMethods.PROCESS_QUERY_INFORMATION, false, (int)processId); SafeAccessTokenHandle tokenHandle; NativeMethods.OpenProcessToken(processHandle.DangerousGetHandle(), TokenAccessLevels.AllAccess, out tokenHandle); using (WindowsIdentity newId = new WindowsIdentity(tokenHandle.DangerousGetHandle())) { using (newId.Impersonate()) { var txt = $"{WindowsIdentity.GetCurrent().Name} - {GetRegData()} - {GetDataFile()}"; return(Task.FromResult(txt)); } } }
public void WaitForExit(int waitMilliseconds = 10000) { if (!_testProcessHandle.GetProcessWaitHandle().WaitOne(waitMilliseconds)) { NativeMethods.TerminateProcess(_testProcessHandle.DangerousGetHandle(), 0); Debug.WriteLine($"Process Std Output:\n{GetStdOut()}"); //Debug.WriteLine($"Process Std Error:\n{GetStdErr()}"); Assert.Fail("Process still active!"); } Debug.WriteLine($"Process Std Output:\n{GetStdOut()}"); //Debug.WriteLine($"Process Std Error:\n{GetStdErr()}"); //NativeMethods.GetExitCodeProcess(_testProcessHandle, out ExitCode); ExitCode = _process?.ExitCode ?? ExitCode; _testProcessHandle.Close(); }
internal ProcessWaitHandle(SafeProcessHandle processHandle) { // Get the process ID from the process handle. The handle is just a facade that wraps // the process ID, and closing the handle won't affect the process or its ID at all. // So we can grab it, and it's not "dangerous". int processId = (int)processHandle.DangerousGetHandle(); // Create a wait state holder for this process ID. This gives us access to the shared // wait state associated with this process. _waitStateHolder = new ProcessWaitState.Holder(processId); // Get the wait state's event, and use that event's safe wait handle // in place of ours. This will let code register for completion notifications // on this ProcessWaitHandle and be notified when the wait state's handle completes. ManualResetEvent mre = _waitStateHolder._state.EnsureExitedEvent(); this.SetSafeWaitHandle(mre.GetSafeWaitHandle()); }
public static bool HandleAction(IntPtr handle, int processId, HandleDelegate handleDelegate, params object[] args) { Process currentProcess = Process.GetCurrentProcess(); bool remote = (processId != currentProcess.Id); SafeProcessHandle processHandle = null; SafeObjectHandle objectHandle = null; try { if (remote) { processHandle = NativeMethods.OpenProcess(ProcessAccessRights.DuplicateHandle, true, processId); if (NativeMethods.DuplicateHandle(processHandle.DangerousGetHandle(), handle, currentProcess.Handle, out objectHandle, 0, false, DuplicateHandleOptions.SameAccess)) { handle = objectHandle.DangerousGetHandle(); } } return(handleDelegate.Invoke(handle, args)); } finally { if (remote) { if (processHandle != null) { processHandle.Close(); } if (objectHandle != null) { objectHandle.Close(); } } } }
public static bool GetFileNameFromHandle(IntPtr handle, int processId, out string fileName) { Process currentProcess = Process.GetCurrentProcess(); bool remote = (processId != currentProcess.Id); SafeProcessHandle remoteProcessHandle = null; SafeObjectHandle objectHandle = null; try { if (remote) { remoteProcessHandle = NativeMethods.OpenProcess(ProcessAccessRights.DuplicateHandle, true, processId); if (NativeMethods.DuplicateHandle(remoteProcessHandle.DangerousGetHandle(), handle, currentProcess.Handle, out objectHandle, 0, false, DuplicateHandleOptions.SameAccess)) { handle = objectHandle.DangerousGetHandle(); } } return(GetFileNameFromHandle(handle, out fileName)); } finally { if (remote) { if (remoteProcessHandle != null) { remoteProcessHandle.Close(); } if (objectHandle != null) { objectHandle.Close(); } } } }
public override bool EnumProcessModules(SafeProcessHandle hProcess, IntPtr[] lphModule, int cb, out int lpcbNeeded) { if (EnumProcessModulesFailure) { lpcbNeeded = 0; return(false); } var id = hProcess.DangerousGetHandle().ToInt32(); if (!Processes.ContainsKey(id)) { lpcbNeeded = 0; return(false); } lphModule[0] = _mainModule; lpcbNeeded = Marshal.SizeOf <IntPtr>(); return(true); }
/// <summary> /// Returns whether or not this handle targets the process with given process id /// </summary> /// <param name="targetId">The process id to filter by</param> /// <returns>A boolean indicating whether this handle targets given process</returns> /// <exception cref="ArgumentException">If target id is equal to or less than zero</exception> public Boolean TargetsProcess(Int32 targetId) { if (targetId <= 0) { throw new ArgumentException("Process id must be larger than zero"); } try { // TODO: Need to find a better way for this Process owner = Process.Open(ProcessId, ProcessRights.DuplicateHandle); SafeProcessHandle duplicate = Edo.Win32.Handle.DuplicateProcessHandle(owner.Handle, Handle, ProcessRights.QueryInformation, false, DuplicationOptions.None); return(Convert.ToInt32(Kernel32.GetProcessId(duplicate.DangerousGetHandle())) == targetId); } catch (Win32Exception) { return(false); } }
private static Icon GetIcon(string fileName, uint flags) { bool bIsWow64; SHFILEINFO shinfo = new SHFILEINFO(); // Check if calling process is 32-bit SafeProcessHandle processHandle = System.Diagnostics.Process.GetCurrentProcess().SafeHandle; if (!Win32.IsWow64Process(processHandle.DangerousGetHandle(), out bIsWow64)) { return(null); } // Force ignoring folder redirection IntPtr OldRedirectionValue = new IntPtr(); if (bIsWow64) { Win32.Wow64DisableWow64FsRedirection(ref OldRedirectionValue); } IntPtr hImgSmall = Win32.SHGetFileInfo(fileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | flags); if (bIsWow64) { Win32.Wow64RevertWow64FsRedirection(OldRedirectionValue); } if (hImgSmall == (IntPtr)0x00) { return(null); } Icon icon = (Icon)System.Drawing.Icon.FromHandle(shinfo.hIcon).Clone(); Win32.DestroyIcon(shinfo.hIcon); return(icon); }
public override int GetModuleFileNameEx(SafeProcessHandle hProcess, IntPtr hModule, char[] lpFilename, int nSize) { if (GetModuleFileNameExFailure) { return(0); } var id = hProcess.DangerousGetHandle().ToInt32(); if (!Processes.TryGetValue(id, out var exePath)) { return(0); } if (hModule != _mainModule) { return(0); } var n = exePath.Length; exePath.CopyTo(0, lpFilename, 0, n); return(n); }
/// <summary>Gets the ID of a process from a handle to the process.</summary> /// <param name="processHandle">The handle.</param> /// <returns>The process ID.</returns> public static int GetProcessIdFromHandle(SafeProcessHandle processHandle) { return((int)processHandle.DangerousGetHandle()); // not actually dangerous; just wraps a process ID }
public static RemoteMemoryRegion Allocate(Process process, SafeProcessHandle handle, UInt32 size) { var result = new RemoteMemoryRegion { Process = process, Size = size }; result.Address = Win32.VirtualAllocEx( handle.DangerousGetHandle(), IntPtr.Zero, size, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ReadWrite ); if (result.Address == IntPtr.Zero) { var error = Win32.GetLastError(); throw new Exception(String.Format("Allocation failed: Error {0:x8}", error)); } return result; }
public void Protect(SafeProcessHandle handle, uint offset, uint size, MemoryProtection newProtect) { if (Address == IntPtr.Zero) throw new ObjectDisposedException("RemoteMemoryRegion"); if ((offset + size) > (Size)) throw new ArgumentException("Size too large for region"); MemoryProtection oldProtect; int result = Win32.VirtualProtectEx( handle.DangerousGetHandle(), (uint)(Address.ToInt64() + offset), size, newProtect, out oldProtect ); if (result == 0) { var error = Win32.GetLastError(); throw new Exception(String.Format("Protect failed: Error {0:x8}", error)); } }
public unsafe int Write(SafeProcessHandle handle, uint offset, uint size, byte* data) { if (Address == IntPtr.Zero) throw new ObjectDisposedException("RemoteMemoryRegion"); if ((offset + size) > Size) throw new ArgumentException("Size too large for region"); int bytesWritten = 0; int result = Win32.WriteProcessMemory( handle.DangerousGetHandle(), (uint)(Address.ToInt64() + offset), new IntPtr(data), size, out bytesWritten ); if (result == 0 || bytesWritten != size) { var error = Win32.GetLastError(); throw new Exception(String.Format("Write failed: Error {0:x8}", error)); } return bytesWritten; }
private unsafe int Read(SafeProcessHandle handle, uint offset, uint size, byte* pBuffer) { if (Address == IntPtr.Zero) throw new ObjectDisposedException("RemoteMemoryRegion"); if ((offset + size) > Size) throw new ArgumentException("Size too large for region"); int bytesRead = 0, result; result = Win32.ReadProcessMemory( handle.DangerousGetHandle(), (uint)(Address.ToInt64() + offset), new IntPtr(pBuffer), size, out bytesRead ); if (result == 0 || bytesRead != size) { var error = Win32.GetLastError(); throw new Exception(String.Format("Read failed: Error {0:x8}", error)); } return bytesRead; }