RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1364707
Accepted
Александр Пузанов
Александр Пузанов
Asked:2022-05-22 16:23:32 +0000 UTC2022-05-22 16:23:32 +0000 UTC 2022-05-22 16:23:32 +0000 UTC

以管理员身份以普通用户身份运行进程

  • 772

该程序在管理员下运行。从程序本身,我想启动另一个进程,但没有管理员权限,即 作为普通用户:

   Process process = new Process();
        process.StartInfo.FileName = @"C:\Program Files\MyApp\MyConfig.exe";
        process.Start();
        process.WaitForExit();

在我指定的子进程的清单中 <requestedExecutionLevel level="asInvoker" uiAccess="false" />

我检查表单是否在管理员权限下运行:它以与父进程相同的权限开始。我的错误在哪里?

c#
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Best Answer
    user300864
    2022-05-25T04:36:45Z2022-05-25T04:36:45Z

    清单中的指示asInvoker并不要求您做任何事情,因为根据官方 M$ 文档(并且只是逻辑),应用程序将以与调用它的进程相同的特权级别执行。

    手头的任务可以通过多种方式解决。一种可能的解决方案可以以调用链的形式表示GetShellWindow-> GetWindowThreadProcessId-> OpenProcessToken-> DuplicateTokenEx-> CreateProcessWithToken(简而言之 - 我们只是转储令牌),如下所示(膝盖上的选项):

    using System;
    using System.IO;
    using System.ComponentModel;
    using System.Runtime.InteropServices;
    
    namespace RunWithLowerRights {
      internal static class NativeMethods {
        [StructLayout(LayoutKind.Sequential)]
        internal struct LUID {
          internal UInt32 LowPart;
          internal Int32  HighPart;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        internal struct LUID_AND_ATTRIBUTES {
          internal LUID   Luid;
          internal UInt32 Attributes;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        internal struct TOKEN_PRIVILEGES {
          internal UInt32 PrivilegeCount;
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
          internal LUID_AND_ATTRIBUTES[] Privileges;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        internal struct PROCESS_INFORMATION {
          internal IntPtr hProcess;
          internal IntPtr hThread;
          internal UInt32 dwProcessId;
          internal UInt32 dwThreadId;
        }
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal struct STARTUPINFO {
          internal UInt32 cd;
          internal String lpReserved;
          internal String lpDesktop;
          internal String lpTitle;
          internal UInt32 dwX;
          internal UInt32 dwY;
          internal UInt32 dwXSize;
          internal UInt32 dwYSize;
          internal UInt32 dwXCountChars;
          internal UInt32 dwYCountChars;
          internal UInt32 dwFillAttribute;
          internal UInt32 dwFlags;
          internal UInt16 wShowWindow;
          internal UInt16 cbReserved2;
          internal IntPtr lpReserved2;
          internal IntPtr hStdInput;
          internal IntPtr hStdOutput;
          internal IntPtr hStdError;
        }
    
        internal enum SECURITY_IMPERSONATION_LEVEL : uint {
          SecurityAnonymous,
          SecurityIdentification,
          SecurityImpersonation,
          SecurityDelegation
        }
    
        internal enum TOKEN_TYPE : uint {
          TokenPrimary = 1,
          TokenImpersonation
        }
    
        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern Boolean AdjustTokenPrivileges(
           IntPtr TokenHandle,
           [MarshalAs(UnmanagedType.Bool)]Boolean DisableAllPrivileges,
           ref TOKEN_PRIVILEGES NewState,
           UInt32 BufferLength,
           IntPtr PreviousState, // ref TOKEN_PRIVILEGES PreviousState
           IntPtr ReturnLength   // out UInt32 ReturnLength
        );
    
        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern Boolean CreateProcessWithToken(
           IntPtr hToken,
           UInt32 dwLogonFlags,
           [MarshalAs(UnmanagedType.LPTStr)]String lpApplicationName,
           [MarshalAs(UnmanagedType.LPTStr)]String lpCommandLine,
           UInt32 dwCreationFlags,
           IntPtr lpEnvironment,
           [MarshalAs(UnmanagedType.LPTStr)]String lpCurrentDirectory,
           ref STARTUPINFO lpStartupInfo,
           out PROCESS_INFORMATION lpProcessInformation
        );
    
        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern Boolean DuplicateTokenEx(
           IntPtr hExistingToken,
           UInt32 dwDesiredAccess,
           IntPtr lpTokenAttributes,
           SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
           TOKEN_TYPE TokenType,
           out IntPtr phNewToken
        );
    
        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern Boolean LookupPrivilegeValue(
           [MarshalAs(UnmanagedType.LPTStr)]String lpSystemName,
           [MarshalAs(UnmanagedType.LPTStr)]String lpName,
           ref LUID lpLuid
        );
    
        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern Boolean OpenProcessToken(
           IntPtr ProcessHandle,
           UInt32 DesiredAccess,
           ref IntPtr TokenHandle
        );
    
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern Boolean CloseHandle(
           IntPtr Handle
        );
    
        [DllImport("kernel32.dll", SetLastError = true)]
        internal static extern IntPtr OpenProcess(
           UInt32 dwDesiredAccess,
           [MarshalAs(UnmanagedType.Bool)]Boolean bInheritHandle,
           UInt32 dwProcessId
        );
    
        [DllImport("user32.dll")]
        internal static extern IntPtr GetShellWindow();
    
        [DllImport("user32.dll", SetLastError = true)]
        internal static extern UInt32 GetWindowThreadProcessId(
           IntPtr hWnd,
           out UInt32 lpdwProcessId
        );
    
        internal static void GetLastError() {
          Console.WriteLine(new Win32Exception(Marshal.GetLastWin32Error()).Message);
        }
    
        internal static void RunAsRegularUser(String path) {
          var token = IntPtr.Zero;
          var privs = new TOKEN_PRIVILEGES {
            PrivilegeCount = 1,
            Privileges = new LUID_AND_ATTRIBUTES[1]
          };
    
          var shell = IntPtr.Zero;
          var c_sps = IntPtr.Zero;
          var c_stk = IntPtr.Zero;
          var c_usr = IntPtr.Zero;
    
          var si = new STARTUPINFO();
          var pi = new PROCESS_INFORMATION();
    
          try {
            if (String.IsNullOrEmpty(path))
              throw new ArgumentException("Путь до исполняемого файла не может быть пустым.");
            if (!OpenProcessToken((IntPtr)(-1), 0x20, ref token))
              throw new Win32Exception(Marshal.GetLastWin32Error());
            if (!LookupPrivilegeValue(null, "SeIncreaseQuotaPrivilege", ref privs.Privileges[0].Luid))
              throw new Win32Exception(Marshal.GetLastWin32Error());
    
            privs.Privileges[0].Attributes = 0x02;
            if (!AdjustTokenPrivileges(token, false, ref privs, 0, IntPtr.Zero, IntPtr.Zero))
              throw new Win32Exception(Marshal.GetLastWin32Error());
            shell = GetShellWindow();
            if (IntPtr.Zero == shell)
              throw new InvalidOperationException("Вызов GetShellWindow ничего не вернул.");
    
            UInt32 pid = 0;
            if (0 == GetWindowThreadProcessId(shell, out pid))
              throw new Win32Exception(Marshal.GetLastWin32Error());
            c_sps = OpenProcess(0x400, false, pid);
            if (IntPtr.Zero == c_sps)
              throw new Win32Exception(Marshal.GetLastWin32Error());
            if (!OpenProcessToken(c_sps, 0x02, ref c_stk))
              throw new Win32Exception(Marshal.GetLastWin32Error());
            if (!DuplicateTokenEx(c_stk, 0x18B, IntPtr.Zero,
               SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, out c_usr))
              throw new Win32Exception(Marshal.GetLastWin32Error());
            if (!CreateProcessWithToken(c_usr, 0, path, null, 0,
                                             IntPtr.Zero, Path.GetDirectoryName(path), ref si, out pi))
              throw new Win32Exception(Marshal.GetLastWin32Error());
    
            if (!CloseHandle(pi.hProcess)) GetLastError();
            if (!CloseHandle(pi.hThread))  GetLastError();
          }
          catch (Exception e) {
            Console.WriteLine(e.Message);
          }
          finally {
            if (IntPtr.Zero != c_usr) if (!CloseHandle(c_usr)) GetLastError();
            if (IntPtr.Zero != c_stk) if (!CloseHandle(c_stk)) GetLastError();
            if (IntPtr.Zero != c_sps) if (!CloseHandle(c_sps)) GetLastError();
            if (IntPtr.Zero != token) if (!CloseHandle(token)) GetLastError();
          }
        }
      } // NativeMethods
    
      internal sealed class Program {
        static void Main() {
          NativeMethods.RunAsRegularUser(@"C:\Windows\system32\cmd.exe");
        }
      } // Program
    }
    

    来自管理控制台的调用应该以普通用户身份启动控制台。

    • 5
  2. Andrew_STOP_RU_AGRESSION_IN_UA
    2022-05-25T06:20:23Z2022-05-25T06:20:23Z
    1. 创建具有所需访问权限级别的用户并为他设置密码
    2. 用这个用户登录
    var credentials = new UserCredentials(domain, username, password);
    Impersonation.RunAsUser(credentials, logonType, () =>
    {
        сделать все что необходимо, например запустить программу.
    });
    

    使用 nuget SimpleImpersonation


    我不需要来自任何选择的 [用户],而是来自普通用户

    关于代表“用户”组运行的愿望,在我看来这是不可能的,因为这不是真正的用户,而只是默认访问权限级别的一些设置。或一组用户,但不是真正的用户。如我错了请纠正我。

    • 1
  3. PRODIGY
    2022-05-23T10:10:21Z2022-05-23T10:10:21Z

    要代表其他用户运行进程,首先需要以他的名义登录系统,获取该用户的SID和token。为此,有一个LogonUser()返回令牌的函数。您现在可以在调用CreateProcessAsUser()以以其他用户身份运行进程时使用它。这是runas实用程序遵循的算法。有关详细信息,请参阅MSDN。

    • 0

相关问题

  • 使用嵌套类导出 xml 文件

  • 分层数据模板 [WPF]

  • 如何在 WPF 中为 ListView 手动创建列?

  • 在 2D 空间中,Collider 2D 挂在玩家身上,它对敌人的重量相同,我需要它这样当它们碰撞时,它们不会飞向不同的方向。统一

  • 如何在 c# 中使用 python 神经网络来创建语音合成?

  • 如何知道类中的方法是否属于接口?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5