-
-
[求助]在遍历Dpc定时器时遇到的疑惑
-
发表于:
2017-9-12 16:03
3506
-
最近在学习Dpc定时器的知识,然后自己写了个遍历系统中所有Dpc定时器的驱动,但是在加载驱动之后会出现死循环的问题,后面反复琢磨了很久,我发现当我的Win7系统在开启内核调试模式之后,然后用windbg附加调试,再加载驱动,就会出现在遍历某一个dpc定时器对象链表陷入死循环的情况;然后我重新启动系统,进入了正常的win7系统,然后再次加载驱动,就没有出现死循环的问题了,而且前前后后试了很多次,始终都是正确的。所以我就觉得奇怪了,为什么开启内核调试模式之后就会总是出现死循环的问题,而正常模式下就不会出现,这其中是什么原理?
下面我附上枚举Dpc定时器函数的代码:
void enum_DPC()
{
ULONG KPRCB;
PKTIMER_TABLE_ENTRY ktime_table_addr;
_asm
{
push eax;
mov eax, fs:[0x20];//KPCR地址
mov KPRCB, eax;
pop eax;
}
__try
{
PKTIMER pTimer;
PLIST_ENTRY pList;
ktime_table_addr = (PKTIMER_TABLE_ENTRY)(KPRCB + 0x1960 + 0x40);
DbgPrint("KPRCB=%08X,KPRCB=%08x,ktime_table_addr=%08X\r\n", KPRCB, KPRCB, ktime_table_addr);
PKTIMER_TABLE_ENTRY table = ktime_table_addr;
for (int i = 0; i < 256; i++, table++)
{
if (!MmIsAddressValid((PVOID)table))
{
return;
}
if (table->Time.HighPart == 0xFFFFFFFF)
continue; //为空的数组高位双字为FFFFFFFF
if (!MmIsAddressValid((PVOID)table->Entry.Blink))
continue;
if (!MmIsAddressValid((PVOID)table->Entry.Flink))
continue;
for (pList = table->Entry.Blink;
pList != &table->Entry;
pList = pList->Blink)
{
pTimer = (PKTIMER)((ULONG)pList - 0x18); //取得timer对象
if (!MmIsAddressValid((PVOID)pTimer) ||
!MmIsAddressValid((PVOID)pTimer->Dpc) ||
!MmIsAddressValid((PVOID)pTimer->Dpc->DeferredRoutine))
{
if (!MmIsAddressValid((PVOID)pList->Blink)) break;
continue;
}
if (!MmIsAddressValid((PVOID)pList->Blink))
break;
DbgPrint("%d= TIMER=%X,DPC=%X,FUN=%X\r\n", i, pTimer, pTimer->Dpc, pTimer->Dpc->DeferredRoutine);
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return;
}
}
[培训]科锐逆向工程师培训第53期2025年7月8日开班!