protected override UnifiedBlockingObject GetCriticalSectionBlockingObject(UnifiedStackFrame frame) { UnifiedBlockingObject result = null; var parameters = GetParameters(frame, ENTER_CRITICAL_SECTION_FUNCTION_PARAM_COUNT); var criticalSectionAddress = ConvertToAddress(parameters[0]); byte[] buffer = new byte[Marshal.SizeOf(typeof(CRITICAL_SECTION))]; int read; if (!_runtime.ReadMemory(criticalSectionAddress, buffer, buffer.Length, out read) || read != buffer.Length) throw new Exception($"Error reading critical section data from address: {criticalSectionAddress}"); var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned); try { CRITICAL_SECTION section = (CRITICAL_SECTION)Marshal.PtrToStructure( gch.AddrOfPinnedObject(), typeof(CRITICAL_SECTION)); result = new UnifiedBlockingObject(section, criticalSectionAddress); } finally { gch.Free(); } return result; }
protected override UnifiedBlockingObject GetCriticalSectionBlockingObject(UnifiedStackFrame frame) { var parameters = GetParameters(frame, ENTER_CRITICAL_SECTION_FUNCTION_PARAM_COUNT); var criticalSectionAddress = ConvertToAddress(parameters[0]); var section = ReadStructureFromAddress <CRITICAL_SECTION>(criticalSectionAddress); return(new UnifiedBlockingObject(section, criticalSectionAddress)); }
protected override void ExtractWaitForSingleObjectInformation(UnifiedStackFrame frame) { var parameters = GetParameters(frame, WAIT_FOR_SINGLE_OBJECT_PARAM_COUNT); if (parameters.Count > 0) { var handle = ConvertToAddress(parameters[0]); AddSingleWaitInformation(frame, handle); } }
protected override void ExtractWaitForMultipleObjectsInformation(UnifiedStackFrame frame) { var parameters = GetParameters(frame, WAIT_FOR_MULTIPLE_OBJECTS_PARAM_COUNT); if (parameters.Count > 0) { var numberOfHandles = BitConverter.ToUInt32(parameters[0], 0); var addressOfHandlesArray = ConvertToAddress(parameters[1]); AddMultipleWaitInformation(frame, numberOfHandles, addressOfHandlesArray); } }
internal override UnifiedBlockingObject GetNtDelayExecutionBlockingObject(UnifiedStackFrame frame) { var parameters = GetParameters(frame, NTDELAY_EXECUTION_FUNCTION_PARAM_COUNT); var largeIntegerAddress = ConvertToAddress(parameters[1]); var largeInt = ReadStructureFromAddress <Int64>(largeIntegerAddress); var awaitMs = (-largeInt) / 10000; return(new UnifiedBlockingObject(awaitMs)); }
public bool GetCriticalSectionBlockingObject(UnifiedStackFrame frame, out UnifiedBlockingObject blockingObject) { blockingObject = null; if (frame.Handles != null && IsMatchingMethod(frame, ENTER_CRITICAL_SECTION_FUNCTION_NAME)) { blockingObject = GetCriticalSectionBlockingObject(frame); } return(blockingObject != null); }
internal bool GetThreadSleepBlockingObject(UnifiedStackFrame frame, out UnifiedBlockingObject blockingObject) { blockingObject = null; if (IsMatchingMethod(frame, NTDELAY_EXECUTION_FUNCTION_NAME)) { blockingObject = GetNtDelayExecutionBlockingObject(frame); } return(blockingObject != null); }
protected void AddSingleWaitInformation(UnifiedStackFrame frame, ulong handleValue) { // TODO The process id can't be zero, or this will always fail! // Currently we are running the stack walker only for dump files, which means // we don't have an id to run DuplicateHandle against. var typeName = GetHandleType((IntPtr)handleValue, 0); var objectName = GetHandleObjectName((IntPtr)handleValue, 0); UnifiedHandle unifiedHandle = new UnifiedHandle(handleValue, typeName, objectName); frame.Handles.Add(unifiedHandle); }
private void FillFaultingThreadAndModuleInformation(CommandExecutionContext context) { UnifiedStackTrace stackTrace = new UnifiedStackTrace(_dbgEngTarget.DebuggerInterface, context); _triageInformation.TotalThreadCount = (int)stackTrace.NumThreads; _triageInformation.ManagedThreadCount = stackTrace.Threads.Count(t => t.IsManagedThread); LastEventInformation lastEventInformation = _dbgEngTarget.GetLastEventInformation(); if (lastEventInformation == null) { return; } ThreadInfo faultingThread = stackTrace.Threads.SingleOrDefault(t => t.OSThreadId == lastEventInformation.OSThreadId); if (faultingThread == null) { return; } _triageInformation.FaultingThreadOSID = faultingThread.OSThreadId; _triageInformation.IsFaultingThreadManaged = faultingThread.IsManagedThread; _triageInformation.EventDescription = lastEventInformation.EventDescription; if (lastEventInformation.ExceptionRecord.HasValue) { _triageInformation.ExceptionCode = lastEventInformation.ExceptionRecord.Value.ExceptionCode; } if (faultingThread.IsManagedThread && faultingThread.ManagedThread.CurrentException != null) { _triageInformation.ManagedExceptionType = faultingThread.ManagedThread.CurrentException.Type.Name; } var frames = stackTrace.GetStackTrace(faultingThread.Index); UnifiedStackFrame faultingFrame = frames.FirstOrDefault(f => f.Module != null && !WellKnownMicrosoftModules.Contains(f.Module)); if (faultingFrame != null) { _triageInformation.FaultingModule = faultingFrame.Module; _triageInformation.FaultingMethod = faultingFrame.Method; } if (ShowFaultingStack) { context.WriteLine("Faulting call stack:"); stackTrace.PrintStackTrace(context, frames); } }
protected void AddMultipleWaitInformation(UnifiedStackFrame frame, uint numberOfHandles, ulong addressOfHandlesArray) { if (numberOfHandles > MAXIMUM_WAIT_OBJECTS) { numberOfHandles = MAXIMUM_WAIT_OBJECTS; } var handles = ReadHandles(addressOfHandlesArray, numberOfHandles); foreach (var handleBytes in handles) { ulong handleValue = ConvertToAddress(handleBytes); AddSingleWaitInformation(frame, handleValue); } }
private List <byte[]> GetParameters(UnifiedStackFrame stackFrame, int paramCount) { List <byte[]> result = new List <byte[]>(); var offset = stackFrame.FramePointer + 4; // Parameters start at EBP + 4 int bytesRead = 0; for (int i = 0; i < paramCount; i++) { byte[] paramBuffer = new byte[IntPtr.Size]; offset += (uint)IntPtr.Size; if (_runtime.ReadMemory(offset, paramBuffer, paramBuffer.Length, out bytesRead)) { result.Add(paramBuffer); } } return(result); }
public bool SetFrameParameters(UnifiedStackFrame frame) { if (IsMatchingMethod(frame, WAIT_FOR_SINGLE_OBJECT_FUNCTION_NAME) || IsMatchingMethod(frame, WAIT_FOR_SINGLE_OBJECT_EX_FUNCTION_NAME)) { ExtractWaitForSingleObjectInformation(frame); return(true); } if (IsMatchingMethod(frame, WAIT_FOR_MULTIPLE_OBJECTS_FUNCTION_NAME) || IsMatchingMethod(frame, WAIT_FOR_MULTIPLE_OBJECTS_EX_FUNCTION_NAME)) { ExtractWaitForMultipleObjectsInformation(frame); return(true); } return(false); }
private List<byte[]> GetParameters(UnifiedStackFrame stackFrame, int paramCount) { List<byte[]> result = new List<byte[]>(); var offset = stackFrame.FramePointer + 4; // Parameters start at EBP + 4 int bytesRead = 0; for (int i = 0; i < paramCount; i++) { byte[] paramBuffer = new byte[IntPtr.Size]; offset += (uint)IntPtr.Size; if (_runtime.ReadMemory(offset, paramBuffer, paramBuffer.Length, out bytesRead)) { result.Add(paramBuffer); } } return result; }
private bool IsMatchingMethod(UnifiedStackFrame frame, string key) { return frame?.Method == key; }
protected abstract void ExtractWaitForSingleObjectInformation(UnifiedStackFrame frame);
protected abstract void ExtractWaitForMultipleObjectsInformation(UnifiedStackFrame frame);
protected abstract UnifiedBlockingObject GetCriticalSectionBlockingObject(UnifiedStackFrame frame);
protected void AddMultipleWaitInformation(UnifiedStackFrame frame, uint numberOfHandles, ulong addressOfHandlesArray) { if (numberOfHandles > MAXIMUM_WAIT_OBJECTS) numberOfHandles = MAXIMUM_WAIT_OBJECTS; var handles = ReadHandles(addressOfHandlesArray, numberOfHandles); foreach (var handleBytes in handles) { ulong handleValue = ConvertToAddress(handleBytes); AddSingleWaitInformation(frame, handleValue); } }
public bool SetFrameParameters(UnifiedStackFrame frame) { if (IsMatchingMethod(frame, WAIT_FOR_SINGLE_OBJECT_FUNCTION_NAME) || IsMatchingMethod(frame, WAIT_FOR_SINGLE_OBJECT_EX_FUNCTION_NAME)) { ExtractWaitForSingleObjectInformation(frame); return true; } if (IsMatchingMethod(frame, WAIT_FOR_MULTIPLE_OBJECTS_FUNCTION_NAME) || IsMatchingMethod(frame, WAIT_FOR_MULTIPLE_OBJECTS_EX_FUNCTION_NAME)) { ExtractWaitForMultipleObjectsInformation(frame); return true; } return false; }
public bool GetCriticalSectionBlockingObject(UnifiedStackFrame frame, out UnifiedBlockingObject blockingObject) { bool result = false; if (frame.Handles != null && IsMatchingMethod(frame, ENTER_CRITICAL_SECTION_FUNCTION_NAME)) { blockingObject = GetCriticalSectionBlockingObject(frame); result = blockingObject != null; } else { blockingObject = null; } return result; }
internal abstract UnifiedBlockingObject GetNtDelayExecutionBlockingObject(UnifiedStackFrame frame);
private bool IsMatchingMethod(UnifiedStackFrame frame, string key) { return(frame?.Method == key); }