Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2208,6 +2208,18 @@
value="0x6017"
version="1"
/>
<event
channel="C_ANALYTIC"
keywords="AmsiState"
level="win:Verbose"
message="$(string.PS_PROVIDER.event.E_A_AmsiState.message)"
opcode="Method"
symbol="AmsiState"
task="Amsi"
template="T_AmsiState"
value="0x4001"
version="1"
/>
</events>
<channels>
<!--There are three channels defined for PowerShell instrumentation
Expand Down Expand Up @@ -2415,6 +2427,12 @@
symbol="T_ISEOperation"
value="120"
/>
<task
message="$(string.PS_PROVIDER.task.T_AmsiState.message)"
name="Amsi"
symbol="T_Amsi"
value="130"
/>
</tasks>
<opcodes>
<opcode
Expand Down Expand Up @@ -2575,6 +2593,12 @@
name="PSWorkflow"
symbol="K_PSWORKFLOW"
/>
<keyword
mask="0x400"
message="$(string.PS_PROVIDER.keyword.K_AmsiState.message)"
name="AmsiState"
symbol="K_AmsiState"
/>
</keywords>
<maps>
<!-- please keep in sync with SerializationMethod from
Expand Down Expand Up @@ -4056,6 +4080,16 @@
name="FileName"
/>
</template>
<template tid="T_AmsiState">
<data
inType="win:UnicodeString"
name="Action"
/>
<data
inType="win:UnicodeString"
name="AmsiContext"
/>
</template>
</templates>
</provider>
</events>
Expand Down Expand Up @@ -4949,7 +4983,11 @@
id="PS_PROVIDER.event.E_O_M3PWorkflowExecutionStarted.message"
value="Workflow execution started. %n %t WorkflowId: %1 %n %t ManagedNodes: %2"
/>
<string
<string
id="PS_PROVIDER.event.E_A_AmsiState.message"
value="AmsiUtil state. %n %t state: %1 %n %t Context: %2"
/>
<string
id="PS_PROVIDER.event.E_O_M3PEndpointRegistered.message"
value="A new PowerShell endpoint was registered. %n %t EndpointName: %1 %n %t EndpointType: %2 %n %t RegisteredBy: %3"
/>
Expand Down Expand Up @@ -5417,7 +5455,11 @@
id="PS_PROVIDER.keyword.K_PSWORKFLOW.message"
value="PSWorkflow Hosting And Execution Layer"
/>
<string
<string
id="PS_PROVIDER.keyword.K_AmsiState.message"
value="Amsi state"
/>
<string
id="PS_PROVIDER.keyword.K_SESSION.message"
value="All session layer"
/>
Expand Down Expand Up @@ -5589,7 +5631,11 @@
id="PS_PROVIDER.task.T_ISEOperation.message"
value="PowerShell ISE Operation"
/>
<string
<string
id="PS_PROVIDER.task.T_AmsiState.message"
value="Amsi State"
/>
<string
id="PS_PROVIDER.event.E_O_ISEExecuteScript.message"
value="Windows PowerShell ISE has started to run script file %1."
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ internal enum PSEventId : int
Provider_Lifecycle = 0x1F03,
Settings = 0x1F04,
Engine_Trace = 0x1F06,
Amsi_Init = 0x4001,

// Experimental Features
ExperimentalFeature_InvalidName = 0x3001,
Expand Down Expand Up @@ -239,7 +240,8 @@ internal enum PSTask : int
ExperimentalFeature = 0x6B,
ScheduledJob = 0x6E,
NamedPipe = 0x6F,
ISEOperation = 0x78
ISEOperation = 0x78,
Amsi = 0X82
}

/// <summary>
Expand Down
16 changes: 16 additions & 0 deletions src/System.Management.Automation/logging/LogProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ internal LogProvider()
/// <param name="previousValue"></param>
internal abstract void LogSettingsEvent(LogContext logContext, string variableName, string value, string previousValue);

/// <summary>
/// Provider interface function for logging AmsiUtil State event.
/// </summary>
/// <param name="state">This the action performed in AmsiUtil class, like init, scan, etc.</param>
/// <param name="context">The amsiContext handled - Session pair.</param>
internal abstract void LogAmsiUtilStateEvent(string state, string context);

/// <summary>
/// True if the log provider needs to use logging variables.
/// </summary>
Expand Down Expand Up @@ -370,6 +377,15 @@ internal override void LogSettingsEvent(LogContext logContext, string variableNa
{
}

/// <summary>
/// Provider interface function for logging provider health event.
/// </summary>
/// <param name="state">This the action performed in AmsiUtil class, like init, scan, etc.</param>
/// <param name="context">The amsiContext handled - Session pair.</param>
internal override void LogAmsiUtilStateEvent(string state, string context)
{
}

#endregion
}
}
23 changes: 14 additions & 9 deletions src/System.Management.Automation/security/SecuritySupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,7 @@ internal enum CertificatePurpose

namespace System.Management.Automation
{
using System.Management.Automation.Tracing;
using System.Security.Cryptography.Pkcs;

/// <summary>
Expand Down Expand Up @@ -1336,6 +1337,14 @@ public enum ResolutionPurpose

internal static class AmsiUtils
{
static AmsiUtils()
{
#if !UNIX
s_amsiInitFailed = !CheckAmsiInit();
PSEtwLog.LogAmsiUtilStateEvent($"init-{s_amsiInitFailed}", $"{s_amsiContext}-{s_amsiSession}");
#endif
}

internal static int Init()
{
Diagnostics.Assert(s_amsiContext == IntPtr.Zero, "Init should be called just once");
Expand All @@ -1357,11 +1366,6 @@ internal static int Init()
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;

var hr = AmsiNativeMethods.AmsiInitialize(appName, ref s_amsiContext);
if (!Utils.Succeeded(hr))
{
s_amsiInitFailed = true;
}

return hr;
}
}
Expand Down Expand Up @@ -1405,13 +1409,15 @@ internal static AmsiNativeMethods.AMSI_RESULT WinScanContent(
// If we had a previous initialization failure, just return the neutral result.
if (s_amsiInitFailed)
{
PSEtwLog.LogAmsiUtilStateEvent("ScanContent-InitFail", $"{s_amsiContext}-{s_amsiSession}");
return AmsiNativeMethods.AMSI_RESULT.AMSI_RESULT_NOT_DETECTED;
}

lock (s_amsiLockObject)
{
if (s_amsiInitFailed)
{
PSEtwLog.LogAmsiUtilStateEvent("ScanContent-InitFail", $"{s_amsiContext}-{s_amsiSession}");
return AmsiNativeMethods.AMSI_RESULT.AMSI_RESULT_NOT_DETECTED;
}

Expand Down Expand Up @@ -1451,14 +1457,15 @@ internal static AmsiNativeMethods.AMSI_RESULT WinScanContent(
if (!Utils.Succeeded(hr))
{
// If we got a failure, just return the neutral result ("AMSI_RESULT_NOT_DETECTED")
PSEtwLog.LogAmsiUtilStateEvent($"AmsiScanBuffer-{hr}", $"{s_amsiContext}-{s_amsiSession}");
return AmsiNativeMethods.AMSI_RESULT.AMSI_RESULT_NOT_DETECTED;
}

return result;
}
catch (DllNotFoundException)
{
s_amsiInitFailed = true;
PSEtwLog.LogAmsiUtilStateEvent("DllNotFoundException", $"{s_amsiContext}-{s_amsiSession}");
return AmsiNativeMethods.AMSI_RESULT.AMSI_RESULT_NOT_DETECTED;
}
}
Expand Down Expand Up @@ -1559,7 +1566,6 @@ private static bool CheckAmsiInit()

if (!Utils.Succeeded(hr))
{
s_amsiInitFailed = true;
return false;
}
}
Expand All @@ -1573,7 +1579,6 @@ private static bool CheckAmsiInit()

if (!Utils.Succeeded(hr))
{
s_amsiInitFailed = true;
return false;
}
}
Expand All @@ -1595,7 +1600,7 @@ internal static void CurrentDomain_ProcessExit(object sender, EventArgs e)
[SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
private static IntPtr s_amsiSession = IntPtr.Zero;

private static bool s_amsiInitFailed = false;
private static readonly bool s_amsiInitFailed = false;
private static bool s_amsiNotifyFailed = false;
Comment thread
suajose marked this conversation as resolved.
private static readonly object s_amsiLockObject = new object();

Expand Down
10 changes: 10 additions & 0 deletions src/System.Management.Automation/utils/tracing/PSEtwLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ internal static void LogProviderLifecycleEvent(LogContext logContext, string pro
provider.LogProviderLifecycleEvent(logContext, providerName, newState);
}

/// <summary>
/// Provider interface function for logging AmsiUtil State event.
/// </summary>
/// <param name="state">This the action performed in AmsiUtil class, like init, scan, etc.</param>
/// <param name="context">The amsiContext handled - Session pair.</param>
internal static void LogAmsiUtilStateEvent(string state, string context)
{
provider.LogAmsiUtilStateEvent(state, context);
}

/// <summary>
/// Provider interface function for logging settings event.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,17 @@ internal override void LogCommandLifecycleEvent(Func<LogContext> getLogContext,
}
else
{
payload.AppendLine(StringUtil.Format(EtwLoggingStrings.CommandStateChange, logContext.CommandName, newState.ToString()));
if (newState == CommandState.Stopped ||
newState == CommandState.Terminated)
{
// When state is stopped or termianted only log the CommandName
payload.AppendLine(StringUtil.Format(EtwLoggingStrings.CommandStateChange, logContext, newState.ToString()));
Comment thread
suajose marked this conversation as resolved.
}
else
{
// When state is Start log the CommandLine which has arguments for completeness.
payload.AppendLine(StringUtil.Format(EtwLoggingStrings.CommandStateChange, logContext.CommandLine, newState.ToString()));
}
}
}

Expand Down Expand Up @@ -182,6 +192,16 @@ internal override void LogProviderHealthEvent(LogContext logContext, string prov
WriteEvent(PSEventId.Provider_Health, PSChannel.Operational, PSOpcode.Exception, PSTask.ExecutePipeline, logContext, payload.ToString());
}

/// <summary>
/// Provider interface function for logging provider health event.
/// </summary>
/// <param name="state">This the action performed in AmsiUtil class, like init, scan, etc.</param>
/// <param name="context">The amsiContext handled - Session pair.</param>
internal override void LogAmsiUtilStateEvent(string state, string context)
{
WriteEvent(PSEventId.Amsi_Init, PSChannel.Analytic, PSOpcode.Method, PSLevel.Informational, PSTask.Amsi, (PSKeyword)0x0, state, context);
}

/// <summary>
/// Provider interface function for logging provider lifecycle event.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ internal override void LogEngineHealthEvent(LogContext logContext, int eventId,
WriteEvent(PSEventId.Engine_Health, PSChannel.Operational, PSOpcode.Exception, PSTask.ExecutePipeline, logContext, payload.ToString());
}

/// <summary>
/// Provider interface function for logging provider health event.
/// </summary>
/// <param name="state">This the action performed in AmsiUtil class, like init, scan, etc</param>
/// <param name="context">The amsiContext handled - Session pair</param>
internal override void LogAmsiUtilStateEvent(string state, string context)
{
WriteEvent(PSEventId.Amsi_Init, PSChannel.Analytic, PSOpcode.Method, PSLevel.Informational, PSTask.Amsi, (PSKeyword)0x0, state, context);
}

/// <summary>
/// Provider interface function for logging engine lifecycle event.
/// </summary>
Expand Down