CreateProcessAsUser 从服务和用户安全问题

2023-12-02

我有一个启动我的应用程序的 Windows 服务。该服务是一个调度程序,用于执行最终用户定义的一些自定义操作。

它作为本地系统帐户运行,并将启动我的应用程序(有窗口)。

为此我使用函数登录用户, 加载用户配置文件, 创建进程为用户。 这很完美但前提是用户,至log on,是管理员组的成员。

我不能将该用户保留为管理员,他需要是默认用户(用户组的成员)。

作为管理员,它从服务中运行良好。但是当进程以默认用户身份启动时,它会异常终止:

ExitCode: 0xC0000142 STATUS_DLL_INIT_FAILED
Message: {DLL Initialization Failed} Initialization of the dynamic link library %hs failed. The process is terminating abnormally.

如果我使用该用户(用户组的成员)登录并手动启动应用程序,一切都会正常。

我还没有弄清楚导致问题的库是什么。我检查了系统事件日志,但没有日志。 我已经尝试过模拟登录用户但没有成功。

这是代码:

type 
    TProcessRec = record
        Token: Cardinal;
        ProfileInfo: TProfileInfo;
        Job: Cardinal;
        Environment: Pointer;
        ProcessInfo: TProcessInformation;
        WinStat: HWINSTA;
      end;

      TProcess = class
      private
        fProcess: TProcessRec;
      public
        constructor Create(aUser, aDomain, aPassword, aCommand, aWorkingDir: string; aUtil: TJJWServiceUtil);
        destructor Destroy; override;

        procedure Terminate(aExitCode: Cardinal);

        function getExitCode: Cardinal;
      end;

    constructor TProcess.Create(aUser, aDomain, aPassword, aCommand, aWorkingDir: string; aUtil: TJJWServiceUtil);
    type
      TCreateProcessFuncType = (cpAsUser, cpWithLogon);
    const
      DES_CREATION_TYPE: array [TCreateProcessFuncType] of string =
        ('CreateProcessAsUser', 'CreateProcessWithLogon');
    var
      sa: TSecurityAttributes;
      si: TStartupInfo;
      limits : TJobObjectExtendedLimitInformation;
      wUser, wDomain, wPassword, wCommand, wWorkingDir: WideString;
      creationType: TCreateProcessFuncType;
    begin

        // se estiver rodando com a conta LocalSystem (em serviço de windows)
        if
          IsPrivilegeEnabled(SE_TCB_NAME) or IsPrivilegeEnabled(SE_INCREASE_QUOTA_NAME)
        then
          creationType := cpAsUser
        else
          creationType := cpWithLogon;

      aUtil.debug('ENV: ' + AnsiReplaceStr(GetEnvironmentVariable('PATH'), '%', '%%'));
      aUtil.debug('Criando novo processo em modo: ' + DES_CREATION_TYPE[creationType]);

      FillChar(fProcess, SizeOf(fProcess), 0);

      FillChar(sa, SizeOf(sa), 0);
      sa.nLength := SizeOf(sa);

      FillChar(si, SizeOf(si), 0);
      si.cb := SizeOf(si);

      case creationType of

        cpAsUser:
          begin
            aUtil.debug('Efetuando o login do usuário %s', [aUser]);
            // login
            if not LogonUser(PChar(aUser), PChar(aDomain), PChar(aPassword), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, fProcess.Token) then
              RaiseLastOSError;

            try
              aUtil.debug('Carrengado o profile do usuário %s', [aUser]);

              // carrega o profile do usuário
              fProcess.ProfileInfo.dwSize := SizeOf(fProcess.ProfileInfo);
              fProcess.ProfileInfo.dwFlags := PI_NOUI;
              fProcess.ProfileInfo.lpUserName := PChar(aUser);
              if not LoadUserProfile(fProcess.Token, fProcess.ProfileInfo) then
                RaiseLastOSError;

              try
                aUtil.debug('Criando o bloco de variáveis de ambiente do usuário %s', [aUser]);
                // variaveis de ambiente
                if not CreateEnvironmentBlock(fProcess.Environment, fProcess.Token, false) then
                  RaiseLastOSError;

                aUtil.debug('Criando o JOB para associar o processo filho ao processo pai');
                // job para associar
                fProcess.Job := CreateJobObject(@sa, nil);
                if fProcess.Job = 0 then
                  RaiseLastOSError;

                try
                  // limita o job para matar o seu processo caso o processo pai termine antes
                  FillChar(Limits,SizeOf(Limits),0);
                  with Limits,BasicLimitInformation do
                    LimitFlags := JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE or JOB_OBJECT_LIMIT_BREAKAWAY_OK;

                  if not SetInformationJobObject(fProcess.Job, JobObjectExtendedLimitInformation, @limits, SizeOf(limits)) then
                    RaiseLastOSError;

                  try
                    fProcess.WinStat := CreateWindowStation(SCHEDULER_WINSTAT, 0, 0, nil);
                    if fProcess.WinStat = 0 then
                      RaiseLastOSError;
                    si.lpDesktop := PChar(SCHEDULER_WINSTAT);

                    aUtil.debug('Criando o processo: %s', [aCommand]);

                    // processo!
                    if not CreateProcessAsUser(
                      fProcess.Token,
                      nil,
                      PChar(aCommand),
                      @sa,
                      nil,
                      false,
                      CREATE_SUSPENDED or CREATE_BREAKAWAY_FROM_JOB or NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE or CREATE_NEW_PROCESS_GROUP or CREATE_UNICODE_ENVIRONMENT,
                      fProcess.Environment,
                      PChar(aWorkingDir),
                      si,
                      fProcess.ProcessInfo)
                    then
                      RaiseLastOSError;

                    try
                      aUtil.debug('Associando o JOB ao processo filho');
                      // associa ao processo do plugin o JOB (gruda nele!)
                      if not AssignProcessToJobObject(fProcess.Job, fProcess.ProcessInfo.hProcess) then
                        RaiseLastOSError;

                      // VOA PROCESSO, VOA!
                      if ResumeThread(fProcess.ProcessInfo.hThread) = $FFFFFFFF then
                        RaiseLastOSError;

                      aUtil.debug('Processo disparado');
                    except
                      TerminateProcess(fProcess.ProcessInfo.hProcess, Cardinal(-1));

                      CloseHandle(fProcess.ProcessInfo.hThread);
                      CloseHandle(fProcess.ProcessInfo.hProcess);

                      FillChar(fProcess.ProcessInfo, SizeOf(fProcess.ProcessInfo), 0);

                      raise;
                    end;

                  except
                    DestroyEnvironmentBlock(fProcess.Environment);
                    fProcess.Environment := nil;
                    raise;
                  end;

                except
                  CloseHandle(fProcess.Job);
                  fProcess.Job := 0;
                  raise;
                end;

              except
                UnloadUserProfile(fProcess.Token, fProcess.ProfileInfo.hProfile);
                FillChar(fProcess.ProfileInfo, SizeOf(fProcess.ProfileInfo), 0);
                raise;
              end;

            except
              CloseHandle(fProcess.Token);
              fProcess.Token := 0;
              raise;
            end;
          end;

        //////////////////////////////////////////////////////////////////////////////

        cpWithLogon:
          begin
            wUser := aUser;
            wDomain := aDomain;
            wPassword := aPassword;
            wCommand := aCommand;
            wWorkingDir := aWorkingDir;

            aUtil.debug('Disparando o processo: %s', [aCommand]);

            // o CreateProcessWithLogon já cria um JOB para evitar
            // que o processo fique órfão no limbo
            if not CreateProcessWithLogon(
               PWideChar(wUser),
               PWideChar(wDomain),
               PWideChar(wPassword),
               LOGON_WITH_PROFILE,
               nil,
               PWideChar(wCommand),
               NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE or CREATE_NEW_PROCESS_GROUP,
               nil,
               PWideChar(wWorkingDir),
               si,
               fProcess.ProcessInfo
             )
            then
              RaiseLastOSError;
          end;

          end;
    end;

    destructor TProcess.Destroy;
    begin
      if fProcess.ProcessInfo.hProcess > 0 then
      begin
        if getExitCode = STILL_ACTIVE then
          TerminateProcess(fProcess.ProcessInfo.hProcess, Cardinal(-1));

        CloseHandle(fProcess.ProcessInfo.hThread);
        CloseHandle(fProcess.ProcessInfo.hProcess);
      end;

      if fProcess.Environment <> nil then
        DestroyEnvironmentBlock(fProcess.Environment);

      if fProcess.Job > 0 then
        CloseHandle(fProcess.Job);

      if fProcess.ProfileInfo.hProfile > 0 then
        UnloadUserProfile(fProcess.Token, fProcess.ProfileInfo.hProfile);

      if fProcess.Token > 0 then
        CloseHandle(fProcess.Token);

      if fProcess.WinStat > 0 then
        CloseWindowStation(fProcess.WinStat);

      FillChar(fProcess, SizeOf(fProcess), 0);

      inherited;
    end;

    function TProcess.getExitCode: Cardinal;
    begin
      if not GetExitCodeProcess(fProcess.ProcessInfo.hProcess, Result) then
        RaiseLastOSError;
    end;

这可能很有用

用 C++ 启动交互式客户端进程


根据这个:用 C++ 启动交互式客户端进程

和这个:CreateProcessAsUser() 窗口站和桌面

我解决了创建新的 Window Station 和桌面来启动该过程的问题:

myWinStat := CreateWindowStation('myWinStat', 0, GENERIC_READ or GENERIC_WRITE, nil);
myDesk := CreateDesktop('myDesktop', nil, nil, 0, GENERIC_READ or GENERIC_WRITE, nil);
startupInfo.lpDesktop := 'myDesktop';
try
   // createProcessAsUser...
   // Wait for process termination...
finally
   CloseDesktop(myDesk);
   CloseWindowStation(myWinStat);
end;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CreateProcessAsUser 从服务和用户安全问题 的相关文章

  • TListView 中的中心子项目图像

    Is it possible to fix the drawing of subitem images in a TListView so that they are not cut off on the left hand side as
  • Sencha Cmd 5 + Java 8 错误

    在我的 Windows 构建服务器上安装 Java 8 JDK 后 执行以下命令时遇到以下错误sencha命令 C gt sencha Error Registry key Software JavaSoft Java Runtime En
  • 如何让R使用所有处理器?

    我有一台运行 Windows XP 的四核笔记本电脑 但查看任务管理器 R 似乎一次只使用一个处理器 如何让 R 使用全部四个处理器并加速我的 R 程序 我有一个基本系统 我使用它在 for 循环上并行化我的程序 一旦您了解需要做什么 此方
  • 即使通过 ssl,在 ViewState 中存储信用卡和定价信息是否安全?

    我有一个带有私有属性的页面 该页面在视图状态中存储信用卡对象和购物车对象 以便我可以在回发期间维护对它们的引用 顺便说一句 涉及的页面将使用 SSL 这安全吗 我不会在视图状态中存储敏感信息 ever 通过这样做 您将安全性委托给浏览器的实
  • Delphi 将面板流传输至文件

    今天我有一个关于将表单的一部分流式传输到文件的问题 在此示例中 我使用 Tmemo 而不是文件来查看流 这是我的表格 表单右上角的面板有一些控件 如标签 编辑等 使用 保存面板 按钮将面板保存在 TStream 上 这里是代码 proced
  • 保护 REST 和 JSON

    我想利用 RESTful 架构构建提供 JSON 数据的 Web 服务 但我只想要我自己的客户端应用程序可以从我的网络服务请求 基本上 我的 Web 服务包含不供公众使用的敏感数据 但我想以这种方式构建它 以便我可以构建连接到我的 Web
  • Delphi - 获取和设置 ListView 的滚动条位置

    这似乎是一个愚蠢而简单的问题 然而 我一直无法找到令人满意的答案 基本上 我有一个列表视图 样式 vsReport 与数据 有时 我必须更新它 因此 我必须清除列表视图并用更新的数据再次填充它 但是 当我这样做时 滚动条位置将重置为 0 我
  • 如何处理来自单独线程的窗口消息?

    我希望启动一个单独的线程来处理窗口消息 通过阻塞 GetMessage 循环 但之后仍然在初始线程中创建窗口 在单独的线程中 一旦启动 我就会调用PeekMessage使用 PM NOREMOVE 确保消息队列存在 有必要吗 然后 Atta
  • 如何使用正则表达式验证带有可选百分比符号的小数?

    正如问题的标题 我需要使用以下值验证正则表达式 最多 2 个小数位和 9 个整数 带有可选的百分比符号 Valid 10 0 1111111 12 15 2 10 2 3 Invalid 12 02 123456789123 123 I t
  • 使用Windows 7计算器进行对数计算[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我想使用Windows计算器在科学模式中为了求解一个非常基本的对数方程 但不幸的是 我无法做到这一点 问题是这样的 log 5 125 非常感谢您的帮
  • 任意通用列表的通配符

    我有一个类 MyClass 它不是通用的 包含任意 TList 并对其执行某些操作 我希望用通用 TList 替换 TList 但 MyClass 必须保持非通用 由于 Delphi 是不变的 这样的事情是行不通的 list1 TList
  • Android 后台倒计时器

    我有一个 Android 应用程序 它管理一个倒计时器 类 CountDownTimer 它显示在应用程序屏幕中 以显示到达 00 00 还剩多少时间 我现在的问题是 当我按主页按钮或启动另一个应用程序时 应用程序 计时器不会在后台运行 所
  • MINIDUMP_TYPE 枚举值的哪种组合将为我提供最“完整”的小型转储?

    我希望我的应用程序创建一个小型转储以帮助调试未处理的异常 在创建转储之前 我可能不知道我需要什么类型的小型转储 那么什么组合小型转储类型 http msdn microsoft com en us library ms680519 28v
  • 如何从 pl/sql 包运行 http Web 服务请求

    我开发了一个新的程序来调用 Web 服务 但当我运行它时 它显示 Oracle 适配器错误 您能指导我如何解决此错误吗 下面的代码有问题吗 Formatted on 17 07 2014 16 49 02 QP5 v5 185 11230
  • Delphi定时器比毫秒更精确

    我在 Delphi 中有一个程序 它以 25 赫兹 每秒 25 次 的速度从外部应用程序获取帧 然后通过创建 1 2 个额外帧将其转换为 60 赫兹 每秒 60 帧 我需要通过连续构建帧缓冲区并从单独的线程输出帧来输出这些额外的帧 问题是
  • 使用 MingW 在 Windows 上传送 PyGObject/GTK+ 应用程序

    我在 Windows 上使用 PyGObject GTK 和 Python3 7 并且担心如何打包我的应用程序 借助Python官方生态系统 可以轻松使用冷冻机和venvs 然而 Windows 上的 PyGObject 和 GTK 需要
  • 具有多处理功能的 Python 代码无法在 Windows 上运行

    以下简单的绝对初学者代码在 Ubuntu 14 04 Python 2 7 6 和 Cygwin Python 2 7 8 上运行 100 但在 Windows 64 位 Python 2 7 8 上挂起 我使用另一个片段观察到了同样的情况
  • 如何在 Spring-Security 中重命名表 persist_logins

    Spring Security 中管理 记住我 身份验证的默认表名称是 persistent logins 由于数据库命名约定 我需要重命名该表 持久登录 to T PERSISTENT LOGINS 请提供任何帮助 您需要编写自己的实现J
  • Medium Trust 中允许哪些反射权限?

    我想问一下Medium Trust中允许使用哪些方法 类 例如 这些方法是否被允许 获取属性 获取方法 激活器 CreateInstance 汇编版本 程序集名称 名称 请告诉我哪些方法是允许的 GetMethods 和 Activator
  • 为什么标签存在却提示“系统找不到指定的批次标签”?

    在 Windows XP 中运行批处理文件时 我发现随机出现的错误消息 系统找不到指定name of label的批次标签 标签当然存在 导致此错误的原因是什么 实际上 要实现这一点 你需要两个条件 批处理文件不得使用 CRLF 行结尾 您

随机推荐

  • 获取 SQL Server 表中每列的每个值的计数

    所以我查了一下 这个问题非常相似 但缺少一个关键部分 SQL Server 计算表中每一列中不同值的数量 因此 在这个问题中 他们想要每列的不同计数 我想要做的是获取表中每一列的每个不同值的计数 并且我正在对特定数据库中的所有表执行此操作
  • 如何从 ElasticSearch 中彻底删除某些内容?

    我们使用 ELK 堆栈进行日志记录 我被要求设计一个流程来删除意外记录的敏感信息 现在基于我对 ElasticSearch Lucene 如何处理的阅读删除和更新数据仍在索引中 只是不可用 随着索引合并等 它最终会被清理 是否有一个流程来运
  • 动态三元运算符

    为什么以及如何在下面的代码中工作 dynamic x c a new D1 x new D2 但不是这个 dynamic x c a new D1 new D2 Code class Program static void Main str
  • 无法正确设置 Android Actionbar 背景

    问题当我设置 ActionBar 背景颜色时 该栏看起来像这样 我无法在这里上传图片 所以这是文件 Android ActionBar问题 我的价值观 风格文件
  • 如何在 Adob​​e Flex 中合并 DataGrid/Advanced DataGrid 中的单元格

    我需要合并单元格 如图所示 Flex 以我的理解 并没有直接提供这一点 你有几个选择 无论哪种方式 您可能需要在分层模型中排列数据 有 3 个孩子的家长似乎描述了您的问题 我看到的第一个选项涉及直接将您的数据声明为高级数据网格的分层结构 如
  • 找出 Eclipse 运行在什么 JVM 上

    我目前正在尝试调整 Eclipse 安装并遇到了 vm 选项 SO 上的其他帖子提到 始终使用可用的最新 JVM 是件好事 因为它们在性能方面不断变得更好 所以我很可能会这样做 我想知道如果您没有指定 vm 参数 您如何找出 Eclipse
  • jenkins 不执行 mvn 命令后的最后一个命令

    我将我的工作配置为自由式 我需要将案例运行到指定的机器上 我的项目是maven项目 我想在案例运行完成后将报告复制到主节点 詹金斯版本 1 483 我使用 pscp 复制文件 这些文件在 Windows 命令提示符下手动工作正常 我的命令如
  • 使用 PHP 和 PDO 访问 Microsoft

    我正在尝试连接到我的访问数据库 但无法连接 我的 Microsoft server 2008 上装有 IIS 7 我不断收到此错误消息 SQLSTATE IM002 SQLDriverConnect 0 Microsoft ODBC 驱动程
  • 陈述/计算的生日悖论

    显然 我实际上应该创建一个数组 在多次试验中随机分配生日 5000 然后 假设每次有 2 50 个人至少有 2 个生日时进行计数 并将结果除以 5 000 以获得近似概率 我相信我的循环搞砸了 需要一些反馈 不是代码 我想确切地了解出了什么
  • Hive SELECT 语句创建结构数组

    我在 Hive 中选择结构数组时遇到问题 我的源表如下所示 field id fieldid fieldlabel fieldtype answer id unitname 这是调查数据 其中id是调查id 中间的四个字段是响应数据 uni
  • 从 Excel VBA 运行 R,无需 RExcel

    这个过程可以简化吗 首先 我在 R 中手动打开该文件 C R ExampleModel ModelScript R 在 R 编辑器中 当从打开的 ModelScript R 文件运行以下代码时 它会正确处理 Model R 脚本 sourc
  • 我应该如何将 UIImage 存储在我的 Core Data 数据库中?

    我正在开发一个应用程序 需要将大约 100 张或更多图像与其他相关信息一起预先插入到核心数据数据库中 现在 我只需编写几行代码就可以轻松添加其他数据 但对于 UIImages 我不确定如何在不编写大量代码的情况下做到这一点 我想知道 是否有
  • AngularJS $http 未定义

    我对 AngularJS 还很陌生 当我打电话时 http get我得到一个 http is not defined error 这是我的模块的内容 var demoApp angular module demoApp demoApp co
  • 在一个语句中输出多个后置和前置增量[重复]

    这个问题在这里已经有答案了 我是 C 语言新手 所以请 sum1 帮助我 写的一段C代码 int i 3 printf d i i 编译器给出 O P 9 如何 结果未定义 您在表达式中多次修改变量 或者序列点更准确 在序列点之间多次修改变
  • EXC_BAD_INSTRUCTION 仅在 iPhone 5 模拟器中

    在 iPhone 5 模拟器上运行我的代码会引发如图所示的异常 在任何其他模拟器上运行代码就可以了 我无法在这行不起眼的代码中发现我在哪里犯了错误 还有其他人有这个问题吗 NSInteger 这是一个类型别名Int在 Swift 中 是 3
  • Android:NullPointerException 使用 SharedPreferences

    使用 SharedPreferences 此活动在启动时崩溃 首先我将发布活动代码 然后我将发布我的 LogCat 非常感谢你们 你们总是给予我们很大的帮助 活动代码 package com creativecoders gymbuddy
  • 在设置 {app} 之前获取 wpSelectDir 中的路径 Inno Setup

    当用户单击时 我想获取安装目录的路径Next 当我在wpSelectDirInno 设置 我需要检查路径 因为我需要验证路径 如果不正确 我不会让用户继续 我的问题是常数 app 尚未设置 因为它将在之后设置wpSelectDir我还在 U
  • 使用Python将日记文件拆分为多个文件

    我保留一份技术笔记的日记文件 每个条目都带有时间戳 如下所示 Monday 02012 05 07 at 01 45 20 PM This is a sample note Lorem ipsum dolor sit amet consec
  • 我可以在ironruby 中运行rubygems 吗?

    目前是否可以通过预发布的ironruby来运行rubygems 好像我必须设置一个环境变量才能找到它们 您已经能够在 IronRuby 下运行 ruby gems 有一段时间了 只需下载并安装最新的来自 codeplex 的 IronRub
  • CreateProcessAsUser 从服务和用户安全问题

    我有一个启动我的应用程序的 Windows 服务 该服务是一个调度程序 用于执行最终用户定义的一些自定义操作 它作为本地系统帐户运行 并将启动我的应用程序 有窗口 为此我使用函数登录用户 加载用户配置文件 创建进程为用户 这很完美但前提是用