Created
June 5, 2025 13:01
-
-
Save Kreijstal/38080e9b6aaa7b76846d628cce4eb533 to your computer and use it in GitHub Desktop.
let us print debug messages.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//gcc KernelDbgPrint.c -o KernelDbgPrint.exe -lkernel32 -luser32 | |
#include <windows.h> | |
#include <stdio.h> // For printf, fprintf, getchar | |
#include <string.h> // For strncpy_s if available, or strncpy + manual null termination | |
// Names of the synchronization objects | |
#define BUFFER_NAME L"DBWIN_BUFFER" | |
#define DATA_READY_EVENT_NAME L"DBWIN_DATA_READY" | |
#define BUFFER_READY_EVENT_NAME L"DBWIN_BUFFER_READY" | |
// Shared memory buffer structure (simplified) | |
// The first DWORD is the ProcessID, followed by the null-terminated string. | |
#define SHARED_MEM_SIZE 4096 // Standard size for DBWIN_BUFFER | |
HANDLE hBufferMapping = NULL; | |
LPVOID pBufferView = NULL; | |
HANDLE hDataReadyEvent = NULL; | |
HANDLE hBufferReadyEvent = NULL; | |
// Global flag to signal the monitoring thread to stop | |
volatile BOOL g_bRunning = TRUE; | |
void Cleanup() { | |
if (pBufferView) { | |
UnmapViewOfFile(pBufferView); | |
pBufferView = NULL; | |
} | |
if (hBufferMapping) { | |
CloseHandle(hBufferMapping); | |
hBufferMapping = NULL; | |
} | |
if (hDataReadyEvent) { | |
CloseHandle(hDataReadyEvent); | |
hDataReadyEvent = NULL; | |
} | |
if (hBufferReadyEvent) { | |
CloseHandle(hBufferReadyEvent); | |
hBufferReadyEvent = NULL; | |
} | |
printf("Cleanup complete.\n"); | |
} | |
BOOL InitializeDebugMonitor() { | |
// 1. Create/Open the "DBWIN_BUFFER_READY" event. | |
hBufferReadyEvent = CreateEventW(NULL, FALSE, FALSE, BUFFER_READY_EVENT_NAME); | |
if (!hBufferReadyEvent) { | |
fprintf(stderr, "Failed to create/open DBWIN_BUFFER_READY event. Error: %lu\n", GetLastError()); | |
return FALSE; | |
} | |
// 2. Create/Open the "DBWIN_DATA_READY" event. | |
hDataReadyEvent = CreateEventW(NULL, FALSE, FALSE, DATA_READY_EVENT_NAME); | |
if (!hDataReadyEvent) { | |
fprintf(stderr, "Failed to create/open DBWIN_DATA_READY event. Error: %lu\n", GetLastError()); | |
CloseHandle(hBufferReadyEvent); | |
return FALSE; | |
} | |
// 3. Create/Open the shared memory file mapping "DBWIN_BUFFER". | |
hBufferMapping = CreateFileMappingW( | |
INVALID_HANDLE_VALUE, | |
NULL, | |
PAGE_READWRITE, | |
0, | |
SHARED_MEM_SIZE, | |
BUFFER_NAME | |
); | |
if (!hBufferMapping) { | |
fprintf(stderr, "Failed to create/open file mapping object DBWIN_BUFFER. Error: %lu\n", GetLastError()); | |
CloseHandle(hDataReadyEvent); | |
CloseHandle(hBufferReadyEvent); | |
return FALSE; | |
} | |
// 4. Map the shared memory. | |
pBufferView = MapViewOfFile( | |
hBufferMapping, | |
FILE_MAP_READ, | |
0, | |
0, | |
SHARED_MEM_SIZE | |
); | |
if (!pBufferView) { | |
fprintf(stderr, "Failed to map view of file. Error: %lu\n", GetLastError()); | |
CloseHandle(hBufferMapping); | |
CloseHandle(hDataReadyEvent); | |
CloseHandle(hBufferReadyEvent); | |
return FALSE; | |
} | |
printf("Debug monitor initialized. Waiting for messages...\n"); | |
// Signal that the buffer is ready for the first message. | |
SetEvent(hBufferReadyEvent); | |
return TRUE; | |
} | |
// Thread function for monitoring debug messages | |
DWORD WINAPI DebugMonitorThreadFunc(LPVOID lpParam) { | |
UNREFERENCED_PARAMETER(lpParam); // Unused parameter | |
while (g_bRunning) { | |
DWORD waitResult = WaitForSingleObject(hDataReadyEvent, 1000); // Timeout after 1 sec | |
if (!g_bRunning) { // Check flag again after wait | |
break; | |
} | |
if (waitResult == WAIT_OBJECT_0) { | |
DWORD processId = *((DWORD*)pBufferView); | |
char* messageAnsi = (char*)pBufferView + sizeof(DWORD); | |
// Create a local buffer to safely copy and null-terminate the string | |
char safeMessage[SHARED_MEM_SIZE - sizeof(DWORD)]; | |
// strncpy_s is safer if available (MSVC) | |
#if defined(_MSC_VER) | |
strncpy_s(safeMessage, sizeof(safeMessage), messageAnsi, _TRUNCATE); | |
#else | |
// Standard C strncpy (less safe, manual termination needed) | |
strncpy(safeMessage, messageAnsi, sizeof(safeMessage) - 1); | |
safeMessage[sizeof(safeMessage) - 1] = '\0'; // Ensure null termination | |
#endif | |
printf("[PID: %lu] %s", processId, safeMessage); | |
// DbgPrint messages often don't include a newline by default. | |
// If the last character is not a newline, and the message is not empty, print one. | |
size_t len = strlen(safeMessage); | |
if (len > 0 && safeMessage[len - 1] != '\n') { | |
printf("\n"); | |
} | |
fflush(stdout); // Ensure output is displayed immediately | |
SetEvent(hBufferReadyEvent); | |
} else if (waitResult == WAIT_TIMEOUT) { | |
// Timeout occurred, loop again to check g_bRunning | |
continue; | |
} else { | |
fprintf(stderr, "WaitForSingleObject on DBWIN_DATA_READY failed. Error: %lu\n", GetLastError()); | |
g_bRunning = FALSE; // Stop monitoring on error | |
break; | |
} | |
} | |
printf("Debug monitor loop stopped.\n"); | |
return 0; // Return value for the thread | |
} | |
int main() { | |
HANDLE hMonitorThread = NULL; | |
if (!InitializeDebugMonitor()) { | |
fprintf(stderr, "Failed to initialize debug monitor. Exiting.\n"); | |
Cleanup(); | |
return 1; | |
} | |
hMonitorThread = CreateThread( | |
NULL, // default security attributes | |
0, // use default stack size | |
DebugMonitorThreadFunc, // thread function name | |
NULL, // argument to thread function | |
0, // use default creation flags | |
NULL); // returns the thread identifier (we don't need it) | |
if (hMonitorThread == NULL) { | |
fprintf(stderr, "Failed to create monitor thread. Error: %lu\n", GetLastError()); | |
Cleanup(); | |
return 1; | |
} | |
printf("Press Enter to stop monitoring...\n"); | |
getchar(); // Wait for user to press Enter | |
g_bRunning = FALSE; // Signal the monitor thread to stop | |
// Wait for the monitor thread to finish | |
if (hMonitorThread != NULL) { | |
WaitForSingleObject(hMonitorThread, INFINITE); | |
CloseHandle(hMonitorThread); | |
} | |
Cleanup(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment