private static int ConnectDebuggerDumpHelper(DebugUtilities debugUtilities, string dumpFile, out SimpleDebugger debuggerInformation) { int hr; SimpleOutputHandler debuggerOutputCallbacks = null; SimpleEventHandler debuggerEventCallbacks = null; debuggerInformation = null; hr = SimpleOutputHandler.Install(debugUtilities, out debuggerOutputCallbacks); if (hr != S_OK) { goto Error; } hr = SimpleEventHandler.Install(debugUtilities, out debuggerEventCallbacks); if (hr != S_OK) { goto ErrorWithDetach; } hr = debugUtilities.DebugClient.OpenDumpFileWide(dumpFile, 0); if (FAILED(hr)) { goto ErrorWithDetach; } while (debuggerEventCallbacks.SessionIsActive == false) { hr = debugUtilities.DebugControl.WaitForEvent(DEBUG_WAIT.DEFAULT, 50); if (FAILED(hr)) { goto ErrorWithDetach; } } debuggerInformation = new SimpleDebugger(debugUtilities, 0, true, debuggerOutputCallbacks, debuggerEventCallbacks); goto Exit; ErrorWithDetach: debugUtilities.DebugClient.DetachProcesses(); debugUtilities.DebugClient.EndSession(DEBUG_END.ACTIVE_DETACH); Error: if (debuggerEventCallbacks != null) { debuggerEventCallbacks.Dispose(); } if (debuggerOutputCallbacks != null) { debuggerOutputCallbacks.Dispose(); } Exit: return(hr); }
public ListEntryEnumerator(ulong head, int entryOffset, bool skipListHead, DebugUtilities d) { _d = d; _head = head; _entryOffset = entryOffset; _isDisposed = false; _skipListHead = skipListHead; _headEnumerated = false; Reset(); }
/// <summary> /// Remove the output handler and restore the previously installed handler. /// If we ever get into a situation where we are reverting but not the active output handler we will not overwrite the /// current handler and will never restore the original handler! /// </summary> private void Dispose(bool disposing) { if (disposing == true) { if (Installed) { Flush(); Installed = false; } IntPtr currentCallbacks = IntPtr.Zero; if (ExecutionUtilities != null) { ExecutionUtilities.DebugClient.GetOutputCallbacksWide(out currentCallbacks); /* Will need to release this */ if (currentCallbacks == ThisIDebugOutputCallbacksPtr) { ExecutionUtilities.DebugClient.SetOutputCallbacksWide(PreviousCallbacks); } if (currentCallbacks != IntPtr.Zero) { Marshal.Release(currentCallbacks); currentCallbacks = IntPtr.Zero; } if (PreviousCallbacks != IntPtr.Zero) { Marshal.Release(PreviousCallbacks); PreviousCallbacks = IntPtr.Zero; } if (ThisIDebugOutputCallbacksPtr != IntPtr.Zero) { Marshal.Release(ThisIDebugOutputCallbacksPtr); ThisIDebugOutputCallbacksPtr = IntPtr.Zero; } ExecutionUtilities = null; /* No need to release, just a copy of what was sent in */ } if (LogFile != null) { LogFile.Dispose(); LogFile = null; } foreach (BufferLine line in BufferedOutput) { line.OutputLine(PassthroughUtilities); } BufferedOutput.Clear(); } }
/// <summary> /// Create a debugging connection to a process /// </summary> /// <param name="processID">The ID of the process to attach to</param> /// <param name="passive">Whether the debugger connection should be passive</param> /// <param name="debuggerInformation">An SimpleDebugger instance which contains connection information. Call Dispose() on this object.</param> /// <returns>HRESULT of the creation process</returns> public static int ConnectDebugger(uint processID, bool passive, out SimpleDebugger debuggerInformation) { IDebugClient debugClient = null; int hr = DebugCreate_IDebugClient(typeof(IDebugClient).GUID, out debugClient); if (FAILED(hr)) { debuggerInformation = null; return(hr); } else { DebugUtilities debugUtilities = new DebugUtilities(debugClient); return(ConnectDebuggerLiveHelper(debugUtilities, processID, passive, out debuggerInformation)); } }
//FIX ME!!! This is a hack due to Win8:235420 private void PassThroughLine(CallbackData cbd) { if (string.IsNullOrEmpty(cbd.Data?.ToString())) { return; } if (_reEnter == false) { _reEnter = true; if (cbd.Mask.HasFlag(DEBUG_OUTPUT.ADDR_TRANSLATE) && cbd.Mask.HasFlag(DEBUG_OUTPUT.NORMAL | DEBUG_OUTPUT.ERROR | DEBUG_OUTPUT.WARNING | DEBUG_OUTPUT.VERBOSE) == false) { cbd.Mask = cbd.Mask | DEBUG_OUTPUT.NORMAL; } try { if (_installedThreadId == Thread.CurrentThread.ManagedThreadId) { foreach (var bufferLine in _bufferedOutput) { bufferLine.Data.Insert(0, "BUFFERED "); bufferLine.OutputLineMaskDisabled(_passthroughUtilities); } _bufferedOutput.Clear(); cbd.OutputLineMaskDisabled(_passthroughUtilities); } else { _bufferedOutput.Add(cbd); } } catch { DebugUtilities.CoUninitialize(); if (_installedThreadId == Thread.CurrentThread.ManagedThreadId) { cbd.OutputLineMaskDisabled(_passthroughUtilities); } else { _bufferedOutput.Add(cbd); } } _reEnter = false; } }
/// <summary> /// Creates a new SimpleOutputHandler instances and sets it as the active handler for the debugger. /// </summary> /// <param name="debugUtilities">A DebugUtilities associated with the debugger.</param> /// <param name="executionUtilities"> /// An utilities associated with the output handler. This interface should be used for all /// actions where output should be redirected to the output handler. /// </param> /// <param name="outputCallbacks"> /// An out parameter to receive the new SimpleOutputHandler. CALL Revert AND/OR Dipose TO /// REMOVE! /// </param> /// <param name="filter">An optional filter object to process the output data.</param> /// <param name="passThrough"> /// Whether the output data should be passed to the previously installed output handler. Default /// is to cache locally only. /// </param> /// <param name="passThroughOnly"> /// Disables local caching of output data. Save memory and is more effient when the primary /// goes it to pass the output data to the previously installed output handled (normally WinDbg). /// </param> /// <returns>Last HRESULT of the install process.</returns> public static int Install(DebugUtilities debugUtilities, out DebugUtilities executionUtilities, out SimpleOutputHandler outputCallbacks, OUTPUT_FILTER filter = null, bool passThrough = false, bool passThroughOnly = false) { IDebugClient executionClient; int hr = debugUtilities.DebugClient.CreateClient(out executionClient); if (FAILED(hr)) { debugUtilities.OutputVerboseLine("SimpleOutputHandler.Install Failed creating a new debug client for execution: {0:x8}", hr); outputCallbacks = null; executionUtilities = null; return(hr); } executionUtilities = new DebugUtilities(executionClient); var oc = new SimpleOutputHandler(executionUtilities, debugUtilities, filter, passThrough, passThroughOnly); outputCallbacks = SUCCEEDED(oc.InstallationHRESULT) ? oc : null; return(oc.InstallationHRESULT); }
/// <summary> /// Creates a new SimpleOutputHandler instances and sets it as the active handler for the debugger. /// </summary> /// <param name="debugUtilities">A DebugUtilities associated with the debugger.</param> /// <param name="executionUtilities"> /// An utilities associated with the output handler. This interface should be used for all /// actions where output should be redirected to the output handler. /// </param> /// <param name="outputCallbacks"> /// An out parameter to receive the new SimpleOutputHandler. CALL Revert AND/OR Dipose TO /// REMOVE! /// </param> /// <param name="filter">An optional filter object to process the output data.</param> /// <param name="wantsDml">Whether DML should be accepted.</param> /// <param name="passThrough"> /// Whether the output data should be passed to the previously installed output handler. Default /// is to cache locally only. /// </param> /// <param name="passThroughOnly"> /// Disables local caching of output data. Save memory and is more effient when the primary /// goes it to pass the output data to the previously installed output handled (normally WinDbg). /// </param> /// <returns>Last HRESULT of the install process.</returns> public static int Install(DebugUtilities debugUtilities, out DebugUtilities executionUtilities, out SimpleOutputHandler2 outputCallbacks, OUTPUT_FILTER filter = null, bool wantsDml = true, bool passThrough = false, bool passThroughOnly = false) { IDebugClient executionClient; executionUtilities = new DebugUtilities(out executionClient); if (executionClient == null) { debugUtilities.OutputVerboseLine("SimpleOutputHandler.Install Failed creating a new debug client for execution"); outputCallbacks = null; executionUtilities = null; return(E_FAIL); } executionUtilities.IsFiltered = true; debugUtilities.IsFiltered = true; var oc = new SimpleOutputHandler2(executionUtilities, debugUtilities, filter, wantsDml, passThrough, passThroughOnly); outputCallbacks = SUCCEEDED(oc.InstallationHRESULT) ? oc : null; return(oc.InstallationHRESULT); }
/// <summary> /// Create a debugging connection to a process /// </summary> /// <param name="processName">The name of the process to attach to</param> /// <param name="passive">Whether the debugger connection should be passive</param> /// <param name="debuggerInformation">An SimpleDebugger instance which contains connection information. Call Dispose() on this object.</param> /// <returns>HRESULT of the creation process</returns> public static int ConnectDebugger(string processName, bool passive, out SimpleDebugger debuggerInformation) { IDebugClient debugClient = null; int hr = DebugCreate_IDebugClient(typeof(IDebugClient).GUID, out debugClient); if (FAILED(hr)) { debuggerInformation = null; return(hr); } uint processID = 0; hr = debugClient.GetRunningProcessSystemIdByExecutableName(0, processName, 0, out processID); if (FAILED(hr)) { goto Error; } DebugUtilities debugUtilities = new DebugUtilities(debugClient); hr = ConnectDebuggerLiveHelper(debugUtilities, processID, passive, out debuggerInformation); if (FAILED(hr)) { goto Error; } goto Exit; Error: if (debugClient != null) { ReleaseComObjectSafely(debugClient); } debuggerInformation = null; Exit: return(hr); }
/// <summary> /// Detaches from the target process /// </summary> public void Detach(bool detaching) { if (Detached == false && detaching == true) { if (OutputHandler != null) { OutputHandler.Dispose(); _OutputHandler = null; } if (EventHandler != null) { EventHandler.Dispose(); _EventHandler = null; } if (OriginatingDebugUtilities != null) { OriginatingDebugUtilities.DebugClient.DetachProcesses(); OriginatingDebugUtilities.DebugClient.EndSession(DEBUG_END.ACTIVE_DETACH); DebugUtilities.ReleaseComObjectSafely(OriginatingDebugUtilities); _OriginatingDebugUtilities = null; } Detached = true; } }
private void Dispose(bool disposing) { if (_installed && disposing) { _installed = false; IntPtr currentCallbacks = IntPtr.Zero; _utilities.DebugClient.GetEventCallbacks(out currentCallbacks); /* We need to release this */ if (this == Marshal.GetObjectForIUnknown(currentCallbacks)) { _utilities.DebugClient.SetEventCallbacks(_previousCallbacks); } if (_previousCallbacks != IntPtr.Zero) { Marshal.Release(_previousCallbacks); _previousCallbacks = IntPtr.Zero; } if (currentCallbacks != IntPtr.Zero) { Marshal.Release(currentCallbacks); currentCallbacks = IntPtr.Zero; } _utilities = null; } }
public int OutputLine(DebugUtilities d) { if (string.IsNullOrEmpty(Data.ToString())) { return(S_OK); } DEBUG_OUTCTL outctl; if (d.IsFirstCommand) { outctl = DEBUG_OUTCTL.ALL_CLIENTS; } else { outctl = DEBUG_OUTCTL.THIS_CLIENT | DEBUG_OUTCTL.NOT_LOGGED; } if (IsDML) { outctl |= DEBUG_OUTCTL.DML; } return(d.ControlledOutputWide(outctl, Mask, Data.ToString())); }
public void SetDebugUtilities(DebugUtilities d) { _utilities = d; }
/// <summary> /// Appends a formatted string to the end of the buffer /// </summary> /// <param name="provider">Format provider</param> /// <param name="format">Format string</param> /// <param name="args">Arguments</param> /// <returns>The DbgStringBuilder instance</returns> public DbgStringBuilder AppendFormatEscaped(IFormatProvider provider, string format, params object[] args) { _sb.Append(DebugUtilities.EncodeTextForXml(_utilities.FormatString(provider, format, args))); return(this); }
/// <summary> /// Appends an items to the end of the buffer followed by a newline, with XML special characters escaped /// </summary> /// <param name="addition">Value to insert</param> /// <returns>The DbgStringBuilder instance</returns> public DbgStringBuilder AppendLineEscaped(string addition) { _sb.Append(DebugUtilities.EncodeTextForXml(addition)); _sb.Append('\n'); return(this); }
/// <summary> /// Constructor /// </summary> /// <param name="debugUtilities">A DebugUtilities associated with the debugger.</param> /// <param name="initialSize">Initial size of the buffer in characters</param> public DbgStringBuilder(DebugUtilities debugUtilities, int initialSize) { _sb = new StringBuilder(initialSize); _utilities = debugUtilities; }
/// <summary> /// Constructor /// </summary> /// <param name="debugUtilities">A DebugUtilities associated with the debugger.</param> public DbgStringBuilder(DebugUtilities debugUtilities) { _sb = new StringBuilder(); _utilities = debugUtilities; }
private static bool DecodePointerArguments(DebugUtilities d, string format, object param, out string outputString) { // fast exit code outputString = null; if (format[0] != 'p' && format[0] != 'P' && format[0] != 'q' && format[0] != 'Q') { return(false); } switch (format[0]) { case 'p': { if (param == null) { outputString = "(null)"; return(true); } try { outputString = d.P2S((ulong)param); break; } catch { if (format.Length == 1) { throw new Exception("Could not convert " + param + " to UInt64 for {x:p}"); } return(false); } } case 'P': { if (param == null) { outputString = "(NULL)"; return(true); } try { outputString = d.P2SUC((ulong)param); break; } catch { if (format.Length == 1) { throw new Exception("Could not convert " + param + " to UInt64 for {x:P}"); } return(false); } } case 'q': { if (param == null) { outputString = "(null)"; return(true); } try { outputString = d.P2S((ulong)param, true); break; } catch { if (format.Length == 1) { throw new Exception("Could not convert " + param + " to UInt64 for {x:q}"); } return(false); } } case 'Q': { if (param == null) { outputString = "(NULL)"; return(true); } try { outputString = d.P2SUC((ulong)param, true); break; } catch { if (format.Length == 1) { throw new Exception("Could not convert " + param + " to UInt64 for {x:Q}"); } return(false); } } } if (format.Length == 1) { return(true); } if (outputString == null) { return(false); } var sb = new StringBuilder(16); bool leftAlign; int desiredWidth; if (!int.TryParse(format.Substring(1), out desiredWidth)) { outputString = null; return(false); } if (desiredWidth < 0) { desiredWidth = -desiredWidth; leftAlign = true; } else { leftAlign = false; } var spacesToAdd = desiredWidth - outputString.Length; if (spacesToAdd > 0) { if (leftAlign) { sb.Append(outputString); sb.Append(' ', spacesToAdd); } else { sb.Append(' ', spacesToAdd); sb.Append(outputString); } } else { sb.Append(outputString); } outputString = sb.ToString(); return(true); }
private static int ConnectDebuggerLiveHelper(DebugUtilities debugUtilities, uint processID, bool passive, out SimpleDebugger debuggerInformation) { int hr; IDebugControl debugControl = null; IDebugSystemObjects debugSystemObjects = null; SimpleOutputHandler debuggerOutputCallbacks = null; SimpleEventHandler debuggerEventCallbacks = null; debuggerInformation = null; hr = SimpleOutputHandler.Install(debugUtilities, out debuggerOutputCallbacks); if (hr != S_OK) { goto Error; } hr = SimpleEventHandler.Install(debugUtilities, out debuggerEventCallbacks); if (hr != S_OK) { goto ErrorWithDetach; } DEBUG_ATTACH attachFlags = passive ? DEBUG_ATTACH.NONINVASIVE | DEBUG_ATTACH.NONINVASIVE_NO_SUSPEND : DEBUG_ATTACH.INVASIVE_RESUME_PROCESS; hr = debugUtilities.DebugClient.AttachProcess(0, processID, attachFlags); if (hr != S_OK) { goto ErrorWithDetach; } while (debuggerEventCallbacks.SessionIsActive == false) { hr = debugControl.WaitForEvent(DEBUG_WAIT.DEFAULT, 50); if (FAILED(hr)) { goto ErrorWithDetach; } } bool foundMatchingProcess = false; uint numProcesses; debugSystemObjects.GetNumberProcesses(out numProcesses); uint[] systemProcessIDs = new uint[numProcesses]; uint[] engineProcessIDs = new uint[numProcesses]; hr = debugSystemObjects.GetProcessIdsByIndex(0, numProcesses, engineProcessIDs, systemProcessIDs); for (uint i = 0; i < numProcesses; ++i) { if (systemProcessIDs[i] == processID) { foundMatchingProcess = true; hr = debugSystemObjects.SetCurrentProcessId(engineProcessIDs[i]); if (FAILED(hr)) { debuggerOutputCallbacks.AddNoteLine(String.Format(CultureInfo.InvariantCulture, "ERROR! Failed to set the active process! hr={0:x8}", hr)); goto ErrorWithDetach; } break; } } if (foundMatchingProcess == false) { hr = E_FAIL; debuggerOutputCallbacks.AddNoteLine(String.Format(CultureInfo.InvariantCulture, "ERROR! The debugger engine could not find the requested process ID ({0})!", processID)); goto ErrorWithDetach; } debuggerInformation = new SimpleDebugger(debugUtilities, processID, passive, debuggerOutputCallbacks, debuggerEventCallbacks); goto Exit; ErrorWithDetach: debugUtilities.DebugClient.DetachProcesses(); debugUtilities.DebugClient.EndSession(DEBUG_END.ACTIVE_DETACH); Error: if (debuggerEventCallbacks != null) { debuggerEventCallbacks.Dispose(); } if (debuggerOutputCallbacks != null) { debuggerOutputCallbacks.Dispose(); } Exit: return(hr); }
public int OutputLine(DebugUtilities d) { return(d.ControlledOutputWide(_outputControl, _mask, _data)); }
public static List <ulong> EnumerateHashTable(DebugUtilities d, StructSymbolPlus HashTable) { // typedef struct _RTL_DYNAMIC_HASH_TABLE // { // // // Entries initialized at creation // ULONG Flags; // ULONG Shift; // // // Entries used in bucket computation. // ULONG TableSize; // ULONG Pivot; // ULONG DivisorMask; // // // Counters // ULONG NumEntries; // ULONG NonEmptyBuckets; // ULONG NumEnumerators; // // // The directory. This field is for internal use only. // PVOID Directory; // // } // RTL_DYNAMIC_HASH_TABLE, *PRTL_DYNAMIC_HASH_TABLE; var entries = new List <ulong>(); var tableSize = HashTable.GetFieldValue("TableSize"); ulong secondLevelDir = 0; ulong dirIndex = 0; ulong secondLevelIndex = 0; ulong bucket = 0; ulong pDirectory = 0; uint indirection = 0; if (tableSize <= KDEXT_RTL_HT_SECOND_LEVEL_DIR_SIZE) { indirection = BUCKET_ARRAY; } else { indirection = FIRST_LEVEL_DIR; // First level dir } pDirectory = HashTable.GetFieldValue("Directory"); for (bucket = 0; bucket < tableSize; bucket++) { ComputeDirIndices(bucket, out dirIndex, out secondLevelIndex); if (0 == secondLevelIndex) { if (indirection == BUCKET_ARRAY) { secondLevelDir = pDirectory; } else // FIRST_LEVEL_DIR { var hr = d.ReadPointer(pDirectory + (dirIndex * d.PointerSize()), out secondLevelDir); if (DebugUtilities.FAILED(hr)) { d.OutputErrorLine("Failed to read second-level dir 0x{0:x}\n", dirIndex); break; } } } // // Read the list head // var bucketHead = secondLevelDir + secondLevelIndex * (2 * d.PointerSize()); var bucketEntries = d.WalkList(bucketHead); entries.AddRange(bucketEntries); } foreach (var entry in entries) { //d.OutputDMLLine("Hash entry: 0x{0:x}", "!ddt netio!WFP_HASH_ENTRY 0x{0:x}", entry); } return(entries); }
public int OutputLine(DebugUtilities d) { return(d.ControlledOutputWide(OutputControl, Mask, Data)); }
public DMLInterceptProvider(DebugUtilities d) { _d = d; }