C#利用服务创建具有System权限指定Session的进程

1. 起因

因为需要在锁屏界面和UAC界面搞点事情,经过测试,发现锁屏和系统弹出UAC 均是切换到了Windows 的安全桌面,一般Windows在启动后(这里说的Windows指的是Vista之后的)会有一个Default和一个安全桌面。这里的Default 就是普通程序运行的桌面,在弹出UAC 或者 锁屏的时候Windows则会自动切换到 安全桌面, 不同桌面的消息等是隔离的。Windows上存在的所有桌面可以用 EnumDesktopsW 这个API获取。然后可以使用 SetThreadDesktop 将线程指定到相应桌面,或者使用 SwitchDesktop 切换到指定桌面。

但是,在普通管理员权限下使用上述API将线程或切换到安全桌面 会因为权限不足的问题导致失败,所以这时候就想到了使用服务来创建相应的进程。

2. 相关Win32API

相关API的P/Invoke 封装,相关结构体有点繁杂放在此文结尾。

[DllImport("Kernel32.dll", CharSet = CharSet.Ansi,SetLastError =true)]
public static extern void OutputDebugString(string lpOutputString); //用来Debug

[DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool OpenProcessToken([In]IntPtr ProcessHandle, [In]uint DesiredAccess, [Out]out IntPtr TokenHandle);

[DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool DuplicateTokenEx([In]IntPtr hExistingToken, uint dwDesiredAccess,IntPtr lpTokenAttributes, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
             [In]TOKEN_TYPE TokenType, [Out]out IntPtr DuplicateTokenHandle);

[DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern uint WTSGetActiveConsoleSessionId();

[DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool SetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength);

[DllImport("Userenv.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CreateEnvironmentBlock([Out]out IntPtr lpEnvironment,[In]IntPtr hToken,[In]bool bInherit);

[DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CreateProcessAsUserW([In]IntPtr hToken,[In][MarshalAs(UnmanagedType.LPWStr)]string lpApplicationName,[In][MarshalAs(UnmanagedType.LPWStr)]string lpCommandLine,                                                       [In]IntPtr lpProcessAttributes,[In]IntPtr lpThreadAttributes,[In] bool bInheritHandles,[In]uint dwCreationFlags,[In]IntPtr lpEnvironment,                                                       [In][MarshalAs(UnmanagedType.LPWStr)] string lpCurrentDirectory,[Out] IntPtr lpStartupInfo,[Out] IntPtr lpProcessInformation);

3. 实现正文

首先使用VS新建一个服务项目(这个怎么建服务就省略了,就是点点点),建好项目之后定位到Service1.cs的OnStart,如下图

OnStart为服务启动时要执行的代码,首先

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值