// Decompiled with JetBrains decompiler // Type: Microsoft.InfoCards.InfoCardUIAgent // Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 // MVID: ADE0A079-11DB-4A46-8BDE-D2A592CA8DEA // Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00000-msil\Virus.Win32.Expiro.w-67b630ead60119692b9abbdfd8717c96904ef041127c2cae033c86b718eaa61e.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, } } }