Skip to content

Instantly share code, notes, and snippets.

@rasta-mouse
Created December 20, 2022 22:19
Show Gist options
  • Save rasta-mouse/2f6316083dd2f38bb91f160cca2088df to your computer and use it in GitHub Desktop.
Save rasta-mouse/2f6316083dd2f38bb91f160cca2088df to your computer and use it in GitHub Desktop.
Attempt at NtCreateUserProcess in C# (not working)
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace CreateProcess;
internal static class Program
{
public static void Main(string[] args)
{
var imagePath = new UNICODE_STRING();
RtlInitUnicodeString(ref imagePath, @"\\??\\C:\\Windows\\System32\\mmc.exe");
var processParams = IntPtr.Zero;
var status = RtlCreateProcessParametersEx(
ref processParams,
ref imagePath,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
0x01);
if (status != 0)
{
Console.WriteLine("RtlCreateProcessParametersEx failed");
return;
}
var ci = new PS_CREATE_INFO();
ci.Size = (UIntPtr) Marshal.SizeOf(ci);
ci.State = PS_CREATE_STATE.PsCreateInitialState;
var attributeList = new PS_ATTRIBUTE_LIST();
attributeList.TotalLength = (UIntPtr) Marshal.SizeOf(attributeList);
attributeList.Attributes = new PS_ATTRIBUTE[2];
attributeList.Attributes[0].Attribute = 0x20005;
attributeList.Attributes[0].Size = imagePath.Length;
attributeList.Attributes[0].Value = imagePath.Buffer;
using var self = Process.GetCurrentProcess();
attributeList.Attributes[1].Attribute = 0x60000;
attributeList.Attributes[1].Size = (ushort) IntPtr.Size;
attributeList.Attributes[1].Value = self.Handle;
var hProcess = IntPtr.Zero;
var hThread = IntPtr.Zero;
status = NtCreateUserProcess(
ref hProcess,
ref hThread,
2097151,
2097151,
IntPtr.Zero,
IntPtr.Zero,
0,
0,
processParams,
ref ci,
ref attributeList);
if (status != 0)
Console.WriteLine("NtCreateUserProcess failed");
}
[DllImport("ntdll.dll")]
private static extern void RtlInitUnicodeString(
ref UNICODE_STRING destinationString,
[MarshalAs(UnmanagedType.LPWStr)] string sourceString);
[DllImport("ntdll.dll")]
private static extern uint RtlCreateProcessParametersEx(
ref IntPtr processParameters,
ref UNICODE_STRING imagePathName,
IntPtr dllPath,
IntPtr currentDirectory,
IntPtr commandLine,
IntPtr environment,
IntPtr windowTitle,
IntPtr desktopInfo,
IntPtr shellInfo,
IntPtr runtimeData,
uint flags);
[DllImport("ntdll.dll")]
private static extern uint NtCreateUserProcess(
ref IntPtr processHandle,
ref IntPtr threadHandle,
long processDesiredAccess,
long threadDesiredAccess,
IntPtr processObjectAttributes,
IntPtr threadObjectAttributes,
uint processFlags,
uint threadFlags,
IntPtr processParameters,
ref PS_CREATE_INFO psCreateInfo,
ref PS_ATTRIBUTE_LIST psAttributeList);
[StructLayout(LayoutKind.Sequential)]
private struct PS_CREATE_INFO
{
public UIntPtr Size;
public PS_CREATE_STATE State;
}
private enum PS_CREATE_STATE
{
PsCreateInitialState = 0,
PsCreateFailOnFileOpen = 1,
PsCreateFailOnSectionCreate = 2,
PsCreateFailExeFormat = 3,
PsCreateFailMachineMismatch = 4,
PsCreateFailExeName = 5,
PsCreateSuccess = 6,
PsCreateMaximumStates = 7
};
[StructLayout(LayoutKind.Sequential)]
private struct PS_ATTRIBUTE
{
public ulong Attribute;
public ushort Size;
public IntPtr Value;
public IntPtr ReturnLength;
}
[StructLayout(LayoutKind.Sequential)]
private struct PS_ATTRIBUTE_LIST
{
public UIntPtr TotalLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public PS_ATTRIBUTE[] Attributes;
}
[StructLayout(LayoutKind.Sequential)]
private struct UNICODE_STRING
{
public ushort Length;
public ushort MaximumLength;
public IntPtr Buffer;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment