[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Windows 0xEF Bugcheck Handler



Adds a bugcheck handler for 0xEF (CRITICAL_PROCESS_DIED) which dumps the
process image file name (if available)
Adds ProcessGetImageFileName() to get the image file name, which relies
on calling MmGetSystemRoutineAddress("PsGetProcessImageFileName")

Suggested-by: Rabish Kumar <rabish.kumar@xxxxxxxxxx>
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxx>
---
 src/xen/bug_check.c | 64 +++++++++++++++++++++++++++++++++++++++++++++
 src/xen/process.c   | 34 ++++++++++++++++++++++--
 src/xen/process.h   |  5 ++++
 3 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/src/xen/bug_check.c b/src/xen/bug_check.c
index e1da159..41b5f73 100644
--- a/src/xen/bug_check.c
+++ b/src/xen/bug_check.c
@@ -43,6 +43,7 @@
 #include "bug_check.h"
 #include "dbg_print.h"
 #include "assert.h"
+#include "process.h"
 
 static KBUGCHECK_CALLBACK_RECORD BugCheckBugCheckCallbackRecord;
 
@@ -1014,6 +1015,68 @@ BugCheckAssertionFailure(
     }
 }
 
+/// <summary>
+/// Bug check handler for critocal process died.
+/// 
https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/bug-check-0xef--critical-process-died
+/// </summary>
+/// <param name="Parameter1">process object.</param>
+/// <param name="Parameter2">If 0, a process terminated. If 1, a thread 
terminated.</param>
+/// <param name="Parameter3">reserved.</param>
+/// <param name="Parameter4">reserved.</param>
+static VOID
+BugCheckBugEFCriticalProcessDied(
+    IN  ULONG_PTR   Parameter1,
+    IN  ULONG_PTR   Parameter2,
+    IN  ULONG_PTR   Parameter3,
+    IN  ULONG_PTR   Parameter4
+    )
+{
+    __try {
+        ULONG_PTR       Code = Parameter2;
+        CONTEXT         Context;
+
+        UNREFERENCED_PARAMETER(Parameter3);
+        UNREFERENCED_PARAMETER(Parameter4);
+
+        switch (Code) {
+        case 0x0: {
+            PEPROCESS   EProcess = (PEPROCESS)Parameter1;
+            PCHAR       Name = ProcessGetImageFileName(EProcess);
+
+            if (Name == NULL)
+                Name = "(unknown)";
+
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: CRITICAL PROCESS: %p Name:%s DIED IRQL:%d 
\n",
+                      __MODULE__,
+                      EProcess,
+                      Name,
+                      KeGetCurrentIrql());
+            break;
+        }
+
+        case 0x1: {
+            PETHREAD    EThread = (PETHREAD)Parameter1;
+
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: CRITICAL THREAD: %p DIED IRQL:%d \n",
+                      __MODULE__,
+                      EThread,
+                      KeGetCurrentIrql());
+            break;
+        }
+
+        default:
+            break;
+        }
+
+        RtlCaptureContext(&Context);
+        BugCheckStackDump(&Context);
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Error of some kind
+    }
+}
+
 struct _BUG_CODE_ENTRY {
     ULONG       Code;
     const CHAR  *Name;
@@ -1035,6 +1098,7 @@ struct _BUG_CODE_ENTRY   BugCodeTable[] = {
     DEFINE_HANDLER(INACCESSIBLE_BOOT_DEVICE, BugCheckInaccessibleBootDevice),
     DEFINE_HANDLER(DRIVER_POWER_STATE_FAILURE, 
BugCheckDriverPowerStateFailure),
     DEFINE_HANDLER(ASSERTION_FAILURE, BugCheckAssertionFailure),
+    DEFINE_HANDLER(CRITICAL_PROCESS_DIED, BugCheckBugEFCriticalProcessDied),
     { 0, NULL, NULL }
 };
 
diff --git a/src/xen/process.c b/src/xen/process.c
index 4491196..2ba6599 100644
--- a/src/xen/process.c
+++ b/src/xen/process.c
@@ -40,8 +40,11 @@
 #include "dbg_print.h"
 #include "assert.h"
 
+typedef PCHAR (*GET_PROCESS_IMAGE_NAME)(PEPROCESS Process);
+
 typedef struct _PROCESS_CONTEXT {
-    LONG            References;
+    LONG                    References;
+    GET_PROCESS_IMAGE_NAME  PsGetProcFileName;
 } PROCESS_CONTEXT, *PPROCESS_CONTEXT;
 
 static PROCESS_CONTEXT  ProcessContext;
@@ -74,6 +77,24 @@ ProcessNotify(
     KeLowerIrql(Irql);
 }
 
+PCHAR
+ProcessGetImageFileName(
+    IN  PEPROCESS   Process
+    )
+{
+    PPROCESS_CONTEXT    Context = &ProcessContext;
+
+    if (Context->PsGetProcFileName == NULL)
+        goto fail1;
+
+    return Context->PsGetProcFileName(Process);
+
+fail1:
+    Error("Fail1 (process=%p)\n", Process);
+
+    return NULL;
+}
+
 VOID
 ProcessTeardown(
     VOID
@@ -81,6 +102,8 @@ ProcessTeardown(
 {
     PPROCESS_CONTEXT    Context = &ProcessContext;
 
+    Context->PsGetProcFileName = NULL;
+
     (VOID) PsSetCreateProcessNotifyRoutine(ProcessNotify, TRUE);
 
     (VOID) InterlockedDecrement(&Context->References);
@@ -90,11 +113,12 @@ ProcessTeardown(
 
 NTSTATUS
 ProcessInitialize(
-    VOID              
+    VOID
     )
 {
     PPROCESS_CONTEXT    Context = &ProcessContext;
     ULONG               References;
+    UNICODE_STRING      Unicode;
     NTSTATUS            status;
 
     References = InterlockedIncrement(&Context->References);
@@ -107,6 +131,12 @@ ProcessInitialize(
     if (!NT_SUCCESS(status))
         goto fail2;
 
+    RtlInitUnicodeString(&Unicode, L"PsGetProcessImageFileName");
+
+    Context->PsGetProcFileName = 
(GET_PROCESS_IMAGE_NAME)MmGetSystemRoutineAddress(&Unicode);
+    if (Context->PsGetProcFileName == NULL)
+        Warning("Unable to get PsGetProcessImageFileName Address\n");
+
     return STATUS_SUCCESS;
 
 fail2:
diff --git a/src/xen/process.h b/src/xen/process.h
index 3b0233e..d25c8f0 100644
--- a/src/xen/process.h
+++ b/src/xen/process.h
@@ -44,4 +44,9 @@ ProcessTeardown(
     VOID
     );
 
+extern PCHAR
+ProcessGetImageFileName(
+    IN  PEPROCESS   Process
+    );
+
 #endif  // _XEN_PROCESS_H
-- 
2.41.0.windows.3




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.