2017年12月26日星期二

DbgPrintEx或KdPrintEx的用法

/*
题目:
简单的说是DbgPrintEx and KdPrintEx的用法。
复杂的说是Windows驱动的(调试)打印信息子系统的设计。

参考:
Reading and Filtering Debugging Messages
https://docs.microsoft.com/zh-cn/windows-hardware/drivers/devtest/reading-and-filtering-debugging-messages

说是说有这么几种类型的设备信息:
IHVVIDEO Video driver
IHVAUDIO Audio driver
IHVNETWORK Network driver
IHVSTREAMING Kernel streaming driver
IHVBUS Bus driver
IHVDRIVER Any other type of driver

我们开发硬件驱动的不多,所以,如果要编写网络驱动就用DPFLTR_IHVNETWORK_ID,其余的非硬件的就用DPFLTR_IHVDRIVER_ID,若文件和磁盘相关的等。
其实dpfilter.h文件里定义的更多。
还可以用windbg来验证/查看:
0: kd> x nt!Kd_*_Mask
fffff802`d35bb310 nt!Kd_LDR_Mask = <no type information>
fffff802`d35bb2bc nt!Kd_WDI_Mask = <no type information>
fffff802`d35bb21c nt!Kd_POWER_Mask = <no type information>
fffff802`d35bb208 nt!Kd_CAPIMG_Mask = <no type information>
fffff802`d35bb45c nt!Kd_SETUP_Mask = <no type information>
fffff802`d35bb358 nt!Kd_DMIO_Mask = <no type information>
fffff802`d35bb2fc nt!Kd_STORMINIPORT_Mask = <no type information>
fffff802`d35bb350 nt!Kd_DMADMIN_Mask = <no type information>
fffff802`d35bb3cc nt!Kd_SCCLIENT_Mask = <no type information>
fffff802`d35bb3ec nt!Kd_TCPIP_Mask = <no type information>
fffff802`d35bb400 nt!Kd_AMLI_Mask = <no type information>
fffff802`d35bb368 nt!Kd_PREFETCHER_Mask = <no type information>
fffff802`d35bb2f0 nt!Kd_VERIFIER_Mask = <no type information>
fffff802`d35bb450 nt!Kd_CRASHDUMP_Mask = <no type information>
fffff802`d35bb3d0 nt!Kd_SCSERVER_Mask = <no type information>
fffff802`d35bb410 nt!Kd_MOUCLASS_Mask = <no type information>
fffff802`d35bb288 nt!Kd_FVEVOL_Mask = <no type information>
fffff802`d35bb384 nt!Kd_MCHGR_Mask = <no type information>
fffff802`d35bb3a4 nt!Kd_WMICORE_Mask = <no type information>
fffff802`d35bb3b0 nt!Kd_UNIMODEM_Mask = <no type information>
fffff802`d35bb380 nt!Kd_IDEP_Mask = <no type information>
fffff802`d35bb230 nt!Kd_EXFAT_Mask = <no type information>
fffff802`d35bb314 nt!Kd_RTLTHREADPOOL_Mask = <no type information>
fffff802`d35bb298 nt!Kd_THREADORDER_Mask = <no type information>
fffff802`d35bb37c nt!Kd_PCIIDE_Mask = <no type information>
fffff802`d35bb320 nt!Kd_IHVSTREAMING_Mask = <no type information>
fffff802`d35bb214 nt!Kd_GPIO_Mask = <no type information>
fffff802`d35bb2e4 nt!Kd_VDSDYN_Mask = <no type information>
fffff802`d35bb3e0 nt!Kd_FASTFAT_Mask = <no type information>
fffff802`d35bb200 nt!Kd_STORAGECLASSMEMORY_Mask = <no type information>
fffff802`d35bb34c nt!Kd_WSOCKTRANSPORT_Mask = <no type information>
fffff802`d35bb24c nt!Kd_MSDSM_Mask = <no type information>
fffff802`d35bb254 nt!Kd_FLTREGRESS_Mask = <no type information>
fffff802`d35bb378 nt!Kd_FLOPPY_Mask = <no type information>
fffff802`d35bb224 nt!Kd_SE_Mask = <no type information>
fffff802`d35bb338 nt!Kd_SR_Mask = <no type information>
fffff802`d35bb3e8 nt!Kd_DMSYNTH_Mask = <no type information>
fffff802`d35bb394 nt!Kd_FUSION_Mask = <no type information>
fffff802`d35bb43c nt!Kd_REDBOOK_Mask = <no type information>
fffff802`d35bb26c nt!Kd_COVERAGE_Mask = <no type information>
fffff802`d35bb330 nt!Kd_IHVDRIVER_Mask = <no type information>
fffff802`d35bb370 nt!Kd_TERMSRV_Mask = <no type information>
fffff802`d35bb3c4 nt!Kd_SERENUM_Mask = <no type information>
fffff802`d35bb32c nt!Kd_IHVVIDEO_Mask = <no type information>
fffff802`d35bb318 nt!Kd_HPS_Mask = <no type information>
fffff802`d35bb2d0 nt!Kd_DEFAULT_Mask = <no type information>
fffff802`d35bb3d4 nt!Kd_NETAPI_Mask = <no type information>
fffff802`d35bb434 nt!Kd_SCSIPORT_Mask = <no type information>
fffff802`d3572920 nt!Kd_WIN2000_Mask = <no type information>
fffff802`d35bb31c nt!Kd_IHVBUS_Mask = <no type information>
fffff802`d35bb3e4 nt!Kd_NTOSPNP_Mask = <no type information>
fffff802`d35bb274 nt!Kd_USBSTOR_Mask = <no type information>
fffff802`d35bb258 nt!Kd_KSECDD_Mask = <no type information>
fffff802`d35bb428 nt!Kd_I8042PRT_Mask = <no type information>
fffff802`d35bb354 nt!Kd_DMCONFIG_Mask = <no type information>
fffff802`d35bb420 nt!Kd_LSERMOUS_Mask = <no type information>
fffff802`d35bb3a0 nt!Kd_BURNENG_Mask = <no type information>
fffff802`d35bb268 nt!Kd_CACHEMGR_Mask = <no type information>
fffff802`d35bb328 nt!Kd_IHVAUDIO_Mask = <no type information>
fffff802`d35bb33c nt!Kd_DMSERVER_Mask = <no type information>
fffff802`d35bb220 nt!Kd_DRIVEEXTENDER_Mask = <no type information>
fffff802`d35bb3fc nt!Kd_HALIA64_Mask = <no type information>
fffff802`d35bb414 nt!Kd_KBDCLASS_Mask = <no type information>
fffff802`d35bb39c nt!Kd_IMAPI_Mask = <no type information>
fffff802`d35bb3b4 nt!Kd_DCOMSS_Mask = <no type information>
fffff802`d35bb458 nt!Kd_NTFS_Mask = <no type information>
fffff802`d35bb35c nt!Kd_PCI_Mask = <no type information>
fffff802`d35bb340 nt!Kd_PROCESSOR_Mask = <no type information>
fffff802`d35bb29c nt!Kd_TPM_Mask = <no type information>
fffff802`d35bb454 nt!Kd_FSTUB_Mask = <no type information>
fffff802`d35bb390 nt!Kd_IDLETASK_Mask = <no type information>
fffff802`d35bb22c nt!Kd_FILETRACE_Mask = <no type information>
fffff802`d35bb2ac nt!Kd_HEAP_Mask = <no type information>
fffff802`d35bb438 nt!Kd_STORPROP_Mask = <no type information>
fffff802`d35bb278 nt!Kd_APPCOMPAT_Mask = <no type information>
fffff802`d35bb290 nt!Kd_EMS_Mask = <no type information>
fffff802`d35bb41c nt!Kd_KBDHID_Mask = <no type information>
fffff802`d35bb2b4 nt!Kd_KTM_Mask = <no type information>
fffff802`d35bb294 nt!Kd_ENVIRON_Mask = <no type information>
fffff802`d35bb388 nt!Kd_TAPE_Mask = <no type information>
fffff802`d35bb3f8 nt!Kd_VIDEO_Mask = <no type information>
fffff802`d35bb218 nt!Kd_CRASHDUMPXHCI_Mask = <no type information>
fffff802`d35bb324 nt!Kd_IHVNETWORK_Mask = <no type information>
fffff802`d35bb448 nt!Kd_CDROM_Mask = <no type information>
fffff802`d35bb464 nt!Kd_SYSTEM_Mask = <no type information>
fffff802`d35bb38c nt!Kd_SOFTPCI_Mask = <no type information>
fffff802`d35bb424 nt!Kd_SERMOUSE_Mask = <no type information>
fffff802`d35bb204 nt!Kd_VPCI_Mask = <no type information>
fffff802`d35bb244 nt!Kd_PSHED_Mask = <no type information>
fffff802`d35bb250 nt!Kd_MPIO_Mask = <no type information>
fffff802`d35bb408 nt!Kd_WMILIB_Mask = <no type information>
fffff802`d35bb3f0 nt!Kd_VIDEOPRT_Mask = <no type information>
fffff802`d35bb3d8 nt!Kd_PNPMGR_Mask = <no type information>
fffff802`d35bb2d8 nt!Kd_VDSUTIL_Mask = <no type information>
fffff802`d35bb23c nt!Kd_LSASS_Mask = <no type information>
fffff802`d35bb2f8 nt!Kd_PRINTSPOOLER_Mask = <no type information>
fffff802`d35bb284 nt!Kd_NDIS_Mask = <no type information>
fffff802`d35bb234 nt!Kd_CNG_Mask = <no type information>
fffff802`d35bb3c0 nt!Kd_UHCD_Mask = <no type information>
fffff802`d35bb2cc nt!Kd_MM_Mask = <no type information>
fffff802`d35bb2a4 nt!Kd_USERGDI_Mask = <no type information>
fffff802`d35bb300 nt!Kd_STORPORT_Mask = <no type information>
fffff802`d35bb30c nt!Kd_TCPIP6_Mask = <no type information>
fffff802`d35bb280 nt!Kd_NVCTRACE_Mask = <no type information>
fffff802`d35bb2b8 nt!Kd_PERFLIB_Mask = <no type information>
fffff802`d35bb440 nt!Kd_DISK_Mask = <no type information>
fffff802`d35bb2d4 nt!Kd_DFRGIFC_Mask = <no type information>
fffff802`d35bb3dc nt!Kd_SAMSS_Mask = <no type information>
fffff802`d35bb364 nt!Kd_RSFILTER_Mask = <no type information>
fffff802`d35bb360 nt!Kd_FCPORT_Mask = <no type information>
fffff802`d35bb3b8 nt!Kd_AUTOCHK_Mask = <no type information>
fffff802`d35bb210 nt!Kd_REFS_Mask = <no type information>
fffff802`d35bb2a0 nt!Kd_MMCSS_Mask = <no type information>
fffff802`d35bb334 nt!Kd_INFINIBAND_Mask = <no type information>
fffff802`d35bb374 nt!Kd_FDC_Mask = <no type information>
fffff802`d35bb2ec nt!Kd_VDS_Mask = <no type information>
fffff802`d35bb20c nt!Kd_WER_Mask = <no type information>
fffff802`d35bb2c4 nt!Kd_WOW64_Mask = <no type information>
fffff802`d35bb308 nt!Kd_ISAPNP_Mask = <no type information>
fffff802`d35bb348 nt!Kd_VSS_Mask = <no type information>
fffff802`d35bb228 nt!Kd_XSAVE_Mask = <no type information>
fffff802`d35bb2e8 nt!Kd_VDSBAS_Mask = <no type information>
fffff802`d35bb344 nt!Kd_PNPMEM_Mask = <no type information>
fffff802`d35bb3a8 nt!Kd_FLTMGR_Mask = <no type information>
fffff802`d35bb42c nt!Kd_CONFIG_Mask = <no type information>
fffff802`d35bb2c8 nt!Kd_DFSC_Mask = <no type information>
fffff802`d35bb444 nt!Kd_CLASSPNP_Mask = <no type information>
fffff802`d35bb3f4 nt!Kd_SVCHOST_Mask = <no type information>
fffff802`d35bb25c nt!Kd_TXF_Mask = <no type information>
fffff802`d35bb264 nt!Kd_MOUNTMGR_Mask = <no type information>
fffff802`d35bb404 nt!Kd_ACPI_Mask = <no type information>
fffff802`d35bb1f8 nt!Kd_ENDOFTABLE_Mask = <no type information>
fffff802`d35bb1fc nt!Kd_FSLIB_Mask = <no type information>
fffff802`d35bb270 nt!Kd_SBP2PORT_Mask = <no type information>
fffff802`d35bb28c nt!Kd_WDT_Mask = <no type information>
fffff802`d35bb40c nt!Kd_TWOTRACK_Mask = <no type information>
fffff802`d35bb44c nt!Kd_CDAUDIO_Mask = <no type information>
fffff802`d35bb2f4 nt!Kd_VSSDYNDISK_Mask = <no type information>
fffff802`d35bb36c nt!Kd_W32TIME_Mask = <no type information>
fffff802`d35bb2c0 nt!Kd_ALPC_Mask = <no type information>
fffff802`d35bb248 nt!Kd_UDFS_Mask = <no type information>
fffff802`d35bb3ac nt!Kd_SIS_Mask = <no type information>
fffff802`d35bb398 nt!Kd_SXS_Mask = <no type information>
fffff802`d35bb3c8 nt!Kd_SERIAL_Mask = <no type information>
fffff802`d35bb238 nt!Kd_SSPICLI_Mask = <no type information>
fffff802`d35bb27c nt!Kd_LUAFV_Mask = <no type information>
fffff802`d35bb2e0 nt!Kd_VDSDYNDR_Mask = <no type information>
fffff802`d35bb240 nt!Kd_STORVSP_Mask = <no type information>
fffff802`d35bb2a8 nt!Kd_WHEA_Mask = <no type information>
fffff802`d35bb3bc nt!Kd_RPCPROXY_Mask = <no type information>
fffff802`d35bb460 nt!Kd_SMSS_Mask = <no type information>
fffff802`d35bb418 nt!Kd_MOUHID_Mask = <no type information>
fffff802`d35bb260 nt!Kd_CFR_Mask = <no type information>
fffff802`d35bb430 nt!Kd_SCSIMINIPORT_Mask = <no type information>
fffff802`d35bb2b0 nt!Kd_IOSTRESS_Mask = <no type information>
fffff802`d35bb2dc nt!Kd_VDSLDR_Mask = <no type information>
fffff802`d35bb304 nt!Kd_SHPC_Mask = <no type information>

这次,我们关系的是:nt!Kd_IHVDRIVER_Mask。

关于级别,在dpfilter.h里就定义了这么几种,不过,自己还可以扩充。
#define DPFLTR_ERROR_LEVEL 0
#define DPFLTR_WARNING_LEVEL 1
#define DPFLTR_TRACE_LEVEL 2
#define DPFLTR_INFO_LEVEL 3
#define DPFLTR_MASK 0x80000000
注意:这是按bit来的。

奇怪:
在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter的DEFAULT or IHVDRIVER都设置为f了,但是用
1: kd> dd nt!Kd_IHVDRIVER_Mask L1
fffff802`d35bb330  00000000
的值不是f.
过一会,去了趟厕所,才明白:
DEFAULT不和nt!Kd_IHVDRIVER_Mask对应,而和nt!Kd_DEFAULT_Mask对应
推测IHVDRIVER不和nt!Kd_DEFAULT_Mask对应,而和nt!Kd_IHVDRIVER_Mask对应。

在这种情况下测试,只有DPFLTR_ERROR_LEVEL的信息会显示。
这大概就是:
If Level is 0, the bitfield is equivalent to 0x00000001. If Level is 31, the bitfield is equivalent to 0x80000000.
这句话来解释。

执行:
ed nt!Kd_IHVDRIVER_Mask 3
然后再测试,错误和告警都显示了。

执行:
ed nt!Kd_IHVDRIVER_Mask 7
然后显示:
1: kd> g
ERROR
WARNING
TRACE

执行:
1: kd> ed nt!Kd_IHVDRIVER_Mask 8
然后显示:
0: kd> g
ERROR
INFO
为何?如此?
8是二进制的1000.
只有这样解释,信息位是第三位(从右边数第四个),而第零位是默认的,无论如何在何种情况下都认为是1(不能说显示)。

执行:
ed nt!Kd_IHVDRIVER_Mask f
然后显示:
0: kd> g
ERROR
WARNING
TRACE
INFO
这四个都显示了。

由此可见,我们可以控制nt!Kd_IHVDRIVER_Mask的值,来控制我们的输出,而不用修改代码。
相应的估计注册表也可以,那是IHVDRIVER的键值。
这是一个调试手法,谨记。

进一步的测试:
本工程和nt!Kd_DEFAULT_Mask的值无关,证明见下:
0: kd> ed nt!Kd_DEFAULT_Mask 1
0: kd> dd nt!Kd_DEFAULT_Mask L1
fffff802`d35bb2d0  00000001
0: kd> g
ERROR
WARNING
TRACE
INFO
1: kd> dd nt!Kd_IHVDRIVER_Mask L1
fffff802`d35bb330  0000000f
不过,nt!Kd_DEFAULT_Mask好像和默认的输出有关。

made by correy
made at 2017.12.22
http://correy.webs.com
*/

#pragma once

#include <fltKernel.h>
#include <ntimage.h>
#include <ntstrsafe.h>
#include <ntdef.h>
#include <ntddk.h>
#include <windef.h>

#define TAG  'tset' //test


VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
    UNREFERENCED_PARAMETER(pDriverObject);
}


extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
UNREFERENCED_PARAMETER(pRegistryPath);

KdBreakPoint();

pDriverObject->DriverUnload = DriverUnload;

DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "ERROR\n");
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_WARNING_LEVEL, "WARNING\n");
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "TRACE\n");
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "INFO\n");

return STATUS_UNSUCCESSFUL;
}