Created
April 10, 2018 21:08
-
-
Save pavel-a/1b00e87831e40cab6e69b9d4d2011a14 to your computer and use it in GitHub Desktop.
Print to the Windows kernel debugger from usermode
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
//////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/// Print to kernel debugger from user mode | |
/// | |
/// Usage: | |
/// #include "winKdprintUm.h" | |
/// | |
/// ULONG getKdPrintPointers(void); | |
/// | |
/// ULONG KdPrintEx((ULONG ComponentId, ULONG Level, PCHAR Format, ...)); | |
/// ULONG KdPrintExWithPrefix((PCHAR prefix, ULONG ComponentId, ULONG Level, PCHAR Format, ...)); | |
/// | |
/// ULONG DbgPrintEx(ULONG ComponentId, ULONG Level, PCHAR Format, ...); | |
/// ULONG DbgPrintExWithPrefix(PCHAR prefix, ULONG ComponentId, ULONG Level, PCHAR Format, ...); | |
/// | |
/// ULONG vDbgPrintEx(IN ULONG ComponentId, ULONG Level, PCHAR Format, va_list arglist); | |
/// ULONG vDbgPrintExWithPrefix(PCHAR pref, ULONG ComponentId, ULONG Level, PCCH Fmt, va_list arglist); | |
/// | |
/// Return value is NTSTATUS (0=success) | |
/// | |
/// This module can be compiled as either C or C++ | |
//////////////////////////////////////////////////////////////////////////////////////////////////////// | |
#ifndef _WIN32_WINNT | |
#define _WIN32_WINNT 0x0501 // minimal platform: WinXP | |
#endif | |
#if (_WIN32_WINNT < 0x0501) | |
#error "No, this won't work on win2k" | |
#endif | |
#include <windows.h> | |
#include "WinKdPrintUm.h" /*self*/ | |
// NOTE: all (...) variants are __cdecl. All (va_list) variants are __stdcall. | |
ULONG ( __cdecl *f_DbgPrintEx)(ULONG ComponentId, ULONG Level, PCHAR Format, ...) = 0; | |
ULONG ( __stdcall *f_vDbgPrintExWithPrefix)(IN PCCH pref, ULONG ComponentId, ULONG Level, PCCH Fmt, va_list arglist) = 0; | |
ULONG ( __stdcall *f_vDbgPrintEx)(IN ULONG ComponentId, IN ULONG Level, IN PCCH Format, IN va_list arglist) = 0; | |
extern ULONG g_KdPrintAvailable = 0; | |
extern | |
ULONG __cdecl DbgPrintExWithPrefix(IN PCCH pref, ULONG ComponentId, ULONG Level, PCCH Fmt, ...) | |
{ | |
ULONG n; | |
va_list arglist; | |
va_start( arglist, Fmt ); | |
n = f_vDbgPrintExWithPrefix( pref, ComponentId, Level, Fmt, arglist ); | |
va_end( arglist ); | |
return n; | |
} | |
//-- Get the kernel debug print interfaces --- | |
// Note: ntdll.dll is always present, | |
// so we use GetModuleHandle instead of LoadLibrary, no "release" action is needed. | |
int getKdPrintPointers_i(void) | |
{ | |
FARPROC f; | |
HMODULE hm = GetModuleHandle(TEXT("ntdll.dll")); | |
if( !hm ) return 0; | |
f = GetProcAddress( hm, "DbgPrintEx" ); | |
if( !f ) return 0; | |
memcpy( &f_DbgPrintEx, &f, sizeof(f) ); | |
f = GetProcAddress( hm, "vDbgPrintExWithPrefix" ); | |
if( !f ) return 0; | |
memcpy( &f_vDbgPrintExWithPrefix, &f, sizeof(f) ); | |
f = GetProcAddress( hm, "vDbgPrintEx" ); | |
if( !f ) return 0; | |
memcpy( &f_vDbgPrintEx, &f, sizeof(f) ); | |
return 1; | |
} | |
extern | |
ULONG getKdPrintPointers(void) | |
{ | |
if ( !g_KdPrintAvailable ) { | |
g_KdPrintAvailable = getKdPrintPointers_i(); | |
} | |
return g_KdPrintAvailable; | |
} | |
#if __cplusplus | |
} // extern "C" | |
#endif //c++ | |
#ifdef _WITH_TESTMAIN | |
int _tmain(int argc, _TCHAR* argv[]) | |
{ | |
getKdPrintPointers(); | |
if( !isKdPrintAvailable() ) return 1; | |
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "test %d\n", 42); | |
DbgPrintExWithPrefix("myprefix:", DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "test2 %d\n", 84); | |
return 0; | |
} | |
#endif |
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
//////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/// Print to kernel debugger from user mode | |
/// | |
/// Usage: | |
/// | |
/// ULONG getKdPrintPointers(void); | |
/// int isKdPrintAvailable(void); | |
/// | |
/// ULONG KdPrintEx((ULONG ComponentId, ULONG Level, PCHAR Format, ...)); | |
/// ULONG KdPrintExWithPrefix((PCHAR prefix, ULONG ComponentId, ULONG Level, PCHAR Format, ...)); | |
/// | |
/// ULONG DbgPrintEx(ULONG ComponentId, ULONG Level, PCHAR Format, ...); | |
/// ULONG DbgPrintExWithPrefix(PCHAR prefix, ULONG ComponentId, ULONG Level, PCHAR Format, ...); | |
/// | |
/// ULONG vDbgPrintEx(IN ULONG ComponentId, ULONG Level, PCHAR Format, va_list arglist); | |
/// ULONG vDbgPrintExWithPrefix(PCHAR pref, ULONG ComponentId, ULONG Level, PCCH Fmt, va_list arglist); | |
/// | |
/// Return value is NTSTATUS (0=success) | |
/// | |
/// * Single debug print is limited to 512 chars, using any variant. | |
/// * Debug print filters are set in HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter | |
/// In kernel debugger: dd nt!Kd_XXXX_Mask, where XXXX is the desired component name. | |
/// Typically the component name to use is IHVDRIVER on NT6 or DEFAULT on NT5 | |
/// * For more details see WDK docum: _Reading and Filtering Debugging Messages_. | |
//////////////////////////////////////////////////////////////////////////////////////////////////////// | |
#pragma once | |
// Include windows.h here to get the types ... | |
//#include <Windows.h> | |
#ifndef _NO_KDPRINT_FILTER_DEFS | |
// Borrow some filter defs from DDK/WDK dpfilter.h | |
enum { | |
DPFLTR_ERROR_LEVEL = 0, | |
DPFLTR_WARNING_LEVEL = 1, | |
DPFLTR_TRACE_LEVEL = 2, | |
DPFLTR_INFO_LEVEL = 3, | |
DPFLTR_MASK = 0x8000000, | |
}; | |
enum { | |
DPFLTR_IHVDRIVER_ID = 77, | |
DPFLTR_SYSTEM_ID = 0, | |
DPFLTR_VERIFIER_ID = 93, | |
DPFLTR_APPCOMPAT_ID = 123, | |
}; | |
#endif /* _NO_KDPRINT_FILTER_DEFS */ | |
#if __cplusplus | |
extern "C" { | |
#endif | |
// NOTE: all variadic (...) wrappers are __cdecl. All (va_list) functions in ntdll are __stdcall. | |
extern ULONG ( __cdecl *f_DbgPrintEx)(ULONG ComponentId, ULONG Level, PCHAR Format, ...); | |
extern ULONG ( __stdcall *f_vDbgPrintExWithPrefix)(IN PCCH pref, ULONG ComponentId, ULONG Level, PCCH Fmt, va_list arglist); | |
extern ULONG ( __stdcall *f_vDbgPrintEx)(IN ULONG ComponentId, IN ULONG Level, IN PCCH Format, IN va_list arglist); | |
extern ULONG __cdecl DbgPrintExWithPrefix(IN PCCH pref, ULONG ComponentId, ULONG Level, PCCH Fmt, ...); | |
extern ULONG g_KdPrintAvailable; | |
extern ULONG getKdPrintPointers(void); | |
__inline int isKdPrintAvailable(void) { return g_KdPrintAvailable; } | |
#define DbgPrintEx f_DbgPrintEx | |
#define vDbgPrintEx f_vDbgPrintEx | |
#define vDbgPrintExWithPrefix f_vDbgPrintExWithPrefix | |
#define KdPrintEx(_varlist_) DbgPrintEx _varlist_ | |
#define KdPrintExWithPrefix(_varlist_) DbgPrintExWithPrefix _varlist_ | |
#if __cplusplus | |
} // extern "C" | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment