【问题标题】:Determine the root cause of a System.AccessViolationException确定 System.AccessViolationException 的根本原因
【发布时间】:2021-05-17 22:11:58
【问题描述】:

我已经查看了与此问题相关的其他问题,特别是 Finding the cause of System.AccessViolationException,但也许还有其他问题可以查看。

我有一个 powershell 脚本,在 windows 10 1909 上的 psversion v5.1 下运行,当它尝试使用以下调用检索用户的 kerberos TGT 时,该脚本会始终使 powershell 崩溃并出现此异常:

$SUCCESS = $Secur32::LsaCallAuthenticationPackage_KERB_QUERY_TKT_CACHE($LsaHandle, $AuthenticationPackage, [ref]$ProtocolSubmitBuffer, $KERB_QUERY_TKT_CACHE_REQUEST::GetSize(), [ref]$ProtocolReturnBuffer, [ref]$ReturnBufferLength, [ref]$ProtocolStatus)

如果我在 powershell 控制台或 ISE 中以交互方式运行脚本,它会毫无问题地运行并检索用户的 TGT。当通过在同一用户下运行的批处理调用同一脚本时,它会在事件查看器中获得以下 .net 异常。

Application: powershell.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.AccessViolationException
at Kerberos.secur32.LsaCallAuthenticationPackage_KERB_QUERY_TKT_CACHE(IntPtr, UInt64, KERB_QUERY_TKT_CACHE_REQUEST ByRef, UInt64, IntPtr ByRef, UInt64 ByRef, UInt32 ByRef)
at DynamicClass.CallSite.Target(System.Runtime.CompilerServices.Closure, System.Runtime.CompilerServices.CallSite, System.Object, System.Object, System.Object, System.Management.Automation.PSReference, System.Object, System.Management.Automation.PSReference, System.Management.Automation.PSReference, System.Management.Automation.PSReference)
at System.Dynamic.UpdateDelegates.UpdateAndExecute8[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.Runtime.CompilerServices.CallSite, System.__Canon, System.__Canon, System.__Canon, System.__Canon, System.__Canon, System.__Canon, System.__Canon, System.__Canon)
at System.Management.Automation.Interpreter.DynamicInstruction`9[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.Interpreter.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.__Canon)
at System.Management.Automation.PSScriptCmdlet.RunClause(System.Action`1<System.Management.Automation.Language.FunctionContext>, System.Object, System.Object)
at System.Management.Automation.PSScriptCmdlet.DoEndProcessing()
at System.Management.Automation.CommandProcessorBase.Complete()
at System.Management.Automation.CommandProcessorBase.DoComplete()
at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(System.Management.Automation.CommandProcessorBase)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(System.Object)
at System.Management.Automation.PipelineOps.InvokePipeline(System.Object, Boolean, System.Management.Automation.CommandParameterInternal[][], System.Management.Automation.Language.CommandBaseAst[], System.Management.Automation.CommandRedirection[][], System.Management.Automation.Language.FunctionContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.Interpreter.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.__Canon)
at System.Management.Automation.PSScriptCmdlet.RunClause(System.Action`1<System.Management.Automation.Language.FunctionContext>, System.Object, System.Object)
at System.Management.Automation.PSScriptCmdlet.DoEndProcessing()
at System.Management.Automation.CommandProcessorBase.Complete()
at System.Management.Automation.CommandProcessorBase.DoComplete()
at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(System.Management.Automation.CommandProcessorBase)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(System.Object)
at System.Management.Automation.PipelineOps.InvokePipeline(System.Object, Boolean, System.Management.Automation.CommandParameterInternal[][], System.Management.Automation.Language.CommandBaseAst[], System.Management.Automation.CommandRedirection[][], System.Management.Automation.Language.FunctionContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.Interpreter.Run(System.Management.Automation.Interpreter.InterpretedFrame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.__Canon)
at System.Management.Automation.DlrScriptCommandProcessor.RunClause(System.Action`1<System.Management.Automation.Language.FunctionContext>, System.Object, System.Object)
at System.Management.Automation.DlrScriptCommandProcessor.Complete()
at System.Management.Automation.CommandProcessorBase.DoComplete()
at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(System.Management.Automation.CommandProcessorBase)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(System.Object)
at System.Management.Automation.Runspaces.LocalPipeline.InvokeHelper()
at System.Management.Automation.Runspaces.LocalPipeline.InvokeThreadProc()
at System.Management.Automation.Runspaces.PipelineThread.WorkerProc()
at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart()

我尝试将 PS 调试器附加到脚本进程,并且在调用之前正确设置了所有变量,并且我已经查看了函数签名类型、结构、枚举等,但我很难过。此堆栈跟踪中是否有任何内容可以揭示根本原因?

【问题讨论】:

  • 这很像找到NullReferenceException 的根本原因:代码设置不正确,因此整个事情以访问冲突结束,可以任意远离调用站点。如果幸运的话,代码离调用站点很近,只是无法检查分配缓冲区或类似的错误。您需要查看整个 代码,而不是这一行。首先在调用之前打印参数值。如果您不调试解释器本身(这可能不是这里的问题),PowerShell 代码的托管堆栈跟踪将毫无用处。
  • @JeroenMostert 如果调用的任何参数为空,如果在调试器中打印,您是否希望 powershell 显示它们?我已经打印了这个调用的每个输入/输出参数,并且都有预期的值,并且没有一个为空,但是,$ProtocolReturnBuffer 设置为 [IntPtr]::Zero,因为该函数旨在将其设置为返回时的有效指针。
  • $null 值默认情况下不会打印为任何内容,不。如果所有参数都有一个开始的值,但是您不能仅从值中判断(例如)指向缓冲区和大小的指针是否有效,或者是否由于不正确的调用而发生了较早的堆损坏。调试本质上除了调用本机函数什么都不做的 PS 代码是一件痛苦的事情。您可能需要考虑在 C# 中编写此位,因为如果不出意外,互操作和调试体验会更好(例如,您可以使用托管调试助手来捕获一些互操作错误)。

标签: .net powershell reflection kerberos windows-10-desktop


【解决方案1】:

这个特定问题的根本原因与代码无关。根本原因恰好是从 32 位 cmd.exe 调用了 powershell 脚本。显然这个特定的 win32 api 调用只能从 64 位进程访问,所以我使用How to launch 64-bit powershell from 32-bit cmd.exe? 提供的信息来解决这个问题。我发布此回复是为了帮助可能遇到相同问题的其他人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-05
    • 2012-01-10
    • 2012-10-29
    • 1970-01-01
    • 2019-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多