HookSSDT 通过HookOpenProcess函数阻止暴力枚举进程

首先要知道Ring3层调用OpenProcess的流程

//当Ring3调用OpenProcess
//1从自己的模块(.exe)的导入表中取值

//2Ntdll.dll模块的导出表中执行ZwOpenProcess(取索引 进入Ring0层)

//3进入Ring0 从Ntoskernel.exe模块的导出表中执行ZwOpenProcess(取索引 获得SSDT服务地址)

//4通过索引在SSDT表中取值(NtOpenProcess的地址)

//5真正调用NtOpenProcess函数

我们可以通过在第4部通过索引将NtOpenProcess 换成 Base[索引] = FakeNtOpenProcess;

1.我们要获取SSDT的结构信息

XP 32位的SSDT在Ntos模块导出表中有

 1 //SSDT表的基地址32位(4Bytes)64位(8Bytes)
 2 //XP 32位Ntos模块导出表中有   Win7 64 Ntos模块导出表中无
 3 BOOLEAN GetSSDTAddressInWinXP_X86(ULONG32* SSDTAddress)
 4 {
 5     //从NtosKernel.exe 模块中的导出表获得该导出变量  KeServiceDescriptorTable
 6 
 7     /*
 8     kd> dd KeServiceDescriptorTable
 9     80563520  804e58a0 00000000 0000011c 805120bc
10     */
11     *SSDTAddress = NULL;
12     *SSDTAddress = (ULONG32)GetExportVariableAddressFormNtosExportTableByVariableName(L"KeServiceDescriptorTable");
13 
14     if (*SSDTAddress!=NULL)
15     {
16         return TRUE;
17     }
18 
19     return FALSE;
20 }
获取SSDT的地址32

win7 64位没有被导出 但可以通过读取制定的msr得出 

// 来自 作者:胡文亮

Msr 的中文全称是就是“特别模块寄存器” (model specific
register) ,它控制 CPU 的工作环境和标示 CPU 的工作状态等信息(例如倍频、最大 TDP、
危险警报温度) ,它能够读取,也能够写入,但是无论读取还是写入,都只能在 Ring 0 下
进行。我们通过读取 C0000082 寄存器,能够得到 KiSystemCall64 的地址,然后从
KiSystemCall64 的地址开始,往下搜索 0x500 字节左右(特征码是 4c8d15) ,就能得到
KeServiceDescriptorTable 的地址了。同理,我们换一下特征码(4c8d1d) ,就能获得
KeServiceDescriptorTableShadow 的地址了。

  1 BOOLEAN GetSSDTAddressInWin7_X64(ULONG64* SSDTAddress)
  2 {
  3 
  4     
  5     /*
  6     kd> rdmsr c0000082 
  7     msr[c0000082] = fffff800`03ecf640
  8     kd> u fffff800`03ecf640 l 50
  9     nt!KiSystemCall64:
 10     fffff800`03ecf640 0f01f8          swapgs
 11     fffff800`03ecf643 654889242510000000 mov   qword ptr gs:[10h],rsp
 12     fffff800`03ecf64c 65488b2425a8010000 mov   rsp,qword ptr gs:[1A8h]
 13     fffff800`03ecf655 6a2b            push    2Bh
 14     fffff800`03ecf657 65ff342510000000 push    qword ptr gs:[10h]
 15     fffff800`03ecf65f 4153            push    r11
 16     fffff800`03ecf661 6a33            push    33h
 17     fffff800`03ecf663 51              push    rcx
 18     fffff800`03ecf664 498bca          mov     rcx,r10
 19     fffff800`03ecf667 4883ec08        sub     rsp,8
 20     fffff800`03ecf66b 55              push    rbp
 21     fffff800`03ecf66c 4881ec58010000  sub     rsp,158h
 22     fffff800`03ecf673 488dac2480000000 lea     rbp,[rsp+80h]
 23     fffff800`03ecf67b 48899dc0000000  mov     qword ptr [rbp+0C0h],rbx
 24     fffff800`03ecf682 4889bdc8000000  mov     qword ptr [rbp+0C8h],rdi
 25     fffff800`03ecf689 4889b5d0000000  mov     qword ptr [rbp+0D0h],rsi
 26     fffff800`03ecf690 c645ab02        mov     byte ptr [rbp-55h],2
 27     fffff800`03ecf694 65488b1c2588010000 mov   rbx,qword ptr gs:[188h]
 28     fffff800`03ecf69d 0f0d8bd8010000  prefetchw [rbx+1D8h]
 29     fffff800`03ecf6a4 0fae5dac        stmxcsr dword ptr [rbp-54h]
 30     fffff800`03ecf6a8 650fae142580010000 ldmxcsr dword ptr gs:[180h]
 31     fffff800`03ecf6b1 807b0300        cmp     byte ptr [rbx+3],0
 32     fffff800`03ecf6b5 66c785800000000000 mov   word ptr [rbp+80h],0
 33     fffff800`03ecf6be 0f848c000000    je      nt!KiSystemCall64+0x110 (fffff800`03ecf750)
 34     fffff800`03ecf6c4 488945b0        mov     qword ptr [rbp-50h],rax
 35     fffff800`03ecf6c8 48894db8        mov     qword ptr [rbp-48h],rcx
 36     fffff800`03ecf6cc 488955c0        mov     qword ptr [rbp-40h],rdx
 37     fffff800`03ecf6d0 f6430303        test    byte ptr [rbx+3],3
 38     fffff800`03ecf6d4 4c8945c8        mov     qword ptr [rbp-38h],r8
 39     fffff800`03ecf6d8 4c894dd0        mov     qword ptr [rbp-30h],r9
 40     fffff800`03ecf6dc 7405            je      nt!KiSystemCall64+0xa3 (fffff800`03ecf6e3)
 41     fffff800`03ecf6de e80d140000      call    nt!KiSaveDebugRegisterState (fffff800`03ed0af0)
 42     fffff800`03ecf6e3 f6430380        test    byte ptr [rbx+3],80h
 43     fffff800`03ecf6e7 7442            je      nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
 44     fffff800`03ecf6e9 b9020100c0      mov     ecx,0C0000102h
 45     fffff800`03ecf6ee 0f32            rdmsr
 46     fffff800`03ecf6f0 48c1e220        shl     rdx,20h
 47     fffff800`03ecf6f4 480bc2          or      rax,rdx
 48     fffff800`03ecf6f7 483983b8000000  cmp     qword ptr [rbx+0B8h],rax
 49     fffff800`03ecf6fe 742b            je      nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
 50     fffff800`03ecf700 483983b0010000  cmp     qword ptr [rbx+1B0h],rax
 51     fffff800`03ecf707 7422            je      nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
 52     fffff800`03ecf709 488b93b8010000  mov     rdx,qword ptr [rbx+1B8h]
 53     fffff800`03ecf710 0fba6b4c0b      bts     dword ptr [rbx+4Ch],0Bh
 54     fffff800`03ecf715 66ff8bc4010000  dec     word ptr [rbx+1C4h]
 55     fffff800`03ecf71c 48898280000000  mov     qword ptr [rdx+80h],rax
 56     fffff800`03ecf723 fb              sti
 57     fffff800`03ecf724 e8170b0000      call    nt!KiUmsCallEntry (fffff800`03ed0240)
 58     fffff800`03ecf729 eb0f            jmp     nt!KiSystemCall64+0xfa (fffff800`03ecf73a)
 59     fffff800`03ecf72b f6430340        test    byte ptr [rbx+3],40h
 60     fffff800`03ecf72f 7409            je      nt!KiSystemCall64+0xfa (fffff800`03ecf73a)
 61     fffff800`03ecf731 f00fbaab0001000008 lock bts dword ptr [rbx+100h],8
 62     fffff800`03ecf73a 488b45b0        mov     rax,qword ptr [rbp-50h]
 63     fffff800`03ecf73e 488b4db8        mov     rcx,qword ptr [rbp-48h]
 64     fffff800`03ecf742 488b55c0        mov     rdx,qword ptr [rbp-40h]
 65     fffff800`03ecf746 4c8b45c8        mov     r8,qword ptr [rbp-38h]
 66     fffff800`03ecf74a 4c8b4dd0        mov     r9,qword ptr [rbp-30h]
 67     fffff800`03ecf74e 6690            xchg    ax,ax
 68     fffff800`03ecf750 fb              sti
 69     fffff800`03ecf751 48898be0010000  mov     qword ptr [rbx+1E0h],rcx
 70     fffff800`03ecf758 8983f8010000    mov     dword ptr [rbx+1F8h],eax
 71     nt!KiSystemServiceStart:
 72     fffff800`03ecf75e 4889a3d8010000  mov     qword ptr [rbx+1D8h],rsp
 73     fffff800`03ecf765 8bf8            mov     edi,eax
 74     fffff800`03ecf767 c1ef07          shr     edi,7
 75     fffff800`03ecf76a 83e720          and     edi,20h
 76     fffff800`03ecf76d 25ff0f0000      and     eax,0FFFh
 77     nt!KiSystemServiceRepeat:
 78     fffff800`03ecf772 4c8d15c7202300  lea     r10,[nt!KeServiceDescriptorTable (fffff800`04101840)]
 79 
 80     fffff800`03ecf772 + 002320c7 + 7  = fffff800`04101840
 81     */
 82 
 83 
 84 
 85 
 86     PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082);   //fffff800`03ecf640
 87     PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
 88     PUCHAR i = NULL;
 89     UCHAR   v1=0,v2=0,v3=0;
 90     INT64   iOffset = 0;    //002320c7
 91     ULONG64 VariableAddress = 0;
 92     *SSDTAddress = NULL;
 93     for(i=StartSearchAddress;i<EndSearchAddress;i++)
 94     {
 95         if( MmIsAddressValid(i) && MmIsAddressValid(i+1) && MmIsAddressValid(i+2) )
 96         {
 97             v1=*i;
 98             v2=*(i+1);
 99             v3=*(i+2);
100             if(v1==0x4c && v2==0x8d && v3==0x15 ) 
101             {
102                 memcpy(&iOffset,i+3,4);
103                 *SSDTAddress = iOffset + (ULONG64)i + 7;
104 
105                 break;
106             }
107         }
108     }
109 
110     if (*SSDTAddress==NULL)
111     {
112         return FALSE;
113     }
114 
115     /*
116     kd> dq fffff800`04101840
117     fffff800`04101840  fffff800`03ed1300 00000000`00000000
118     fffff800`04101850  00000000`00000191 fffff800`03ed1f8c
119 
120     */
121     return TRUE;
122 }
获取SSDT

2从Ntdll模块中的导出表获得要Hook的函数索引

 1 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex)
 2 {
 3     /*
 4     0:001> u zwopenprocess
 5     ntdll!ZwOpenProcess:
 6     7c92d5e0 b87a000000      mov     eax,7Ah
 7     7c92d5e5 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
 8     7c92d5ea ff12            call    dword ptr [edx]
 9     7c92d5ec c21000          ret     10h
10     7c92d5ef 90              nop
11     */
12 
13     ULONG32     ulOffset_SSDTFunctionIndex = 1;
14 
15 
16     //从Ntdll模块的导出表中获得7c92d5e0
17     //使用内存映射将Ntdll模块映射到System进程的内存空间进行查找(Ntdll.dll模块的导出表中进行搜索)
18     ULONG   i;
19     BOOLEAN  bOk = FALSE;
20     WCHAR    wzFileFullPath[] = L"\SystemRoot\System32\ntdll.dll";
21     SIZE_T  MappingViewSize   = 0;
22     PVOID    MappingBaseAddress = NULL;
23     PIMAGE_NT_HEADERS  NtHeader = NULL;
24     PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
25     ULONG32*  AddressOfFunctions    = NULL;
26     ULONG32*  AddressOfNames        = NULL;
27     USHORT* AddressOfNameOrdinals = NULL;
28     CHAR*   szFunctionName        = NULL;
29     ULONG32 ulFunctionOrdinal     = 0;
30     ULONG32 ulFunctionAddress     = 0;
31     
32     *SSDTFunctionIndex = -1;
33 
34 
35     //将Ntdll.dll 当前的空间中
36     bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
37     if (bOk==FALSE)
38     {
39         return FALSE;
40     }
41     else
42     {
43         __try{
44             NtHeader = RtlImageNtHeader(MappingBaseAddress);
45             if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
46             {
47                 ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG32)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
48                 
49                 
50                 
51                 AddressOfFunctions = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
52                 AddressOfNames = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNames);
53                 AddressOfNameOrdinals = (USHORT*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
54                 for(i = 0; i < ExportDirectory->NumberOfNames; i++)
55                 {
56                     szFunctionName = (char*)((ULONG32)MappingBaseAddress + AddressOfNames[i]);   //获得函数名称
57                     if (_stricmp(szFunctionName, szFindFunctionName) == 0)   
58                     {
59                         ulFunctionOrdinal = AddressOfNameOrdinals[i]; 
60                         ulFunctionAddress = (ULONG32)((ULONG32)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]);
61                         
62                         
63                         *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex); 
64                         break;
65                     }
66                 }
67             }
68         }__except(EXCEPTION_EXECUTE_HANDLER)
69         {
70             ;
71         }
72     }
73 
74 
75     ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress);
76 
77 
78     if (*SSDTFunctionIndex==-1)
79     {
80         return FALSE;
81     }
82     
83     return TRUE;
84 }
获取函数索引32
 1 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex)
 2 {
 3     /*
 4     0:004> u zwopenprocess
 5     ntdll!NtOpenProcess:
 6     00000000`774ddc10 4c8bd1          mov     r10,rcx
 7     00000000`774ddc13 b823000000      mov     eax,23h
 8     00000000`774ddc18 0f05            syscall
 9     00000000`774ddc1a c3              ret
10     00000000`774ddc1b 0f1f440000      nop     dword ptr [rax+rax]
11     */
12 
13     ULONG32     ulOffset_SSDTFunctionIndex = 4;
14 
15     ULONG   i;
16     BOOLEAN  bOk = FALSE;
17     WCHAR    wzFileFullPath[] = L"\SystemRoot\System32\ntdll.dll";
18     SIZE_T   MappingViewSize   = 0;
19     PVOID    MappingBaseAddress = NULL;
20     PIMAGE_NT_HEADERS  NtHeader = NULL;
21     PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
22     ULONG32*  AddressOfFunctions    = NULL;
23     ULONG32*  AddressOfNames        = NULL;
24     USHORT*   AddressOfNameOrdinals = NULL;
25     CHAR*     szFunctionName        = NULL;
26     ULONG32   ulFunctionOrdinal     = 0;
27     ULONG64   ulFunctionAddress     = 0;
28 
29     *SSDTFunctionIndex = -1;
30 
31 
32     //将Ntdll.dll 当前的空间中
33     bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
34     if (bOk==FALSE)
35     {
36         return FALSE;
37     }
38     else
39     {
40         __try{
41             NtHeader = RtlImageNtHeader(MappingBaseAddress);
42             if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
43             {
44                 ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG64)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
45 
46 
47 
48                 AddressOfFunctions = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
49                 AddressOfNames = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNames);
50                 AddressOfNameOrdinals = (USHORT*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
51                 for(i = 0; i < ExportDirectory->NumberOfNames; i++)
52                 {
53                     szFunctionName = (char*)((ULONG64)MappingBaseAddress + AddressOfNames[i]);   //获得函数名称
54                     if (_stricmp(szFunctionName, szFindFunctionName) == 0)   
55                     {
56                         ulFunctionOrdinal = AddressOfNameOrdinals[i]; 
57                         ulFunctionAddress = (ULONG64)((ULONG64)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]);
58 
59 
60                         *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex); 
61                         break;
62                     }
63                 }
64             }
65         }__except(EXCEPTION_EXECUTE_HANDLER)
66         {
67             ;
68         }
69     }
70 
71 
72     ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress);
73 
74 
75     if (*SSDTFunctionIndex==-1)
76     {
77         return FALSE;
78     }
79 
80     return TRUE;
81 }
获取函数索引64

3.保存原先函数的地址

64位与32位不同 64为中存放的并不是SSDT函数的完整地址而是其相对于

ServiceTableBase[Index]>>4 的数据(称它为偏移地址)

4.在32位中换掉Base中索引里的数据 NtOpenProcess    Base[索引] == FakeNtOpenProcess  -->HookSSDT

在32位中 直接替换就可以了但是......................

/* 一系列的说明 作者:胡文亮 */

HOOK SSDT 就很简单了,首先获得待 HOOK 函数的序号
Index,然后通过公式把自己的代理函数的地址转化为偏移地址,然后把偏移地
址的数据填入 ServiceTableBase[Index]。也许有些读者看到这里,已经觉得胜
利在望了,我当时也是如此。但实际上我在这里栽了个大跟头,整整郁闷了很长
时间!因为我低估了设计这套算法的工程师的智商,我没有考虑一个问题,为什
么 WIN64 的 SSDT 表存放地址的形式这么奇怪?只存放偏移地址,而不存放完整
地址?难道是为了节省内存?这肯定是不可能的,要知道现在内存白菜价。那么
不是为了节省内存,唯一的可能性就是要给试图挂钩 SSDT 的人制造麻烦!要知
道,WIN64 内核里每个驱动都 不在同一个 B 4GB 里,而 4 字节的整数只能表示 4GB
的范围!所以无论你怎么修改这个值,都跳不出 ntoskrnl 的手掌心。如果你想
通过修改这个值来跳转到你的代理函数, 那是绝对不可能的。 因为你的驱动的地
址不 可能跟 l ntoskrnl 在同一个 B 4GB 里。然而,这位工程师也低估了我们中国人
的智商, 在中国有两句成语, 这位工程师一定没听过, 叫 “明修栈道, 暗渡陈仓”
以及“上有政策,下有对策” 。虽然不能直接用 4 字节来表示自己的代理函数所
在的地址, 但是还是可以修改这个值的。 要知道, ntoskrnl 虽然有很多地方的代
码通常是不会被执行的, 比如 KeBugCheckEx。 所以我的办法是: 修改这个偏移地
址的值,使之跳转到 KeBugCheckEx ,然后在 x KeBugCheckEx 的头部写一个 2 12 字
节的 mov - - jmp , 这是一个可以跨越 4GB B ! 的跳转, 跳到我们的函数里!

 1 VOID HookSSDTWin7_X64(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG64 ulFakeVariable)
 2 {
 3     //寻找一个内核不常用的函数(KeBugCheckEx) 进行InlineHook使其跳转到Fake_NtOpenProcess函数
 4     ULONG32  ulVariable = 0;
 5 
 6     WPOFF(); 
 7     InlineHook(KeBugCheckEx,ulFakeVariable,szOldKeBugCheckExCode,15);
 8     WPON();
 9 
10 
11     //寻找一个内核不常用的函数(KeBugCheckEx) 计算SSDT中的偏移 进行置换
12 
13     ulVariable = CalcFunctionOffsetInSSDT(KeBugCheckEx,5);
14 
15     WPOFF(); 
16     ServiceTableBase[ulSSDTFunctionIndex] = (ULONG32)ulVariable;
17     WPON();
18 }
HookSSDT64
1 VOID HookSSDTWinXP_X86(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulFakeVariable)
2 {
3     WPOFF(); 
4     ServiceTableBase[ulSSDTFunctionIndex] = (ULONG32)ulFakeVariable;
5     WPON();
6 }
HookSSDT32

完整代码

  1 #ifndef CXX_HOOKSSDT_H
  2 #    include "HookSSDT.h"
  3 #endif
  4 
  5 
  6 //1获得SSDT表的结构信息     Base
  7 //2从Ntdll模块中的导出表获得要Hook的函数索引
  8 //3换掉Base中索引里的数据 NtOpenProcess    Base[索引] == FakeNtOpenProcess      --->HookSSDT
  9 
 10 PULONG32  ServiceTableBase            = NULL;
 11 ULONG32   SSDT_NtOpenProcessIndex     = 0;
 12 pfnNtOpenProcess  Old_NtOpenProcess  = NULL;
 13 ULONG32           Old_NtOpenProcessOffset = 0;    //针对Win7 x64
 14 
 15 UCHAR             szOldKeBugCheckExCode[15] = {0};
 16 NTSTATUS  DriverEntry(PDRIVER_OBJECT  DriverObject,PUNICODE_STRING RegisterPath)
 17 {
 18 
 19 
 20 #ifdef _WIN64
 21     ULONG64   SSDTAddress = NULL;
 22     ULONG32   ulVariable  = 0;
 23 
 24     CHAR      szFindFunctionName[] = "ZwOpenProcess";
 25 
 26 
 27     if (GetSSDTAddressInWin7_X64(&SSDTAddress)==FALSE)
 28     {
 29         return STATUS_UNSUCCESSFUL;
 30     }
 31 
 32     DbgPrint("Win7x64 SSDT:%p
",SSDTAddress);
 33     DbgPrint("Win7x64 SSDTBase:%p
",((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase);
 34 
 35 
 36     /*
 37     kd> dd FFFFF80003E8B300 l 200
 38     fffff800`03e8b300  040d9a00 02f55c00 fff6ea00 02e87805
 39     fffff800`03e8b310  031a4a06 03116a05 02bb9901 02b4f200
 40     fffff800`03e8b320  0312cc40 03dd7400 02c84700 02e7d100
 41     fffff800`03e8b330  02f68100 02e02301 02dd0601 02d96100
 42     fffff800`03e8b340  02df4602 02f18600 02ad0500 02cefe01
 43     fffff800`03e8b350  02d01d02 02f69902 03101101 0323ca01
 44     fffff800`03e8b360  0455c305 02ed29c0 02b2e703 ffec1d00
 45     fffff800`03e8b370  043c2800 02f51040 02c52c01 03126c00
 46     fffff800`03e8b380  02d96302 02d30380 02ec7301 02d1fec0(NtOpenProcess Offset)
 47 
 48 
 49 
 50     */
 51 
 52     /*
 53     kd> u NtOpenProcess
 54     nt!NtOpenProcess:
 55     fffff800`0415d2ec 4883ec38        sub     rsp,38h
 56     fffff800`0415d2f0 65488b042588010000 mov   rax,qword ptr gs:[188h]
 57     fffff800`0415d2f9 448a90f6010000  mov     r10b,byte ptr [rax+1F6h]
 58     fffff800`0415d300 4488542428      mov     byte ptr [rsp+28h],r10b
 59     fffff800`0415d305 4488542420      mov     byte ptr [rsp+20h],r10b
 60     fffff800`0415d30a e851fcffff      call    nt!PsOpenProcess (fffff800`0415cf60)
 61     fffff800`0415d30f 4883c438        add     rsp,38h
 62     fffff800`0415d313 c3              ret
 63 
 64 
 65     */
 66 
 67     //fffff8000415d2ec - FFFFF80003E8B300 = 2D1FEC<<4 = 2D1FEC0
 68     DbgPrint("Win7x64 SSDTNumberOfService:%d
",((PSYSTEM_SERVICE_TABLE)SSDTAddress)->NumberOfServices);
 69 
 70 
 71     if (GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(szFindFunctionName,&SSDT_NtOpenProcessIndex)==FALSE)
 72     {
 73         return STATUS_UNSUCCESSFUL;
 74     }
 75 
 76     DbgPrint("Win7x64 SSDT_NtOpenProcessIndex:%d
",SSDT_NtOpenProcessIndex);
 77     
 78     
 79     
 80     ServiceTableBase   = (PULONG32)((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase;
 81     Old_NtOpenProcessOffset  = (ULONG32)(ServiceTableBase[SSDT_NtOpenProcessIndex]);
 82     ulVariable = Old_NtOpenProcessOffset>>4;
 83     Old_NtOpenProcess = (ULONG64)((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase + ulVariable;
 84     DbgPrint("Win7x64 Old_NtOpenProcess:%p
",ulVariable);
 85 
 86     /*
 87     kd> u FFFFF8000415D2EC
 88     nt!NtOpenProcess:
 89     fffff800`0415d2ec 4883ec38        sub     rsp,38h
 90     fffff800`0415d2f0 65488b042588010000 mov   rax,qword ptr gs:[188h]
 91     fffff800`0415d2f9 448a90f6010000  mov     r10b,byte ptr [rax+1F6h]
 92     fffff800`0415d300 4488542428      mov     byte ptr [rsp+28h],r10b
 93     fffff800`0415d305 4488542420      mov     byte ptr [rsp+20h],r10b
 94     fffff800`0415d30a e851fcffff      call    nt!PsOpenProcess (fffff800`0415cf60)
 95     fffff800`0415d30f 4883c438        add     rsp,38h
 96     fffff800`0415d313 c3              ret
 97     */
 98 
 99     HookSSDTWin7_X64(ServiceTableBase,SSDT_NtOpenProcessIndex,(ULONG64)Fake_NtOpenProcess);
100 #else
101     ULONG32   SSDTAddress      = NULL;
102     CHAR      szFindFunctionName[] = "ZwOpenProcess";
103 
104     
105     if (GetSSDTAddressInWinXP_X86(&SSDTAddress)==FALSE)
106     {
107         return STATUS_UNSUCCESSFUL;
108     }
109     DbgPrint("WinXPx86 SSDT:%p
",SSDTAddress);
110     DbgPrint("WinXPx86 SSDTBase:%p
",((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase);
111     /*
112     kd> dd 804E58A0 l 200   SSDTBase
113     804e58a0  80591bfb 80585356 805e1f35 805dbc47
114     804e58b0  805e1fbc 80640cc2 80642e4b 80642e94
115     804e58c0  805835b2 80650bbb 8064047d 805e1787
116     804e58d0  8063878a 80586fa1 805e08e8 8062f432
117     804e58e0  805d9781 80571d45 805e8258 805e939e
118     804e58f0  804e5eb4 80650ba7 805cd537 804ed812
119     804e5900  805719b7 80570af2 805e1b65 80656cec
120     804e5910  805e0ff3 805887b7 80656f5b 80586563
121     804e5920  804e221d 8066239e 805aa76b 8057dd2d
122     804e5930  8065120c 8057d330 805db662 805d6cd6
123     804e5940  80638c31 80578925 805d7e7f 805803c0
124     804e5950  80589caa 805b5823 8059a02a 805b1470
125     804e5960  8058c7cd 8065182d 8056eb66 8057b9e4
126     804e5970  805e7e56 80587c43 80598cb2 805a7ada
127     804e5980  805ab552 80663519 80663673 8056fb07
128     804e5990  805ddc8b 80650ba7 805d64ac 80594334
129     804e59a0  80642eef 80592f8b 805899a6 805b6cd8
130     804e59b0  8058221e 80584451 80650bbb 80579e1c
131     804e59c0  80650b93 80588691 8062e3f1 805cf473
132     804e59d0  805e36f2 80586ceb 80588bf9 805da3bb
133     804e59e0  805e9ab6 8062fc8f 8062f7e5 805723df
134     804e59f0  805813f3 80636711 80634be3 8059c497
135     804e5a00  8054070f 80599bde 805e0d66 8058968d
136     804e5a10  805aad25 806349af 80638ae7 80634bca
137     804e5a20  805aab94 805a9f96 805cf7e5 805cf944
138     804e5a30  805de058 805cece7 805c8155 805af0d5
139     804e5a40  805e804c 805e8113 8062ea8e 8062eee7
140     804e5a50  8057f371 80650ba7 805de2ef 805e318f
141     804e5a60  805e2fa1 8058b0b6 8058aa51 806512fd
142     804e5a70  8057d4a4 806220ab 80638e89 80573bfc
143     804e5a80  8058046e 805ea252 8058270a(NtOpenProcess) 80578308
144 
145     */
146     DbgPrint("WinXPx86 SSDTNumberOfService:%d
",((PSYSTEM_SERVICE_TABLE)SSDTAddress)->NumberOfServices);
147 
148     if (GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(szFindFunctionName,&SSDT_NtOpenProcessIndex)==FALSE)
149     {
150         return STATUS_UNSUCCESSFUL;
151     }
152     DbgPrint("WinXPx86 SSDT_NtOpenProcessIndex:%d
",SSDT_NtOpenProcessIndex);
153 
154     //先保存原先的函数地址
155     ServiceTableBase   = (PULONG32)((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase;
156     Old_NtOpenProcess  = (pfnNtOpenProcess)(ServiceTableBase[SSDT_NtOpenProcessIndex]);
157     DbgPrint("WinXPx86 Old_NtOpenProcess:%p
",Old_NtOpenProcess);
158     
159 
160     /*
161     kd> u 8058270A
162     nt!NtOpenProcess:
163     8058270a 68c4000000      push    0C4h
164     8058270f 68d8524f80      push    offset nt!ObWatchHandles+0x25c (804f52d8)
165     80582714 e85a17f6ff      call    nt!_SEH_prolog (804e3e73)
166     80582719 33f6            xor     esi,esi
167     8058271b 8975d4          mov     dword ptr [ebp-2Ch],esi
168     8058271e 33c0            xor     eax,eax
169     80582720 8d7dd8          lea     edi,[ebp-28h]
170     80582723 ab              stos    dword ptr es:[edi]
171 
172     */
173     HookSSDTWinXP_X86(ServiceTableBase,SSDT_NtOpenProcessIndex,(ULONG32)Fake_NtOpenProcess);
174 
175 
176     
177 #endif
178     
179 
180     DriverObject->DriverUnload = UnloadDriver;
181 
182 
183     return  STATUS_SUCCESS;
184 }
185 
186 //SSDT表的基地址32位(4Bytes)64位(8Bytes)
187 //XP 32位Ntos模块导出表中有   Win7 64 Ntos模块导出表中无
188 BOOLEAN GetSSDTAddressInWinXP_X86(ULONG32* SSDTAddress)
189 {
190     //从NtosKernel.exe 模块中的导出表获得该导出变量  KeServiceDescriptorTable
191 
192     /*
193     kd> dd KeServiceDescriptorTable
194     80563520  804e58a0 00000000 0000011c 805120bc
195     */
196     *SSDTAddress = NULL;
197     *SSDTAddress = (ULONG32)GetExportVariableAddressFormNtosExportTableByVariableName(L"KeServiceDescriptorTable");
198 
199     if (*SSDTAddress!=NULL)
200     {
201         return TRUE;
202     }
203 
204     return FALSE;
205 }
206 
207 
208 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex)
209 {
210     /*
211     0:001> u zwopenprocess
212     ntdll!ZwOpenProcess:
213     7c92d5e0 b87a000000      mov     eax,7Ah
214     7c92d5e5 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
215     7c92d5ea ff12            call    dword ptr [edx]
216     7c92d5ec c21000          ret     10h
217     7c92d5ef 90              nop
218     */
219 
220     ULONG32     ulOffset_SSDTFunctionIndex = 1;
221 
222 
223     //从Ntdll模块的导出表中获得7c92d5e0
224     //使用内存映射将Ntdll模块映射到System进程的内存空间进行查找(Ntdll.dll模块的导出表中进行搜索)
225     ULONG   i;
226     BOOLEAN  bOk = FALSE;
227     WCHAR    wzFileFullPath[] = L"\SystemRoot\System32\ntdll.dll";
228     SIZE_T  MappingViewSize   = 0;
229     PVOID    MappingBaseAddress = NULL;
230     PIMAGE_NT_HEADERS  NtHeader = NULL;
231     PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
232     ULONG32*  AddressOfFunctions    = NULL;
233     ULONG32*  AddressOfNames        = NULL;
234     USHORT* AddressOfNameOrdinals = NULL;
235     CHAR*   szFunctionName        = NULL;
236     ULONG32 ulFunctionOrdinal     = 0;
237     ULONG32 ulFunctionAddress     = 0;
238     
239     *SSDTFunctionIndex = -1;
240 
241 
242     //将Ntdll.dll 当前的空间中
243     bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
244     if (bOk==FALSE)
245     {
246         return FALSE;
247     }
248     else
249     {
250         __try{
251             NtHeader = RtlImageNtHeader(MappingBaseAddress);
252             if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
253             {
254                 ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG32)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
255                 
256                 
257                 
258                 AddressOfFunctions = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
259                 AddressOfNames = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNames);
260                 AddressOfNameOrdinals = (USHORT*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
261                 for(i = 0; i < ExportDirectory->NumberOfNames; i++)
262                 {
263                     szFunctionName = (char*)((ULONG32)MappingBaseAddress + AddressOfNames[i]);   //获得函数名称
264                     if (_stricmp(szFunctionName, szFindFunctionName) == 0)   
265                     {
266                         ulFunctionOrdinal = AddressOfNameOrdinals[i]; 
267                         ulFunctionAddress = (ULONG32)((ULONG32)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]);
268                         
269                         
270                         *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex); 
271                         break;
272                     }
273                 }
274             }
275         }__except(EXCEPTION_EXECUTE_HANDLER)
276         {
277             ;
278         }
279     }
280 
281 
282     ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress);
283 
284 
285     if (*SSDTFunctionIndex==-1)
286     {
287         return FALSE;
288     }
289     
290     return TRUE;
291 }
292 
293 
294 
295 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex)
296 {
297     /*
298     0:004> u zwopenprocess
299     ntdll!NtOpenProcess:
300     00000000`774ddc10 4c8bd1          mov     r10,rcx
301     00000000`774ddc13 b823000000      mov     eax,23h
302     00000000`774ddc18 0f05            syscall
303     00000000`774ddc1a c3              ret
304     00000000`774ddc1b 0f1f440000      nop     dword ptr [rax+rax]
305     */
306 
307     ULONG32     ulOffset_SSDTFunctionIndex = 4;
308 
309     ULONG   i;
310     BOOLEAN  bOk = FALSE;
311     WCHAR    wzFileFullPath[] = L"\SystemRoot\System32\ntdll.dll";
312     SIZE_T   MappingViewSize   = 0;
313     PVOID    MappingBaseAddress = NULL;
314     PIMAGE_NT_HEADERS  NtHeader = NULL;
315     PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
316     ULONG32*  AddressOfFunctions    = NULL;
317     ULONG32*  AddressOfNames        = NULL;
318     USHORT*   AddressOfNameOrdinals = NULL;
319     CHAR*     szFunctionName        = NULL;
320     ULONG32   ulFunctionOrdinal     = 0;
321     ULONG64   ulFunctionAddress     = 0;
322 
323     *SSDTFunctionIndex = -1;
324 
325 
326     //将Ntdll.dll 当前的空间中
327     bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
328     if (bOk==FALSE)
329     {
330         return FALSE;
331     }
332     else
333     {
334         __try{
335             NtHeader = RtlImageNtHeader(MappingBaseAddress);
336             if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
337             {
338                 ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG64)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
339 
340 
341 
342                 AddressOfFunctions = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
343                 AddressOfNames = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNames);
344                 AddressOfNameOrdinals = (USHORT*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
345                 for(i = 0; i < ExportDirectory->NumberOfNames; i++)
346                 {
347                     szFunctionName = (char*)((ULONG64)MappingBaseAddress + AddressOfNames[i]);   //获得函数名称
348                     if (_stricmp(szFunctionName, szFindFunctionName) == 0)   
349                     {
350                         ulFunctionOrdinal = AddressOfNameOrdinals[i]; 
351                         ulFunctionAddress = (ULONG64)((ULONG64)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]);
352 
353 
354                         *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex); 
355                         break;
356                     }
357                 }
358             }
359         }__except(EXCEPTION_EXECUTE_HANDLER)
360         {
361             ;
362         }
363     }
364 
365 
366     ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress);
367 
368 
369     if (*SSDTFunctionIndex==-1)
370     {
371         return FALSE;
372     }
373 
374     return TRUE;
375 }
376 
377 
378 BOOLEAN GetSSDTAddressInWin7_X64(ULONG64* SSDTAddress)
379 {
380 
381     
382     /*
383     kd> rdmsr c0000082 
384     msr[c0000082] = fffff800`03ecf640
385     kd> u fffff800`03ecf640 l 50
386     nt!KiSystemCall64:
387     fffff800`03ecf640 0f01f8          swapgs
388     fffff800`03ecf643 654889242510000000 mov   qword ptr gs:[10h],rsp
389     fffff800`03ecf64c 65488b2425a8010000 mov   rsp,qword ptr gs:[1A8h]
390     fffff800`03ecf655 6a2b            push    2Bh
391     fffff800`03ecf657 65ff342510000000 push    qword ptr gs:[10h]
392     fffff800`03ecf65f 4153            push    r11
393     fffff800`03ecf661 6a33            push    33h
394     fffff800`03ecf663 51              push    rcx
395     fffff800`03ecf664 498bca          mov     rcx,r10
396     fffff800`03ecf667 4883ec08        sub     rsp,8
397     fffff800`03ecf66b 55              push    rbp
398     fffff800`03ecf66c 4881ec58010000  sub     rsp,158h
399     fffff800`03ecf673 488dac2480000000 lea     rbp,[rsp+80h]
400     fffff800`03ecf67b 48899dc0000000  mov     qword ptr [rbp+0C0h],rbx
401     fffff800`03ecf682 4889bdc8000000  mov     qword ptr [rbp+0C8h],rdi
402     fffff800`03ecf689 4889b5d0000000  mov     qword ptr [rbp+0D0h],rsi
403     fffff800`03ecf690 c645ab02        mov     byte ptr [rbp-55h],2
404     fffff800`03ecf694 65488b1c2588010000 mov   rbx,qword ptr gs:[188h]
405     fffff800`03ecf69d 0f0d8bd8010000  prefetchw [rbx+1D8h]
406     fffff800`03ecf6a4 0fae5dac        stmxcsr dword ptr [rbp-54h]
407     fffff800`03ecf6a8 650fae142580010000 ldmxcsr dword ptr gs:[180h]
408     fffff800`03ecf6b1 807b0300        cmp     byte ptr [rbx+3],0
409     fffff800`03ecf6b5 66c785800000000000 mov   word ptr [rbp+80h],0
410     fffff800`03ecf6be 0f848c000000    je      nt!KiSystemCall64+0x110 (fffff800`03ecf750)
411     fffff800`03ecf6c4 488945b0        mov     qword ptr [rbp-50h],rax
412     fffff800`03ecf6c8 48894db8        mov     qword ptr [rbp-48h],rcx
413     fffff800`03ecf6cc 488955c0        mov     qword ptr [rbp-40h],rdx
414     fffff800`03ecf6d0 f6430303        test    byte ptr [rbx+3],3
415     fffff800`03ecf6d4 4c8945c8        mov     qword ptr [rbp-38h],r8
416     fffff800`03ecf6d8 4c894dd0        mov     qword ptr [rbp-30h],r9
417     fffff800`03ecf6dc 7405            je      nt!KiSystemCall64+0xa3 (fffff800`03ecf6e3)
418     fffff800`03ecf6de e80d140000      call    nt!KiSaveDebugRegisterState (fffff800`03ed0af0)
419     fffff800`03ecf6e3 f6430380        test    byte ptr [rbx+3],80h
420     fffff800`03ecf6e7 7442            je      nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
421     fffff800`03ecf6e9 b9020100c0      mov     ecx,0C0000102h
422     fffff800`03ecf6ee 0f32            rdmsr
423     fffff800`03ecf6f0 48c1e220        shl     rdx,20h
424     fffff800`03ecf6f4 480bc2          or      rax,rdx
425     fffff800`03ecf6f7 483983b8000000  cmp     qword ptr [rbx+0B8h],rax
426     fffff800`03ecf6fe 742b            je      nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
427     fffff800`03ecf700 483983b0010000  cmp     qword ptr [rbx+1B0h],rax
428     fffff800`03ecf707 7422            je      nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
429     fffff800`03ecf709 488b93b8010000  mov     rdx,qword ptr [rbx+1B8h]
430     fffff800`03ecf710 0fba6b4c0b      bts     dword ptr [rbx+4Ch],0Bh
431     fffff800`03ecf715 66ff8bc4010000  dec     word ptr [rbx+1C4h]
432     fffff800`03ecf71c 48898280000000  mov     qword ptr [rdx+80h],rax
433     fffff800`03ecf723 fb              sti
434     fffff800`03ecf724 e8170b0000      call    nt!KiUmsCallEntry (fffff800`03ed0240)
435     fffff800`03ecf729 eb0f            jmp     nt!KiSystemCall64+0xfa (fffff800`03ecf73a)
436     fffff800`03ecf72b f6430340        test    byte ptr [rbx+3],40h
437     fffff800`03ecf72f 7409            je      nt!KiSystemCall64+0xfa (fffff800`03ecf73a)
438     fffff800`03ecf731 f00fbaab0001000008 lock bts dword ptr [rbx+100h],8
439     fffff800`03ecf73a 488b45b0        mov     rax,qword ptr [rbp-50h]
440     fffff800`03ecf73e 488b4db8        mov     rcx,qword ptr [rbp-48h]
441     fffff800`03ecf742 488b55c0        mov     rdx,qword ptr [rbp-40h]
442     fffff800`03ecf746 4c8b45c8        mov     r8,qword ptr [rbp-38h]
443     fffff800`03ecf74a 4c8b4dd0        mov     r9,qword ptr [rbp-30h]
444     fffff800`03ecf74e 6690            xchg    ax,ax
445     fffff800`03ecf750 fb              sti
446     fffff800`03ecf751 48898be0010000  mov     qword ptr [rbx+1E0h],rcx
447     fffff800`03ecf758 8983f8010000    mov     dword ptr [rbx+1F8h],eax
448     nt!KiSystemServiceStart:
449     fffff800`03ecf75e 4889a3d8010000  mov     qword ptr [rbx+1D8h],rsp
450     fffff800`03ecf765 8bf8            mov     edi,eax
451     fffff800`03ecf767 c1ef07          shr     edi,7
452     fffff800`03ecf76a 83e720          and     edi,20h
453     fffff800`03ecf76d 25ff0f0000      and     eax,0FFFh
454     nt!KiSystemServiceRepeat:
455     fffff800`03ecf772 4c8d15c7202300  lea     r10,[nt!KeServiceDescriptorTable (fffff800`04101840)]
456 
457     fffff800`03ecf772 + 002320c7 + 7  = fffff800`04101840
458     */
459 
460 
461 
462 
463     PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082);   //fffff800`03ecf640
464     PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
465     PUCHAR i = NULL;
466     UCHAR   v1=0,v2=0,v3=0;
467     INT64   iOffset = 0;    //002320c7
468     ULONG64 VariableAddress = 0;
469     *SSDTAddress = NULL;
470     for(i=StartSearchAddress;i<EndSearchAddress;i++)
471     {
472         if( MmIsAddressValid(i) && MmIsAddressValid(i+1) && MmIsAddressValid(i+2) )
473         {
474             v1=*i;
475             v2=*(i+1);
476             v3=*(i+2);
477             if(v1==0x4c && v2==0x8d && v3==0x15 ) 
478             {
479                 memcpy(&iOffset,i+3,4);
480                 *SSDTAddress = iOffset + (ULONG64)i + 7;
481 
482                 break;
483             }
484         }
485     }
486 
487     if (*SSDTAddress==NULL)
488     {
489         return FALSE;
490     }
491 
492     /*
493     kd> dq fffff800`04101840
494     fffff800`04101840  fffff800`03ed1300 00000000`00000000
495     fffff800`04101850  00000000`00000191 fffff800`03ed1f8c
496 
497     */
498     return TRUE;
499 }
500 
501 PVOID 
502 GetExportVariableAddressFormNtosExportTableByVariableName(WCHAR *wzVariableName)
503 {
504     UNICODE_STRING uniVariableName;  
505     PVOID VariableAddress = NULL;
506 
507     if (wzVariableName && wcslen(wzVariableName) > 0)
508     {
509         RtlInitUnicodeString(&uniVariableName, wzVariableName);  
510 
511         //从Ntos模块的导出表中获得一个导出变量的地址
512         VariableAddress = MmGetSystemRoutineAddress(&uniVariableName); 
513     }
514 
515     return VariableAddress;
516 }
517 
518 
519 
520 VOID  UnloadDriver(PDRIVER_OBJECT DriverObject)
521 {
522 
523 
524 #ifdef _WIN64
525     UnHookSSDTWin7_X64(ServiceTableBase,SSDT_NtOpenProcessIndex,(ULONG32)Old_NtOpenProcessOffset);
526 #else
527     UnHookSSDTWinXP_X86(ServiceTableBase,SSDT_NtOpenProcessIndex,(ULONG32)Old_NtOpenProcess);
528 #endif
529     
530      
531     
532 }
533 
534 
535 VOID HookSSDTWin7_X64(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG64 ulFakeVariable)
536 {
537     //寻找一个内核不常用的函数(KeBugCheckEx) 进行InlineHook使其跳转到Fake_NtOpenProcess函数
538     ULONG32  ulVariable = 0;
539 
540     WPOFF(); 
541     InlineHook(KeBugCheckEx,ulFakeVariable,szOldKeBugCheckExCode,15);
542     WPON();
543 
544 
545     //寻找一个内核不常用的函数(KeBugCheckEx) 计算SSDT中的偏移 进行置换
546 
547     ulVariable = CalcFunctionOffsetInSSDT(KeBugCheckEx,5);
548 
549     WPOFF(); 
550     ServiceTableBase[ulSSDTFunctionIndex] = (ULONG32)ulVariable;
551     WPON();
552 }
553 
554 
555 VOID HookSSDTWinXP_X86(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulFakeVariable)
556 {
557     WPOFF(); 
558     ServiceTableBase[ulSSDTFunctionIndex] = (ULONG32)ulFakeVariable;
559     WPON();
560 }
561 
562 
563 VOID
564 UnHookSSDTWin7_X64(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulOldVariable)
565 {
566 
567     WPOFF(); 
568     UnInlineHook(KeBugCheckEx,szOldKeBugCheckExCode,15);
569     WPON();
570 
571     WPOFF(); 
572     ServiceTableBase[ulSSDTFunctionIndex] = (ULONG32)ulOldVariable; 
573     WPON();    
574 }
575 
576 
577 VOID
578 UnHookSSDTWinXP_X86(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulOldVariable)
579 {
580     WPOFF(); 
581     ServiceTableBase[ulSSDTFunctionIndex] = (ULONG32)ulOldVariable; 
582     WPON();
583 }
584 
585 
586 
587 
588 //将Ntdll.dll 模块映射到System.exe进程空间中
589 BOOLEAN 
590 MappingPEFileInRing0Space(WCHAR* wzFileFullPath,OUT PVOID* MappingBaseAddress,PSIZE_T MappingViewSize)
591 {
592     UNICODE_STRING    uniFileFullPath;
593     OBJECT_ATTRIBUTES oa;
594     NTSTATUS          Status;
595     IO_STATUS_BLOCK   Iosb;
596 
597     HANDLE   hFile = NULL;
598     HANDLE   hSection = NULL;
599 
600     if (!wzFileFullPath || !MappingBaseAddress){
601         return FALSE;
602     }
603 
604     RtlInitUnicodeString(&uniFileFullPath, wzFileFullPath);
605     InitializeObjectAttributes(&oa,
606         &uniFileFullPath,
607         OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
608         NULL,
609         NULL
610         );
611 
612 
613     //获得文件句柄
614     Status = IoCreateFile(&hFile,
615         GENERIC_READ | SYNCHRONIZE,
616         &oa,   //文件绝对路径
617         &Iosb,
618         NULL,
619         FILE_ATTRIBUTE_NORMAL,
620         FILE_SHARE_READ,
621         FILE_OPEN,
622         FILE_SYNCHRONOUS_IO_NONALERT,
623         NULL,
624         0,
625         CreateFileTypeNone,
626         NULL,
627         IO_NO_PARAMETER_CHECKING
628         );
629     if (!NT_SUCCESS(Status))
630     {
631         
632         return FALSE;
633     }
634     
635     oa.ObjectName = NULL;
636     Status = ZwCreateSection(&hSection,
637         SECTION_QUERY | SECTION_MAP_READ,
638         &oa,
639         NULL,
640         PAGE_WRITECOPY,
641         SEC_IMAGE,  //??  指示内存对齐
642         hFile
643         );
644     ZwClose(hFile);
645     if (!NT_SUCCESS(Status))
646     {
647     
648         return FALSE;
649     }
650     Status = ZwMapViewOfSection(hSection, 
651         NtCurrentProcess(),    //映射到当前进程的内存空间中
652         MappingBaseAddress, 
653         0, 
654         0, 
655         0, 
656         MappingViewSize, 
657         ViewUnmap, 
658         0, 
659         PAGE_WRITECOPY
660         );
661     ZwClose(hSection);
662     if (!NT_SUCCESS(Status))
663     {
664         return FALSE;
665     }
666 
667     return TRUE;
668 }
669 
670 
671 
672 
673 
674 VOID WPOFF()
675 {
676     //选择性编译,是给编译器看的
677 #if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_)
678     _disable();
679     __writecr0(__readcr0() & (~(0x10000)));
680 #else
681     __asm
682     {
683         CLI  ;                 
684         MOV    EAX, CR0;    
685         AND    EAX, NOT 10000H;
686         MOV    CR0, EAX;        
687     }
688 #endif
689 }
690 VOID WPON()
691 {
692 #if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_)
693     __writecr0(__readcr0() ^ 0x10000);
694     _enable();
695 #else
696     __asm
697     {
698         MOV    EAX, CR0;        
699         OR     EAX, 10000H;            
700         MOV    CR0, EAX;              
701         STI;                    
702     }
703 #endif
704 }
705 
706 
707 
708 NTSTATUS Fake_NtOpenProcess(
709     PHANDLE ProcessHandle,
710     ACCESS_MASK DesiredAccess,
711     POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId)
712 {
713     PEPROCESS  EProcess = PsGetCurrentProcess();    //进程上下背景文
714     if (EProcess!=NULL)
715     {
716         //通过EProcess 获得进程名称 
717 
718         char *szProcessImageName = PsGetProcessImageFileName(EProcess);
719 
720         if (strstr(szProcessImageName,"EnumProcess")!=0)
721         {
722     
723             return STATUS_ACCESS_DENIED;
724         }
725     }
726 
727     Old_NtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
728 }
729 
730 
731 
732 
733 
734 
735 ULONG32 CalcFunctionOffsetInSSDT(ULONG64 ulFunctionAddress,ULONG32 ulParamCount)
736 {
737 
738     /*
739     kd> rdmsr c0000082 
740     msr[c0000082] = fffff800`03edd640
741     
742     kd>u fffff800`03edd640
743     fffff800`03edd751 48898be0010000  mov     qword ptr [rbx+1E0h],rcx
744     fffff800`03edd758 8983f8010000    mov     dword ptr [rbx+1F8h],eax
745     nt!KiSystemServiceStart:
746     fffff800`03edd75e 4889a3d8010000  mov     qword ptr [rbx+1D8h],rsp
747     fffff800`03edd765 8bf8            mov     edi,eax
748     fffff800`03edd767 c1ef07          shr     edi,7
749     fffff800`03edd76a 83e720          and     edi,20h
750     fffff800`03edd76d 25ff0f0000      and     eax,0FFFh
751     nt!KiSystemServiceRepeat:
752     fffff800`03edd772 4c8d15c7202300  lea     r10,[nt!KeServiceDescriptorTable (fffff800`0410f840)]
753 
754 
755     kd> dq fffff800`0410f840
756     fffff800`0410f840  fffff800`03edf300 00000000`00000000
757     fffff800`0410f850  00000000`00000191 fffff800`03edff8c
758     fffff800`0410f860  00000000`00000000 00000000`00000000
759     fffff800`0410f870  00000000`00000000 00000000`00000000
760 
761     kd> dd fffff800`03edf300
762     fffff800`03edf300  040d9a00 02f55c00 fff6ea00 02e87805
763     fffff800`03edf310  031a4a06 03116a05 02bb9901 02b4f200
764 
765     fffff800`03edf300 + (02e87805>>4) = FFFFF800041C7A80
766 
767     kd> u FFFFF800041C7A80
768     nt!NtReadFile:
769     fffff800`041c7a80 4c8bdc          mov     r11,rsp
770     fffff800`041c7a83 4d894b20        mov     qword ptr [r11+20h],r9
771     fffff800`041c7a87 4d894318        mov     qword ptr [r11+18h],r8
772     fffff800`041c7a8b 49895310        mov     qword ptr [r11+10h],rdx
773     fffff800`041c7a8f 53              push    rbx
774 
775 
776     5 --->9
777     6 --->10
778 
779     如果一个函数的参数个数小于等于4  就是0
780 
781     */
782 
783     ULONG32 ulVariable = 0,i;
784     CHAR v1 = 0;
785 
786     CHAR   szBits[4] = {0};
787     
788 
789     ulVariable = (ULONG32)(ulFunctionAddress-(ULONG64)ServiceTableBase); 
790     ulVariable = ulVariable<<4;
791 
792 
793     if(ulParamCount>4)
794     {
795         ulParamCount = ulParamCount-4;     //NtReadFile  9个参数
796     }
797     else
798     {
799         ulParamCount = 0;
800     }
801     
802     //处理低四位,填写参数个数   如果一个函数的参数为5 那么dwTemp的低4位就是 0001  如果参数是6 就是0002 因为 6要减4 
803 
804 #define SETBIT(x,y) x|=(1<<y)         //将X的第Y位置1
805 #define CLRBIT(x,y) x&=~(1<<y)        //将X的第Y位清0
806 #define GETBIT(x,y) (x & (1 << y))    //取X的第Y位,返回0或非0
807 
808 
809     for(i=0;i<4;i++)    //一个16进制 4个二进制      0000
810     {
811         szBits[i]=GETBIT(ulParamCount,i);      
812         if(szBits[i])
813         {
814             SETBIT(v1,i);                     
815         }
816         else
817         {
818             CLRBIT(v1,i);                    
819         }
820     }
821     /*
822     ulParamCount    i        szBits[i]    b       i       b
823     0101            0         1          0000     0      0001   set
824     0101            1         0          0001     1      0001   clr
825     0101            2         1          0001     2      0101   set
826     0101            3         0          0101     3      0101   clr
827 
828     */
829 
830 
831     //把数据复制回去
832     memcpy(&ulVariable,&v1,1);
833     return ulVariable;
834 }
835 
836 
837 
838 VOID InlineHook(ULONG64 ulOldVariable,ULONG64 ulFakeVariable,UCHAR* szOldCode,ULONG32 ulOldeCodeLength)  
839 {
840     
841     ULONG64  ulVariable = 0;
842     UCHAR szNewCode[]="xFFx25x00x00x00x00xFFxFFxFFxFFxFFxFFxFFxFF";   //InlineHook
843 
844 
845     ulVariable = ulFakeVariable;
846     memcpy(szOldCode,(PVOID)ulOldVariable,ulOldeCodeLength);
847     memcpy(szNewCode+6,&ulVariable,8);  
848 
849     memset((PVOID)ulOldVariable,0x90,ulOldeCodeLength);     
850     memcpy((PVOID)ulOldVariable,szNewCode,14);  
851 }
852 
853 
854 VOID  UnInlineHook(ULONG64 ulOldVariable,UCHAR* szOldCode,ULONG32 ulOldCodeLength)
855 {
856     memcpy((PVOID)ulOldVariable,szOldCode,ulOldCodeLength);  
857 }
.c
 1 #ifndef CXX_HOOKSSDT_H
 2 #define CXX_HOOKSSDT_H
 3 
 4 #include <ntifs.h>
 5 #include <ntimage.h>
 6 
 7 
 8 #define SEC_IMAGE  0x01000000
 9 
10 //定义SSDT表的结构
11 typedef struct _SYSTEM_SERVICE_TABLE_X64{
12     PVOID          ServiceTableBase; 
13     PVOID          ServiceCounterTableBase; 
14     ULONG64      NumberOfServices;                     //SSDT表中的函数个数   0x191
15     PVOID          ParamTableBase; 
16 } SYSTEM_SERVICE_TABLE_X64, *PSYSTEM_SERVICE_TABLE_X64;
17 
18 typedef struct _SYSTEM_SERVICE_TABLE_X86 {
19     PVOID   ServiceTableBase;
20     PVOID   ServiceCounterTableBase;
21     ULONG32 NumberOfServices;                         //SSDT表中的函数个数   0x11c
22     PVOID   ParamTableBase;
23 } SYSTEM_SERVICE_TABLE_X86, *PSYSTEM_SERVICE_TABLE_X86;
24 
25 
26 
27 #ifdef _WIN64
28 #define PSYSTEM_SERVICE_TABLE PSYSTEM_SERVICE_TABLE_X64    
29 #else
30 #define PSYSTEM_SERVICE_TABLE PSYSTEM_SERVICE_TABLE_X86   
31 #endif
32 
33 
34 
35 
36 
37 
38 /*
39 ServiceTableBase  [][][][][][][][]   
40 */
41 extern
42     char* PsGetProcessImageFileName(PEPROCESS EProcess);
43 
44 extern
45     PIMAGE_NT_HEADERS
46     NTAPI
47     RtlImageNtHeader(PVOID BaseAddress);
48 
49 typedef
50     NTSTATUS
51     (*pfnNtOpenProcess)(
52     PHANDLE ProcessHandle,
53     ACCESS_MASK DesiredAccess,
54     POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);
55 
56 NTSTATUS Fake_NtOpenProcess(
57     PHANDLE ProcessHandle,
58     ACCESS_MASK DesiredAccess,
59     POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);
60 
61 
62 VOID  UnloadDriver(PDRIVER_OBJECT DriverObject);
63 
64 BOOLEAN GetSSDTAddressInWinXP_X86(ULONG32* SSDTAddress);
65 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex);
66 
67 
68 
69 BOOLEAN GetSSDTAddressInWin7_X64(ULONG64* SSDTAddress);
70 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex);
71 ULONG32 CalcFunctionOffsetInSSDT(ULONG64 ulFunctionAddress,ULONG32 ulParamCount);
72 VOID  InlineHook(ULONG64 ulOldVariable,ULONG64 ulFakeVariable,UCHAR* szOldCode,ULONG32 ulOldeCodeLength);
73 VOID  UnInlineHook(ULONG64 ulOldVariable,UCHAR* szOldCode,ULONG32 ulOldCodeLength);
74 
75 PVOID GetExportVariableAddressFormNtosExportTableByVariableName(WCHAR *wzVariableName);
76 
77 BOOLEAN MappingPEFileInRing0Space(WCHAR* wzFileFullPath,OUT PVOID* MappingBaseAddress,PSIZE_T MappingViewSize);
78 
79 
80 VOID WPOFF();
81 VOID WPON();
82 VOID HookSSDTWinXP_X86(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulFakeVariable);
83 VOID HookSSDTWin7_X64(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG64 ulFakeVariable);
84 
85 
86 VOID UnHookSSDTWinXP_X86(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulOldVariable);
87 VOID UnHookSSDTWin7_X64(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulOldVariable);
88 #endif    
.h
爱程序 不爱bug 爱生活 不爱黑眼圈 我和你们一样 我和你们不一样 我不是凡客 我要做geek
原文地址:https://www.cnblogs.com/yifi/p/4898406.html