zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    System.currentTimeMillis();
    Spark Core源代码分析: Spark任务模型
    CocoaPods on Xcode 6 and Yosemite
    leetcode第一刷_Binary Tree Inorder Traversal
    struts2讲义----建立一个struts2工程
    Java实现 蓝桥杯VIP 算法提高 班级排名
    Java实现 蓝桥杯VIP 算法提高 种树
    Java实现 蓝桥杯VIP 算法提高 种树
    Java实现 蓝桥杯VIP 算法提高 种树
    Java实现 蓝桥杯VIP 算法提高 种树
  • 原文地址:https://www.cnblogs.com/yifi/p/4898406.html
Copyright © 2011-2022 走看看