. net应用程序在创建processasuser后崩溃

本文关键字:崩溃 processasuser 创建 应用程序 net | 更新日期: 2023-09-27 18:02:55

我有一个在System帐户中运行的服务,它应该在用户模式下启动应用程序。在c++中没有问题,但在。net中有很多问题。

最后复制当前用户会话(explorer.exe)的用户令牌

应用程序似乎在用户模式下启动,但在我的代码到达第一行之前直接崩溃;)

我使用进程资源管理器检查了当我直接调用进程或通过我的服务调用进程时的差异。

似乎。net程序集的加载不起作用,但我不知道为什么(或唯一的一个是因为我重复了一个非。net令牌,但读取所有应用程序开始为非。net版本和windows在加载期间检测到程序集必须加载)

我代码:

var adjustToken = IntPtr.Zero;
        int lastError;
        if (
                        !NativeMethods.OpenProcessToken(
                                                        NativeMethods.GetCurrentProcess(),
                                                        ProcessTools.TokenAdjustPrivileges | ProcessTools.TokenQuery,
                                                        ref adjustToken))
        {
            lastError = Marshal.GetLastWin32Error();
            throw new Exception($"OpenProcessToken() failed, error = {lastError}.");
        }
        try
        {
            Luid luidSeDebugNameValue;
            if (!NativeMethods.LookupPrivilegeValue(null, ProcessTools.SeDebugName, out luidSeDebugNameValue))
            {
                lastError = Marshal.GetLastWin32Error();
                throw new Exception(
                                $"LookupPrivilegeValue() failed, error = {lastError}. SeDebugPrivilege is not available");
            }
            var tokenPrivileges = new TokenPrivileges
            {
                PrivilegeCount = 1,
                Luid = luidSeDebugNameValue,
                Attributes = ProcessTools.SePrivilegeEnabled
            };
            if (
                            !NativeMethods.AdjustTokenPrivileges(
                                                                 adjustToken,
                                                                 false,
                                                                 ref tokenPrivileges,
                                                                 0,
                                                                 IntPtr.Zero,
                                                                 IntPtr.Zero))
            {
                lastError = Marshal.GetLastWin32Error();
                throw new Exception($"AdjustTokenPrivileges() failed, error = {lastError}.");
            }
            else
            {
                var userTokenDup = IntPtr.Zero;
                var token = IntPtr.Zero;
                var processes = Process.GetProcessesByName("explorer");
                var process = ProcessTools.OpenProcess(
                                                       processes.FirstOrDefault(),
                                                       ProcessAccessFlags.All,
                                                       out lastError);
                if (process == IntPtr.Zero)
                {
                    throw new Exception($"Can't open process. Last error = {lastError}.");
                }
                try
                {
                    if (!NativeMethods.OpenProcessToken(process, ProcessTools.TokenDuplicate, ref token))
                    {
                        lastError = Marshal.GetLastWin32Error();
                        throw new Exception($"Can't open process token. Last error = {lastError}.");
                    }
                    var sa = new SecurityAttributes();
                    sa.Length = Marshal.SizeOf(sa);
                    try
                    {
                        if (
                                        !NativeMethods.DuplicateTokenEx(
                                                                        token,
                                                                        ProcessTools.TokenAllAccess,
                                                                        ref sa,
                                                                        (int)
                                                                        SecurityImpersonationLevel
                                                                                        .SecurityImpersonation,
                                                                        (int) TokenType.TokenPrimary,
                                                                        ref userTokenDup))
                        {
                            lastError = Marshal.GetLastWin32Error();
                            throw new Exception($"Can't duplicate process token. Last error = {lastError}.");
                        }
                        var si = new Startupinfo();
                        si.Cbyte = Marshal.SizeOf(si);
                        si.Desktop = @"winsta0'default";
                        var inputHandle =
                            NativeMethods.GetStdHandle(NativeMethods.ConsoleStandardHandle.StandardInputHandle);
                        var outputHandle =
                            NativeMethods.GetStdHandle(NativeMethods.ConsoleStandardHandle.StandardInputHandle);
                        var errHandle =
                            NativeMethods.GetStdHandle(NativeMethods.ConsoleStandardHandle.StandardInputHandle);
                        if (errHandle != IntPtr.Zero)
                        {
                            si.StandardError = errHandle;
                        }
                        if (outputHandle != IntPtr.Zero)
                        {
                            si.StandardOutput = outputHandle;
                        }
                        if (inputHandle != IntPtr.Zero)
                        {
                            si.StandardInput = inputHandle;
                        }
                        const int CreationFlags = ProcessTools.NormalPriorityClass | ProcessTools.CreateNewConsole;
                        var file = new FileInfo(applicationName);
                        var dir = file.Directory?.FullName;
                        ProcessInformation procInfo;
                        var result = NativeMethods.CreateProcessAsUser(
                                                                       userTokenDup,
                                                                       file.FullName,
                                                                       arguments,
                                                                       ref sa,
                                                                       ref sa,
                                                                       false,
                                                                       CreationFlags,
                                                                       IntPtr.Zero,
                                                                       dir,
                                                                       ref si,
                                                                       out procInfo);
                        lastError = Marshal.GetLastWin32Error();
                        NativeMethods.CloseHandle(userTokenDup);
                        if (!result)
                        {
                            throw new Exception(
                                            $"Could not create process in user interactive mode. Last error = {lastError}.");
                        }
                        if (milliseconds == 0)
                        {
                            return;
                        }
                        var res = NativeMethods.WaitForSingleObject(procInfo.Process, milliseconds);
                        if (res == ProcessTools.WaitTimeOut)
                        {
                            throw new Exception(
                                            $"Process not started within = {milliseconds} seconds.");
                        }

                    }
                    finally
                    {
                        NativeMethods.CloseHandle(token);
                    }
                }
                finally
                {
                    NativeMethods.CloseHandle(process);
                }
            }
        }
        finally
        {
            NativeMethods.CloseHandle(adjustToken);
        }

. net应用程序在创建processasuser后崩溃

在转储中我没有看到太多,只有未处理的异常过滤器正在调用WER服务并等待用户输入。没有其他线程在运行

FAULTING_IP: 
+0
00000000 ??              ???
EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 00000000
   ExceptionCode: 80000003 (Break instruction exception)
  ExceptionFlags: 00000000
NumberParameters: 0
CONTEXT:  00000000 -- (.cxr 0x0;r)
eax=00000000 ebx=00000000 ecx=00000001 edx=00000000 esi=00000003 edi=00000003
eip=771dd72c esp=00a7e3bc ebp=00a7e53c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
ntdll!NtWaitForMultipleObjects+0xc:
771dd72c c21400          ret     14h
FAULTING_THREAD:  000019e4
DEFAULT_BUCKET_ID:  WRONG_SYMBOLS
PROCESS_NAME:  ReleaseManager.exe
ADDITIONAL_DEBUG_TEXT:  
You can run '.symfix; .reload' to try to fix the symbol path and load symbols.
MODULE_NAME: ntdll
FAULTING_MODULE: 771a0000 ntdll
DEBUG_FLR_IMAGE_TIMESTAMP:  5308893d
ERROR_CODE: (NTSTATUS) 0x80000003 - {AUSNAHME}  Haltepunkt  Im Quellprogramm wurde ein Haltepunkt erreicht.
EXCEPTION_CODE: (HRESULT) 0x80000003 (2147483651) - Mindestens ein Argument ist ung ltig.
APP:  releasemanager.exe
ANALYSIS_VERSION: 6.3.9600.16384 (debuggers(dbg).130821-1623) x86fre
PRIMARY_PROBLEM_CLASS:  WRONG_SYMBOLS
BUGCHECK_STR:  APPLICATION_FAULT_WRONG_SYMBOLS
LAST_CONTROL_TRANSFER:  from 75699188 to 771dd72c
STACK_TEXT:  
WARNING: Stack unwind information not available. Following frames may be wrong.
00a7e53c 75699188 00000000 00a7e580 00000000 ntdll!NtWaitForMultipleObjects+0xc
00a7e558 756eb399 00000003 00a7e580 00000000 kernel32!WaitForMultipleObjects+0x19
00a7e994 756eae92 00000000 00000001 00000000 kernel32!WerpLaunchAeDebug+0x1956
00a7e9ac 75b996fd 00a7ea68 00000001 d8e06f96 kernel32!WerpLaunchAeDebug+0x144f
00a7ea38 7724366d 00a7ea68 771df7b4 fffffffe KERNELBASE!UnhandledExceptionFilter+0x1d2
00a7f968 771ea8a1 ffffffff 771df69b 00000000 ntdll!LdrSetAppCompatDllRedirectionCallback+0x1411e
00a7f978 00000000 7460bb40 ff21e000 00000000 ntdll!RtlInitializeExceptionChain+0x5a

STACK_COMMAND:  ~0s; .ecxr ; kb
FOLLOWUP_IP: 
ntdll!NtWaitForMultipleObjects+c
771dd72c c21400          ret     14h
SYMBOL_STACK_INDEX:  0
SYMBOL_NAME:  ntdll!NtWaitForMultipleObjects+c
FOLLOWUP_NAME:  MachineOwner
IMAGE_NAME:  ntdll.dll
BUCKET_ID:  WRONG_SYMBOLS
FAILURE_BUCKET_ID:  WRONG_SYMBOLS_80000003_ntdll.dll!NtWaitForMultipleObjects
ANALYSIS_SOURCE:  UM
FAILURE_ID_HASH_STRING:  um:wrong_symbols_80000003_ntdll.dll!ntwaitformultipleobjects
FAILURE_ID_HASH:  {b36f8a59-3ae7-2592-4531-80a59fca9974}
Followup: MachineOwner
---------