mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 19:36:11 +00:00
f2ac1ece55
add
531 lines
19 KiB
C#
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: 516D8B44-4448-4D2C-8B8E-FFBB3FFE472B
|
|
// Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00000-msil\Virus.Win32.Expiro.w-69bb73081eac86b8cf86f45e33515d0095855636967076e2b593d7a30cd80a07.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,
|
|
}
|
|
}
|
|
}
|