DbgPrint/KdPrint输出格式控制 PS:mark一下

本文详细介绍了在驱动编程中DbgPrint与KdPrint的使用方法及输出格式控制,这两种函数常用于输出调试信息,并解释了它们在不同编译环境下的行为差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在驱动编程学习中,往往需要通过DbgPrint或者KdPrint来输出调试信息,对于Check版本,KdPrint只是DbgPrint的一个宏定义,而对于Free版本,KdPrint将被优化掉。这些输出信息可以通过DebugView对内核的监控来看到。

KdPrint is identical to the DbgPrint routine in code that is compiled in a checked build environment. This routine has no effect if compiled in a free build environment. Only kernel-mode drivers can call the KdPrint routine.

下面还是说一下他们的输出格式控制吧:

符号格式说明符类型
%c, %lcANSI字符char
%C, %wc宽字符wchar_t
%d, %i十进制有符号整数int
%D十进制__int64__int64
%L十六进制的LARGE_INTEGERLARGE_INTEGER
%s, %lsNULL终止的ANSI字符串char*
%S, %wsNULL终止的宽字符串wchar_t*
%ZANSI_STRING字符串ANSI_STRING
%wZUNICODE_STRING字符串UNICODE_STRING
%u十进制的ULONGULONG
%x小写字符十六进制的ULONGULONG
%X大写字符十六进制的ULONGULONG
%p指针Pointer 32/64位 

就那么多。根据DDK上说明,Unicode格式(%C, %S, %lc, %ls, %wc, %ws, and %wZ)只能在 IRQL = PASSIVE_LEVEL时才能使用。

原创文章,转载请注明:
本文出自程序人生 >> DbgPrint/KdPrint输出格式控制
作者:代码疯子


通过我给出的代码,分析它的作用BOOLEAN HookDbgkDebugObjectType() { //如果是不以原始DbgkDebugObjectType指针来操作,以启动方式时则需要替换PspInsertProcess中的DbgkDebugObjectType UNICODE_STRING ObjectTypeName; //获取原始DbgkDebugObjectType CKernelTable Ssdt; /*根据给定的函数名NtCreateDebugObject,在系统服务描述符表(SSDT)中查找对应的函数地址*/ PVOID NtCreateDebugObject = Ssdt.GetAddressFromName("NtCreateDebugObject"); if (!NtCreateDebugObject) { return FALSE; } ULONG templong = 0; /* 指令序列用于查找 DbgkDebugObjectType 地址*/ UCHAR tzm[] = { 0x48, 0x8B, 0x15, 0xEC, 0x85, 0x47, 0x00 }; ULONG64 addr = 0; for (PUCHAR i = (PUCHAR)NtCreateDebugObject; i < (PUCHAR)NtCreateDebugObject + 0x100; i++) { if (*i == 0x48 && *(i + 1) == 0x8B && *(i + 2) == 0x15 ) { // 复制相对偏移量 memcpy(&templong, i + 3, 4); addr = (ULONG64)((ULONG)templong + (ULONG64)i + 7);// 计算绝对地址 break; } } g_DbgkDebugObjectType = (POBJECT_TYPE*)addr; if (g_DbgkDebugObjectType == 0) { return FALSE; // 返回失败状态,无法获取 DbgkDebugObjectType 地址 } DbgPrint("fh:sys g_DbgkDebugObjectType:%p\n", g_DbgkDebugObjectType); RtlInitUnicodeString(&ObjectTypeName, L"styone"); // 初始化对象类型名称 OBJECT_TYPE_INITIALIZER_WIN10 ObjectTypeInitializer; POBJECT_TYPE* DbgkDebugObjectType = g_DbgkDebugObjectType; //参数构造 //memcpy(&ObjectTypeInitializer, &DbgkDebugObjectType->TypeInfo, sizeof(ObjectTypeInitializer)); // 复制对象类型信息 memcpy(&ObjectTypeInitializer, &(*DbgkDebugObjectType)->TypeInfo, sizeof(OBJECT_TYPE_INITIALIZER_WIN10)); //这里恢复调试权限 //ObjectTypeInitializer.DeleteProcedure = &DbgkpDeleteObject; //ObjectTypeInitializer.CloseProcedure = &DbgkpCloseObject; //ObjectTypeInitializer.DeleteProcedure = &proxyDbgkpDeleteObject; //ObjectTypeInitializer.CloseProcedure = &proxyDbgkpCloseObject; ObjectTypeInitializer.DeleteProcedure = NULL; // 设置删除过程为空 ObjectTypeInitializer.CloseProcedure = NULL;// 设置关闭过程为空 ObjectTypeInitializer.GenericMapping.GenericRead = 0x00020001;// 设置通用读权限 ObjectTypeInitializer.GenericMapping.GenericWrite = 0x00020002; // 设置通用写权限 ObjectTypeInitializer.GenericMapping.GenericExecute = 0x00120000;// 设置通用执行权限 ObjectTypeInitializer.GenericMapping.GenericAll = 0x001f000f;// 设置通用所有权限 ObjectTypeInitializer.ValidAccessMask = 0x001f000f; // 设置有效访问掩码 //创建调试对象类型 NTSTATUS status = ObCreateObjectType(&ObjectTypeName, &ObjectTypeInitializer, NULL, (PVOID*)g_DbgkDebugObjectType); //return FALSE; if (!NT_SUCCESS(status)) { if (status == STATUS_OBJECT_NAME_COLLISION) { //对象名已经存在 DbgPrint("ObCreateObjectType STATUS_OBJECT_NAME_COLLISION 对象名已经存在\n"); PUCHAR j_ObGetObjectType = (PUCHAR)GetKernelAddress("ObGetObjectType"); if (!j_ObGetObjectType) { DbgPrint("ObGetObjectType函数 failed\n"); // 获取 ObGetObjectType函数 失败 return FALSE; } //ULONG uloffset = (ULONG)(*(PUINT32)(j_ObGetObjectType + 31)); //DbgPrint("uloffset:%x\n", uloffset); //ULONG64 baseAddr = (ULONG64)j_ObGetObjectType + 35; //DbgPrint("baseAddr:%p\n", baseAddr); //POBJECT_TYPE* ObTypeIndexTable = (POBJECT_TYPE*)(baseAddr + uloffset); // 获取对象类型索引表地址 POBJECT_TYPE* ObTypeIndexTable = (POBJECT_TYPE*)(*(PUINT32)(j_ObGetObjectType + 31) + (ULONG64)j_ObGetObjectType + 35); if (!ObTypeIndexTable) { DbgPrint("ObGetObjectType get failed\n"); // 获取对象类型索引表失败 return FALSE; } DbgPrint("ObTypeIndexTable:%p\n", ObTypeIndexTable); // 打印对象类型索引表地址 //DbgPrint("sizeof(_OBJECT_TYPE):%x\n", sizeof(_OBJECT_TYPE)); // 打印对象类型索引表第2个元素地址 DbgPrint("ObTypeIndexTable[2]:%p\n", ObTypeIndexTable[2]); ULONG Index = 2; while (ObTypeIndexTable[Index]) { // 打印当前对象类型地址 DbgPrint("ObTypeIndexTable[Index]:%p\n", ObTypeIndexTable[Index]); if (&ObTypeIndexTable[Index]->Name) { if (ObTypeIndexTable[Index]->Name.Buffer) { DbgPrint("RtlCompareUnicodeString:%ws %ws\n", ObTypeIndexTable[Index]->Name.Buffer, ObjectTypeName.Buffer); // 比较对象类型名称 if (RtlCompareUnicodeString(&ObTypeIndexTable[Index]->Name, &ObjectTypeName, FALSE) == 0) { // 设置 DbgkDebugObjectType 为找到的对象类型 *g_DbgkDebugObjectType = ObTypeIndexTable[Index]; // 打印已存在的 DbgkDebugObjectType 地址 DbgPrint("ObCreateObjectType already exist *g_DbgkDebugObjectType:%p\n", *g_DbgkDebugObjectType); return TRUE; } } } Index++; } } else { DbgPrint("ObCreateObjectType eeor!\n"); // 创建对象类型失败 return FALSE; } } // 打印创建成功的 DbgkDebugObjectType 地址 DbgPrint("ObCreateObjectType ok g_DbgkDebugObjectType:%p\n", g_DbgkDebugObjectType); return TRUE;// 返回成功状态 }
最新发布
08-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值