pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


catdbgprint.c - print Windows kernel |DbgPrint()| messages
Posted by Anonymous on Tue 2nd Dec 2025 21:13
raw | new post

  1. /*
  2.  * MIT License
  3.  *
  4.  * Copyright (c) 2024-2025 Roland Mainz <roland.mainz@nrubsig.org>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a copy
  7.  * of this software and associated documentation files (the "Software"), to deal
  8.  * in the Software without restriction, including without limitation the rights
  9.  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10.  * copies of the Software, and to permit persons to whom the Software is
  11.  * furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included in
  14.  * all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19.  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22.  * SOFTWARE.
  23.  */
  24.  
  25. /*
  26.  * catdbgprint.c - print Windows kernel |DbgPrint()| messages
  27.  *
  28.  * Written by Roland Mainz <roland.mainz@nrubsig.org>
  29.  */
  30.  
  31. /*
  32.  * Compile with:
  33.  * clang -target x86_64-pc-windows-gnu -Wall -Wextra -DUNICODE=1 -D_UNICODE=1 -g catdbgprint.c -o catdbgprint.exe
  34.  */
  35.  
  36. #include <windows.h>
  37. #include <evntrace.h>
  38. #include <evntcons.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <ctype.h>
  42.  
  43. typedef struct _DBGPRINT_EVENT {
  44.     ULONG ComponentId;   /* DPFLTR_xxx_ID */
  45.     ULONG Level;         /* DPFLTR_LEVEL_xxx */
  46.     CHAR  Message[];     /* '\0'-terminated ANSI string */
  47. } DBGPRINT_EVENT;
  48.  
  49. static
  50. void int_to_octal3(int value, char *restrict out)
  51. {
  52.     if (value < 0)
  53.         value = 0;
  54.     if (value > 0777)
  55.         value = 0777; /* clamp to max 0777/511 */
  56.  
  57.     out[2] = (char)('0' + (value & 7));
  58.     out[1] = (char)('0' + ((value >> 3) & 7));
  59.     out[0] = (char)('0' + ((value >> 6) & 7));
  60. }
  61.  
  62. static
  63. VOID WINAPI EventCallback(PEVENT_RECORD ev)
  64. {
  65.     char buffer[2048];
  66.     char *b = buffer;
  67.  
  68.     if (ev->UserDataLength > 0) {
  69.         int i;
  70.         int c;
  71.         const DBGPRINT_EVENT *dpe = (const DBGPRINT_EVENT *)ev->UserData;
  72.         const char *msg = dpe->Message;
  73.  
  74.         for (i=0 ; ; i++) {
  75.             if ((msg[i] == '\0') ||
  76.                 ((msg[i] == '\n') && (msg[i+1] == '\0')))
  77.                 break;
  78.  
  79.             c = msg[i];
  80.  
  81.             if (c == '\n') {
  82.                 *b++ = '\\';
  83.                 *b++ = 'n';
  84.             }
  85.             else if (c == '\v') {
  86.                 *b++ = '\\';
  87.                 *b++ = 'v';
  88.             }
  89.             else if (c == '\r') {
  90.                 *b++ = '\\';
  91.                 *b++ = 'r';
  92.             }
  93.             else if (c == '\\') {
  94.                 /*
  95.                  * Yes, we only print one backslash, otherwise we screw-up
  96.                  * Windows paths
  97.                  * FIXME: There should be a command-line argument to define
  98.                  * how to handle non-printable+backslash characters
  99.                  */
  100.                 *b++ = '\\';
  101.             }
  102.             else if (isprint(c)) {
  103.                 *b++ = c;
  104.             }
  105.             else {
  106.                 *b++ = '\\';
  107.                 int_to_octal3(c, b);
  108.                 b+=3;
  109.             }
  110.         }
  111.         *b++ = '\0';
  112.         (void)fprintf(stdout, "%s\n", buffer);
  113.         (void)fflush(stdout);
  114.     }
  115. }
  116.  
  117. int main(int ac, char *av[])
  118. {
  119.     TRACEHANDLE hSession = 0;
  120.     TRACEHANDLE hTrace = 0;
  121.     ULONG status;
  122.     int retval = EXIT_SUCCESS;
  123.  
  124.     (void)ac;
  125.  
  126.     size_t propsSize = sizeof(EVENT_TRACE_PROPERTIES) + 1024;
  127.     EVENT_TRACE_PROPERTIES *props = (EVENT_TRACE_PROPERTIES*)calloc(1, propsSize);
  128.     if (props == NULL) {
  129.         (void)fprintf(stderr, "%s: Malloc failed\n", av[0]);
  130.         retval = EXIT_FAILURE;
  131.         goto done;
  132.     }
  133.  
  134.     props->Wnode.BufferSize = (ULONG)propsSize;
  135.     props->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
  136.     props->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
  137.     props->EnableFlags = EVENT_TRACE_FLAG_DBGPRINT;
  138.     props->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  139. #if 1
  140.     /* Increase buffer size to 16MB */
  141.     props->BufferSize = 64;             /* Buffer size in KB (64KB per buffer) */
  142.     props->MinimumBuffers = 256;        /* Minimum buffers */
  143.     props->MaximumBuffers = 256;        /* Maximum buffers */
  144. #endif
  145.  
  146.     status = StartTraceW(&hSession, KERNEL_LOGGER_NAME, props);
  147.     if (status == ERROR_ALREADY_EXISTS) {
  148.         (void)fprintf(stderr,
  149.             "#### Kernel Logger already running, attaching...\n");
  150.         hSession = 0;
  151.     } else if (status != ERROR_SUCCESS) {
  152.         (void)fprintf(stderr, "%s: StartTraceA() failed with error=%d\n",
  153.             av[0], (int)status);
  154.         retval = EXIT_FAILURE;
  155.         goto done;
  156.     } else {
  157.         (void)fprintf(stderr,
  158.             "#### Started Kernel Logger session.\n");
  159.     }
  160.  
  161.     EVENT_TRACE_LOGFILE log = {
  162.         .LoggerName = KERNEL_LOGGER_NAME,
  163.         .ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD,
  164.         .EventRecordCallback = EventCallback
  165.     };
  166.  
  167.     hTrace = OpenTrace(&log);
  168.     if (hTrace == INVALID_PROCESSTRACE_HANDLE) {
  169.         (void)fprintf(stderr, "%s: OpenTrace() failed with error=%d\n",
  170.             av[0], (int)GetLastError());
  171.         retval = EXIT_FAILURE;
  172.         goto done;
  173.     }
  174.  
  175.     (void)fprintf(stderr,
  176.         "#### Listening for |DbgPrint*()| messages...\n");
  177.     status = ProcessTrace(&hTrace, 1, NULL, NULL);
  178.  
  179. done:
  180.     return retval;
  181. }

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at