微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用模拟在C#中间接启动进程

我正在开发一个使用Selenium来控制浏览器的应用程序. Selenium在初始化时启动浏览器,因此我从不直接在浏览器的.exe上调用Process.Start.我希望Selenium及其所有子进程在不同于我的应用程序的用户下运行(因为我不希望它访问我的源代码).使用模拟样本 here,我试图用模拟包装Selenium代码,但似乎所有子进程都由启动其父进程的用户启动.

有没有人知道用户模仿包装代码块的方法,并使用模拟用户的权限启动所有子进程?如果没有,那么实现这一目标的最佳策略是什么?在另一个进程中运行所有Selenium逻辑并以某种方式管道命令到它?

解决方法

试试这个 .

本课程使您能够以用户身份进行午餐过程,

在这里,我使用Explorer会话.

using System.Runtime.InteropServices;
using System;
using System.Diagnostics;


[StructLayout(LayoutKind.Sequential)]
internal struct PROCESS_@R_128_4045@ION
{
    public IntPtr hProcess;
    public IntPtr hThread;
    public uint dwProcessId;
    public uint dwThreadId;
 }



 [StructLayout(LayoutKind.Sequential)]
 internal struct Security_ATTRIBUTES
 {
    public uint nLength;
    public IntPtr lpSecurityDescriptor;
    public bool bInheritHandle;
  }


  [StructLayout(LayoutKind.Sequential)]
  public struct STARTUPINFO
  {
      public uint cb;
      public string lpReserved;
      public string lpDesktop;
      public string lpTitle;
      public uint dwX;
      public uint dwY;
      public uint dwXSize;
      public uint dwYSize;
      public uint dwXCountChars;
      public uint dwYCountChars;
      public uint dwFillAttribute;
      public uint dwFlags;
      public short wShowWindow;
      public short cbReserved2;
      public IntPtr lpReserved2;
      public IntPtr hStdInput;
      public IntPtr hStdOutput;
      public IntPtr hStdError;

  }

   internal enum Security_IMPERSONATION_LEVEL
   {
       SecurityAnonymous,SecurityIdentification,SecurityImpersonation,SecurityDelegation
    }

    internal enum TOKEN_TYPE
    {
         TokenPrimary = 1,TokenImpersonation
     }

 public class ProcessAsUser
 {

[DllImport("advapi32.dll",SetLastError = true)]
private static extern bool CreateProcessAsUser(
    IntPtr hToken,string lpApplicationName,string lpCommandLine,ref Security_ATTRIBUTES lpProcessAttributes,ref Security_ATTRIBUTES lpThreadAttributes,bool bInheritHandles,uint dwCreationFlags,IntPtr lpEnvironment,string lpCurrentDirectory,ref STARTUPINFO lpStartupInfo,out PROCESS_@R_128_4045@ION lpProcess@R_128_4045@ion);


[DllImport("advapi32.dll",EntryPoint = "DuplicatetokenEx",SetLastError = true)]
private static extern bool DuplicatetokenEx(
    IntPtr hExistingToken,uint dwDesiredAccess,Int32 ImpersonationLevel,Int32 dwTokenType,ref IntPtr phNewToken);


[DllImport("advapi32.dll",SetLastError = true)]
private static extern bool OpenProcesstoken(
    IntPtr ProcessHandle,UInt32 DesiredAccess,ref IntPtr TokenHandle);

[DllImport("userenv.dll",SetLastError = true)]
private static extern bool CreateEnvironmentBlock(
        ref IntPtr lpEnvironment,IntPtr hToken,bool bInherit);


[DllImport("userenv.dll",SetLastError = true)]
private static extern bool DestroyEnvironmentBlock(
        IntPtr lpEnvironment);

[DllImport("kernel32.dll",SetLastError = true)]
private static extern bool CloseHandle(
    IntPtr hObject);

private const short SW_SHOW = 5;
private const uint TOKEN_QUERY = 0x0008;
private const uint TOKEN_DUPLICATE = 0x0002;
private const uint TOKEN_ASSIGN_PRIMARY = 0x0001;
private const int GENERIC_ALL_ACCESS = 0x10000000;
private const int STARTF_USESHOWWINDOW = 0x00000001;
private const int STARTF_FORCEONFeedBACK = 0x00000040;
private const uint CREATE_UNICODE_ENVIRONMENT = 0x00000400;


private static bool LaunchProcessAsUser(string cmdLine,IntPtr token,IntPtr envBlock)
{
    bool result = false;


    PROCESS_@R_128_4045@ION pi = new PROCESS_@R_128_4045@ION();
    Security_ATTRIBUTES saProcess = new Security_ATTRIBUTES();
    Security_ATTRIBUTES saThread = new Security_ATTRIBUTES();
    saProcess.nLength = (uint)Marshal.SizeOf(saProcess);
    saThread.nLength = (uint)Marshal.SizeOf(saThread);

    STARTUPINFO si = new STARTUPINFO();
    si.cb = (uint)Marshal.SizeOf(si);


    //if this member is NULL,the new process inherits the desktop 
    //and window station of its parent process. If this member is 
    //an empty string,the process does not inherit the desktop and 
    //window station of its parent process; instead,the system 
    //determines if a new desktop and window station need to be created. 
    //If the impersonated user already has a desktop,the system uses the 
    //existing desktop. 

    si.lpDesktop = @"WinSta0\Default"; //Modify as needed 
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFeedBACK;
    si.wShowWindow = SW_SHOW;
    //Set other si properties as required. 

    result = CreateProcessAsUser(
        token,null,cmdLine,ref saProcess,ref saThread,false,CREATE_UNICODE_ENVIRONMENT,envBlock,ref si,out pi);


    if (result == false)
    {
        int error = Marshal.GetLastWin32Error();
        string message = String.Format("CreateProcessAsUser Error: {0}",error);
        Debug.WriteLine(message);

    }

    return result;
}


private static IntPtr GetPrimaryToken(int processId)
{
    IntPtr token = IntPtr.Zero;
    IntPtr primaryToken = IntPtr.Zero;
    bool retVal = false;
    Process p = null;

    try
    {
        p = Process.GetProcessById(processId);
    }

    catch (ArgumentException)
    {

        string details = String.Format("ProcessID {0} Not Available",processId);
        Debug.WriteLine(details);
        throw;
    }


    //Gets impersonation token 
    retVal = OpenProcesstoken(p.Handle,TOKEN_DUPLICATE,ref token);
    if (retVal == true)
    {

        Security_ATTRIBUTES sa = new Security_ATTRIBUTES();
        sa.nLength = (uint)Marshal.SizeOf(sa);

        //Convert the impersonation token into Primary token 
        retVal = DuplicatetokenEx(
            token,TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY,ref sa,(int)Security_IMPERSONATION_LEVEL.SecurityIdentification,(int)TOKEN_TYPE.TokenPrimary,ref primaryToken);

        //Close the Token that was prevIoUsly opened. 
        CloseHandle(token);
        if (retVal == false)
        {
            string message = String.Format("DuplicatetokenEx Error: {0}",Marshal.GetLastWin32Error());
            Debug.WriteLine(message);
        }

    }

    else
    {

        string message = String.Format("OpenProcesstoken Error: {0}",Marshal.GetLastWin32Error());
        Debug.WriteLine(message);

    }

    //We'll Close this token after it is used. 
    return primaryToken;

}

private static IntPtr GetEnvironmentBlock(IntPtr token)
{

    IntPtr envBlock = IntPtr.Zero;
    bool retVal = CreateEnvironmentBlock(ref envBlock,token,false);
    if (retVal == false)
    {

        //Environment Block,things like common paths to My Documents etc. 
        //Will not be created if "false" 
        //It should not adversley affect CreateProcessAsUser. 

        string message = String.Format("CreateEnvironmentBlock Error: {0}",Marshal.GetLastWin32Error());
        Debug.WriteLine(message);

    }
    return envBlock;
}

public static bool Launch(string appCmdLine /*,int processId*/)
{

    bool ret = false;

    //Either specify the processID explicitly 
    //Or try to get it from a process owned by the user. 
    //In this case assuming there is only one explorer.exe 

    Process[] ps = Process.GetProcessesByName("explorer");
    int processId = -1;//=processId 
    if (ps.Length > 0)
    {
        processId = ps[0].Id;
    }

    if (processId > 1)
    {
        IntPtr token = GetPrimaryToken(processId);

        if (token != IntPtr.Zero)
        {

            IntPtr envBlock = GetEnvironmentBlock(token);
            ret = LaunchProcessAsUser(appCmdLine,envBlock);
            if (envBlock != IntPtr.Zero)
                DestroyEnvironmentBlock(envBlock);

            CloseHandle(token);
        }

    }
    return ret;
}

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐