Skip to content

Instantly share code, notes, and snippets.

@stackcoder
Created November 19, 2022 22:58
Show Gist options
  • Save stackcoder/156198f1f6c3fa92474f0f6d942ccda8 to your computer and use it in GitHub Desktop.
Save stackcoder/156198f1f6c3fa92474f0f6d942ccda8 to your computer and use it in GitHub Desktop.
Start process suspended using CreateProcess and Powershell. Usefull for (remote) debugging, even bevore main().
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)][string]$CommandLine = ''
)
$ErrorActionPreference = 'Stop'
# lifted from https://stackoverflow.com/questions/16686122/calling-createprocess-from-powershell
Add-Type -TypeDefinition @"
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
public static class Win32Natives
{
[StructLayout(LayoutKind.Sequential)]
private struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public uint dwProcessId;
public uint dwThreadId;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct STARTUPINFO
{
public uint cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public STARTF dwFlags;
public ShowWindow wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
private struct SECURITY_ATTRIBUTES
{
public int length;
public IntPtr lpSecurityDescriptor;
public bool bInheritHandle;
}
[Flags]
private enum CreationFlags : int
{
NONE = 0,
DEBUG_PROCESS = 0x00000001,
DEBUG_ONLY_THIS_PROCESS = 0x00000002,
CREATE_SUSPENDED = 0x00000004,
DETACHED_PROCESS = 0x00000008,
CREATE_NEW_CONSOLE = 0x00000010,
CREATE_NEW_PROCESS_GROUP = 0x00000200,
CREATE_UNICODE_ENVIRONMENT = 0x00000400,
CREATE_SEPARATE_WOW_VDM = 0x00000800,
CREATE_SHARED_WOW_VDM = 0x00001000,
CREATE_PROTECTED_PROCESS = 0x00040000,
EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
CREATE_DEFAULT_ERROR_MODE = 0x04000000,
CREATE_NO_WINDOW = 0x08000000,
}
[Flags]
private enum STARTF : uint
{
STARTF_USESHOWWINDOW = 0x00000001,
STARTF_USESIZE = 0x00000002,
STARTF_USEPOSITION = 0x00000004,
STARTF_USECOUNTCHARS = 0x00000008,
STARTF_USEFILLATTRIBUTE = 0x00000010,
STARTF_RUNFULLSCREEN = 0x00000020, // ignored for non-x86 platforms
STARTF_FORCEONFEEDBACK = 0x00000040,
STARTF_FORCEOFFFEEDBACK = 0x00000080,
STARTF_USESTDHANDLES = 0x00000100,
}
private enum ShowWindow : short
{
SW_HIDE = 0,
SW_SHOWNORMAL = 1,
SW_NORMAL = 1,
SW_SHOWMINIMIZED = 2,
SW_SHOWMAXIMIZED = 3,
SW_MAXIMIZE = 3,
SW_SHOWNOACTIVATE = 4,
SW_SHOW = 5,
SW_MINIMIZE = 6,
SW_SHOWMINNOACTIVE = 7,
SW_SHOWNA = 8,
SW_RESTORE = 9,
SW_SHOWDEFAULT = 10,
SW_FORCEMINIMIZE = 11,
SW_MAX = 11
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CreateProcess(
IntPtr lpApplicationName,
string lpCommandLine,
IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes,
bool bInheritHandles,
CreationFlags dwCreationFlags,
IntPtr lpEnvironment,
IntPtr lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo,
ref PROCESS_INFORMATION lpProcessInformation);
public static void CreateSuspended(string commandLine)
{
var startupInfo = new STARTUPINFO();
var provessInfo = new PROCESS_INFORMATION();
if (!CreateProcess(
IntPtr.Zero,
commandLine,
IntPtr.Zero,
IntPtr.Zero,
false,
CreationFlags.CREATE_SUSPENDED,
IntPtr.Zero,
IntPtr.Zero,
ref startupInfo,
ref provessInfo))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
}
"@
[Win32Natives]::CreateSuspended($CommandLine)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment