Skip to content

Instantly share code, notes, and snippets.

@BinToss
Last active May 11, 2023 04:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BinToss/01e31e88a64372848ed10be761d6e2b6 to your computer and use it in GitHub Desktop.
Save BinToss/01e31e88a64372848ed10be761d6e2b6 to your computer and use it in GitHub Desktop.
What does OpenProcess do when it cannot find a process with the given PID?
#!meta
{"kernelInfo":{"defaultKernelName":"csharp","items":[{"aliases":[],"name":"csharp"}]}}
#!csharp
/** Q: What does OpenProcess do when it cannot find a process with the given PID?
A: Returns a null handle and writes ERROR_SUCCESS (0) to "LastError"
*/
using Microsoft.Win32.SafeHandles;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
HANDLE handle = OpenProcess(PROCESS_ACCESS_RIGHTS.PROCESS_ALL_ACCESS, (BOOL)false, 99999);
handle.Display();
/** Submission#14+HANDLE
IsNull True
Value 0
*/
Win32Exception err = new();
Console.WriteLine("P/Invoke status: " + err.ToString() + Environment.NewLine + Marshal.GetLastPInvokeError());
/** P/Invoke status: System.ComponentModel.Win32Exception (0x80004005): The operation completed successfully.
0
*/
public readonly partial struct HANDLE : IEquatable<HANDLE>
{
public readonly IntPtr Value;
public HANDLE(IntPtr value) => this.Value = value;
public static HANDLE Null => default;
public bool IsNull => Value == default;
public static implicit operator IntPtr(HANDLE value) => value.Value;
public static explicit operator HANDLE(IntPtr value) => new HANDLE(value);
public static bool operator ==(HANDLE left, HANDLE right) => left.Value == right.Value;
public static bool operator !=(HANDLE left, HANDLE right) => !(left == right);
public bool Equals(HANDLE other) => this.Value == other.Value;
public override bool Equals(object obj) => obj is HANDLE other && this.Equals(other);
public override int GetHashCode() => this.Value.GetHashCode();
}
public readonly partial struct BOOL : IEquatable<BOOL>
{
public readonly int Value;
public BOOL(int value) => this.Value = value;
public static implicit operator int(BOOL value) => value.Value;
public static explicit operator BOOL(int value) => new BOOL(value);
public static bool operator ==(BOOL left, BOOL right) => left.Value == right.Value;
public static bool operator !=(BOOL left, BOOL right) => !(left == right);
public bool Equals(BOOL other) => this.Value == other.Value;
public override bool Equals(object obj) => obj is BOOL other && this.Equals(other);
public override int GetHashCode() => this.Value.GetHashCode();
public BOOL(bool value) => this.Value = value ? 1 : 0;
public static implicit operator bool(BOOL value) => value.Value != 0;
public static implicit operator BOOL(bool value) => new BOOL(value);
}
[Flags]
public enum PROCESS_ACCESS_RIGHTS : uint
{
PROCESS_TERMINATE = 0x00000001,
PROCESS_CREATE_THREAD = 0x00000002,
PROCESS_SET_SESSIONID = 0x00000004,
PROCESS_VM_OPERATION = 0x00000008,
PROCESS_VM_READ = 0x00000010,
PROCESS_VM_WRITE = 0x00000020,
PROCESS_DUP_HANDLE = 0x00000040,
PROCESS_CREATE_PROCESS = 0x00000080,
PROCESS_SET_QUOTA = 0x00000100,
PROCESS_SET_INFORMATION = 0x00000200,
PROCESS_QUERY_INFORMATION = 0x00000400,
PROCESS_SUSPEND_RESUME = 0x00000800,
PROCESS_QUERY_LIMITED_INFORMATION = 0x00001000,
PROCESS_SET_LIMITED_INFORMATION = 0x00002000,
PROCESS_ALL_ACCESS = 0x001FFFFF,
PROCESS_DELETE = 0x00010000,
PROCESS_READ_CONTROL = 0x00020000,
PROCESS_WRITE_DAC = 0x00040000,
PROCESS_WRITE_OWNER = 0x00080000,
PROCESS_SYNCHRONIZE = 0x00100000,
PROCESS_STANDARD_RIGHTS_REQUIRED = 0x000F0000,
}
/// <summary>Opens an existing local process object.</summary>
/// <param name="dwDesiredAccess">
/// <para>The access to the process object. This access right is checked against the security descriptor for the process. This parameter can be one or more of the <a href="https://docs.microsoft.com/windows/desktop/ProcThread/process-security-and-access-rights">process access rights</a>. If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the contents of the security descriptor.</para>
/// <para><see href="https://docs.microsoft.com/windows/win32/api//processthreadsapi/nf-processthreadsapi-openprocess#parameters">Read more on docs.microsoft.com</see>.</para>
/// </param>
/// <param name="bInheritHandle">If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle.</param>
/// <param name="dwProcessId">
/// <para>The identifier of the local process to be opened. If the specified process is the System Idle Process (0x00000000), the function fails and the last error code is `ERROR_INVALID_PARAMETER`. If the specified process is the System process or one of the Client Server Run-Time Subsystem (CSRSS) processes, this function fails and the last error code is `ERROR_ACCESS_DENIED` because their access restrictions prevent user-level code from opening them. If you are using <a href="https://docs.microsoft.com/windows/desktop/api/processthreadsapi/nf-processthreadsapi-getcurrentprocessid">GetCurrentProcessId</a> as an argument to this function, consider using <a href="https://docs.microsoft.com/windows/desktop/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess">GetCurrentProcess</a> instead of OpenProcess, for improved performance.</para>
/// <para><see href="https://docs.microsoft.com/windows/win32/api//processthreadsapi/nf-processthreadsapi-openprocess#parameters">Read more on docs.microsoft.com</see>.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is an open handle to the specified process. If the function fails, the return value is NULL. To get extended error information, call <a href="/windows/desktop/api/errhandlingapi/nf-errhandlingapi-getlasterror">GetLastError</a>.</para>
/// </returns>
/// <remarks>
/// <para><see href="https://docs.microsoft.com/windows/win32/api//processthreadsapi/nf-processthreadsapi-openprocess">Learn more about this API from docs.microsoft.com</see>.</para>
/// </remarks>
[DllImport("KERNEL32.dll", ExactSpelling = true, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[SupportedOSPlatform("windows5.1.2600")]
public static extern HANDLE OpenProcess(PROCESS_ACCESS_RIGHTS dwDesiredAccess, BOOL bInheritHandle, uint dwProcessId);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment