MalwareSourceCode/MSIL/Virus/Win32/E/Virus.Win32.Expiro.w-f8f9f26e940480624825f6bddbea86e70fc4aa746c4dd8efa7d98dcb477000ed/Microsoft/InfoCards/InfoCardUIAgent.cs
2022-08-18 06:28:56 -05:00

531 lines
19 KiB
C#

// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.InfoCardUIAgent
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 1D4D5564-A025-490C-AF1D-DF4FBB709D1F
// Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00001-msil\Virus.Win32.Expiro.w-f8f9f26e940480624825f6bddbea86e70fc4aa746c4dd8efa7d98dcb477000ed.exe
using Microsoft.InfoCards.Diagnostics;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Security.Principal;
using System.Threading;
namespace Microsoft.InfoCards
{
internal class InfoCardUIAgent
{
private const string UiAgentName = "icardagt.exe";
private const string IdleTimeoutKey = "software\\microsoft\\infocard";
private const int IdleTimeoutDefault = 300;
private const string IdleTimeoutValue = "sleep1";
public static readonly string UiAgentFullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "icardagt.exe");
private static bool s_initialized;
private static bool s_isShuttingDown;
private static ManualResetEvent s_doneShuttingDownEvent = new ManualResetEvent(false);
private static InfoCardUIAgent.UInt32IndexedHybridDictionary s_sessionIdCollection = new InfoCardUIAgent.UInt32IndexedHybridDictionary();
private static InfoCardUIAgent.UInt32IndexedHybridDictionary s_pidCollection = new InfoCardUIAgent.UInt32IndexedHybridDictionary();
private readonly TimeSpan AgentStateChangeTimeOut = new TimeSpan(0, 0, 300);
private static TimeSpan s_idleTimeout = new TimeSpan(0, 0, 300);
private static object s_syncRoot = new object();
private ManualResetEvent m_uiStatusRecieved;
private AutoResetEvent m_agentGetWorkStart;
private AutoResetEvent m_agentGetWorkComplete;
private ClientUIRequest m_request;
private int m_tsSessionId;
private Process m_process;
private EventHandler m_processExitHandler;
private Timer m_timer;
private string m_trustedUserSid;
private SafeNativeHandle m_trustedUserToken;
private string m_desktopName;
private string m_user;
private InfoCardUIAgent.CallMode m_mode;
private RpcUIAgentGetWorkCallback m_getWorkCallback;
private ClientUIRequest.RequestResult m_currentStatus;
private object m_memberSync;
private InfoCardUIAgent(int callerPid, WindowsIdentity userIdentity, int tsSessionId)
{
this.m_agentGetWorkStart = new AutoResetEvent(false);
this.m_agentGetWorkComplete = new AutoResetEvent(false);
this.m_uiStatusRecieved = new ManualResetEvent(false);
this.m_tsSessionId = tsSessionId;
this.m_timer = (Timer) null;
IntPtr zero1 = IntPtr.Zero;
IntPtr zero2 = IntPtr.Zero;
int pid = 0;
this.m_mode = InfoCardUIAgent.CallMode.Sleep;
this.m_currentStatus = ClientUIRequest.RequestResult.Pending;
this.m_user = userIdentity.User.ToString();
this.m_memberSync = new object();
int num = NativeMcppMethods.VerifyTrust(InfoCardUIAgent.UiAgentFullPath);
if (num != 0)
InfoCardTrace.FailFast(SR.GetString("FailedToVerifySignature", (object) num));
IntPtr zero3 = IntPtr.Zero;
bool fElevateToken = false;
int trustedUserWrapper = (int) NativeMcppMethods.CreateProcessAsTrustedUserWrapper(InfoCardUIAgent.UiAgentFullPath, "", (uint) callerPid, "WinSta0\\Default", userIdentity.Name, (uint) this.m_tsSessionId, ref zero2, ref zero1, ref pid, zero3, ref this.m_trustedUserSid, fElevateToken);
if (trustedUserWrapper != 0)
throw InfoCardTrace.ThrowHelperError((Exception) new FailedToStartupUIException(SR.GetString("CreateProcessFailed", (object) trustedUserWrapper), (Exception) new Win32Exception(trustedUserWrapper)));
this.m_trustedUserToken = new SafeNativeHandle(zero2, true);
using (SafeWaitHandle processHandle = new SafeWaitHandle(zero1, true))
{
this.m_process = ProcessMonitor.GetProcessById(pid);
this.m_processExitHandler = new EventHandler(this.OnProcessExit);
this.m_process.Exited += this.m_processExitHandler;
Utility.ThrowIfProcessExited(processHandle);
}
}
public uint ProcessId => (uint) this.m_process.Id;
public string DesktopName => this.m_desktopName;
private ClientUIRequest Request => this.m_request;
public int TsSessionId => this.m_tsSessionId;
public bool IsActive
{
get
{
switch (this.m_mode)
{
case InfoCardUIAgent.CallMode.GetToken:
case InfoCardUIAgent.CallMode.Manage:
case InfoCardUIAgent.CallMode.Import:
case InfoCardUIAgent.CallMode.Error:
return true;
default:
return false;
}
}
}
public bool IsShuttingDown => this.m_mode == InfoCardUIAgent.CallMode.Shutdown;
public SafeNativeHandle TrustedUserToken => this.m_trustedUserToken;
public string TrustedUserSid => this.m_trustedUserSid;
public string User => this.m_user;
private static void InitializeIfNecessary()
{
if (InfoCardUIAgent.s_initialized)
return;
lock (InfoCardUIAgent.s_syncRoot)
{
if (InfoCardUIAgent.s_initialized)
return;
using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("software\\microsoft\\infocard", false))
{
if (registryKey != null)
{
object seconds = registryKey.GetValue("sleep1", (object) 300);
if (seconds is int num)
{
if (num > 0)
InfoCardUIAgent.s_idleTimeout = new TimeSpan(0, 0, (int) seconds);
}
}
}
InfoCardUIAgent.s_initialized = true;
}
}
public static InfoCardUIAgent Create(
int callerPid,
WindowsIdentity callerIdentity,
int tsSessionId)
{
InfoCardUIAgent.InitializeIfNecessary();
InfoCardUIAgent infoCardUiAgent = (InfoCardUIAgent) null;
lock (InfoCardUIAgent.s_syncRoot)
{
InfoCardUIAgent.ThrowIfShuttingDown();
infoCardUiAgent = (InfoCardUIAgent) InfoCardUIAgent.s_sessionIdCollection[(uint) tsSessionId];
if (infoCardUiAgent != null)
{
if (infoCardUiAgent.IsShuttingDown)
{
infoCardUiAgent = (InfoCardUIAgent) null;
}
else
{
if (infoCardUiAgent.Request != null)
throw InfoCardTrace.ThrowHelperError((Exception) new ServiceBusyException());
if (infoCardUiAgent.User != callerIdentity.User.ToString())
{
infoCardUiAgent.Shutdown();
infoCardUiAgent = (InfoCardUIAgent) null;
}
}
}
if (infoCardUiAgent == null)
{
infoCardUiAgent = new InfoCardUIAgent(callerPid, callerIdentity, tsSessionId);
InfoCardUIAgent.s_pidCollection[infoCardUiAgent.ProcessId] = (object) infoCardUiAgent;
InfoCardUIAgent.s_sessionIdCollection[(uint) tsSessionId] = (object) infoCardUiAgent;
}
}
return infoCardUiAgent;
}
public RpcUIAgentGetWorkCallback Bind(
string desktopName,
out SecurityIdentifier userSid,
out SafeWaitHandle hStartEvent,
out SafeWaitHandle hCompleteEvent)
{
lock (this.m_memberSync)
{
userSid = new SecurityIdentifier(this.m_trustedUserSid);
hStartEvent = Utility.GetRemoteHandleFromLocalHandle(this.m_agentGetWorkStart.SafeWaitHandle, this.m_process);
hCompleteEvent = Utility.GetRemoteHandleFromLocalHandle(this.m_agentGetWorkComplete.SafeWaitHandle, this.m_process);
this.m_desktopName = desktopName;
return this.m_getWorkCallback = new RpcUIAgentGetWorkCallback(this.GetWork);
}
}
public void ResetUIResult()
{
this.m_currentStatus = ClientUIRequest.RequestResult.Pending;
this.m_uiStatusRecieved.Reset();
}
public ClientUIRequest.RequestResult ShowUI(InfoCardUIAgent.CallMode mode)
{
if (this.m_currentStatus == ClientUIRequest.RequestResult.Pending)
{
bool flag = false;
lock (this.m_memberSync)
{
if (this.m_currentStatus == ClientUIRequest.RequestResult.Pending)
{
switch (mode)
{
case InfoCardUIAgent.CallMode.GetToken:
case InfoCardUIAgent.CallMode.Manage:
case InfoCardUIAgent.CallMode.Import:
case InfoCardUIAgent.CallMode.Error:
if (this.SetMode(mode))
{
flag = true;
break;
}
break;
default:
InfoCardTrace.ThrowInvalidArgumentConditional(true, nameof (mode));
break;
}
}
}
if (flag)
this.WaitForModeChange();
this.m_uiStatusRecieved.WaitOne();
}
return this.m_currentStatus;
}
public void SetUIStatus(ClientUIRequest.RequestResult status)
{
lock (this.m_memberSync)
{
this.m_currentStatus = status;
if (this.m_request != null && (ClientUIRequest.RequestResult.Cancel == this.m_currentStatus || ClientUIRequest.RequestResult.Untrusted == this.m_currentStatus || ClientUIRequest.RequestResult.Error == this.m_currentStatus))
this.m_request.UserCancel(ClientUIRequest.RequestResult.Untrusted == this.m_currentStatus);
this.m_uiStatusRecieved.Set();
}
}
public void SetRequest(ClientUIRequest request)
{
InfoCardTrace.Assert(null != request, "Request should not be null");
bool flag = false;
lock (InfoCardUIAgent.s_syncRoot)
{
if (this.m_timer != null)
{
this.m_timer.Dispose();
this.m_timer = (Timer) null;
}
this.m_request = request;
if (this.SetMode(InfoCardUIAgent.CallMode.Initialize))
flag = true;
this.m_currentStatus = ClientUIRequest.RequestResult.Pending;
this.m_uiStatusRecieved.Reset();
}
if (!flag)
return;
this.WaitForModeChange();
}
private bool SetMode(InfoCardUIAgent.CallMode mode)
{
bool flag = false;
lock (this.m_memberSync)
{
if (InfoCardUIAgent.CallMode.Shutdown != this.m_mode)
{
if (this.m_mode != mode)
{
switch (mode)
{
case InfoCardUIAgent.CallMode.Sleep:
InfoCardTrace.ThrowInvalidArgumentConditional(this.m_mode != InfoCardUIAgent.CallMode.Release, nameof (mode));
goto case InfoCardUIAgent.CallMode.Shutdown;
case InfoCardUIAgent.CallMode.Initialize:
InfoCardTrace.ThrowInvalidArgumentConditional(this.m_mode != InfoCardUIAgent.CallMode.Sleep, nameof (mode));
goto case InfoCardUIAgent.CallMode.Shutdown;
case InfoCardUIAgent.CallMode.GetToken:
case InfoCardUIAgent.CallMode.Manage:
case InfoCardUIAgent.CallMode.Import:
case InfoCardUIAgent.CallMode.Error:
InfoCardTrace.ThrowInvalidArgumentConditional(this.m_mode != InfoCardUIAgent.CallMode.Initialize, nameof (mode));
goto case InfoCardUIAgent.CallMode.Shutdown;
case InfoCardUIAgent.CallMode.Shutdown:
label_10:
this.m_mode = mode;
flag = true;
break;
case InfoCardUIAgent.CallMode.Release:
switch (this.m_mode)
{
case InfoCardUIAgent.CallMode.Initialize:
case InfoCardUIAgent.CallMode.GetToken:
case InfoCardUIAgent.CallMode.Manage:
case InfoCardUIAgent.CallMode.Import:
case InfoCardUIAgent.CallMode.Error:
goto label_10;
default:
InfoCardTrace.ThrowInvalidArgumentConditional(true, nameof (mode));
goto label_10;
}
default:
InfoCardTrace.ThrowInvalidArgumentConditional(true, nameof (mode));
goto case InfoCardUIAgent.CallMode.Shutdown;
}
}
}
}
return flag;
}
public void ReleaseUI()
{
if (!this.IsActive && InfoCardUIAgent.CallMode.Initialize != this.m_mode || !this.SetMode(InfoCardUIAgent.CallMode.Release))
return;
this.WaitForModeChange();
}
private void WaitForModeChange()
{
this.m_agentGetWorkStart.Set();
if (!this.m_agentGetWorkComplete.WaitOne(this.AgentStateChangeTimeOut, false))
{
Utility.KillHelper(this.m_process);
throw InfoCardTrace.ThrowHelperError((Exception) new CommunicationException(SR.GetString("UIAgentCrash")));
}
}
private void GetWork(out InfoCardUIAgent.CallMode mode, out int requestHandle)
{
lock (this.m_memberSync)
{
mode = InfoCardUIAgent.CallMode.Shutdown;
requestHandle = 0;
try
{
mode = this.m_mode;
if (this.m_request != null)
requestHandle = this.m_request.RequestHandle;
if (mode != InfoCardUIAgent.CallMode.Sleep)
return;
this.m_timer = new Timer(InfoCardTrace.ThunkCallback(new TimerCallback(this.OnTimeout)), (object) null, InfoCardUIAgent.s_idleTimeout, new TimeSpan(0, 0, 0, 0, -1));
}
catch (Exception ex)
{
if (InfoCardTrace.IsFatal(ex))
InfoCardService.Crash(ex);
ClientUIRequest request = this.Request;
if (request == null)
return;
request.ProcessingException = ex;
}
}
}
public void ClearRequest(ClientUIRequest request)
{
bool flag = false;
lock (InfoCardUIAgent.s_syncRoot)
{
if (this.m_request == request)
{
if (this.SetMode(InfoCardUIAgent.CallMode.Sleep))
flag = true;
this.m_request = (ClientUIRequest) null;
}
}
if (!flag)
return;
this.WaitForModeChange();
if (ClientUIRequest.RequestResult.Error != this.m_currentStatus)
return;
this.Shutdown();
}
private void OnTimeout(object state)
{
lock (InfoCardUIAgent.s_syncRoot)
{
if (this.m_request != null || this.IsShuttingDown)
return;
this.Shutdown();
}
}
private void OnProcessExit(int exitCode)
{
lock (InfoCardUIAgent.s_syncRoot)
{
this.m_mode = InfoCardUIAgent.CallMode.Shutdown;
InfoCardUIAgent.s_pidCollection.Remove(this.ProcessId);
InfoCardUIAgent.s_sessionIdCollection.Remove((uint) this.TsSessionId);
if (this.m_request != null && (this.m_currentStatus == ClientUIRequest.RequestResult.Pending || ClientUIRequest.RequestResult.Ok == this.m_currentStatus))
{
switch ((EventCode) exitCode)
{
case EventCode.E_ICARD_UNTRUSTED:
this.m_request.UserCancel(true);
this.m_currentStatus = ClientUIRequest.RequestResult.Untrusted;
break;
case EventCode.E_ICARD_USERCANCELLED:
this.m_request.UserCancel(false);
this.m_currentStatus = ClientUIRequest.RequestResult.Cancel;
break;
case EventCode.E_ICARD_UI_INITIALIZATION:
this.m_request.UserCancel(false);
this.m_currentStatus = ClientUIRequest.RequestResult.UIFailedInitialization;
break;
default:
this.m_request.UserCancel(false);
this.m_currentStatus = ClientUIRequest.RequestResult.UICrashed;
break;
}
this.m_uiStatusRecieved.Set();
}
this.m_agentGetWorkComplete.Set();
if (InfoCardUIAgent.s_isShuttingDown && InfoCardUIAgent.s_pidCollection.Count == 0)
InfoCardUIAgent.s_doneShuttingDownEvent.Set();
if (this.m_timer != null)
{
this.m_timer.Dispose();
this.m_timer = (Timer) null;
}
if (this.m_trustedUserToken == null)
return;
this.m_trustedUserToken.Dispose();
this.m_trustedUserToken = (SafeNativeHandle) null;
}
}
private void OnProcessExit(object sender, EventArgs e)
{
this.m_process.Exited -= this.m_processExitHandler;
Process process = sender as Process;
InfoCardTrace.Assert(null != process, "Should be of type process.");
InfoCardTrace.Assert(process.ExitCode == this.m_process.ExitCode, "Should be the same!");
this.OnProcessExit(process.ExitCode);
}
private static void ThrowIfShuttingDown()
{
if (InfoCardUIAgent.s_isShuttingDown)
throw InfoCardTrace.ThrowHelperError((Exception) new SystemShuttingDownException());
}
private void Shutdown()
{
if (!this.SetMode(InfoCardUIAgent.CallMode.Shutdown))
return;
this.WaitForModeChange();
}
private void Kill() => Utility.KillHelper(this.m_process);
public static void OnLogout(uint sessionId)
{
if (!InfoCardUIAgent.s_initialized)
return;
lock (InfoCardUIAgent.s_syncRoot)
((InfoCardUIAgent) InfoCardUIAgent.s_sessionIdCollection[sessionId])?.Shutdown();
}
public static void DoShutdown()
{
bool flag = false;
if (!InfoCardUIAgent.s_initialized)
return;
lock (InfoCardUIAgent.s_syncRoot)
{
InfoCardUIAgent.s_isShuttingDown = true;
foreach (InfoCardUIAgent infoCardUiAgent in (IEnumerable) InfoCardUIAgent.s_sessionIdCollection.Values)
{
flag = true;
infoCardUiAgent.Shutdown();
}
}
if (!flag || InfoCardUIAgent.s_doneShuttingDownEvent.WaitOne(new TimeSpan(0, 0, 15), false))
return;
lock (InfoCardUIAgent.s_syncRoot)
{
foreach (InfoCardUIAgent infoCardUiAgent in (IEnumerable) InfoCardUIAgent.s_sessionIdCollection.Values)
infoCardUiAgent.Kill();
}
}
public static InfoCardUIAgent FindByPid(uint pid)
{
lock (InfoCardUIAgent.s_syncRoot)
return (InfoCardUIAgent) InfoCardUIAgent.s_pidCollection[pid];
}
private class UInt32IndexedHybridDictionary
{
private HybridDictionary m_realDictionary = new HybridDictionary();
public int Count => this.m_realDictionary.Count;
public ICollection Values => this.m_realDictionary.Values;
public object this[uint index]
{
get => this.m_realDictionary[(object) index];
set => this.m_realDictionary[(object) index] = value;
}
public void Remove(uint index) => this.m_realDictionary.Remove((object) index);
}
public enum CallMode
{
Sleep,
Initialize,
GetToken,
Manage,
Import,
Shutdown,
Crash,
Error,
Release,
}
}
}