for
(int i=0;i<0x100;i++)
//
初始化i为0,范围100,第二次运行生效循环体代码。
{
pnode = (PLIST_ENTRY)(addr+i*8);
//KiTimerTableListHead
+8.我这里函数KiTimerTableListHead的位置是0x8055d780,这句话运行后pnode就是0x8055d788?并且吧pnode强制为_LIST_ENTRY结构.
lkd> dt _LIST_ENTRY
nt!_LIST_ENTRY
+0x000 Flink : Ptr32 _LIST_ENTRY
+0x004 Blink : Ptr32 _LIST_ENTRY
pnext = pnode->Blink;
//_LIST_ENTRY
结构第2个成员Blink,pnext=8055D78C?;
while
(pnext!=pnode)
//
如果addr+i*8(Blink?)和addr+i*4(Flink?)相等就跳走。否则运行下面的代码。
{
PKTIMER ptimer = CONTAINING_RECORD(pnext,KTIMER,TimerListEntry);
//
上面那句,通过TimerListEntry成员得到KTIME中第一个成员Header的地址。
//pnext
是0x18这个成员的地址??不会和上面矛盾吗。
nt!_KTIMER
+0x000 Header : _DISPATCHER_HEADER
+0x010 DueTime : _ULARGE_INTEGER
+0x018 TimerListEntry : _LIST_ENTRY
+0x020 Dpc : Ptr32 _KDPC
+0x024 Period : Int4B
if
(MmIsAddressValid(ptimer)
//Dpc
定时器对象地址是否有效
&& MmIsAddressValid(ptimer->Dpc)
//Dpc
地址是否有效
lkd> dt _KDPC
nt!_KDPC
+0x000 Type : Int2B
+0x002 Number : UChar
+0x003 Importance : UChar
+0x004 DpcListEntry : _LIST_ENTRY
+0x00c DeferredRoutine : Ptr32 void
+0x010 DeferredContext : Ptr32 Void
+0x014 SystemArgument1 : Ptr32 Void
+0x018 SystemArgument2 : Ptr32 Void
+0x01c Lock : Ptr32 Uint4B
&& MmIsAddressValid(ptimer->Dpc->DeferredRoutine))
//
接着检查函数入口地址是否有效.
{
routine = (ULONG)ptimer->Dpc->DeferredRoutine;
//
函数入口传给routine
DbgPrint(
"kitimer:0x%x addr:0x%x "
,(ULONG)ptimer,routine);
//
输出DPC定时对象和函数入口地址。
..........省略无关代码............