如何冒充目标计算机上的所有当前会话?

huangapple go评论75阅读模式
英文:

How can I impersonate all current sessions on the target computer?

问题

I have this piece of code:

public static void Registrar(string caminho, Estilo estilo)
{
    try
    {
        RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", true);

        switch (estilo)
        {
            case Estilo.Fill:
                registryKey.SetValue("WallpaperStyle", 10.ToString());
                registryKey.SetValue("TileWallpaper", 0.ToString());
                break;
            case Estilo.Fit:
                registryKey.SetValue("WallpaperStyle", 6.ToString());
                registryKey.SetValue("TileWallpaper", 0.ToString());
                break;
            case Estilo.Span:
                registryKey.SetValue("WallpaperStyle", 22.ToString());
                registryKey.SetValue("TileWallpaper", 0.ToString());
                break;
            case Estilo.Stretch:
                registryKey.SetValue("WallpaperStyle", 2.ToString());
                registryKey.SetValue("TileWallpaper", 0.ToString());
                break;
            case Estilo.Tile:
                registryKey.SetValue("WallpaperStyle", 0.ToString());
                registryKey.SetValue("TileWallpaper", 1.ToString());
                break;
            case Estilo.Center:
                registryKey.SetValue("WallpaperStyle", 0.ToString());
                registryKey.SetValue("TileWallpaper", 0.ToString());
                break;
            default:
                registryKey.SetValue("WallpaperStyle", 10.ToString());
                registryKey.SetValue("TileWallpaper", 0.ToString());
                break;
        }

        SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, caminho, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
    }
    catch
    {
        throw;
    }
}

EDIT

This is the actual solution, but I'm getting the "Unable to impersonate" error.

while (!stoppingToken.IsCancellationRequested)
{
    IntPtr usuarioSessaoToken = IntPtr.Zero;

    Dictionary<string, IntPtr> usuariosLogados = new Dictionary<string, IntPtr>();

    foreach (Process process in Process.GetProcesses())
    {
        try
        {
            OpenProcessToken(process.Handle, TOKEN_QUERY, out usuarioSessaoToken);

            if (usuarioSessaoToken != null && usuarioSessaoToken != IntPtr.Zero)
            {
                using (WindowsIdentity windowsIdentity = new WindowsIdentity(usuarioSessaoToken))
                {
                    if (!usuariosLogados.ContainsKey(windowsIdentity.Name) &&
                        !windowsIdentity.Name.Contains("NT ") &&
                        !windowsIdentity.Name.Contains("Font ") &&
                        !windowsIdentity.Name.Contains("Window "))
                    {
                        usuariosLogados.Add(windowsIdentity.Name, usuarioSessaoToken);
                    }
                }
            }
        }
        catch
        {
        }
    }

    foreach (var usuarioLogado in usuariosLogados)
    {
        Console.WriteLine("{0}: {1}", usuarioLogado.Value, usuarioLogado.Key);

        using (WindowsIdentity windowsIdentity = new WindowsIdentity(usuarioLogado.Value))
        {
            WindowsIdentity.RunImpersonated(windowsIdentity.AccessToken, () =>
            {
                _OnSite.InicializarProcesso(modeloConfiguracao);
            });
        }

        if (usuarioLogado.Value != IntPtr.Zero)
        {
            CloseHandle(usuarioLogado.Value);
        }
    }

    if (usuarioSessaoToken != IntPtr.Zero)
    {
        CloseHandle(usuarioSessaoToken);
    }

    ArquivoLog.EscreverInformacao("PROCESSO DE GERENCIAMENTO INTERNO FINALIZADO.");
    ArquivoLog.EscreverInformacao("ENTRARÁ EM ESPERA DE TRÊS (3) HORAS.");

    await Task.Delay(TimeSpan.FromHours(3), stoppingToken);
}

Any solution?

英文:

I have this piece of code:

public static void Registrar(string caminho, Estilo estilo)
{
	try
	{
		RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(@&quot;Control Panel\Desktop&quot;, true);

		switch (estilo)
		{
			case Estilo.Fill:
				registryKey.SetValue(@&quot;WallpaperStyle&quot;, 10.ToString());
				registryKey.SetValue(@&quot;TileWallpaper&quot;, 0.ToString());
				break;
			case Estilo.Fit:
				registryKey.SetValue(@&quot;WallpaperStyle&quot;, 6.ToString());
				registryKey.SetValue(@&quot;TileWallpaper&quot;, 0.ToString());
				break;
			case Estilo.Span:
				registryKey.SetValue(@&quot;WallpaperStyle&quot;, 22.ToString());
				registryKey.SetValue(@&quot;TileWallpaper&quot;, 0.ToString());
				break;
			case Estilo.Stretch:
				registryKey.SetValue(@&quot;WallpaperStyle&quot;, 2.ToString());
				registryKey.SetValue(@&quot;TileWallpaper&quot;, 0.ToString());
				break;
			case Estilo.Tile:
				registryKey.SetValue(@&quot;WallpaperStyle&quot;, 0.ToString());
				registryKey.SetValue(@&quot;TileWallpaper&quot;, 1.ToString());
				break;
			case Estilo.Center:
				registryKey.SetValue(@&quot;WallpaperStyle&quot;, 0.ToString());
				registryKey.SetValue(@&quot;TileWallpaper&quot;, 0.ToString());
				break;
			default:
				registryKey.SetValue(@&quot;WallpaperStyle&quot;, 10.ToString());
				registryKey.SetValue(@&quot;TileWallpaper&quot;, 0.ToString());
				break;
		}

		SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, caminho, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
	}
	catch
	{
		throw;
	}
}

Context: I need send a program and execute it on the target machine (many on my organization), but I have to send it throw LogMeIn, and it require an User/Password to login and copy/execute this program on target.

The problem: As LogMeIn logged on the target and this application is executed, this piece of code change the WallPapper only for the user that LogMeIn logged in. I make a search and found that I can impersionate any account on the target computer, but I need to impersonate from the current sessions on the computer.

The question: How can I get all the live sessions and impersonate, to execute this piece of code for all the sessions?

EDIT

This is the actual solution, but I'm getting the "Unable impersonate" error.

while (!stoppingToken.IsCancellationRequested)
{
	IntPtr usuarioSessaoToken = IntPtr.Zero;

	Dictionary&lt;string, IntPtr&gt; usuariosLogados = new Dictionary&lt;string, IntPtr&gt;();

	foreach (Process process in Process.GetProcesses())
	{
		try
		{
			OpenProcessToken(process.Handle, TOKEN_QUERY, out usuarioSessaoToken);

			if (usuarioSessaoToken != null &amp;&amp; usuarioSessaoToken != IntPtr.Zero)
			{
				using (WindowsIdentity windowsIdentity = new WindowsIdentity(usuarioSessaoToken))
				{
					if (!usuariosLogados.ContainsKey(windowsIdentity.Name) &amp;&amp;
						!windowsIdentity.Name.Contains(&quot;NT &quot;) &amp;&amp;
						!windowsIdentity.Name.Contains(&quot;Font &quot;) &amp;&amp;
						!windowsIdentity.Name.Contains(&quot;Window &quot;))
					{
						usuariosLogados.Add(windowsIdentity.Name, usuarioSessaoToken);
					}
				}
			}
		}
		catch
		{
		}
	}

	foreach (var usuarioLogado in usuariosLogados)
	{
		Console.WriteLine(&quot;{0}: {1}&quot;, usuarioLogado.Value, usuarioLogado.Key);

		using (WindowsIdentity windowsIdentity = new WindowsIdentity(usuarioLogado.Value))
		{
			WindowsIdentity.RunImpersonated(windowsIdentity.AccessToken, () =&gt;
			{
				_OnSite.InicializarProcesso(modeloConfiguracao);
			});
		}

		if (usuarioLogado.Value != IntPtr.Zero)
		{
			CloseHandle(usuarioLogado.Value);
		}
	}

	if (usuarioSessaoToken != IntPtr.Zero)
	{
		CloseHandle(usuarioSessaoToken);
	}

	ArquivoLog.EscreverInformacao(&quot;PROCESSO DE GERENCIAMENTO INTERNO FINALIZADO.&quot;);
	ArquivoLog.EscreverInformacao(&quot;ENTRAR&#193; EM ESPERA DE TR&#202;S (3) HORAS.&quot;);

	await Task.Delay(TimeSpan.FromHours(3), stoppingToken);
}

Any solution?

答案1

得分: 0

找到一个答案:

负责类,Impersonate

const UInt32 SE_PRIVILEGE_ENABLED = 0x00000002;
const Int32 ANYSIZE_ARRAY = 1;
const string SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege";
const int ERROR_NOT_ALL_ASSIGNED = 1300;

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID lpLuid);

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, [MarshalAs(UnmanagedType.Bool)] bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, UInt32 Zero, IntPtr Null1, IntPtr Null2);

[DllImport("user32.dll")]
static extern IntPtr GetShellWindow();

[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

[DllImport("kernel32.dll")]
static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId);

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool OpenProcessToken(IntPtr ProcessHandle, TokenAccessFlags DesiredAccess, out IntPtr TokenHandle);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
extern static bool DuplicateTokenEx(IntPtr hExistingToken, TokenAccessFlags dwDesiredAccess, IntPtr lpThreadAttributes, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, TOKEN_TYPE TokenType, out IntPtr phNewToken);

[DllImport("kernel32.dll", EntryPoint = "CloseHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
extern static bool CloseHandle(IntPtr handle);

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool CreateProcessAsUserW(IntPtr hToken, string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, CreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);

[StructLayout(LayoutKind.Sequential)]
struct LUID
{
    public uint LowPart;
    public int HighPart;
}

[StructLayout(LayoutKind.Sequential)]
struct LUID_AND_ATTRIBUTES
{
    public LUID Luid;
    public UInt32 Attributes;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct STARTUPINFO
{
    public Int32 cb;
    public string lpReserved;
    public string lpDesktop;
    public string lpTitle;
    public Int32 dwX;
    public Int32 dwY;
    public Int32 dwXSize;
    public Int32 dwYSize;
    public Int32 dwXCountChars;
    public Int32 dwYCountChars;
    public Int32 dwFillAttribute;
    public Int32 dwFlags;
    public Int16 wShowWindow;
    public Int16 cbReserved2;
    public IntPtr lpReserved2;
    public IntPtr hStdInput;
    public IntPtr hStdOutput;
    public IntPtr hStdError;
}

[StructLayout(LayoutKind.Sequential)]
struct PROCESS_INFORMATION
{
    public IntPtr hProcess;
    public IntPtr hThread;
    public int dwProcessId;
    public int dwThreadId;
}

[StructLayout(LayoutKind.Sequential)]
struct SECURITY_ATTRIBUTES
{
    public int nLength;
    public IntPtr lpSecurityDescriptor;
    public bool bInheritHandle;
}

struct TOKEN_PRIVILEGES
{
    public UInt32 PrivilegeCount;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = ANYSIZE_ARRAY)]
    public LUID_AND_ATTRIBUTES[] Privileges;
}

[Flags()]
enum ProcessAccessFlags : int
{
    AllAccess = CreateThread | DuplicateHandle | QueryInformation | SetInformation | Terminate | VMOperation | VMRead | VMWrite | Synchronize,
    CreateThread = 0x2,
    DuplicateHandle = 0x40,
    QueryInformation = 0x400,
    SetInformation = 0x200,
    Terminate = 0x1,
    VMOperation = 0x8,
    VMRead = 0x10,
    VMWrite = 0x20,
    Synchronize = 0x100000
}

[Flags()]
enum TokenAccessFlags : int
{
    STANDARD_RIGHTS_REQUIRED = 0x000F0000,
    STANDARD_RIGHTS_READ = 0x00020000,
    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_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY),
    TOKEN_ALL_ACCESS = (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)
}

[Flags]
enum CreationFlags
{
    CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
    CREATE_DEFAULT_ERROR_MODE = 0x04000000,
    CREATE_NEW_CONSOLE = 0x00000010,
    CREATE_NEW_PROCESS_GROUP = 0x00000200,
    CREATE_NO_WINDOW = 0x08000000,
    CREATE_PROTECTED_PROCESS = 0x00040000,
    CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
    CREATE_SEPARATE_WOW_VDM = 0x00001000,
    CREATE_SUSPENDED = 0x00000004,
    CREATE_UNICODE_ENVIRONMENT = 0x00000400,
    DEBUG_ONLY_THIS_PROCESS = 0x00000002,
    DEBUG_PROCESS = 0x00000001,
    DETACHED_PROCESS = 0x00000008,
    EXTENDED_STARTUPINFO_PRESENT = 0x00080000
}

enum SECURITY_IMPERSONATION_LEVEL
{
    SecurityAnonymous,
    SecurityIdentification,
    SecurityImpersonation,
    SecurityDelegation
}

enum TOKEN_TYPE
{
    TokenPrimary = 1,
    TokenImpersonation
}

public void ExecutarComoUsuario(string caminhoExecutavel, string[] argumentos)
{
    try
    {
        IntPtr currentToken;
        int lastError;

        if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TokenAccessFlags.TOKEN_ADJUST_PRIVILEGES, out currentToken))
        {
            lastError = Marshal.GetLastWin32Error();
            throw new Win32Exception(lastError, "HOUVE UM ERRO AO RECUPERAR O TOKEN DO PROCESSO ATUAL.");
        }

        LUID myLUID;

        if (!LookupPrivilegeValue(null, SE_INCREASE_QUOTA_NAME, out myLUID))
        {
            lastError = Marshal.GetLastWin32Error();
            throw new Win32Exception(lastError, "H

<details>
<summary>英文:</summary>

Found an anwser:

The class responsable, **Impersonate**:

	const UInt32 SE_PRIVILEGE_ENABLED = 0x00000002;
	const Int32 ANYSIZE_ARRAY = 1;
	const string SE_INCREASE_QUOTA_NAME = &quot;SeIncreaseQuotaPrivilege&quot;;
	const int ERROR_NOT_ALL_ASSIGNED = 1300;

	[DllImport(&quot;advapi32.dll&quot;, SetLastError = true, CharSet = CharSet.Auto)]
	[return: MarshalAs(UnmanagedType.Bool)]
	static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID lpLuid);

	[DllImport(&quot;advapi32.dll&quot;, SetLastError = true)]
	[return: MarshalAs(UnmanagedType.Bool)]
	static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, [MarshalAs(UnmanagedType.Bool)] bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, UInt32 Zero, IntPtr Null1, IntPtr Null2);

	[DllImport(&quot;user32.dll&quot;)]
	static extern IntPtr GetShellWindow();

	[DllImport(&quot;user32.dll&quot;, SetLastError = true)]
	static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

	[DllImport(&quot;kernel32.dll&quot;)]
	static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId);

	[DllImport(&quot;advapi32.dll&quot;, SetLastError = true)]
	[return: MarshalAs(UnmanagedType.Bool)]
	static extern bool OpenProcessToken(IntPtr ProcessHandle, TokenAccessFlags DesiredAccess, out IntPtr TokenHandle);

	[DllImport(&quot;advapi32.dll&quot;, CharSet = CharSet.Auto, SetLastError = true)]
	extern static bool DuplicateTokenEx(IntPtr hExistingToken, TokenAccessFlags dwDesiredAccess, IntPtr lpThreadAttributes, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, TOKEN_TYPE TokenType, out IntPtr phNewToken);

	[DllImport(&quot;kernel32.dll&quot;, EntryPoint = &quot;CloseHandle&quot;, SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
	extern static bool CloseHandle(IntPtr handle);

	[DllImport(&quot;advapi32.dll&quot;, SetLastError = true, CharSet = CharSet.Auto)]
	static extern bool CreateProcessAsUserW(IntPtr hToken, string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, CreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);

	[StructLayout(LayoutKind.Sequential)]
	struct LUID
	{
		public uint LowPart;
		public int HighPart;
	}

	[StructLayout(LayoutKind.Sequential)]
	struct LUID_AND_ATTRIBUTES
	{
		public LUID Luid;
		public UInt32 Attributes;
	}

	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
	struct STARTUPINFO
	{
		public Int32 cb;
		public string lpReserved;
		public string lpDesktop;
		public string lpTitle;
		public Int32 dwX;
		public Int32 dwY;
		public Int32 dwXSize;
		public Int32 dwYSize;
		public Int32 dwXCountChars;
		public Int32 dwYCountChars;
		public Int32 dwFillAttribute;
		public Int32 dwFlags;
		public Int16 wShowWindow;
		public Int16 cbReserved2;
		public IntPtr lpReserved2;
		public IntPtr hStdInput;
		public IntPtr hStdOutput;
		public IntPtr hStdError;
	}

	[StructLayout(LayoutKind.Sequential)]
	struct PROCESS_INFORMATION
	{
		public IntPtr hProcess;
		public IntPtr hThread;
		public int dwProcessId;
		public int dwThreadId;
	}

	[StructLayout(LayoutKind.Sequential)]
	struct SECURITY_ATTRIBUTES
	{
		public int nLength;
		public IntPtr lpSecurityDescriptor;
		public bool bInheritHandle;
	}

	struct TOKEN_PRIVILEGES
	{
		public UInt32 PrivilegeCount;
		[MarshalAs(UnmanagedType.ByValArray, SizeConst = ANYSIZE_ARRAY)]
		public LUID_AND_ATTRIBUTES[] Privileges;
	}

	[Flags()]
	enum ProcessAccessFlags : int
	{
		AllAccess = CreateThread | DuplicateHandle | QueryInformation | SetInformation | Terminate | VMOperation | VMRead | VMWrite | Synchronize,
		CreateThread = 0x2,
		DuplicateHandle = 0x40,
		QueryInformation = 0x400,
		SetInformation = 0x200,
		Terminate = 0x1,
		VMOperation = 0x8,
		VMRead = 0x10,
		VMWrite = 0x20,
		Synchronize = 0x100000
	}

	[Flags()]
	enum TokenAccessFlags : int
	{
		STANDARD_RIGHTS_REQUIRED = 0x000F0000,
		STANDARD_RIGHTS_READ = 0x00020000,
		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_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY),
		TOKEN_ALL_ACCESS = (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)
	}

	[Flags]
	enum CreationFlags
	{
		CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
		CREATE_DEFAULT_ERROR_MODE = 0x04000000,
		CREATE_NEW_CONSOLE = 0x00000010,
		CREATE_NEW_PROCESS_GROUP = 0x00000200,
		CREATE_NO_WINDOW = 0x08000000,
		CREATE_PROTECTED_PROCESS = 0x00040000,
		CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
		CREATE_SEPARATE_WOW_VDM = 0x00001000,
		CREATE_SUSPENDED = 0x00000004,
		CREATE_UNICODE_ENVIRONMENT = 0x00000400,
		DEBUG_ONLY_THIS_PROCESS = 0x00000002,
		DEBUG_PROCESS = 0x00000001,
		DETACHED_PROCESS = 0x00000008,
		EXTENDED_STARTUPINFO_PRESENT = 0x00080000
	}

	enum SECURITY_IMPERSONATION_LEVEL
	{
		SecurityAnonymous,
		SecurityIdentification,
		SecurityImpersonation,
		SecurityDelegation
	}

	enum TOKEN_TYPE
	{
		TokenPrimary = 1,
		TokenImpersonation
	}

	public void ExecutarComoUsuario(string caminhoExecutavel, string[] argumentos)
	{
		try
		{
			IntPtr currentToken;
			int lastError;

			if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TokenAccessFlags.TOKEN_ADJUST_PRIVILEGES, out currentToken))
			{
				lastError = Marshal.GetLastWin32Error();
				throw new Win32Exception(lastError, &quot;HOUVE UM ERRO AO RECUPERAR O TOKEN DO PROCESSO ATUAL.&quot;);
			}

			LUID myLUID;

			if (!LookupPrivilegeValue(null, SE_INCREASE_QUOTA_NAME, out myLUID))
			{
				lastError = Marshal.GetLastWin32Error();
				throw new Win32Exception(lastError, &quot;HOUVE UM ERRO AO RECUPERAR OS VALORES DE \&quot;PRIVILEGIO\&quot; ATUAL.&quot;);
			}

			TOKEN_PRIVILEGES myTokenPrivileges;

			myTokenPrivileges.PrivilegeCount = 1;
			myTokenPrivileges.Privileges = new LUID_AND_ATTRIBUTES[1];
			myTokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
			myTokenPrivileges.Privileges[0].Luid = myLUID;

			if (!AdjustTokenPrivileges(currentToken, false, ref myTokenPrivileges, 0, IntPtr.Zero, IntPtr.Zero))
			{
				lastError = Marshal.GetLastWin32Error();
				throw new Win32Exception(lastError, &quot;HOUVE UM ERRO AO AJUSTAR OS \&quot;PRIVILEGIOS\&quot; ATUAIS.&quot;);
			}

			CloseHandle(currentToken);
			lastError = Marshal.GetLastWin32Error();

			if (lastError == ERROR_NOT_ALL_ASSIGNED)
			{
				lastError = Marshal.GetLastWin32Error();
				throw new Win32Exception(lastError, &quot;HOUVE UM ERRO \&quot;GEN&#201;RICO\&quot;.&quot;);
			}

			Process processExplorer = Process.GetProcessesByName(&quot;explorer&quot;).FirstOrDefault();

			if (processExplorer == null || processExplorer == default(Process))
			{
				lastError = Marshal.GetLastWin32Error();
				throw new Win32Exception(lastError, &quot;HOUVE UM ERRO AO RECUPERAR O PROCESSO \&quot;EXPLORER\&quot;.&quot;);
			}
			else
			{
				uint processID = uint.Parse(processExplorer.Id.ToString());

				IntPtr processHandle = OpenProcess(ProcessAccessFlags.QueryInformation, true, processID);

				if (processHandle == IntPtr.Zero)
				{
					lastError = Marshal.GetLastWin32Error();
					throw new Win32Exception(lastError, &quot;HOUVE UM ERRO AO ABRIR O PROCESSO \&quot;EXPLORER\&quot;.&quot;);
				}

				IntPtr explorerProcessToken;

				TokenAccessFlags tokenAccess = TokenAccessFlags.TOKEN_QUERY | TokenAccessFlags.TOKEN_ASSIGN_PRIMARY | TokenAccessFlags.TOKEN_DUPLICATE | TokenAccessFlags.TOKEN_ADJUST_DEFAULT | TokenAccessFlags.TOKEN_ADJUST_SESSIONID;

				if (!OpenProcessToken(processHandle, tokenAccess, out explorerProcessToken))
				{
					lastError = Marshal.GetLastWin32Error();
					throw new Win32Exception(lastError, &quot;HOUVE UM ERRO AO RECUPERAR O TOKEN DO PROCESSO \&quot;EXPLORER\&quot;.&quot;);
				}

				IntPtr newPrimaryToken;
				if (!DuplicateTokenEx(explorerProcessToken, tokenAccess, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, out newPrimaryToken))
				{
					lastError = Marshal.GetLastWin32Error();
					throw new Win32Exception(lastError);
					throw new Win32Exception(lastError, &quot;HOUVE UM ERRO AO DUPLICAR O TOKEN DO PROCESSO \&quot;EXPLORER\&quot;.&quot;);
				}

				STARTUPINFO startupInfo = new STARTUPINFO();
				startupInfo.cb = Marshal.SizeOf(startupInfo);
				startupInfo.lpDesktop = &quot;&quot;;

				PROCESS_INFORMATION processInfo = new PROCESS_INFORMATION();

				if (!CreateProcessAsUserW(newPrimaryToken, caminhoExecutavel, caminhoExecutavel + &quot; &quot; + argumentos, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref startupInfo, out processInfo))
				{
					lastError = Marshal.GetLastWin32Error();
					throw new Win32Exception(lastError, &quot;HOUVE UM ERRO AO CRIAR UM NOVO PROCESSO.&quot;);
				}

				CloseHandle(processInfo.hProcess);
				CloseHandle(processInfo.hThread);
			}
		}
		catch (Exception ex)
		{
			throw;
		}
	}

You can use this class inside a service, as I did, and when you call it, you pass the path for another Console Application, in this new Console, you can interact with the Desktop.

</details>



huangapple
  • 本文由 发表于 2023年5月29日 09:48:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76354251.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定