• IoTimerInLineHook


      1 #ifndef CXX_IOTIMERINLINEHOOK_H
      2 #    include "IoTimerInlineHook.h"
      3 #endif
      4 
      5 
      6 ULONG32           SSDT_NtOpenProcessIndex     = 0;
      7 pfnNtOpenProcess  Old_NtOpenProcess           = NULL;
      8 PULONG32          ServiceTableBase            = NULL;
      9 
     10 
     11 
     12 ULONG32           Old_NtOpenProcessOffset = 0;    //针对Win7 x64
     13 
     14 
     15 PVOID             NtOpenProcessPassCode        = NULL;           //释放内存
     16 PVOID             Old_NtOpenProcessHeaderBytes = NULL;           //释放内存
     17 
     18 NTSTATUS
     19 DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegisterPath)
     20 {
     21 
     22     NTSTATUS  Status;
     23     PDEVICE_OBJECT   DeviceObject = NULL;
     24     UNICODE_STRING   uniDeviceName;
     25 
     26 #ifdef _WIN64
     27     ULONG64   SSDTAddress = NULL;
     28     ULONG32   ulVariable  = 0;
     29 
     30     CHAR      szFindFunctionName[] = "ZwOpenProcess";
     31 
     32 
     33     if (GetSSDTAddressInWin7_X64(&SSDTAddress)==FALSE)
     34     {
     35         return STATUS_UNSUCCESSFUL;
     36     }
     37 
     38     DbgPrint("Win7_X64 SSDT:%p
    ",SSDTAddress);
     39     DbgPrint("Win7_X64 SSDTBase:%p
    ",((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase);
     40 
     41     
     42 
     43     if (GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(szFindFunctionName,
     44         &SSDT_NtOpenProcessIndex)==FALSE)
     45     {
     46         return STATUS_UNSUCCESSFUL;
     47     }
     48 
     49     DbgPrint("Win7x64 SSDT_NtOpenProcessIndex:%d
    ",SSDT_NtOpenProcessIndex);
     50     
     51     
     52     
     53     ServiceTableBase   = (PULONG32)((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase;
     54     Old_NtOpenProcessOffset  = (ULONG32)(ServiceTableBase[SSDT_NtOpenProcessIndex]);
     55     ulVariable = Old_NtOpenProcessOffset>>4;
     56     Old_NtOpenProcess = (ULONG64)((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase + ulVariable;
     57     DbgPrint("Win7_X64 Old_NtOpenProcess:%p
    ",ulVariable);
     58 
     59 
     60 #else
     61     ULONG32   SSDTAddress      = NULL;
     62     CHAR      szFindFunctionName[] = "ZwOpenProcess";
     63     
     64     if (GetSSDTAddressInWinXP_X86(&SSDTAddress)==FALSE)
     65     {
     66         return STATUS_UNSUCCESSFUL;
     67     }
     68     DbgPrint("WinXP_X86 SSDT:%p
    ",SSDTAddress);
     69     DbgPrint("WinXP_X86 SSDTBase:%p
    ",((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase);
     70     
     71 
     72     if (GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(szFindFunctionName,
     73         &SSDT_NtOpenProcessIndex)==FALSE)
     74     {
     75         return STATUS_UNSUCCESSFUL;
     76     }
     77     DbgPrint("WinXP_X86 SSDT_NtOpenProcessIndex:%d
    ",SSDT_NtOpenProcessIndex);
     78 
     79     //先保存原先的函数地址
     80     ServiceTableBase   = (PULONG32)((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase;
     81     Old_NtOpenProcess  = (pfnNtOpenProcess)(ServiceTableBase[SSDT_NtOpenProcessIndex]);
     82     DbgPrint("WinXP_X86 Old_NtOpenProcess:%p
    ",Old_NtOpenProcess);
     83     
     84 #endif
     85 
     86     RtlInitUnicodeString(&uniDeviceName,DEVICE_NAME);
     87 
     88     Status = IoCreateDevice(DriverObject,0,&uniDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&DeviceObject);
     89 
     90 
     91     if (!NT_SUCCESS(Status))
     92     {
     93         return Status;
     94     }
     95 
     96 
     97     IoInitializeTimer(DeviceObject,(PIO_TIMER_ROUTINE)CallBackProcedure,NULL);
     98     IoStartTimer(DeviceObject);
     99 
    100 
    101     DriverObject->DriverUnload = UnloadDriver;
    102 
    103     return Status;
    104 }
    105 
    106 VOID
    107     CallBackProcedure(PDEVICE_OBJECT DeviceObject,PVOID Context)
    108 {
    109     
    110 #ifdef _WIN64
    111     InlineHookSSDTWin7_X64((ULONG64)Old_NtOpenProcess,(ULONG64)Fake_NtOpenProcess,14);
    112 #else 
    113     InlineHookSSDTWinXP_X86((ULONG32)Old_NtOpenProcess,(ULONG32)Fake_NtOpenProcess,5);
    114 #endif
    115     
    116 
    117 
    118 
    119 
    120 }
    121 
    122 VOID  UnloadDriver(PDRIVER_OBJECT DriverObject)
    123 {
    124 
    125 
    126     IoStopTimer(DriverObject->DeviceObject);
    127     if (DriverObject->DeviceObject!=NULL)
    128     {
    129         IoDeleteDevice(DriverObject->DeviceObject);
    130     }
    131 
    132 #ifdef _WIN64
    133 
    134     UnInlineHookSSDTWin7_X64((ULONG64)Old_NtOpenProcess,(ULONG64)Old_NtOpenProcessHeaderBytes,14);
    135 
    136 
    137     if (Old_NtOpenProcessHeaderBytes!=NULL)
    138     {
    139         ExFreePool(Old_NtOpenProcessHeaderBytes);
    140         Old_NtOpenProcessHeaderBytes = NULL;
    141     }
    142 
    143     if (NtOpenProcessPassCode!=NULL)
    144     {
    145         ExFreePool(NtOpenProcessPassCode);
    146         NtOpenProcessPassCode = NULL;
    147     }
    148 #else
    149 
    150     UnInlineHookSSDTWinXP_X86((ULONG32)Old_NtOpenProcess,(ULONG32)Old_NtOpenProcessHeaderBytes,5);
    151 
    152 
    153     if (Old_NtOpenProcessHeaderBytes!=NULL)
    154     {
    155         ExFreePool(Old_NtOpenProcessHeaderBytes);
    156         Old_NtOpenProcessHeaderBytes = NULL;
    157     }
    158 
    159     if (NtOpenProcessPassCode!=NULL)
    160     {
    161         ExFreePool(NtOpenProcessPassCode);
    162         NtOpenProcessPassCode = NULL;
    163     }
    164 #endif
    165 
    166 
    167 
    168 }
    169 
    170 BOOLEAN GetSSDTAddressInWinXP_X86(ULONG32* SSDTAddress)
    171 {
    172     //从NtosKernel.exe 模块中的导出表获得该导出变量  KeServiceDescriptorTable
    173 
    174     /*
    175     kd> dd KeServiceDescriptorTable
    176     80563520  804e58a0 00000000 0000011c 805120bc
    177     */
    178     *SSDTAddress = NULL;
    179     *SSDTAddress = (ULONG32)GetExportVariableAddressFormNtosExportTableByVariableName(L"KeServiceDescriptorTable");
    180 
    181     if (*SSDTAddress!=NULL)
    182     {
    183         return TRUE;
    184     }
    185 
    186     return FALSE;
    187 }
    188 
    189 
    190 PVOID 
    191     GetExportVariableAddressFormNtosExportTableByVariableName(WCHAR *wzVariableName)
    192 {
    193     UNICODE_STRING uniVariableName;  
    194     PVOID VariableAddress = NULL;
    195 
    196     if (wzVariableName && wcslen(wzVariableName) > 0)
    197     {
    198         RtlInitUnicodeString(&uniVariableName, wzVariableName);  
    199 
    200         //从Ntos模块的导出表中获得一个导出变量的地址
    201         VariableAddress = MmGetSystemRoutineAddress(&uniVariableName); 
    202     }
    203 
    204     return VariableAddress;
    205 }
    206 
    207 
    208 
    209 
    210 VOID UnInlineHookSSDTWinXP_X86(ULONG32 ulCurrentVariable,ULONG32 ulOldVariable,ULONG32 ulPatchSize)
    211 {
    212     WPOFF();
    213     memcpy((PVOID)ulCurrentVariable,(PVOID)ulOldVariable,ulPatchSize);  
    214     WPON();
    215 }
    216 
    217 
    218 BOOLEAN InlineHookSSDTWinXP_X86(ULONG32 ulOldVariable,ULONG32 ulFakeVariable,ULONG32 ulPatchSize)
    219 {
    220     UCHAR v1[] = "xe9x00x00x00x00";
    221     UCHAR v2[] = "xe9x00x00x00x00";
    222     ULONG32 ulTemp = 0;
    223 
    224     /*
    225     kd> u 8058270A
    226     nt!NtOpenProcess:
    227     8058270a 68c4000000      push    0C4h
    228     8058270f 68d8524f80      push    offset nt!ObWatchHandles+0x25c (804f52d8)
    229     80582714 e85a17f6ff      call    nt!_SEH_prolog (804e3e73)
    230     80582719 33f6            xor     esi,esi
    231     8058271b 8975d4          mov     dword ptr [ebp-2Ch],esi
    232     8058271e 33c0            xor     eax,eax
    233     80582720 8d7dd8          lea     edi,[ebp-28h]
    234     80582723 ab              stos    dword ptr es:[edi]
    235     */
    236 
    237 
    238 
    239     Old_NtOpenProcessHeaderBytes = ExAllocatePool(NonPagedPool,ulPatchSize); 
    240 
    241     if (Old_NtOpenProcessHeaderBytes==NULL)
    242     {
    243         return FALSE;
    244     }
    245 
    246 
    247     WPOFF();
    248     memcpy(Old_NtOpenProcessHeaderBytes,(PVOID)ulOldVariable,ulPatchSize);
    249     //    Old_NtOpenProcessHeaderBytes[   68c4000000      ]
    250     WPON();
    251 
    252 
    253 
    254     NtOpenProcessPassCode = ExAllocatePool(NonPagedPool,(ulPatchSize+5));
    255     if (NtOpenProcessPassCode==NULL)
    256     {
    257 
    258         if (Old_NtOpenProcessHeaderBytes!=NULL)
    259         {
    260             ExFreePool(Old_NtOpenProcessHeaderBytes);
    261             Old_NtOpenProcessHeaderBytes = NULL;
    262         }
    263         return FALSE;
    264     }
    265 
    266     
    267 
    268     RtlFillMemory(NtOpenProcessPassCode,ulPatchSize+5,0x90);  //NOP
    269     //NtOpenProcessPassCode[0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90]
    270 
    271 
    272     memcpy((PUCHAR)NtOpenProcessPassCode,Old_NtOpenProcessHeaderBytes,ulPatchSize);  
    273     //NtOpenProcessPassCode[ 68c4000000 0x90 0x90 0x90 0x90 0x90]
    274 
    275 
    276     ulTemp=(ULONG32)ulOldVariable+ulPatchSize;       
    277     //8058270a  + 5  = 8058270f   = ulTemp                  
    278 
    279     *((ULONG32*)&v2[1]) = (ULONG32)ulTemp  - ((ULONG32)NtOpenProcessPassCode +5 + 5); //第一个+5 是过前5个字节 第二个加 是 新 - (旧+5)
    280 
    281     memcpy((PUCHAR)NtOpenProcessPassCode+ulPatchSize,v2,5);
    282 
    283 
    284     ulTemp = (ULONG32)ulFakeVariable;
    285 
    286     *((ULONG32*)&v1[1]) = (ULONG32)ulTemp  - ((ULONG32)ulOldVariable +5); 
    287 
    288     WPOFF();
    289     RtlFillMemory((PVOID)ulOldVariable,ulPatchSize,0x90);
    290     memcpy((PVOID)ulOldVariable,v1,5);
    291     WPON();
    292 
    293     return TRUE;
    294 }
    295 
    296 
    297 
    298 BOOLEAN GetSSDTAddressInWin7_X64(ULONG64* SSDTAddress)
    299 {
    300 
    301     
    302     /*
    303     kd> rdmsr c0000082 
    304     msr[c0000082] = fffff800`03ecf640
    305     kd> u fffff800`03ecf640 l 50
    306     nt!KiSystemCall64:
    307     fffff800`03ecf640 0f01f8          swapgs
    308     fffff800`03ecf643 654889242510000000 mov   qword ptr gs:[10h],rsp
    309     fffff800`03ecf64c 65488b2425a8010000 mov   rsp,qword ptr gs:[1A8h]
    310     fffff800`03ecf655 6a2b            push    2Bh
    311     fffff800`03ecf657 65ff342510000000 push    qword ptr gs:[10h]
    312     fffff800`03ecf65f 4153            push    r11
    313     fffff800`03ecf661 6a33            push    33h
    314     fffff800`03ecf663 51              push    rcx
    315     fffff800`03ecf664 498bca          mov     rcx,r10
    316     fffff800`03ecf667 4883ec08        sub     rsp,8
    317     fffff800`03ecf66b 55              push    rbp
    318     fffff800`03ecf66c 4881ec58010000  sub     rsp,158h
    319     fffff800`03ecf673 488dac2480000000 lea     rbp,[rsp+80h]
    320     fffff800`03ecf67b 48899dc0000000  mov     qword ptr [rbp+0C0h],rbx
    321     fffff800`03ecf682 4889bdc8000000  mov     qword ptr [rbp+0C8h],rdi
    322     fffff800`03ecf689 4889b5d0000000  mov     qword ptr [rbp+0D0h],rsi
    323     fffff800`03ecf690 c645ab02        mov     byte ptr [rbp-55h],2
    324     fffff800`03ecf694 65488b1c2588010000 mov   rbx,qword ptr gs:[188h]
    325     fffff800`03ecf69d 0f0d8bd8010000  prefetchw [rbx+1D8h]
    326     fffff800`03ecf6a4 0fae5dac        stmxcsr dword ptr [rbp-54h]
    327     fffff800`03ecf6a8 650fae142580010000 ldmxcsr dword ptr gs:[180h]
    328     fffff800`03ecf6b1 807b0300        cmp     byte ptr [rbx+3],0
    329     fffff800`03ecf6b5 66c785800000000000 mov   word ptr [rbp+80h],0
    330     fffff800`03ecf6be 0f848c000000    je      nt!KiSystemCall64+0x110 (fffff800`03ecf750)
    331     fffff800`03ecf6c4 488945b0        mov     qword ptr [rbp-50h],rax
    332     fffff800`03ecf6c8 48894db8        mov     qword ptr [rbp-48h],rcx
    333     fffff800`03ecf6cc 488955c0        mov     qword ptr [rbp-40h],rdx
    334     fffff800`03ecf6d0 f6430303        test    byte ptr [rbx+3],3
    335     fffff800`03ecf6d4 4c8945c8        mov     qword ptr [rbp-38h],r8
    336     fffff800`03ecf6d8 4c894dd0        mov     qword ptr [rbp-30h],r9
    337     fffff800`03ecf6dc 7405            je      nt!KiSystemCall64+0xa3 (fffff800`03ecf6e3)
    338     fffff800`03ecf6de e80d140000      call    nt!KiSaveDebugRegisterState (fffff800`03ed0af0)
    339     fffff800`03ecf6e3 f6430380        test    byte ptr [rbx+3],80h
    340     fffff800`03ecf6e7 7442            je      nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
    341     fffff800`03ecf6e9 b9020100c0      mov     ecx,0C0000102h
    342     fffff800`03ecf6ee 0f32            rdmsr
    343     fffff800`03ecf6f0 48c1e220        shl     rdx,20h
    344     fffff800`03ecf6f4 480bc2          or      rax,rdx
    345     fffff800`03ecf6f7 483983b8000000  cmp     qword ptr [rbx+0B8h],rax
    346     fffff800`03ecf6fe 742b            je      nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
    347     fffff800`03ecf700 483983b0010000  cmp     qword ptr [rbx+1B0h],rax
    348     fffff800`03ecf707 7422            je      nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
    349     fffff800`03ecf709 488b93b8010000  mov     rdx,qword ptr [rbx+1B8h]
    350     fffff800`03ecf710 0fba6b4c0b      bts     dword ptr [rbx+4Ch],0Bh
    351     fffff800`03ecf715 66ff8bc4010000  dec     word ptr [rbx+1C4h]
    352     fffff800`03ecf71c 48898280000000  mov     qword ptr [rdx+80h],rax
    353     fffff800`03ecf723 fb              sti
    354     fffff800`03ecf724 e8170b0000      call    nt!KiUmsCallEntry (fffff800`03ed0240)
    355     fffff800`03ecf729 eb0f            jmp     nt!KiSystemCall64+0xfa (fffff800`03ecf73a)
    356     fffff800`03ecf72b f6430340        test    byte ptr [rbx+3],40h
    357     fffff800`03ecf72f 7409            je      nt!KiSystemCall64+0xfa (fffff800`03ecf73a)
    358     fffff800`03ecf731 f00fbaab0001000008 lock bts dword ptr [rbx+100h],8
    359     fffff800`03ecf73a 488b45b0        mov     rax,qword ptr [rbp-50h]
    360     fffff800`03ecf73e 488b4db8        mov     rcx,qword ptr [rbp-48h]
    361     fffff800`03ecf742 488b55c0        mov     rdx,qword ptr [rbp-40h]
    362     fffff800`03ecf746 4c8b45c8        mov     r8,qword ptr [rbp-38h]
    363     fffff800`03ecf74a 4c8b4dd0        mov     r9,qword ptr [rbp-30h]
    364     fffff800`03ecf74e 6690            xchg    ax,ax
    365     fffff800`03ecf750 fb              sti
    366     fffff800`03ecf751 48898be0010000  mov     qword ptr [rbx+1E0h],rcx
    367     fffff800`03ecf758 8983f8010000    mov     dword ptr [rbx+1F8h],eax
    368     nt!KiSystemServiceStart:
    369     fffff800`03ecf75e 4889a3d8010000  mov     qword ptr [rbx+1D8h],rsp
    370     fffff800`03ecf765 8bf8            mov     edi,eax
    371     fffff800`03ecf767 c1ef07          shr     edi,7
    372     fffff800`03ecf76a 83e720          and     edi,20h
    373     fffff800`03ecf76d 25ff0f0000      and     eax,0FFFh
    374     nt!KiSystemServiceRepeat:
    375     fffff800`03ecf772 4c8d15c7202300  lea     r10,[nt!KeServiceDescriptorTable (fffff800`04101840)]
    376 
    377     fffff800`03ecf772 + 002320c7 + 7  = fffff800`04101840
    378     */
    379 
    380 
    381 
    382 
    383     PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082);   //fffff800`03ecf640
    384     PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
    385     PUCHAR i = NULL;
    386     UCHAR   v1=0,v2=0,v3=0;
    387     INT64   iOffset = 0;    //002320c7
    388     ULONG64 VariableAddress = 0;
    389     *SSDTAddress = NULL;
    390     for(i=StartSearchAddress;i<EndSearchAddress;i++)
    391     {
    392         if( MmIsAddressValid(i) && MmIsAddressValid(i+1) && MmIsAddressValid(i+2) )
    393         {
    394             v1=*i;
    395             v2=*(i+1);
    396             v3=*(i+2);
    397             if(v1==0x4c && v2==0x8d && v3==0x15 ) 
    398             {
    399                 memcpy(&iOffset,i+3,4);
    400                 *SSDTAddress = iOffset + (ULONG64)i + 7;
    401 
    402                 break;
    403             }
    404         }
    405     }
    406 
    407     if (*SSDTAddress==NULL)
    408     {
    409         return FALSE;
    410     }
    411 
    412     /*
    413     kd> dq fffff800`04101840
    414     fffff800`04101840  fffff800`03ed1300 00000000`00000000
    415     fffff800`04101850  00000000`00000191 fffff800`03ed1f8c
    416 
    417     */
    418     return TRUE;
    419 }
    420 
    421 
    422 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex)
    423 {
    424     /*
    425     0:004> u zwopenprocess
    426     ntdll!NtOpenProcess:
    427     00000000`774ddc10 4c8bd1          mov     r10,rcx
    428     00000000`774ddc13 b823000000      mov     eax,23h
    429     00000000`774ddc18 0f05            syscall
    430     00000000`774ddc1a c3              ret
    431     00000000`774ddc1b 0f1f440000      nop     dword ptr [rax+rax]
    432     */
    433 
    434     ULONG32     ulOffset_SSDTFunctionIndex = 4;
    435 
    436     ULONG   i;
    437     BOOLEAN  bOk = FALSE;
    438     WCHAR    wzFileFullPath[] = L"\SystemRoot\System32\ntdll.dll";
    439     SIZE_T   MappingViewSize   = 0;
    440     PVOID    MappingBaseAddress = NULL;
    441     PIMAGE_NT_HEADERS  NtHeader = NULL;
    442     PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
    443     ULONG32*  AddressOfFunctions    = NULL;
    444     ULONG32*  AddressOfNames        = NULL;
    445     USHORT*   AddressOfNameOrdinals = NULL;
    446     CHAR*     szFunctionName        = NULL;
    447     ULONG32   ulFunctionOrdinal     = 0;
    448     ULONG64   ulFunctionAddress     = 0;
    449 
    450     *SSDTFunctionIndex = -1;
    451 
    452 
    453     //将Ntdll.dll 当前的空间中
    454     bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
    455     if (bOk==FALSE)
    456     {
    457         return FALSE;
    458     }
    459     else
    460     {
    461         __try{
    462             NtHeader = RtlImageNtHeader(MappingBaseAddress);
    463             if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
    464             {
    465                 ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG64)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
    466 
    467 
    468 
    469                 AddressOfFunctions = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
    470                 AddressOfNames = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNames);
    471                 AddressOfNameOrdinals = (USHORT*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
    472                 for(i = 0; i < ExportDirectory->NumberOfNames; i++)
    473                 {
    474                     szFunctionName = (char*)((ULONG64)MappingBaseAddress + AddressOfNames[i]);   //获得函数名称
    475                     if (_stricmp(szFunctionName, szFindFunctionName) == 0)   
    476                     {
    477                         ulFunctionOrdinal = AddressOfNameOrdinals[i]; 
    478                         ulFunctionAddress = (ULONG64)((ULONG64)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]);
    479 
    480 
    481                         *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex); 
    482                         break;
    483                     }
    484                 }
    485             }
    486         }__except(EXCEPTION_EXECUTE_HANDLER)
    487         {
    488             ;
    489         }
    490     }
    491 
    492 
    493     ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress);
    494 
    495 
    496     if (*SSDTFunctionIndex==-1)
    497     {
    498         return FALSE;
    499     }
    500 
    501     return TRUE;
    502 }
    503 
    504 
    505 VOID UnInlineHookSSDTWin7_X64(ULONG64 ulCurrentVariable,ULONG64 ulOldVariable,ULONG32 ulPatchSize)
    506 {
    507     WPOFF();
    508     memcpy((PVOID)ulCurrentVariable,(PVOID)ulOldVariable,ulPatchSize);  
    509     WPON();
    510 }
    511 
    512 
    513 BOOLEAN InlineHookSSDTWin7_X64(ULONG64 ulOldVariable,ULONG64 ulFakeVariable,ULONG32 ulPatchSize)
    514 {
    515     UCHAR v1[]="xFFx25x00x00x00x00xFFxFFxFFxFFxFFxFFxFFxFF";
    516     UCHAR v2[]="xFFx25x00x00x00x00xFFxFFxFFxFFxFFxFFxFFxFF";
    517     ULONG64 ulTemp = 0;
    518 
    519     //保存这14个字节的内容
    520     Old_NtOpenProcessHeaderBytes = ExAllocatePool(NonPagedPool,ulPatchSize);
    521 
    522     if (Old_NtOpenProcessHeaderBytes==NULL)
    523     {
    524         return FALSE;
    525     }
    526     WPOFF();
    527     memcpy(Old_NtOpenProcessHeaderBytes,(PVOID)ulOldVariable,ulPatchSize);
    528     WPON();
    529 
    530 
    531     //构建保存原先的前14个字节的内容和跳转到14个字节之后的指令的内容
    532     NtOpenProcessPassCode = ExAllocatePool(NonPagedPool,(ulPatchSize+14));     
    533     if (NtOpenProcessPassCode==NULL)
    534     {
    535         ExFreePool(Old_NtOpenProcessHeaderBytes);
    536         Old_NtOpenProcessHeaderBytes = NULL;
    537         return FALSE;
    538     }
    539 
    540     RtlFillMemory(NtOpenProcessPassCode,ulPatchSize+14,0x90);//NOP
    541 
    542     memcpy((PUCHAR)NtOpenProcessPassCode,Old_NtOpenProcessHeaderBytes,ulPatchSize);   //保存原先的14个字节
    543 
    544     ulTemp=(ULONG64)ulOldVariable+ulPatchSize;                             //原先函数14个字节之后的内容所在的地址    Temp = 0x12345678
    545 
    546     memcpy(v2+6,&ulTemp,8);                                    //构建跳转到该地址的Shell
    547 
    548     memcpy((PUCHAR)NtOpenProcessPassCode+ulPatchSize,v2,ulPatchSize);           //保存
    549 
    550 
    551 
    552 
    553     //构建跳转到我们Fake函数的Shell
    554     ulTemp = (ULONG64)ulFakeVariable;
    555     memcpy(v1+6,&ulTemp,8);
    556 
    557 
    558 
    559     //修改原先的14个字节为跳转到Fake的指令
    560     WPOFF();
    561     RtlFillMemory((PVOID)ulOldVariable,ulPatchSize,0x90);
    562     memcpy((PVOID)ulOldVariable,v1,ulPatchSize);
    563     WPON();
    564 }
    565 
    566 
    567 
    568 VOID WPOFF()
    569 {
    570     //选择性编译,是给编译器看的
    571 #if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_)
    572     _disable();
    573     __writecr0(__readcr0() & (~(0x10000)));
    574 #else
    575     __asm
    576     {
    577         CLI  ;                 
    578         MOV    EAX, CR0;    
    579         AND    EAX, NOT 10000H;
    580         MOV    CR0, EAX;        
    581     }
    582 #endif
    583 }
    584 VOID WPON()
    585 {
    586 #if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_)
    587     __writecr0(__readcr0() ^ 0x10000);
    588     _enable();
    589 #else
    590     __asm
    591     {
    592         MOV    EAX, CR0;        
    593         OR     EAX, 10000H;            
    594         MOV    CR0, EAX;              
    595         STI;                    
    596     }
    597 #endif
    598 }
    599 
    600 
    601 
    602 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(CHAR* szFindFunctionName,
    603     ULONG32* SSDTFunctionIndex)
    604 {
    605     /*
    606     0:001> u zwopenprocess
    607     ntdll!ZwOpenProcess:
    608     7c92d5e0 b87a000000      mov     eax,7Ah
    609     7c92d5e5 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
    610     7c92d5ea ff12            call    dword ptr [edx]
    611     7c92d5ec c21000          ret     10h
    612     7c92d5ef 90              nop
    613     */
    614 
    615     ULONG32     ulOffset_SSDTFunctionIndex = 1;
    616 
    617 
    618     //从Ntdll模块的导出表中获得7c92d5e0
    619     //使用内存映射将Ntdll模块映射到System进程的内存空间进行查找(Ntdll.dll模块的导出表中进行搜索)
    620     ULONG   i;
    621     BOOLEAN  bOk = FALSE;
    622     WCHAR    wzFileFullPath[] = L"\SystemRoot\System32\ntdll.dll";
    623     SIZE_T  MappingViewSize   = 0;
    624     PVOID    MappingBaseAddress = NULL;
    625     PIMAGE_NT_HEADERS  NtHeader = NULL;
    626     PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
    627     ULONG32*  AddressOfFunctions    = NULL;
    628     ULONG32*  AddressOfNames        = NULL;
    629     USHORT* AddressOfNameOrdinals = NULL;
    630     CHAR*   szFunctionName        = NULL;
    631     ULONG32 ulFunctionOrdinal     = 0;
    632     ULONG32 ulFunctionAddress     = 0;
    633     
    634     *SSDTFunctionIndex = -1;
    635 
    636 
    637     //将Ntdll.dll 当前的空间中
    638     bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
    639     if (bOk==FALSE)
    640     {
    641         return FALSE;
    642     }
    643     else
    644     {
    645         __try{
    646             NtHeader = RtlImageNtHeader(MappingBaseAddress);
    647             if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
    648             {
    649                 ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG32)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
    650                 
    651                 
    652                 
    653                 AddressOfFunctions = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
    654                 AddressOfNames = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNames);
    655                 AddressOfNameOrdinals = (USHORT*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
    656                 for(i = 0; i < ExportDirectory->NumberOfNames; i++)
    657                 {
    658                     szFunctionName = (char*)((ULONG32)MappingBaseAddress + AddressOfNames[i]);   //获得函数名称
    659                     if (_stricmp(szFunctionName, szFindFunctionName) == 0)   
    660                     {
    661                         ulFunctionOrdinal = AddressOfNameOrdinals[i]; 
    662                         ulFunctionAddress = (ULONG32)((ULONG32)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]);
    663                         
    664                         
    665                         *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex); 
    666                         break;
    667                     }
    668                 }
    669             }
    670         }__except(EXCEPTION_EXECUTE_HANDLER)
    671         {
    672             ;
    673         }
    674     }
    675 
    676 
    677     ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress);
    678 
    679 
    680     if (*SSDTFunctionIndex==-1)
    681     {
    682         return FALSE;
    683     }
    684     
    685     return TRUE;
    686 }
    687 
    688 BOOLEAN 
    689     MappingPEFileInRing0Space(WCHAR* wzFileFullPath,OUT PVOID* MappingBaseAddress,PSIZE_T MappingViewSize)
    690 {
    691     UNICODE_STRING    uniFileFullPath;
    692     OBJECT_ATTRIBUTES oa;
    693     NTSTATUS          Status;
    694     IO_STATUS_BLOCK   Iosb;
    695 
    696     HANDLE   hFile = NULL;
    697     HANDLE   hSection = NULL;
    698 
    699     if (!wzFileFullPath || !MappingBaseAddress){
    700         return FALSE;
    701     }
    702 
    703     RtlInitUnicodeString(&uniFileFullPath, wzFileFullPath);
    704     InitializeObjectAttributes(&oa,
    705         &uniFileFullPath,
    706         OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
    707         NULL,
    708         NULL
    709         );
    710 
    711 
    712     //获得文件句柄
    713     Status = IoCreateFile(&hFile,
    714         GENERIC_READ | SYNCHRONIZE,
    715         &oa,   //文件绝对路径
    716         &Iosb,
    717         NULL,
    718         FILE_ATTRIBUTE_NORMAL,
    719         FILE_SHARE_READ,
    720         FILE_OPEN,
    721         FILE_SYNCHRONOUS_IO_NONALERT,
    722         NULL,
    723         0,
    724         CreateFileTypeNone,
    725         NULL,
    726         IO_NO_PARAMETER_CHECKING
    727         );
    728     if (!NT_SUCCESS(Status))
    729     {
    730 
    731         return FALSE;
    732     }
    733 
    734     oa.ObjectName = NULL;
    735     Status = ZwCreateSection(&hSection,
    736         SECTION_QUERY | SECTION_MAP_READ,
    737         &oa,
    738         NULL,
    739         PAGE_WRITECOPY,
    740         SEC_IMAGE,  //??  指示内存对齐
    741         hFile
    742         );
    743     ZwClose(hFile);
    744     if (!NT_SUCCESS(Status))
    745     {
    746 
    747         return FALSE;
    748     }
    749     Status = ZwMapViewOfSection(hSection, 
    750         NtCurrentProcess(),    //映射到当前进程的内存空间中
    751         MappingBaseAddress, 
    752         0, 
    753         0, 
    754         0, 
    755         MappingViewSize, 
    756         ViewUnmap, 
    757         0, 
    758         PAGE_WRITECOPY
    759         );
    760     ZwClose(hSection);
    761     if (!NT_SUCCESS(Status))
    762     {
    763         return FALSE;
    764     }
    765 
    766     return TRUE;
    767 }
    768 
    769 
    770 
    771 NTSTATUS Fake_NtOpenProcess(
    772     PHANDLE ProcessHandle,
    773     ACCESS_MASK DesiredAccess,
    774     POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId)
    775 {
    776     PEPROCESS  EProcess = PsGetCurrentProcess();    //进程上下背景文
    777     if (EProcess!=NULL)
    778     {
    779         //通过EProcess 获得进程名称 
    780 
    781         char *szProcessImageName = PsGetProcessImageFileName(EProcess);
    782 
    783         if (strstr(szProcessImageName,"EnumProcess")!=0)
    784         {
    785 
    786             return STATUS_ACCESS_DENIED;
    787         }
    788     }
    789 
    790     if (NtOpenProcessPassCode!=NULL)
    791     {
    792         ((pfnNtOpenProcess)NtOpenProcessPassCode)(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
    793     }
    794 }
    View Code
     1 /***************************************************************************************
     2 * AUTHOR : 
     3 * DATE   : 2015-11-1
     4 * MODULE : IoTimerInlineHook.H
     5 *
     6 * IOCTRL Sample Driver
     7 *
     8 * Description:
     9 *        Demonstrates communications between USER and KERNEL.
    10 *
    11 ****************************************************************************************
    12 * Copyright (C) 2010 .
    13 ****************************************************************************************/
    14 
    15 #ifndef CXX_IOTIMERINLINEHOOK_H
    16 #define CXX_IOTIMERINLINEHOOK_H
    17 
    18 
    19 
    20 #include <ntifs.h>
    21 
    22 #include <ntimage.h>
    23 #define DEVICE_NAME   L"\Device\IoTimerInlineHookDeviceName"
    24 
    25 #define SEC_IMAGE  0x01000000
    26 
    27 //定义SSDT表的结构
    28 typedef struct _SYSTEM_SERVICE_TABLE_WIN7_X64{
    29     PVOID          ServiceTableBase; 
    30     PVOID          ServiceCounterTableBase; 
    31     ULONG64      NumberOfServices;                     //SSDT表中的函数个数   0x191
    32     PVOID          ParamTableBase; 
    33 } SYSTEM_SERVICE_TABLE_WIN7_X64, *PSYSTEM_SERVICE_TABLE_WIN7_X64;
    34 
    35 typedef struct _SYSTEM_SERVICE_TABLE_WINXP_X86 {
    36     PVOID   ServiceTableBase;
    37     PVOID   ServiceCounterTableBase;
    38     ULONG32 NumberOfServices;                         //SSDT表中的函数个数   0x11c
    39     PVOID   ParamTableBase;
    40 } SYSTEM_SERVICE_TABLE_WINXP_X86, *PSYSTEM_SERVICE_TABLE_WINXP_X86;
    41 
    42 extern
    43     char* PsGetProcessImageFileName(PEPROCESS EProcess);
    44 
    45 extern
    46     PIMAGE_NT_HEADERS
    47     NTAPI
    48     RtlImageNtHeader(PVOID BaseAddress);
    49 
    50 typedef
    51     NTSTATUS
    52     (*pfnNtOpenProcess)(
    53     PHANDLE ProcessHandle,
    54     ACCESS_MASK DesiredAccess,
    55     POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);
    56 
    57 NTSTATUS Fake_NtOpenProcess(
    58     PHANDLE ProcessHandle,
    59     ACCESS_MASK DesiredAccess,
    60     POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);
    61 
    62 
    63 #ifdef _WIN64
    64 #define PSYSTEM_SERVICE_TABLE PSYSTEM_SERVICE_TABLE_WIN7_X64    
    65 #else
    66 #define PSYSTEM_SERVICE_TABLE PSYSTEM_SERVICE_TABLE_WINXP_X86   
    67 #endif
    68 
    69 VOID  UnloadDriver(PDRIVER_OBJECT DriverObject);
    70 
    71 
    72 BOOLEAN GetSSDTAddressInWinXP_X86(ULONG32* SSDTAddress);
    73 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(CHAR* szFindFunctionName,
    74     ULONG32* SSDTFunctionIndex);
    75 BOOLEAN InlineHookSSDTWinXP_X86(ULONG32 ulOldVariable,ULONG32 ulFakeVariable,ULONG32 ulPatchSize);
    76 VOID UnInlineHookSSDTWinXP_X86(ULONG32 ulCurrentVariable,ULONG32 ulOldVariable,ULONG32 ulPatchSize);
    77 
    78 
    79 BOOLEAN GetSSDTAddressInWin7_X64(ULONG64* SSDTAddress);
    80 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex);
    81 BOOLEAN InlineHookSSDTWin7_X64(ULONG64 ulOldVariable,ULONG64 ulFakeVariable,ULONG32 ulPatchSize);
    82 VOID UnInlineHookSSDTWin7_X64(ULONG64 ulCurrentVariable,ULONG64 ulOldVariable,ULONG32 ulPatchSize);
    83 
    84 PVOID 
    85     GetExportVariableAddressFormNtosExportTableByVariableName(WCHAR *wzVariableName);
    86 
    87 BOOLEAN 
    88     MappingPEFileInRing0Space(WCHAR* wzFileFullPath,OUT PVOID* MappingBaseAddress,PSIZE_T MappingViewSize);
    89 
    90 
    91 
    92 VOID WPOFF();
    93 VOID WPON();
    94 
    95 VOID
    96     CallBackProcedure(PDEVICE_OBJECT DeviceObject,PVOID Context);
    97 
    98 
    99 #endif    
    View Code
    爱程序 不爱bug 爱生活 不爱黑眼圈 我和你们一样 我和你们不一样 我不是凡客 我要做geek
  • 相关阅读:
    java接口变量问题
    FileInputStream与BufferedInputStream的对比
    eclipse使用javaFX写一个HelloWorkld
    Windows 安装Java与配置环境变量
    asp.net core处理中文的指南
    修改release management client对应的服务器的地址
    在server2012安装tfs遇到的问题:KB2919355
    release management客户端无法连接到release management server的问题解决
    如何升级PowerShell
    VS2010下调试.NET源码
  • 原文地址:https://www.cnblogs.com/yifi/p/4953165.html
Copyright © 2020-2023  润新知