mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
e19d664c27
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@512 21ef857c-d57f-4fe0-8362-d861dc6d29cd
750 lines
26 KiB
C#
750 lines
26 KiB
C#
/*
|
|
* Process Hacker Assistant
|
|
*
|
|
* Copyright (C) 2008 wj32
|
|
*
|
|
* This file is part of Process Hacker.
|
|
*
|
|
* Process Hacker is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Process Hacker is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security.Principal;
|
|
|
|
namespace Assistant
|
|
{
|
|
static class Program
|
|
{
|
|
const int SecurityDescriptorMinLength = 20;
|
|
const int SecuritDescriptorRevision = 1;
|
|
|
|
#region Enums & Structs
|
|
|
|
enum LogonType : int
|
|
{
|
|
Interactive = 2,
|
|
Network = 3,
|
|
Batch = 4,
|
|
Service = 5,
|
|
Unlock = 7,
|
|
NetworkCleartext = 8,
|
|
NewCredentials = 9
|
|
}
|
|
|
|
enum LogonProvider : int
|
|
{
|
|
Default = 0,
|
|
WinNT35 = 1,
|
|
WinNT40 = 2,
|
|
WinNT50 = 3
|
|
}
|
|
|
|
[Flags]
|
|
enum CreationFlags : uint
|
|
{
|
|
DebugProcess = 0x1,
|
|
DebugOnlyThisProcess = 0x2,
|
|
CreateSuspended = 0x4,
|
|
DetachedProcess = 0x8,
|
|
CreateNewConsole = 0x10,
|
|
NormalPriorityClass = 0x20,
|
|
IdlePriorityClass = 0x40,
|
|
HighPriorityClass = 0x80,
|
|
RealtimePriorityClass = 0x100,
|
|
CreateNewProcessGroup = 0x200,
|
|
CreateUnicodeEnvironment = 0x400,
|
|
CreateSeparateWowVdm = 0x800,
|
|
CreateSharedWowVdm = 0x1000,
|
|
CreateForceDos = 0x2000,
|
|
BelowNormalPriorityClass = 0x4000,
|
|
AboveNormalPriorityClass = 0x8000,
|
|
StackSizeParamIsAReservation = 0x10000,
|
|
InheritCallerPriority = 0x20000,
|
|
CreateProtectedProcess = 0x40000,
|
|
ExtendedStartupInfoPresent = 0x80000,
|
|
ProcessModeBackgroundBegin = 0x100000,
|
|
ProcessModeBackgroundEnd = 0x200000,
|
|
CreateBreakawayFromJob = 0x1000000,
|
|
CreatePreserveCodeAuthzLevel = 0x2000000,
|
|
CreateDefaultErrorMode = 0x4000000,
|
|
CreateNoWindow = 0x8000000,
|
|
ProfileUser = 0x10000000,
|
|
ProfileKernel = 0x20000000,
|
|
ProfileServer = 0x40000000,
|
|
CreateIgnoreSystemDefault = 0x80000000
|
|
}
|
|
|
|
[Flags]
|
|
enum StartupFlags : uint
|
|
{
|
|
UseShowWindow = 0x1,
|
|
UseSize = 0x2,
|
|
UsePosition = 0x4,
|
|
UseCountChars = 0x8,
|
|
UseFillAttribute = 0x10,
|
|
RunFullScreen = 0x20,
|
|
ForceOnFeedback = 0x40,
|
|
ForceOffFeedback = 0x80,
|
|
UseStdHandles = 0x100,
|
|
UseHotkey = 0x200
|
|
}
|
|
|
|
enum ShowWindowType : short
|
|
{
|
|
Hide = 0,
|
|
ShowNormal = 1,
|
|
Normal = 1,
|
|
ShowMinimized = 2,
|
|
ShowMaximized = 3,
|
|
Maximize = 3,
|
|
ShowNoActivate = 4,
|
|
Show = 5,
|
|
Minimize = 6,
|
|
ShowMinNoActive = 7,
|
|
ShowNa = 8,
|
|
Restore = 9,
|
|
ShowDefault = 10,
|
|
ForceMinimize = 11,
|
|
Max = 11
|
|
}
|
|
|
|
[Flags]
|
|
enum Access : uint
|
|
{
|
|
DesktopReadObjects = 0x1,
|
|
DesktopWriteObjects = 0x80,
|
|
ReadControl = 0x20000,
|
|
WriteDac = 0x40000
|
|
}
|
|
|
|
[Flags]
|
|
enum SIRequested : uint
|
|
{
|
|
OwnerSecurityInformation = 0x1,
|
|
GroupSecurityInformation = 0x2,
|
|
DaclSecurityInformation = 0x4,
|
|
SaclSecurityInformation = 0x8,
|
|
LabelSecurityInformation = 0x10
|
|
}
|
|
|
|
[Flags]
|
|
enum AllocFlags : uint
|
|
{
|
|
LHnd = 0x42,
|
|
LMemFixed = 0x0,
|
|
LMemMoveable = 0x2,
|
|
LMemZeroInit = 0x40,
|
|
LPtr = 0x40,
|
|
NonZeroLHnd = LMemMoveable,
|
|
NonZeroLPtr = LMemFixed
|
|
}
|
|
|
|
enum TokenInformationClass
|
|
{
|
|
TokenUser = 1,
|
|
TokenGroups,
|
|
TokenPrivileges,
|
|
TokenOwner,
|
|
TokenPrimaryGroup,
|
|
TokenDefaultDacl,
|
|
TokenSource,
|
|
TokenType,
|
|
TokenImpersonationLevel,
|
|
TokenStatistics,
|
|
TokenRestrictedSids,
|
|
TokenSessionId,
|
|
TokenGroupsAndPrivileges,
|
|
TokenSessionReference,
|
|
TokenSandBoxInert,
|
|
TokenAuditPolicy,
|
|
TokenOrigin,
|
|
TokenElevationType,
|
|
TokenLinkedToken,
|
|
TokenElevation,
|
|
TokenHasRestrictions,
|
|
TokenAccessInformation,
|
|
TokenVirtualizationAllowed,
|
|
TokenVirtualizationEnabled,
|
|
TokenIntegrityLevel,
|
|
TokenUIAccess,
|
|
TokenMandatoryPolicy,
|
|
TokenLogonSid,
|
|
MaxTokenInfoClass // MaxTokenInfoClass should always be the last enum
|
|
}
|
|
|
|
enum ImpersonationLevel
|
|
{
|
|
SecurityAnonymous = 0,
|
|
SecurityIdentification,
|
|
SecurityImpersonation,
|
|
SecurityDelegation
|
|
}
|
|
|
|
enum TokenType
|
|
{
|
|
TokenPrimary = 1,
|
|
TokenImpersonation
|
|
}
|
|
|
|
[Flags]
|
|
public enum STANDARD_RIGHTS : uint
|
|
{
|
|
DELETE = 0x00010000,
|
|
READ_CONTROL = 0x00020000,
|
|
WRITE_DAC = 0x00040000,
|
|
WRITE_OWNER = 0x00080000,
|
|
SYNCHRONIZE = 0x00100000,
|
|
|
|
STANDARD_RIGHTS_REQUIRED = 0x000f0000,
|
|
|
|
STANDARD_RIGHTS_READ = READ_CONTROL,
|
|
STANDARD_RIGHTS_WRITE = READ_CONTROL,
|
|
STANDARD_RIGHTS_EXECUTE = READ_CONTROL,
|
|
|
|
STANDARD_RIGHTS_ALL = 0x001f0000,
|
|
|
|
SPECIFIC_RIGHTS_ALL = 0x0000ffff,
|
|
ACCESS_SYSTEM_SECURITY = 0x01000000,
|
|
MAXIMUM_ALLOWED = 0x02000000,
|
|
GENERIC_READ = 0x80000000,
|
|
GENERIC_WRITE = 0x40000000,
|
|
GENERIC_EXECUTE = 0x20000000,
|
|
GENERIC_ALL = 0x10000000
|
|
}
|
|
|
|
[Flags]
|
|
public enum TokenRights : uint
|
|
{
|
|
TOKEN_ASSIGN_PRIMARY = 0x0001,
|
|
TOKEN_DUPLICATE = 0x0002,
|
|
TOKEN_IMPERSONATE = 0x0004,
|
|
TOKEN_QUERY = 0x0008,
|
|
TOKEN_QUERY_SOURCE = 0x0010,
|
|
TOKEN_ADJUST_PRIVILEGES = 0x0020,
|
|
TOKEN_ADJUST_GROUPS = 0x0040,
|
|
TOKEN_ADJUST_DEFAULT = 0x0080,
|
|
TOKEN_ADJUST_SESSIONID = 0x0100,
|
|
TOKEN_ALL_ACCESS = STANDARD_RIGHTS.STANDARD_RIGHTS_REQUIRED |
|
|
TOKEN_ASSIGN_PRIMARY |
|
|
TOKEN_DUPLICATE |
|
|
TOKEN_IMPERSONATE |
|
|
TOKEN_QUERY |
|
|
TOKEN_QUERY_SOURCE |
|
|
TOKEN_ADJUST_PRIVILEGES |
|
|
TOKEN_ADJUST_GROUPS |
|
|
TOKEN_ADJUST_DEFAULT |
|
|
TOKEN_ADJUST_SESSIONID,
|
|
TOKEN_READ = STANDARD_RIGHTS.STANDARD_RIGHTS_READ | TOKEN_QUERY,
|
|
TOKEN_WRITE = STANDARD_RIGHTS.STANDARD_RIGHTS_WRITE |
|
|
TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT,
|
|
TOKEN_EXECUTE = STANDARD_RIGHTS.STANDARD_RIGHTS_EXECUTE
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
struct StartupInfo
|
|
{
|
|
public int Size;
|
|
public int Reserved;
|
|
|
|
[MarshalAs(UnmanagedType.LPWStr)]
|
|
public string Desktop;
|
|
|
|
[MarshalAs(UnmanagedType.LPWStr)]
|
|
public string Title;
|
|
|
|
public int X;
|
|
public int Y;
|
|
public int XSize;
|
|
public int YSize;
|
|
public int XCountChars;
|
|
public int YCountChars;
|
|
public int FillAttribute;
|
|
public StartupFlags Flags;
|
|
|
|
public ShowWindowType ShowWindow;
|
|
public short Reserved2;
|
|
public int Reserved3;
|
|
|
|
public int StdInputHandle;
|
|
public int StdOutputHandle;
|
|
public int StdErrorHandle;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
struct ProcessInformation
|
|
{
|
|
public int ProcessHandle;
|
|
public int ThreadHandle;
|
|
public int ProcessId;
|
|
public int ThreadId;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Imports
|
|
|
|
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
|
static extern bool CloseHandle(int Handle);
|
|
|
|
[DllImport("advapi32.dll", SetLastError = true)]
|
|
public static extern bool OpenProcessToken(int ProcessHandle, TokenRights DesiredAccess,
|
|
out int TokenHandle);
|
|
|
|
[DllImport("advapi32.dll", SetLastError = true)]
|
|
static extern bool DuplicateToken(
|
|
int TokenHandle,
|
|
int Level,
|
|
out int DuplicatedToken);
|
|
|
|
[DllImport("advapi32.dll", SetLastError = true)]
|
|
static extern bool DuplicateTokenEx(
|
|
int TokenHandle,
|
|
TokenRights DesiredAccess,
|
|
int TokenAttributes,
|
|
ImpersonationLevel ImpersonationLevel,
|
|
TokenType TokenType,
|
|
out int DuplicatedToken);
|
|
|
|
[DllImport("advapi32.dll", SetLastError = true)]
|
|
static extern bool SetTokenInformation(
|
|
int TokenHandle,
|
|
TokenInformationClass TokenInformationClass,
|
|
ref int SessionId,
|
|
int InformationLength);
|
|
|
|
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
static extern bool LogonUser(
|
|
[MarshalAs(UnmanagedType.LPWStr)] string Username,
|
|
[MarshalAs(UnmanagedType.LPWStr)] string Domain,
|
|
[MarshalAs(UnmanagedType.LPWStr)] string Password,
|
|
LogonType LogonType, LogonProvider LogonProvider,
|
|
out int TokenHandle
|
|
);
|
|
|
|
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
static extern bool CreateProcessAsUser(
|
|
int TokenHandle,
|
|
[MarshalAs(UnmanagedType.LPWStr)] string ApplicationName,
|
|
[MarshalAs(UnmanagedType.LPWStr)] string CommandLine,
|
|
int ProcessAttributes,
|
|
int ThreadAttributes,
|
|
[MarshalAs(UnmanagedType.Bool)] bool InheritHandles,
|
|
CreationFlags CreationFlags,
|
|
int Environment,
|
|
[MarshalAs(UnmanagedType.LPWStr)] string CurrentDirectory,
|
|
[MarshalAs(UnmanagedType.Struct)] ref StartupInfo StartupInfo,
|
|
[MarshalAs(UnmanagedType.Struct)] ref ProcessInformation ProcessInformation
|
|
);
|
|
|
|
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
static extern bool CreateProcess(
|
|
[MarshalAs(UnmanagedType.LPWStr)] string ApplicationName,
|
|
[MarshalAs(UnmanagedType.LPWStr)] string CommandLine,
|
|
int ProcessAttributes,
|
|
int ThreadAttributes,
|
|
[MarshalAs(UnmanagedType.Bool)] bool InheritHandles,
|
|
CreationFlags CreationFlags,
|
|
int Environment,
|
|
[MarshalAs(UnmanagedType.LPWStr)] string CurrentDirectory,
|
|
[MarshalAs(UnmanagedType.Struct)] ref StartupInfo StartupInfo,
|
|
[MarshalAs(UnmanagedType.Struct)] ref ProcessInformation ProcessInformation
|
|
);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
static extern int GetCurrentThreadId();
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
static extern IntPtr LocalAlloc(AllocFlags Flags, int Bytes);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
static extern IntPtr LocalFree(IntPtr Memory);
|
|
|
|
[DllImport("user32.dll", SetLastError = true)]
|
|
static extern int GetThreadDesktop(int ThreadId);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
static extern int OpenDesktop(
|
|
[MarshalAs(UnmanagedType.LPWStr)] string Desktop,
|
|
int Flags,
|
|
[MarshalAs(UnmanagedType.Bool)] bool Inherit,
|
|
Access DesiredAccess
|
|
);
|
|
|
|
[DllImport("user32.dll")]
|
|
static extern bool CloseDesktop(int Handle);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
static extern int OpenWindowStation(
|
|
[MarshalAs(UnmanagedType.LPWStr)] string WinSta,
|
|
[MarshalAs(UnmanagedType.Bool)] bool Inherit,
|
|
Access DesiredAccess
|
|
);
|
|
|
|
[DllImport("user32.dll")]
|
|
static extern bool CloseWindowStation(int Handle);
|
|
|
|
[DllImport("user32.dll")]
|
|
static extern bool SetUserObjectSecurity(
|
|
int Handle,
|
|
ref SIRequested SIRequested,
|
|
IntPtr SID
|
|
);
|
|
|
|
[DllImport("advapi32.dll", SetLastError = true)]
|
|
static extern bool InitializeSecurityDescriptor(IntPtr SecurityDescriptor, int Revision);
|
|
|
|
[DllImport("advapi32.dll", SetLastError = true)]
|
|
static extern bool SetSecurityDescriptorDacl(IntPtr SecurityDescriptor,
|
|
[MarshalAs(UnmanagedType.Bool)] bool DaclPresent,
|
|
int Dacl,
|
|
[MarshalAs(UnmanagedType.Bool)] bool DaclDefaulted
|
|
);
|
|
|
|
#endregion
|
|
|
|
static void ThrowLastWin32Error()
|
|
{
|
|
throw new Win32Exception(Marshal.GetLastWin32Error());
|
|
}
|
|
|
|
static string GetLastErrorMessage()
|
|
{
|
|
try
|
|
{
|
|
ThrowLastWin32Error();
|
|
}
|
|
catch (Win32Exception ex)
|
|
{
|
|
return ex.Message;
|
|
}
|
|
|
|
throw new Exception("wtf");
|
|
}
|
|
|
|
static void SetAllAccess(int ObjectHandle)
|
|
{
|
|
IntPtr sd = LocalAlloc(AllocFlags.LPtr, SecurityDescriptorMinLength);
|
|
|
|
try
|
|
{
|
|
if (!InitializeSecurityDescriptor(sd, SecuritDescriptorRevision))
|
|
ThrowLastWin32Error();
|
|
|
|
if (!SetSecurityDescriptorDacl(sd, true, 0, false))
|
|
ThrowLastWin32Error();
|
|
|
|
SIRequested si = SIRequested.DaclSecurityInformation;
|
|
|
|
if (!SetUserObjectSecurity(ObjectHandle, ref si, sd))
|
|
ThrowLastWin32Error();
|
|
}
|
|
finally
|
|
{
|
|
LocalFree(sd);
|
|
}
|
|
}
|
|
|
|
static void SetDesktopWinStaAccess()
|
|
{
|
|
int WinStaHandle, DesktopHandle;
|
|
|
|
if ((WinStaHandle = OpenWindowStation("WinSta0", false, Access.WriteDac)) == 0)
|
|
ThrowLastWin32Error();
|
|
|
|
try
|
|
{
|
|
SetAllAccess(WinStaHandle);
|
|
}
|
|
finally
|
|
{
|
|
CloseWindowStation(WinStaHandle);
|
|
}
|
|
|
|
if ((DesktopHandle = OpenDesktop("Default", 0, false,
|
|
Access.WriteDac | Access.DesktopReadObjects | Access.DesktopWriteObjects)) == 0)
|
|
ThrowLastWin32Error();
|
|
|
|
try
|
|
{
|
|
SetAllAccess(DesktopHandle);
|
|
}
|
|
finally
|
|
{
|
|
CloseDesktop(DesktopHandle);
|
|
}
|
|
}
|
|
|
|
static Dictionary<string, string> ParseArgs(string[] args)
|
|
{
|
|
Dictionary<string, string> dict = new Dictionary<string, string>();
|
|
string argPending = null;
|
|
|
|
foreach (string s in args)
|
|
{
|
|
if (s.StartsWith("-"))
|
|
{
|
|
if (dict.ContainsKey(s))
|
|
throw new Exception("Option already specified.");
|
|
|
|
dict.Add(s, "");
|
|
argPending = s;
|
|
}
|
|
else
|
|
{
|
|
if (argPending != null)
|
|
{
|
|
dict[argPending] = s;
|
|
argPending = null;
|
|
}
|
|
else
|
|
{
|
|
if (dict.ContainsKey(""))
|
|
throw new Exception("Input file already specified.");
|
|
|
|
dict.Add("", s);
|
|
}
|
|
}
|
|
}
|
|
|
|
return dict;
|
|
}
|
|
|
|
static void PrintUsage()
|
|
{
|
|
Console.Write("Process Hacker Assistant\nCopyright (c) 2008 wj32. Licensed under the GNU GPL v3.\n\nUsage:\n" +
|
|
"\tassistant [-w] [-k] [-P pid] [-u username] [-p password] [-t logontype] [-s sessionid] [-d dir] " +
|
|
"[-c cmdline] [-f filename]\n\n" +
|
|
"-w\t\tSpecifies that the permissions of WinSta0 and WinSta0\\Default should be " +
|
|
"modified with all access. You should use this option as a normal user (\"assistant -w\") before attempting to " +
|
|
"use this program as a Windows service.\n" +
|
|
"-k\t\tDebugging purposes: specifies that this program should sleep after completion.\n" +
|
|
"-P pid\t\t\"Steals\" the token of the specified process to start the specified program. You must not use " +
|
|
"the -u and -p options with this option.\n" +
|
|
"-u username\tSpecifies the user under which the program should be run. The username can be specified " +
|
|
"as username, domain\\username, or username@domain. On Windows XP, specifying NT AUTHORITY\\SYSTEM does " +
|
|
"not work by itself. You must specify \"-t newcredentials\" as well.\n" +
|
|
"-p password\tSpecifies the password for the user.\n" +
|
|
"-t logontype\tSpecifies the logon type. For logons to normal users, specify \"interactive\". For logons " +
|
|
"to NT AUTHORITY\\SYSTEM, LOCAL SERVICE or NETWORK SERVICE, specify \"service\" (see above for using SYSTEM on " +
|
|
"Windows XP).\n" +
|
|
"-s sessionid\tSpecifies the session ID under which the program should be run.\n" +
|
|
"-d dir\t\tSpecifies the current directory for the program.\n" +
|
|
"-c cmdline\tSpecifies the command line for the program. You must not use the -f option if you use this.\n" +
|
|
"-f filename\tSpecifies the full path to the program.\n\n" +
|
|
"This application is not useful by itself; even Administrators do not normally have " +
|
|
"SeAssignPrimaryTokenPrivilege and SeTcbPrivilege, both of which are required for the useful " +
|
|
"functioning of this program. You must create a Windows service for this program:\n" +
|
|
"\tsc.exe create PHAssistant binPath= \"\\\"[path to this program]\\\" -u \\\"SYSTEM@NT AUTHORITY\\\" " +
|
|
"-t service -s [your session Id, normally 0 on XP and 1 on Vista] -c calc.exe\"\n" +
|
|
"then start it:\n\tsc.exe start PHAssistant\n" +
|
|
"and finally delete it:\n\tsc.exe delete PHAssistant\n");
|
|
}
|
|
|
|
static void Exit(int exitCode)
|
|
{
|
|
if (args.ContainsKey("-k"))
|
|
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
|
|
|
|
Environment.Exit(exitCode);
|
|
}
|
|
|
|
static void Exit()
|
|
{
|
|
Exit(0);
|
|
}
|
|
|
|
static Dictionary<string, string> args;
|
|
|
|
static void Main()
|
|
{
|
|
try
|
|
{
|
|
args = ParseArgs(Environment.GetCommandLineArgs());
|
|
|
|
bool bad = false;
|
|
|
|
if (!args.ContainsKey("-w"))
|
|
{
|
|
if (!args.ContainsKey("-c") && !args.ContainsKey("-f"))
|
|
bad = true;
|
|
|
|
if (args.ContainsKey("-c") && args.ContainsKey("-f"))
|
|
bad = true;
|
|
|
|
if (!args.ContainsKey("-u") && !args.ContainsKey("-P"))
|
|
bad = true;
|
|
|
|
if (args.ContainsKey("-u") && args.ContainsKey("-P"))
|
|
bad = true;
|
|
}
|
|
|
|
if (args.ContainsKey("-v") || args.ContainsKey("-h"))
|
|
bad = true;
|
|
|
|
if (bad)
|
|
{
|
|
PrintUsage();
|
|
Exit();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
PrintUsage();
|
|
Exit();
|
|
}
|
|
|
|
if (args.ContainsKey("-w"))
|
|
{
|
|
try
|
|
{
|
|
SetDesktopWinStaAccess();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine("Warning: Could not set desktop and window station access: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
int token = 0;
|
|
|
|
if (args.ContainsKey("-u"))
|
|
{
|
|
string user = args["-u"];
|
|
string domain = null;
|
|
string username = "";
|
|
|
|
if (user.Contains("\\"))
|
|
{
|
|
domain = user.Split('\\')[0];
|
|
username = user.Split('\\')[1];
|
|
}
|
|
else if (user.Contains("@"))
|
|
{
|
|
username = user.Split('@')[0];
|
|
domain = user.Split('@')[1];
|
|
}
|
|
else
|
|
{
|
|
username = user;
|
|
}
|
|
|
|
LogonType type = LogonType.Interactive;
|
|
|
|
if (args.ContainsKey("-t"))
|
|
{
|
|
try
|
|
{
|
|
type = (LogonType)Enum.Parse(typeof(LogonType), args["-t"], true);
|
|
}
|
|
catch
|
|
{
|
|
Console.WriteLine("Error: Invalid logon type.");
|
|
Exit(-1);
|
|
}
|
|
}
|
|
|
|
if (!LogonUser(username, domain, args.ContainsKey("-p") ? args["-p"] : "", type,
|
|
LogonProvider.Default, out token))
|
|
{
|
|
Console.WriteLine("Error: Could not logon as user: " + GetLastErrorMessage());
|
|
Exit(Marshal.GetLastWin32Error());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int pid = System.Diagnostics.Process.GetCurrentProcess().Id;
|
|
|
|
try
|
|
{
|
|
if (args.ContainsKey("-P"))
|
|
pid = int.Parse(args["-P"]);
|
|
}
|
|
catch
|
|
{
|
|
Console.WriteLine("Error: Invalid PID.");
|
|
}
|
|
|
|
int handle = 0;
|
|
|
|
try
|
|
{
|
|
handle = System.Diagnostics.Process.GetProcessById(pid).Handle.ToInt32();
|
|
}
|
|
catch
|
|
{
|
|
Console.WriteLine("Error: Could not open process.");
|
|
}
|
|
|
|
if (!OpenProcessToken(handle, TokenRights.TOKEN_ALL_ACCESS, out token))
|
|
{
|
|
Console.WriteLine("Error: Could not open process token: " + GetLastErrorMessage());
|
|
Exit(Marshal.GetLastWin32Error());
|
|
}
|
|
|
|
if (Environment.OSVersion.Version.Major != 5)
|
|
{
|
|
int dupToken;
|
|
|
|
if (!DuplicateTokenEx(token, TokenRights.TOKEN_ALL_ACCESS, 0, ImpersonationLevel.SecurityImpersonation,
|
|
TokenType.TokenPrimary, out dupToken))
|
|
{
|
|
Console.WriteLine("Error: Could not duplicate own token: " + GetLastErrorMessage());
|
|
Exit(Marshal.GetLastWin32Error());
|
|
}
|
|
|
|
CloseHandle(token);
|
|
token = dupToken;
|
|
}
|
|
}
|
|
|
|
if (args.ContainsKey("-s"))
|
|
{
|
|
int sessionId = int.Parse(args["-s"]);
|
|
|
|
if (!SetTokenInformation(token, TokenInformationClass.TokenSessionId, ref sessionId, 4))
|
|
{
|
|
Console.WriteLine("Error: Could not set token session Id: " + GetLastErrorMessage());
|
|
}
|
|
}
|
|
|
|
if (args.ContainsKey("-c") || args.ContainsKey("-f"))
|
|
{
|
|
StartupInfo info = new StartupInfo();
|
|
ProcessInformation pinfo = new ProcessInformation();
|
|
|
|
info.Size = Marshal.SizeOf(info);
|
|
info.Desktop = "WinSta0\\Default";
|
|
|
|
if (!CreateProcessAsUser(token,
|
|
args.ContainsKey("-f") ? args["-f"] : null,
|
|
args.ContainsKey("-c") ? args["-c"] : null,
|
|
0, 0, false, 0, 0,
|
|
args.ContainsKey("-d") ? args["-d"] : null,
|
|
ref info, ref pinfo))
|
|
{
|
|
Console.WriteLine("Error: Could not create process: " + GetLastErrorMessage());
|
|
Exit(Marshal.GetLastWin32Error());
|
|
}
|
|
|
|
CloseHandle(token);
|
|
}
|
|
|
|
Exit();
|
|
}
|
|
}
|
|
}
|