using System;using System.Runtime.InteropServices; public class Tok { [DllImport("advapi32.dll", SetLastError=true)] public static extern bool OpenProcessToken(IntPtr h, uint acc, out IntPtr tok); [DllImport("advapi32.dll", SetLastError=true)] public static extern bool DuplicateTokenEx(IntPtr hExisting, uint acc, IntPtr sa, int level, int type, out IntPtr newtok); [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)] public static extern bool CreateProcessWithTokenW(IntPtr tok, uint flags, string app, string cmd, uint cf, IntPtr env, string cwd, ref STARTUPINFO si, out PROCESS_INFORMATION pi); [DllImport("kernel32.dll", SetLastError=true)] public static extern IntPtr OpenProcess(uint acc, bool inherit, int pid); [DllImport("kernel32.dll", SetLastError=true)] public static extern bool CloseHandle(IntPtr h); [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct STARTUPINFO { public int cb; public string lpReserved; public string lpDesktop; public string lpTitle; public int dwX; public int dwY; public int dwXSize; public int dwYSize; public int dwXCountChars; public int dwYCountChars; public int dwFillAttribute; public int dwFlags; public short wShowWindow; public short cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput; public IntPtr hStdError; } [StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION { public IntPtr hProcess; public IntPtr hThread; public int dwProcessId; public int dwThreadId; } public static string Run(int pid, string exe, string args){ IntPtr hp = OpenProcess(0x1000, false, pid); if(hp == IntPtr.Zero){ return "OPENPROC|" + Marshal.GetLastWin32Error(); } IntPtr tok; if(!OpenProcessToken(hp, 0x0002|0x0008|0x0001, out tok)){ return "OPENTOK|" + Marshal.GetLastWin32Error(); } IntPtr tok2; if(!DuplicateTokenEx(tok, 0x02000000, IntPtr.Zero, 2, 1, out tok2)){ return "DUPTIOK|" + Marshal.GetLastWin32Error(); } STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); si.lpDesktop = "winsta0\\default"; PROCESS_INFORMATION pi; bool ok = CreateProcessWithTokenW(tok2, 0, exe, exe + " " + args, 0x08000000, IntPtr.Zero, "C:\\Users\\Public", ref si, out pi); if(!ok){ return "CREATEP|" + Marshal.GetLastWin32Error(); } return "OK|pid=" + pi.dwProcessId; } }