microsoft / DbgShell

A PowerShell front-end for the Windows debugger engine.
MIT License
675 stars 89 forks source link

Trying to access an element of a `Span<byte>` throws a VerificationException #57

Closed jazzdelightsme closed 5 years ago

jazzdelightsme commented 5 years ago

Something is amiss with how PowerShell generates code to access a Span. (DbgShell currently uses Windows PowerShell 5.1 (latest Win10/.NET circa 1/1/2019).)

Repro steps:

ntna
$mem = dd $ip
$mem.GetMemory().Span
$mem.GetMemory().Span[ 0 ]

Expected result: The last command should give you the first byte in the memory block.

Actual result:

Operation could destabilize the runtime.
At line:4 char:1
+ $mem.GetMemory().Span[ 0 ]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], VerificationException
    + FullyQualifiedErrorId : System.Security.VerificationException

When searching for more info about this sort of exception, I found reports that indicate it is the kind of thing that can happen when the C# compiler accidentally generates unverifiable IL. In this case, it's not the C# compiler, of course; it's the PowerShell script interpreter/compiler or maybe the Dynamic stuff it uses.

Expanded error info:

AddedByShowError      : True
PSMessageDetails      :
Exception             : System.Security.VerificationException: Operation could destabilize the runtime.
                           at CallSite.Target(Closure , CallSite , Object , Int32 )
                           at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1
                        arg1)
                           at System.Management.Automation.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame)
                           at
                        System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame
                        frame)
TargetObject          :
CategoryInfo          : OperationStopped: (:) [], VerificationException
FullyQualifiedErrorId : System.Security.VerificationException
ErrorDetails          :
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 4
PipelineIterationInfo : {}

MyCommand             :
BoundParameters       : {}
UnboundArguments      : {}
ScriptLineNumber      : 4
OffsetInLine          : 1
HistoryId             : -1
ScriptName            :
Line                  : $mem.GetMemory().Span[ 0 ]

PositionMessage       : At line:4 char:1
                        + $mem.GetMemory().Span[ 0 ]
                        + ~~~~~~~~~~~~~~~~~~~~~~~~~~
PSScriptRoot          :
PSCommandPath         :
InvocationName        :
PipelineLength        : 0
PipelinePosition      : 0
ExpectingInput        : False
CommandOrigin         : Internal
DisplayScriptPosition :

00000000000000000000000000000000000000000000000000000000000000000000000000000000
ExceptionType : System.Security.VerificationException
Message        : Operation could destabilize the runtime.
Data           : {System.Management.Automation.Interpreter.InterpretedFrameInfo}
InnerException :
TargetSite     : System.Object CallSite.Target(System.Runtime.CompilerServices.Closure,
                 System.Runtime.CompilerServices.CallSite, System.Object, Int32)
StackTrace     :    at CallSite.Target(Closure , CallSite , Object , Int32 )
                    at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
                    at System.Management.Automation.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame)
                    at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame
                 frame)
HelpLink       :
Source         : Anonymously Hosted DynamicMethods Assembly
HResult        : -2146233075
0xd4d commented 5 years ago

I debugged this with VS and I see a BOXED ReadOnlySpan<byte>. Span<T>/ReadOnlySpan<T> are special types that can't be boxed and must only live on the stack.

Note that the following command using the latest open source powershell, shows a better error message:

[System.MemoryExtensions]::AsSpan("Hello")
Cannot invoke the method "AsSpan" of the ByRef-like return type "System.ReadOnlySpan`1[System.Char]". ByRef-like types are not supported in PowerShell.
At line:1 char:1
+ [System.MemoryExtensions]::AsSpan("Hello")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : CannotCallMethodWithByRefLikeReturnType
jazzdelightsme commented 5 years ago

Makes sense. Thanks @0xd4d !