RemoveDPC

HOOKSSDT中加入了DPC之后 要取消DPC

首先找到DPCHookSSDT.sys的基地址和大小

通过枚举所有DPC的地址  将在范围之内的DPC定时器全部移除

枚举DPC:

WinXP:

1.首先要得到KiTimerTableListHead

 

在WinXP中只需要通过查找8d就可以定位到KiTimerTableListHead 

 

 1 BOOLEAN GetKiTimerTableListHeadInWinXP_X86(ULONG32* KiTimerTableListHead)
 2 {
 3 
 4     ULONG32 KeUpdateSystemTime = 0;
 5     PUCHAR i = NULL;
 6 
 7     KeUpdateSystemTime = (ULONG32)GetExportVariableAddressFormNtosExportTableByVariableName(L"KeUpdateSystemTime");
 8 
 9 
10 
11     DbgPrint("KeUpdateSystemTime: 0X%08x\n", KeUpdateSystemTime);
12 
13     if (KeUpdateSystemTime)
14     {
15     
16         PUCHAR StartSearchAddress = (PUCHAR)KeUpdateSystemTime;  //fffff800`03ecf640
17         PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
18         UCHAR   v1=0;
19         for (i=StartSearchAddress;i<EndSearchAddress;i++)
20         {
21             /*
22 
23             kd> u KeUpdateSystemTime l 50
24             nt!KeUpdateSystemTime:
25             804e35d8 b90000dfff      mov     ecx,0FFDF0000h
26             804e35dd 8b7908          mov     edi,dword ptr [ecx+8]
27             804e35e0 8b710c          mov     esi,dword ptr [ecx+0Ch]
28             804e35e3 03f8            add     edi,eax
29             804e35e5 83d600          adc     esi,0
30             804e35e8 897110          mov     dword ptr [ecx+10h],esi
31             804e35eb 897908          mov     dword ptr [ecx+8],edi
32             804e35ee 89710c          mov     dword ptr [ecx+0Ch],esi
33             804e35f1 290514b05580    sub     dword ptr [nt!KiTickOffset (8055b014)],eax
34             804e35f7 a100b05580      mov     eax,dword ptr [nt!KeTickCount (8055b000)]
35             804e35fc 8bd8            mov     ebx,eax
36             804e35fe 0f8f84000000    jg      nt!KeUpdateSystemTime+0xb0 (804e3688)
37             804e3604 bb0000dfff      mov     ebx,0FFDF0000h
38             804e3609 8b4b14          mov     ecx,dword ptr [ebx+14h]
39             804e360c 8b5318          mov     edx,dword ptr [ebx+18h]
40             804e360f 030d10b05580    add     ecx,dword ptr [nt!KeTimeAdjustment (8055b010)]
41             804e3615 83d200          adc     edx,0
42             804e3618 89531c          mov     dword ptr [ebx+1Ch],edx
43             804e361b 894b14          mov     dword ptr [ebx+14h],ecx
44             804e361e 895318          mov     dword ptr [ebx+18h],edx
45             804e3621 8bd8            mov     ebx,eax
46             804e3623 8bc8            mov     ecx,eax
47             804e3625 8b1504b05580    mov     edx,dword ptr [nt!KeTickCount+0x4 (8055b004)]
48             804e362b 83c101          add     ecx,1
49             804e362e 83d200          adc     edx,0
50             804e3631 891508b05580    mov     dword ptr [nt!KeTickCount+0x8 (8055b008)],edx
51             804e3637 890d00b05580    mov     dword ptr [nt!KeTickCount (8055b000)],ecx
52             804e363d 891504b05580    mov     dword ptr [nt!KeTickCount+0x4 (8055b004)],edx
53             804e3643 50              push    eax
54             804e3644 a10000dfff      mov     eax,dword ptr ds:[FFDF0000h]
55             804e3649 83c001          add     eax,1
56             804e364c 7306            jae     nt!KeUpdateSystemTime+0x7c (804e3654)
57             804e364e ff059c005680    inc     dword ptr [nt!ExpTickCountAdjustmentCount (8056009c)]
58             804e3654 a198005680      mov     eax,dword ptr [nt!ExpTickCountAdjustment (80560098)]
59             804e3659 0faf059c005680  imul    eax,dword ptr [nt!ExpTickCountAdjustmentCount (8056009c)]
60             804e3660 03c1            add     eax,ecx
61             804e3662 a30000dfff      mov     dword ptr ds:[FFDF0000h],eax
62             804e3667 58              pop     eax
63             804e3668 25ff000000      and     eax,0FFh
64             804e366d 8d0cc5a0355680  lea     ecx,nt!KiTimerTableListHead (805635a0)[eax*8]
65 
66             */
67             if( MmIsAddressValid(i))
68             {
69                 v1=*i;
70                 
71                 if(v1==0x8d) 
72                 {
73                     memcpy(KiTimerTableListHead,i+3,4);
74                 
75                     if (*KiTimerTableListHead && MmIsAddressValid((PVOID)*KiTimerTableListHead))
76                     {
77                         return TRUE;
78                     }    
79                 }
80             }
81         }
82     }
83 
84     return FALSE;
85 }
View Code

2.TimerTableList为一个循环带空头的循环链表

通过循环遍历 枚举DPC的信息

 1  BOOLEAN GetDPCTimerInformationInWinXP_X86(PLIST_ENTRY KiTimerTableListHead)
 2 {
 3     NTSTATUS Status = STATUS_UNSUCCESSFUL;
 4    
 5     PLIST_ENTRY NextEntry;
 6     ULONG  n = 0;
 7 
 8     if (KiTimerTableListHead && 
 9         MmIsAddressValid((PVOID)KiTimerTableListHead))  
10     {
11         ULONG i = 0;
12         KIRQL OldIrql = KeRaiseIrqlToDpcLevel();
13 
14         for (i=0;i<0x100;i++)
15         {
16 
17             NextEntry = KiTimerTableListHead[i].Flink; 
18 
19             while (MmIsAddressValid(NextEntry) && &KiTimerTableListHead[i] != NextEntry )  
20             {
21                 PKTIMER Timer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry);
22 
23                 if (Timer && 
24                     MmIsAddressValid(Timer) &&
25                     MmIsAddressValid(Timer->Dpc) &&
26                     MmIsAddressValid(Timer->Dpc->DeferredRoutine))
27                 {
28 
29                     {
30                         PKDPC Dpc = Timer->Dpc;    //DPC 对象  
31                         PVOID TimerDispatch = Dpc->DeferredRoutine;   //回调例程
32 
33 
34 
35                         DbgPrint("DPCObject:%p\r\n",Dpc);
36                         DbgPrint("DPCCallBack:%p\r\n",TimerDispatch);
37                         DbgPrint("TimerObject:%p\r\n",Timer);
38                         DbgPrint("倒计时:%d\r\n:",Timer->Period);
39 
40                         n++;   //记录总数
41                     }
42                 }
43 
44                 NextEntry = NextEntry->Flink;
45             }
46         }
47 
48         KeLowerIrql(OldIrql);
49     }
50 
51 
52     DbgPrint("个数:%d\r\n",n);
53     return Status;
54 }
遍历TimerTableList
 1 PVOID 
 2 GetExportVariableAddressFormNtosExportTableByVariableName(WCHAR *wzVariableName)
 3 {
 4     UNICODE_STRING uniVariableName;  
 5     PVOID VariableAddress = NULL;
 6 
 7     if (wzVariableName && wcslen(wzVariableName) > 0)
 8     {
 9         RtlInitUnicodeString(&uniVariableName, wzVariableName);  
10 
11         //从Ntos模块的导出表中获得一个导出变量的地址
12         VariableAddress = MmGetSystemRoutineAddress(&uniVariableName); 
13     }
14 
15     return VariableAddress;
16 }
从Ntos模块的导出表中获得一个导出变量的地址

 

Win7_64:

在win7_64中 TimerTableList中存储的并不是一个真实的DPC

 1 KDPC* TransTimerDPCEx(PKTIMER Timer,ULONG64 AddressOf_KiWaitNever, ULONG64 AddressOf_KiWaitAlways)
 2 {
 3     ULONG64            DPC = (ULONG64)Timer->Dpc;   
 4     DPC ^= AddressOf_KiWaitNever;
 5     DPC = _rotl64(DPC, (UCHAR)(AddressOf_KiWaitNever & 0xFF));
 6     DPC ^= (ULONG64)Timer;
 7     DPC = _byteswap_uint64(DPC);
 8     DPC ^= AddressOf_KiWaitAlways;
 9     return (KDPC*)DPC;
10 }
转化为真正的DPC
BOOLEAN FindKiWaitVariableAddress(PULONG64 *KiWaitNeverAddress, PULONG64 *KiWaitAlwaysAddress)
{
    /*
    kd> u kesettimer l 50
    nt!KeSetTimer:
    fffff800`03ef10a8 4883ec38        sub     rsp,38h
    fffff800`03ef10ac 4c89442420      mov     qword ptr [rsp+20h],r8
    fffff800`03ef10b1 4533c9          xor     r9d,r9d
    fffff800`03ef10b4 4533c0          xor     r8d,r8d
    fffff800`03ef10b7 e814000000      call    nt!KiSetTimerEx (fffff800`03ef10d0)
    fffff800`03ef10bc 4883c438        add     rsp,38h
    fffff800`03ef10c0 c3              ret
    fffff800`03ef10c1 90              nop
    fffff800`03ef10c2 90              nop
    fffff800`03ef10c3 90              nop
    fffff800`03ef10c4 90              nop
    fffff800`03ef10c5 90              nop
    fffff800`03ef10c6 90              nop
    fffff800`03ef10c7 90              nop
    nt!KxWaitForLockChainValid:
    fffff800`03ef10c8 90              nop
    fffff800`03ef10c9 90              nop
    fffff800`03ef10ca 90              nop
    fffff800`03ef10cb 90              nop
    fffff800`03ef10cc 90              nop
    fffff800`03ef10cd 90              nop
    fffff800`03ef10ce 90              nop
    fffff800`03ef10cf 90              nop
    nt!KiSetTimerEx:
    fffff800`03ef10d0 48895c2408      mov     qword ptr [rsp+8],rbx
    fffff800`03ef10d5 4889542410      mov     qword ptr [rsp+10h],rdx
    fffff800`03ef10da 55              push    rbp
    fffff800`03ef10db 56              push    rsi
    fffff800`03ef10dc 57              push    rdi
    fffff800`03ef10dd 4154            push    r12
    fffff800`03ef10df 4155            push    r13
    fffff800`03ef10e1 4156            push    r14
    fffff800`03ef10e3 4157            push    r15
    fffff800`03ef10e5 4883ec50        sub     rsp,50h
    fffff800`03ef10e9 488b0518502200  mov     rax,qword ptr [nt!KiWaitNever (fffff800`04116108)]
    fffff800`03ef10f0 488b1de9502200  mov     rbx,qword ptr [nt!KiWaitAlways (fffff800`041161e0)]
    */

    ULONG64 KeSetTimer = 0;
    PUCHAR StartSearchAddress = 0; 
    PUCHAR EndSearchAddress   = 0;

    
    INT64   iOffset = 0;    

    PUCHAR i = NULL;
    KeSetTimer = (ULONG64)GetExportVariableAddressFormNtosExportTableByVariableName(L"KeSetTimer");


    StartSearchAddress = (PUCHAR)KeSetTimer; 
    EndSearchAddress = StartSearchAddress + 0x500;

    

    for(i=StartSearchAddress; i<EndSearchAddress; i++)
    {
        if(*i==0x48 && *(i+1)==0x8B && *(i+2)==0x05)
        {
            memcpy(&iOffset,i+3,4);
            *KiWaitNeverAddress=(PULONG64)(iOffset + (ULONG64)i + 7);
            i=i+7;
            memcpy(&iOffset,i+3,4);
            *KiWaitAlwaysAddress=(PULONG64)(iOffset + (ULONG64)i + 7);
            return TRUE;
        }
    }

    return FALSE;
}
View Code
  1 BOOLEAN GetDPCTimerInformationInWin7_X64()
  2 {
  3     
  4     ULONG32 ulCPUNumber = KeNumberProcessors;   
  5     
  6     
  7     
  8     ULONG64 AddressOf_KPRCB = NULL;             //CPU控制块
  9     PUCHAR  TimerEntries = NULL;
 10     PLIST_ENTRY CurrentEntry = NULL;
 11     PLIST_ENTRY NextEntry = NULL;
 12     PULONG64    AddressOf_KiWaitAlways = NULL;
 13     PULONG64    AddressOf_KiWaitNever  = NULL;
 14     int i = 0;
 15     int j = 0;
 16     int n = 0;
 17     PKTIMER Timer;
 18     for(j=0;j<ulCPUNumber; j++)
 19     {
 20         KeSetSystemAffinityThread(j+1);   //使当前线程运行在第一个处理器上,因为只有第一个处理器的值才有效
 21         
 22         AddressOf_KPRCB=(ULONG64)__readmsr(0xC0000101) + 0x20;      //dt _KPRCB
 23         
 24         KeRevertToUserAffinityThread();   ////恢复线程运行的处理器
 25     
 26         TimerEntries=(PUCHAR)(*(ULONG64*)AddressOf_KPRCB + 0x2200 + 0x200);
 27         /*
 28         kd> dt _Kprcb
 29         nt!_KPRCB
 30         +0x000 MxCsr            : Uint4B
 31         +0x004 LegacyNumber     : UChar
 32         +0x005 ReservedMustBeZero : UChar
 33         +0x006 InterruptRequest : UChar
 34         +0x21ec UnusedPad        : Uint4B
 35         +0x21f0 PrcbPad50        : [2] Uint8B
 36         +0x2200 TimerTable       : _KTIMER_TABLE
 37 
 38 
 39         kd> dt _KTIMER_TABLE
 40         nt!_KTIMER_TABLE
 41         +0x000 TimerExpiry      : [64] Ptr64 _KTIMER
 42         +0x200 TimerEntries     : [256] _KTIMER_TABLE_ENTRY
 43 
 44 
 45         kd> dt _KTIMER_TABLE_ENTRY
 46         nt!_KTIMER_TABLE_ENTRY
 47         +0x000 Lock             : Uint8B
 48         +0x008 Entry            : _LIST_ENTRY
 49         +0x018 Time             : _ULARGE_INTEGER
 50         */
 51 
 52     
 53         if(FindKiWaitVariableAddress(&AddressOf_KiWaitNever,&AddressOf_KiWaitAlways)==FALSE)
 54         {
 55             return FALSE;
 56         }
 57         for(i=0; i<0x100; i++)
 58         {
 59             typedef struct _KTIMER_TABLE_ENTRY
 60             {
 61                 ULONG64            Lock;
 62                 LIST_ENTRY        Entry;
 63                 ULARGE_INTEGER    Time;
 64             } KTIMER_TABLE_ENTRY, *PKTIMER_TABLE_ENTRY;
 65             CurrentEntry = (PLIST_ENTRY)(TimerEntries + sizeof(KTIMER_TABLE_ENTRY) * i + 8);  //这里是个数组  + 8 过Lock
 66             NextEntry = CurrentEntry->Blink;
 67             if( MmIsAddressValid(CurrentEntry) && MmIsAddressValid(NextEntry) )
 68             {
 69                 while( NextEntry != CurrentEntry )
 70                 {
 71                     PKDPC RealDPC;
 72 
 73                     //获得首地址
 74                     Timer = CONTAINING_RECORD(NextEntry,KTIMER,TimerListEntry);
 75                     /*
 76                     kd> dt _KTIMER
 77                     nt!_KTIMER
 78                     +0x000 Header           : _DISPATCHER_HEADER
 79                     +0x018 DueTime          : _ULARGE_INTEGER
 80                     +0x020 TimerListEntry   : _LIST_ENTRY
 81                     +0x030 Dpc              : Ptr64 _KDPC
 82                     +0x038 Processor        : Uint4B
 83                     +0x03c Period           : Uint4B
 84                     */
 85                     RealDPC=TransTimerDPCEx(Timer,*AddressOf_KiWaitNever,*AddressOf_KiWaitAlways);
 86                     if( MmIsAddressValid(Timer)&&MmIsAddressValid(RealDPC)&&MmIsAddressValid(RealDPC->DeferredRoutine))
 87                     {
 88                 
 89                         DbgPrint("DPCObject:%p\r\n",(ULONG64)RealDPC);
 90                         DbgPrint("DPCCallBack:%p\r\n",(ULONG64)RealDPC->DeferredRoutine);
 91                         DbgPrint("TimerObject:%p\r\n",(ULONG64)Timer);
 92                         DbgPrint("倒计时:%d\r\n:",Timer->Period);
 93 
 94                         n++;
 95                     
 96                 
 97                     }
 98                     NextEntry = NextEntry->Blink;
 99                 }
100             }
101         }
102     }
103 
104     DbgPrint("个数:%d\r\n",n);
105 
106     return TRUE;
107 }
枚举DPC信息

获取驱动的模块信息:

通过DriverObject->DriverSection中的Ldr获取驱动信息

在x86和64位系统中

 1 typedef struct _LDR_DATA_TABLE_ENTRY_WIN7_X64                        
 2 {                                                                                                
 3     LIST_ENTRY64 InLoadOrderLinks;                      
 4     LIST_ENTRY64 InMemoryOrderLinks;                   
 5     LIST_ENTRY64 InInitializationOrderLinks;           
 6     ULONG64      DllBase;                                                                        
 7     ULONG64      EntryPoint;                                                                     
 8     ULONG32      SizeOfImage;                                                                    
 9     UINT8        _PADDING0_[0x4];                                                                   
10     UNICODE_STRING64 FullDllName;                     
11     UNICODE_STRING64 BaseDllName;                       
12     ULONG32      Flags;                                                                          
13     USHORT       LoadCount;
14     USHORT       TlsIndex;                                                                      
15     union                                                    
16     {                                                                                            
17         LIST_ENTRY64 HashLinks;                       
18         struct                                              
19         {                                                                                        
20             ULONG64      SectionPointer;                                                         
21             ULONG32      CheckSum;                                                               
22             UINT8        _PADDING1_[0x4];                                                        
23         };                                                                                       
24     };                                                                                           
25     union                                                  
26     {                                                                                            
27         ULONG32      TimeDateStamp;                                                              
28         ULONG64      LoadedImports;                                                              
29     };                                                                                           
30 }LDR_DATA_TABLE_ENTRY_WIN7_X64, *PLDR_DATA_TABLE_ENTRY_WIN7_X64;         
31 
32 
33 
34 typedef struct _LDR_DATA_TABLE_ENTRY_WINXP_X86 
35 {
36     LIST_ENTRY32 InLoadOrderLinks;
37     LIST_ENTRY32 InMemoryOrderLinks;
38     LIST_ENTRY32 InInitializationOrderLinks;
39     ULONG32 DllBase;
40     ULONG32 EntryPoint;
41     ULONG32 SizeOfImage;
42     UNICODE_STRING32 FullDllName;
43     UNICODE_STRING32 BaseDllName;
44     ULONG32 Flags;
45     USHORT LoadCount;
46     USHORT TlsIndex;
47     union {
48         LIST_ENTRY32 HashLinks;
49         struct {
50             ULONG32 SectionPointer;
51             ULONG32  CheckSum;
52         };
53     };
54     union {
55         struct {
56             ULONG32  TimeDateStamp;
57         };
58         struct {
59             ULONG32 LoadedImports;
60         };
61     };
62 } LDR_DATA_TABLE_ENTRY_WINXP_X86, *PLDR_DATA_TABLE_ENTRY_WINXP_X86;
63 
64 
65 #ifdef _WIN64
66 #define PLDR_DATA_TABLE_ENTRY PLDR_DATA_TABLE_ENTRY_WIN7_X64
67 #else
68 #define PLDR_DATA_TABLE_ENTRY PLDR_DATA_TABLE_ENTRY_WINXP_X86
69 #endif
PLDR_DATA_TABLE_ENTRY

 

 1 BOOLEAN EnumDriverModuleInforByLdr(PDRIVER_OBJECT DriverObject)  
 2 {
 3     BOOLEAN bRet = FALSE;
 4     if (DriverObject)
 5     {
 6         PLDR_DATA_TABLE_ENTRY CurrentEntry = NULL, NextEntry = NULL;
 7         
 8         CurrentEntry = NextEntry = (PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection;  
 9 
10         if (CurrentEntry->BaseDllName.Buffer&&                                                                 
11             CurrentEntry->BaseDllName.Length>0    &&                                                                
12             MmIsAddressValid((PVOID)CurrentEntry->BaseDllName.Buffer))
13         {
14             DbgPrint("模块地址:%p\r\n",CurrentEntry->DllBase);
15             DbgPrint("模块大小:%d\r\n",CurrentEntry->SizeOfImage);
16             DbgPrint("模块名称:%wZ\r\n",&CurrentEntry->BaseDllName);
17         }
18 
19         NextEntry   = (PLDR_DATA_TABLE_ENTRY)CurrentEntry->InLoadOrderLinks.Flink;
20 
21         while((PLDR_DATA_TABLE_ENTRY)NextEntry!= CurrentEntry)
22         {
23 
24             if (NextEntry->BaseDllName.Buffer&&                                                                 
25                 NextEntry->BaseDllName.Length>0    &&                                                                
26                 MmIsAddressValid((PVOID)NextEntry->BaseDllName.Buffer))
27             {
28                 DbgPrint("模块地址:%p\r\n",NextEntry->DllBase);
29                 DbgPrint("模块大小:%d\r\n",NextEntry->SizeOfImage);
30                 DbgPrint("模块名称:%wZ\r\n",&NextEntry->BaseDllName);
31             }
32 
33             NextEntry = (PLDR_DATA_TABLE_ENTRY)NextEntry->InLoadOrderLinks.Flink;
34         }
35     }
36 
37     else
38     {
39         return FALSE;
40     }
41 
42     return TRUE;
43 }
在Ldr中获取驱动模块信息

 

 

1 if (Timer&&MmIsAddressValid((PVOID)Timer))
2     {
3 
4         if (KeCancelTimer((PKTIMER)Timer))  
5         {
6             return STATUS_SUCCESS;
7         }
8     }
移除DPC

 

 

 1 #ifndef CXX_REMOVEDPCRESUMESSDT_H
 2 #define CXX_REMOVEDPCRESUMESSDT_H
 3 
 4 #include <ntifs.h>
 5 
 6 
 7 
 8 typedef struct _LDR_DATA_TABLE_ENTRY_WIN7_X64                        
 9 {                                                                                                
10     LIST_ENTRY64 InLoadOrderLinks;                      
11     LIST_ENTRY64 InMemoryOrderLinks;                   
12     LIST_ENTRY64 InInitializationOrderLinks;           
13     ULONG64      DllBase;                                                                        
14     ULONG64      EntryPoint;                                                                     
15     ULONG32      SizeOfImage;                                                                    
16     UINT8        _PADDING0_[0x4];                                                                   
17     UNICODE_STRING64 FullDllName;                     
18     UNICODE_STRING64 BaseDllName;                       
19     ULONG32      Flags;                                                                          
20     USHORT       LoadCount;
21     USHORT       TlsIndex;                                                                      
22     union                                                    
23     {                                                                                            
24         LIST_ENTRY64 HashLinks;                       
25         struct                                              
26         {                                                                                        
27             ULONG64      SectionPointer;                                                         
28             ULONG32      CheckSum;                                                               
29             UINT8        _PADDING1_[0x4];                                                        
30         };                                                                                       
31     };                                                                                           
32     union                                                  
33     {                                                                                            
34         ULONG32      TimeDateStamp;                                                              
35         ULONG64      LoadedImports;                                                              
36     };                                                                                           
37 }LDR_DATA_TABLE_ENTRY_WIN7_X64, *PLDR_DATA_TABLE_ENTRY_WIN7_X64;         
38 
39 
40 
41 typedef struct _LDR_DATA_TABLE_ENTRY_WINXP_X86 
42 {
43     LIST_ENTRY32 InLoadOrderLinks;
44     LIST_ENTRY32 InMemoryOrderLinks;
45     LIST_ENTRY32 InInitializationOrderLinks;
46     ULONG32 DllBase;
47     ULONG32 EntryPoint;
48     ULONG32 SizeOfImage;
49     UNICODE_STRING32 FullDllName;
50     UNICODE_STRING32 BaseDllName;
51     ULONG32 Flags;
52     USHORT LoadCount;
53     USHORT TlsIndex;
54     union {
55         LIST_ENTRY32 HashLinks;
56         struct {
57             ULONG32 SectionPointer;
58             ULONG32  CheckSum;
59         };
60     };
61     union {
62         struct {
63             ULONG32  TimeDateStamp;
64         };
65         struct {
66             ULONG32 LoadedImports;
67         };
68     };
69 } LDR_DATA_TABLE_ENTRY_WINXP_X86, *PLDR_DATA_TABLE_ENTRY_WINXP_X86;
70 
71 
72 #ifdef _WIN64
73 #define PLDR_DATA_TABLE_ENTRY PLDR_DATA_TABLE_ENTRY_WIN7_X64
74 #else
75 #define PLDR_DATA_TABLE_ENTRY PLDR_DATA_TABLE_ENTRY_WINXP_X86
76 #endif
77 
78 VOID  UnloadDriver(PDRIVER_OBJECT DriverObject);
79 
80 BOOLEAN  RemoveDPCByKernelModuleName(PDRIVER_OBJECT DriverObject,WCHAR* wzFindKernelModuleName);
81 BOOLEAN GetKiTimerTableListHeadInWinXP_X86(ULONG32* KiTimerTableListHead);
82 BOOLEAN GetDPCTimerInformationInWinXP_X86(PLIST_ENTRY KiTimerTableListHead,PVOID KernelModuleBase,ULONG32 ulKernelModuleSize,ULONG32* ulTimer);
83 BOOLEAN GetDPCTimerInformationInWin7_X64(PVOID KernelModuleBase,ULONG32 ulKernelModuleSize,ULONG64* ulTimer);
84 BOOLEAN FindKiWaitVariableAddress(PULONG64* AddressOf_KiWaitNever, PULONG64* AddressOf_KiWaitAlways);
85 KDPC* TransTimerDPCEx(PKTIMER Timer,ULONG64 AddressOf_KiWaitNever, ULONG64 AddressOf_KiWaitAlways);
86 PVOID 
87     GetExportVariableAddressFormNtosExportTableByVariableName(WCHAR *wzVariableName);
88 
89 BOOLEAN FindKernelModuleInformationInLdrByDriverName(PDRIVER_OBJECT DriverObject,WCHAR* wzFindKernelModuleName,
90     PVOID* KernelModuleBase,ULONG32* ulKernelModuleSize);
91 #endif    
View Code
  1 #ifndef CXX_REMOVEDPCRESUMESSDT_H
  2 #    include "RemoveDPCResumeSSDT.h"
  3 #endif
  4 
  5 NTSTATUS  DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegisterPath)
  6 {
  7 
  8     WCHAR   wzFindKernelModuleName[] = L"DPCHookSSDT.sys";
  9     RemoveDPCByKernelModuleName(DriverObject,wzFindKernelModuleName);
 10     DriverObject->DriverUnload = UnloadDriver;
 11 
 12 
 13 
 14 
 15     return STATUS_SUCCESS;
 16 }
 17 
 18 
 19 BOOLEAN  RemoveDPCByKernelModuleName(PDRIVER_OBJECT DriverObject,WCHAR* wzFindKernelModuleName)
 20 {
 21 
 22 
 23     PVOID   KernelModuleBase     = NULL;
 24     ULONG32 ulKernelModuleSize   = 0;
 25 
 26 
 27  
 28 #ifdef _WIN64
 29     ULONG64 Timer                = 0;
 30     if(FindKernelModuleInformationInLdrByDriverName(DriverObject,wzFindKernelModuleName,
 31         &KernelModuleBase,&ulKernelModuleSize)==FALSE)
 32     {
 33         return FALSE;
 34     }
 35 
 36     DbgPrint("模块的大小:%p\r\n",ulKernelModuleSize);
 37     DbgPrint("模块的的地址:%p\r\n",KernelModuleBase);
 38     if (GetDPCTimerInformationInWin7_X64(KernelModuleBase,ulKernelModuleSize,&Timer)==FALSE)
 39     {
 40         return STATUS_UNSUCCESSFUL;
 41     }
 42     DbgPrint("TimerObject: Win7_X64:%p\r\n",Timer);
 43 
 44 #else
 45     ULONG32 KiTimerTableListHead = 0;
 46     ULONG32 Timer                = 0;
 47 
 48     if(FindKernelModuleInformationInLdrByDriverName(DriverObject,wzFindKernelModuleName,
 49         &KernelModuleBase,&ulKernelModuleSize)==FALSE)
 50     {
 51         return FALSE;
 52     }
 53 
 54     DbgPrint("模块的大小:%p\r\n",ulKernelModuleSize);
 55     DbgPrint("模块的的地址:%p\r\n",KernelModuleBase);
 56     
 57     if (GetKiTimerTableListHeadInWinXP_X86(&KiTimerTableListHead)==FALSE)
 58     {
 59         return STATUS_UNSUCCESSFUL;
 60     }
 61 
 62     DbgPrint("KiTimerTableListHead: WinXP_X86:%p\r\n",KiTimerTableListHead);
 63 
 64     if(GetDPCTimerInformationInWinXP_X86((PLIST_ENTRY)KiTimerTableListHead,KernelModuleBase,ulKernelModuleSize,&Timer)==FALSE)
 65     {
 66         return STATUS_UNSUCCESSFUL;
 67     }
 68 
 69     DbgPrint("TimerObject: WinXP_X86:%p\r\n",Timer);
 70 #endif
 71 
 72 
 73     if (Timer&&MmIsAddressValid((PVOID)Timer))
 74     {
 75 
 76         if (KeCancelTimer((PKTIMER)Timer))  
 77         {
 78             return STATUS_SUCCESS;
 79         }
 80     }
 81 
 82 }
 83 
 84 
 85 
 86 BOOLEAN FindKernelModuleInformationInLdrByDriverName(PDRIVER_OBJECT DriverObject,WCHAR* wzFindKernelModuleName,
 87     PVOID* KernelModuleBase,ULONG32* ulKernelModuleSize)
 88 {
 89 
 90     ULONG32  ulLength = 0;
 91     PLDR_DATA_TABLE_ENTRY CurrentEntry = NULL, NextEntry = NULL;
 92     if (DriverObject)
 93     {
 94     
 95         ulLength = wcslen(wzFindKernelModuleName) * sizeof(WCHAR);
 96         CurrentEntry = NextEntry = (PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection;  
 97 
 98         NextEntry   = (PLDR_DATA_TABLE_ENTRY)CurrentEntry->InLoadOrderLinks.Flink;
 99 
100         while((PLDR_DATA_TABLE_ENTRY)NextEntry!= CurrentEntry)
101         {
102             if (NextEntry->BaseDllName.Buffer&& 
103                 MmIsAddressValid((PVOID)NextEntry->BaseDllName.Buffer)&&
104                 !_wcsnicmp(wzFindKernelModuleName,(WCHAR*)NextEntry->BaseDllName.Buffer, ulLength / sizeof(WCHAR)))
105             {
106 
107 
108                 *KernelModuleBase = NextEntry->DllBase;
109                 *ulKernelModuleSize = NextEntry->SizeOfImage;
110                 break;
111             }
112 
113             NextEntry = (PLDR_DATA_TABLE_ENTRY)NextEntry->InLoadOrderLinks.Flink;
114         }
115     }
116 
117     else
118     {
119         return FALSE;
120     }
121 
122     return TRUE;
123 }
124 
125 
126 
127 
128 BOOLEAN GetKiTimerTableListHeadInWinXP_X86(ULONG32* KiTimerTableListHead)
129 {
130 
131     ULONG32 KeUpdateSystemTime = 0;
132     PUCHAR i = NULL;
133 
134     KeUpdateSystemTime = (ULONG32)GetExportVariableAddressFormNtosExportTableByVariableName(L"KeUpdateSystemTime");
135 
136 
137 
138     DbgPrint("KeUpdateSystemTime: WinXP_X86:%p\r\n", KeUpdateSystemTime);
139 
140     if (KeUpdateSystemTime)
141     {
142     
143         PUCHAR StartSearchAddress = (PUCHAR)KeUpdateSystemTime;  //fffff800`03ecf640
144         PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
145         UCHAR   v1=0;
146         for (i=StartSearchAddress;i<EndSearchAddress;i++)
147         {
148             /*
149 
150             kd> u KeUpdateSystemTime l 50
151             nt!KeUpdateSystemTime:
152             804e35d8 b90000dfff      mov     ecx,0FFDF0000h
153             804e35dd 8b7908          mov     edi,dword ptr [ecx+8]
154             804e35e0 8b710c          mov     esi,dword ptr [ecx+0Ch]
155             804e35e3 03f8            add     edi,eax
156             804e35e5 83d600          adc     esi,0
157             804e35e8 897110          mov     dword ptr [ecx+10h],esi
158             804e35eb 897908          mov     dword ptr [ecx+8],edi
159             804e35ee 89710c          mov     dword ptr [ecx+0Ch],esi
160             804e35f1 290514b05580    sub     dword ptr [nt!KiTickOffset (8055b014)],eax
161             804e35f7 a100b05580      mov     eax,dword ptr [nt!KeTickCount (8055b000)]
162             804e35fc 8bd8            mov     ebx,eax
163             804e35fe 0f8f84000000    jg      nt!KeUpdateSystemTime+0xb0 (804e3688)
164             804e3604 bb0000dfff      mov     ebx,0FFDF0000h
165             804e3609 8b4b14          mov     ecx,dword ptr [ebx+14h]
166             804e360c 8b5318          mov     edx,dword ptr [ebx+18h]
167             804e360f 030d10b05580    add     ecx,dword ptr [nt!KeTimeAdjustment (8055b010)]
168             804e3615 83d200          adc     edx,0
169             804e3618 89531c          mov     dword ptr [ebx+1Ch],edx
170             804e361b 894b14          mov     dword ptr [ebx+14h],ecx
171             804e361e 895318          mov     dword ptr [ebx+18h],edx
172             804e3621 8bd8            mov     ebx,eax
173             804e3623 8bc8            mov     ecx,eax
174             804e3625 8b1504b05580    mov     edx,dword ptr [nt!KeTickCount+0x4 (8055b004)]
175             804e362b 83c101          add     ecx,1
176             804e362e 83d200          adc     edx,0
177             804e3631 891508b05580    mov     dword ptr [nt!KeTickCount+0x8 (8055b008)],edx
178             804e3637 890d00b05580    mov     dword ptr [nt!KeTickCount (8055b000)],ecx
179             804e363d 891504b05580    mov     dword ptr [nt!KeTickCount+0x4 (8055b004)],edx
180             804e3643 50              push    eax
181             804e3644 a10000dfff      mov     eax,dword ptr ds:[FFDF0000h]
182             804e3649 83c001          add     eax,1
183             804e364c 7306            jae     nt!KeUpdateSystemTime+0x7c (804e3654)
184             804e364e ff059c005680    inc     dword ptr [nt!ExpTickCountAdjustmentCount (8056009c)]
185             804e3654 a198005680      mov     eax,dword ptr [nt!ExpTickCountAdjustment (80560098)]
186             804e3659 0faf059c005680  imul    eax,dword ptr [nt!ExpTickCountAdjustmentCount (8056009c)]
187             804e3660 03c1            add     eax,ecx
188             804e3662 a30000dfff      mov     dword ptr ds:[FFDF0000h],eax
189             804e3667 58              pop     eax
190             804e3668 25ff000000      and     eax,0FFh
191             804e366d 8d0cc5a0355680  lea     ecx,nt!KiTimerTableListHead (805635a0)[eax*8]
192 
193 
194 
195 
196             kd> dd 805635a0
197             805635a0  805635a0 805635a0 89b08c08 897e5700
198             805635b0  898954e0 898954e0 805635b8 805635b8
199             805635c0  805635c0 805635c0 805635c8 805635c8
200             805635d0  805635d0 805635d0 8056b718 8056b718
201             805635e0  805635e0 805635e0 895e1f80 895e1f80
202             805635f0  898dc5d8 89992d40 895c3800 895c3800
203             80563600  80563600 80563600 80563608 80563608
204             80563610  895efa98 897ea430 89a9fcf8 89893cf0
205 
206             */
207             if( MmIsAddressValid(i))
208             {
209                 v1=*i;
210                 
211                 if(v1==0x8d) 
212                 {
213                     memcpy(KiTimerTableListHead,i+3,4);
214                 
215                     if (*KiTimerTableListHead && MmIsAddressValid((PVOID)*KiTimerTableListHead))
216                     {
217                         return TRUE;
218                     }    
219                 }
220             }
221         }
222     }
223 
224     return FALSE;
225 }
226 
227 
228 
229 
230 
231 
232 BOOLEAN GetDPCTimerInformationInWinXP_X86(PLIST_ENTRY KiTimerTableListHead,PVOID KernelModuleBase,ULONG32 ulKernelModuleSize,ULONG32* ulTimer)
233 {
234     NTSTATUS Status = STATUS_UNSUCCESSFUL;
235 
236     PLIST_ENTRY NextEntry;
237     ULONG  n = 0;
238 
239     if (KiTimerTableListHead && 
240         MmIsAddressValid((PVOID)KiTimerTableListHead))  
241     {
242         ULONG i = 0;
243         KIRQL OldIrql = KeRaiseIrqlToDpcLevel();
244 
245         for (i=0;i<0x100;i++)
246         {
247 
248             NextEntry = KiTimerTableListHead[i].Flink;  //b0
249 
250             while (MmIsAddressValid(NextEntry) && &KiTimerTableListHead[i] != NextEntry )  //a0!=b0
251             {
252                 PKTIMER Timer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry);
253 
254 
255                 /*
256                 kd> dt _KTIMER
257                 nt!_KTIMER
258                 +0x000 Header           : _DISPATCHER_HEADER
259                 +0x010 DueTime          : _ULARGE_INTEGER
260                 +0x018 TimerListEntry   : _LIST_ENTRY
261                 +0x020 Dpc              : Ptr32 _KDPC
262                 +0x024 Period           : Int4B
263 
264                 */
265                 if (Timer && 
266                     MmIsAddressValid(Timer) &&
267                     MmIsAddressValid(Timer->Dpc) &&
268                     MmIsAddressValid(Timer->Dpc->DeferredRoutine))
269                 {
270                     if ((ULONG32)Timer>=(ULONG32)KernelModuleBase&&(ULONG32)Timer<=(ULONG32)KernelModuleBase+ulKernelModuleSize)
271                     {
272 
273                         *ulTimer = (ULONG32)Timer;
274                         KeLowerIrql(OldIrql);
275 
276 
277                         return TRUE;
278                     }
279                 }
280 
281                 NextEntry = NextEntry->Flink;
282             }
283         }
284 
285         KeLowerIrql(OldIrql);
286     }
287 
288     return FALSE;
289 }
290 
291 
292 
293 
294 PVOID 
295     GetExportVariableAddressFormNtosExportTableByVariableName(WCHAR *wzVariableName)
296 {
297     UNICODE_STRING uniVariableName;  
298     PVOID VariableAddress = NULL;
299 
300     if (wzVariableName && wcslen(wzVariableName) > 0)
301     {
302         RtlInitUnicodeString(&uniVariableName, wzVariableName);  
303 
304         //从Ntos模块的导出表中获得一个导出变量的地址
305         VariableAddress = MmGetSystemRoutineAddress(&uniVariableName); 
306     }
307 
308     return VariableAddress;
309 }
310 
311 
312 
313 
314 BOOLEAN GetDPCTimerInformationInWin7_X64(PVOID KernelModuleBase,ULONG32 ulKernelModuleSize,ULONG64* ulTimer)
315 {
316     
317     ULONG32 ulCPUNumber = KeNumberProcessors;   //CPU个数
318     ULONG64 AddressOf_KPRCB = NULL;             //CPU控制块
319     PUCHAR  TimerEntries = NULL;
320     PLIST_ENTRY CurrentEntry = NULL;
321     PLIST_ENTRY NextEntry = NULL;
322     PULONG64    AddressOf_KiWaitAlways = NULL;
323     PULONG64    AddressOf_KiWaitNever  = NULL;
324     int i = 0;
325     int j = 0;
326     int n = 0;
327     PKTIMER Timer;
328     for(j=0;j<ulCPUNumber; j++)
329     {
330         KeSetSystemAffinityThread(j+1);   //使当前线程运行在第一个处理器上,因为只有第一个处理器的值才有效
331         
332         AddressOf_KPRCB=(ULONG64)__readmsr(0xC0000101) + 0x20;      //dt _KPRCB
333         
334         KeRevertToUserAffinityThread();   ////恢复线程运行的处理器
335     
336         TimerEntries=(PUCHAR)(*(ULONG64*)AddressOf_KPRCB + 0x2200 + 0x200);
337         /*
338         kd> dt _Kprcb
339         nt!_KPRCB
340         +0x000 MxCsr            : Uint4B
341         +0x004 LegacyNumber     : UChar
342         +0x005 ReservedMustBeZero : UChar
343         +0x006 InterruptRequest : UChar
344         +0x21ec UnusedPad        : Uint4B
345         +0x21f0 PrcbPad50        : [2] Uint8B
346         +0x2200 TimerTable       : _KTIMER_TABLE
347 
348 
349         kd> dt _KTIMER_TABLE
350         nt!_KTIMER_TABLE
351         +0x000 TimerExpiry      : [64] Ptr64 _KTIMER
352         +0x200 TimerEntries     : [256] _KTIMER_TABLE_ENTRY
353 
354 
355         kd> dt _KTIMER_TABLE_ENTRY
356         nt!_KTIMER_TABLE_ENTRY
357         +0x000 Lock             : Uint8B
358         +0x008 Entry            : _LIST_ENTRY
359         +0x018 Time             : _ULARGE_INTEGER
360         */
361 
362     
363         if(FindKiWaitVariableAddress(&AddressOf_KiWaitNever,&AddressOf_KiWaitAlways)==FALSE)
364         {
365             return FALSE;
366         }
367         for(i=0; i<0x100; i++)
368         {
369             typedef struct _KTIMER_TABLE_ENTRY
370             {
371                 ULONG64            Lock;
372                 LIST_ENTRY        Entry;
373                 ULARGE_INTEGER    Time;
374             } KTIMER_TABLE_ENTRY, *PKTIMER_TABLE_ENTRY;
375             CurrentEntry = (PLIST_ENTRY)(TimerEntries + sizeof(KTIMER_TABLE_ENTRY) * i + 8);  //这里是个数组  + 8 过Lock
376             NextEntry = CurrentEntry->Blink;
377             if( MmIsAddressValid(CurrentEntry) && MmIsAddressValid(NextEntry) )
378             {
379                 while( NextEntry != CurrentEntry )
380                 {
381                     PKDPC RealDPC;
382 
383                     //获得首地址
384                     Timer = CONTAINING_RECORD(NextEntry,KTIMER,TimerListEntry);
385                     /*
386                     kd> dt _KTIMER
387                     nt!_KTIMER
388                     +0x000 Header           : _DISPATCHER_HEADER
389                     +0x018 DueTime          : _ULARGE_INTEGER
390                     +0x020 TimerListEntry   : _LIST_ENTRY
391                     +0x030 Dpc              : Ptr64 _KDPC
392                     +0x038 Processor        : Uint4B
393                     +0x03c Period           : Uint4B
394                     */
395                     RealDPC=TransTimerDPCEx(Timer,*AddressOf_KiWaitNever,*AddressOf_KiWaitAlways);
396                     if( MmIsAddressValid(Timer)&&MmIsAddressValid(RealDPC)&&MmIsAddressValid(RealDPC->DeferredRoutine))
397                     {
398                         if ((ULONG64)Timer>=(ULONG64)KernelModuleBase&&(ULONG64)Timer<=(ULONG64)KernelModuleBase+ulKernelModuleSize)
399                         {
400 
401                             *ulTimer = (ULONG64)Timer;
402                     
403 
404                             return TRUE;
405                         }
406                 
407                     }
408                     NextEntry = NextEntry->Blink;
409                 }
410             }
411         }
412     }
413     return FALSE;
414 }
415 
416 
417 
418 
419 
420 BOOLEAN FindKiWaitVariableAddress(PULONG64* AddressOf_KiWaitNever, PULONG64* AddressOf_KiWaitAlways)
421 {
422     /*
423     kd> u kesettimer l 50
424     nt!KeSetTimer:
425     fffff800`03ef10a8 4883ec38        sub     rsp,38h
426     fffff800`03ef10ac 4c89442420      mov     qword ptr [rsp+20h],r8
427     fffff800`03ef10b1 4533c9          xor     r9d,r9d
428     fffff800`03ef10b4 4533c0          xor     r8d,r8d
429     fffff800`03ef10b7 e814000000      call    nt!KiSetTimerEx (fffff800`03ef10d0)
430     fffff800`03ef10bc 4883c438        add     rsp,38h
431     fffff800`03ef10c0 c3              ret
432     fffff800`03ef10c1 90              nop
433     fffff800`03ef10c2 90              nop
434     fffff800`03ef10c3 90              nop
435     fffff800`03ef10c4 90              nop
436     fffff800`03ef10c5 90              nop
437     fffff800`03ef10c6 90              nop
438     fffff800`03ef10c7 90              nop
439     nt!KxWaitForLockChainValid:
440     fffff800`03ef10c8 90              nop
441     fffff800`03ef10c9 90              nop
442     fffff800`03ef10ca 90              nop
443     fffff800`03ef10cb 90              nop
444     fffff800`03ef10cc 90              nop
445     fffff800`03ef10cd 90              nop
446     fffff800`03ef10ce 90              nop
447     fffff800`03ef10cf 90              nop
448     nt!KiSetTimerEx:
449     fffff800`03ef10d0 48895c2408      mov     qword ptr [rsp+8],rbx
450     fffff800`03ef10d5 4889542410      mov     qword ptr [rsp+10h],rdx
451     fffff800`03ef10da 55              push    rbp
452     fffff800`03ef10db 56              push    rsi
453     fffff800`03ef10dc 57              push    rdi
454     fffff800`03ef10dd 4154            push    r12
455     fffff800`03ef10df 4155            push    r13
456     fffff800`03ef10e1 4156            push    r14
457     fffff800`03ef10e3 4157            push    r15
458     fffff800`03ef10e5 4883ec50        sub     rsp,50h
459     fffff800`03ef10e9 488b0518502200  mov     rax,qword ptr [nt!KiWaitNever (fffff800`04116108)]
460     fffff800`03ef10f0 488b1de9502200  mov     rbx,qword ptr [nt!KiWaitAlways (fffff800`041161e0)]
461     */
462 
463     ULONG64 KeSetTimer = 0;
464     PUCHAR StartSearchAddress = 0; 
465     PUCHAR EndSearchAddress   = 0;
466 
467     
468     INT64   iOffset = 0;    
469 
470     PUCHAR i = NULL;
471     KeSetTimer = (ULONG64)GetExportVariableAddressFormNtosExportTableByVariableName(L"KeSetTimer");
472 
473 
474     StartSearchAddress = (PUCHAR)KeSetTimer; 
475     EndSearchAddress = StartSearchAddress + 0x500;
476 
477     
478 
479     for(i=StartSearchAddress; i<EndSearchAddress; i++)
480     {
481         if(*i==0x48 && *(i+1)==0x8B && *(i+2)==0x05)
482         {
483             memcpy(&iOffset,i+3,4);
484             *AddressOf_KiWaitNever=(PULONG64)(iOffset + (ULONG64)i + 7);
485             i=i+7;
486             memcpy(&iOffset,i+3,4);
487             *AddressOf_KiWaitAlways=(PULONG64)(iOffset + (ULONG64)i + 7);
488             return TRUE;
489         }
490     }
491 
492     return FALSE;
493 }
494 
495 
496 
497 KDPC* TransTimerDPCEx(PKTIMER Timer,ULONG64 AddressOf_KiWaitNever, ULONG64 AddressOf_KiWaitAlways)
498 {
499     ULONG64            DPC = (ULONG64)Timer->Dpc;   
500     DPC ^= AddressOf_KiWaitNever;
501     DPC = _rotl64(DPC, (UCHAR)(AddressOf_KiWaitNever & 0xFF));
502     DPC ^= (ULONG64)Timer;
503     DPC = _byteswap_uint64(DPC);
504     DPC ^= AddressOf_KiWaitAlways;
505     return (KDPC*)DPC;
506 }
507 
508 VOID  UnloadDriver(PDRIVER_OBJECT DriverObject)
509 {
510 
511 }
View Code

 

posted on 2015-11-16 13:45  yifi  阅读(279)  评论(0编辑  收藏  举报

导航