您当前的位置: 首页 > 

[转贴]内核级HOOK的几种实现与应用

发布时间:2007-09-25 16:12:00 ,浏览量:0

内核级HOOK的几种实现与应用
作者: sinister

内核级HOOK的几种实现与应用 Author  : sinister Email   : sinister@whitecell.org HomePage: http://www.whitecell.org       实现内核级 HOOK 对于拦截、分析、跟踪系统内核起着致关重要的作用。实现的方法不同意味着应用侧重点的不同。如想要拦截 NATIVE API 那么可能常用的就是 HOOK SERVICE TABLE 的方法。如果要分析一些系统调用,那么可能想到用 HOOK INT 2E 中断来实现。如果想要拦截或跟踪其他内核 DRIVER 的调用,那么就要用到HOOK PE 的方法来实现。这里我们更注重的是实现,原理方面已有不少高手在网上发表过文章。大家可以结合起来读。下面以我写的几个实例程序来讲解一下各种方法的实现。错误之处还望各位指正。 1、HOOK SERVICE TABLE 方法:    这种方法对于拦截 NATIVE API 来说用的比较多。原理就是通过替换系统导 出的一个 SERVICE TABLE 中相应的 NATIVE API 的地址来达到拦截的目的。 因为此方法较为简单,网上也有不少资料来介绍。所以这里就不给出实例程序了。SERVICE TABLE 的结构如下: typedef struct ServiceDescriptorEntry {     unsigned int *ServiceTableBase;     unsigned int *ServiceCounterTableBase;      unsigned int NumberOfServices;     unsigned char *ParamTableBase; } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;     2、HOOK INT 2E 方法:    这种方法对于跟踪、分析系统调用来说用的比较多。原理是通过替换 IDT 表中的 INT 2E 中断,使之指向我们自己的中断服务处理例程来实现的。掌握 此方法需要你对保护模式有一定的基础。下面的程序演示了这一过程。 /***************************************************************** 文件名        : WssHookInt2e.c 描述          : 系统调用跟踪 作者          : sinister 最后修改日期  : 2002-11-02 *****************************************************************/ #include "ntddk.h" #include "string.h" #define DWORD unsigned __int32 #define WORD unsigned __int16 #define BYTE unsigned __int8 #define BOOL __int32 #define LOWORD(l)           ((WORD)(l)) #define HIWORD(l)           ((WORD)(((DWORD)(l) >> 16) & 0xFFFF)) #define LOBYTE(w)           ((BYTE)(w)) #define HIBYTE(w)           ((BYTE)(((WORD)(w) >> 8) & 0xFF)) #define MAKELONG(a, b) ((LONG) (((WORD) (a)) | ((DWORD) ((WORD) (b))) << 16))  #define SYSTEMCALL 0x2e #define SYSNAME "System" #define PROCESSNAMELEN 16 #pragma pack(1) //定义 IDTR  typedef struct tagIDTR {         WORD IDTLimit;         WORD LowIDTbase;         WORD HiIDTbase; }IDTR, *PIDTR; //定义 IDT  typedef struct tagIDTENTRY{     WORD OffsetLow;     WORD selector;     BYTE unused_lo;     unsigned char unused_hi:5;     unsigned char DPL:2;     unsigned char P:1;     WORD OffsetHigh; } IDTENTRY, *PIDTENTRY; #pragma pack() DWORD    OldInt2eService; ULONG    ProcessNameOffset; TCHAR   ProcessName[PROCESSNAMELEN]; static NTSTATUS  MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject); ULONG GetProcessNameOffset(); VOID GetProcessName( PCHAR Name ); VOID InstallNewInt2e(); VOID UninstallNewInt2e(); VOID __fastcall NativeApiCall() {     KIRQL OldIrql;          DWORD ServiceID;     DWORD ProcessId;     __asm mov ServiceID,eax;     ProcessId = (DWORD)PsGetCurrentProcessId();     GetProcessName(ProcessName);     KeRaiseIrql(HIGH_LEVEL, &OldIrql); // 提升当前的 IRQL 级别防止被中断     switch ( ServiceID )     {             case 0x20:                  DbgPrint("NEWINT2E: ProcessName: %s; ProcessID: %d; Native Api: NtCreateFile() /n",ProcessName,ProcessId);                  break;             case 0x2b:                  DbgPrint("NEWINT2E: ProcessName: %s; ProcessID: %d; Native Api: NtCreateSection() /n",ProcessName,ProcessId);                                   break;             case 0x30:                  DbgPrint("NEWINT2E: ProcessName: %s; ProcessID: %d; Native Api: NtCreateToken() /n",ProcessName,ProcessId);                                   break;                       }     KeLowerIrql(OldIrql); //恢复原始 IRQL } __declspec(naked) NewInt2eService() {     __asm{         pushad         pushfd         push fs         mov bx,0x30         mov fs,bx         push ds         push es         sti         call NativeApiCall; // 调用记录函数         cli         pop es         pop ds         pop fs         popfd         popad         jmp    OldInt2eService;  //跳到原始 INT 2E 继续工作     } } VOID InstallNewInt2e() {     IDTR         idtr;     PIDTENTRY    OIdt;     PIDTENTRY    NIdt;     //得到 IDTR 中得段界限与基地址     __asm {          sidt idtr;     }     //得到IDT基地址     OIdt = (PIDTENTRY)MAKELONG(idtr.LowIDTbase,idtr.HiIDTbase);      //保存原来的 INT 2E 服务例程     OldInt2eService = MAKELONG(OIdt[SYSTEMCALL].OffsetLow,OIdt[SYSTEMCALL].OffsetHigh);          NIdt = &(OIdt[SYSTEMCALL]);     __asm {         cli         lea eax,NewInt2eService;  //得到新的 INT 2E 服务例程偏移         mov ebx, NIdt;         mov [ebx],ax;   //INT 2E 服务例程低 16 位         shr eax,16      //INT 2E 服务例程高 16 位         mov [ebx+6],ax;         lidt idtr  //装入新的 IDT         sti     } } VOID UninstallNewInt2e() {     IDTR         idtr;     PIDTENTRY    OIdt;     PIDTENTRY    NIdt;     __asm {         sidt idtr;     }     OIdt = (PIDTENTRY)MAKELONG(idtr.LowIDTbase,idtr.HiIDTbase);      NIdt = &(OIdt[SYSTEMCALL]);     _asm {         cli         lea eax,OldInt2eService;         mov ebx, NIdt;         mov [ebx],ax;         shr eax,16         mov [ebx+6],ax;         lidt idtr         sti     } } // 驱动入口 NTSTATUS  DriverEntry( IN PDRIVER_OBJECT DriverObject,  IN PUNICODE_STRING RegistryPath )  {          UNICODE_STRING  nameString, linkString;     PDEVICE_OBJECT  deviceObject;     NTSTATUS        status;     HANDLE          hHandle;     int                i;          //卸载驱动     DriverObject->DriverUnload = DriverUnload;     //建立设备     RtlInitUnicodeString( &nameString, L"//Device//WssHookInt2e" );          status = IoCreateDevice( DriverObject,                              0,                              &nameString,                              FILE_DEVICE_UNKNOWN,                              0,                              TRUE,                              &deviceObject                            );                                 if (!NT_SUCCESS( status ))         return status;          RtlInitUnicodeString( &linkString, L"//DosDevices//WssHookInt2e" );     status = IoCreateSymbolicLink (&linkString, &nameString);     if (!NT_SUCCESS( status ))     {         IoDeleteDevice (DriverObject->DeviceObject);         return status;     }              for ( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)    {           DriverObject->MajorFunction[i] = MydrvDispatch;     }       DriverObject->DriverUnload = DriverUnload;     ProcessNameOffset = GetProcessNameOffset();     InstallNewInt2e();   return STATUS_SUCCESS;  }  //处理设备对象操作 static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {      Irp->IoStatus.Status = STATUS_SUCCESS;     Irp->IoStatus.Information = 0L;     IoCompleteRequest( Irp, 0 );     return Irp->IoStatus.Status;      } VOID DriverUnload (IN PDRIVER_OBJECT    pDriverObject) {     UNICODE_STRING  nameString;     UninstallNewInt2e();     RtlInitUnicodeString( &nameString, L"//DosDevices//WssHookInt2e" );         IoDeleteSymbolicLink(&nameString);     IoDeleteDevice(pDriverObject->DeviceObject);     return; } ULONG GetProcessNameOffset() {         PEPROCESS curproc;         int i;                  curproc = PsGetCurrentProcess();         //         // Scan for 12KB, hopping the KPEB never grows that big!         //         for( i = 0; i < 3*PAGE_SIZE; i++ ) {             if( !strncmp( SYSNAME, (PCHAR) curproc + i, strlen(SYSNAME) )) {                 return i;             }         }         //         // Name not found - oh, well         //         return 0; } VOID GetProcessName( PCHAR Name ) {         PEPROCESS curproc;         char *nameptr;         ULONG i;         if( ProcessNameOffset ) {             curproc = PsGetCurrentProcess();             nameptr = (PCHAR) curproc + ProcessNameOffset;             strncpy( Name, nameptr, 16 );         } else {             strcpy( Name, "???");         } }  3、 HOOK PE 方法     这种方法对于拦截、分析其他内核驱动的函数调用来说用的比较多。原理 是根据替换 PE 格式导出表中的相应函数来实现的。此方法中需要用到一些小 技巧。如内核模式并没有直接提供类似应用层的 GetModuleHandl()、GetProcAddress() 等函数来获得模块的地址。那么我们就需要自己来编写,这 里用到了一个未公开的函数与结构。ZwQuerySystemInformation 与 SYSTEM_MODULE_INFORMATION 来实现得到模块的基地址。这样我们就可以根据 PE 格式来枚举导出表中的函数来替换了。但这又引出了一个问题,那就是从 WINDOWS 2000 后内核数据的页属性都是只读的,不能更改。内核模式也没有 提供类似应用层的 VirtualProtectEx() 等函数来修改页面属性。那么也需要 我们自己来编写。因为我们是在内核模式所以我们可以通过修改 cr0 寄存器的 的写保护位来达到我们的目的。这样我们所期望的拦截内核模式函数的功能便 得以实现。此方法需要你对 PE 格式有一定的基础。下面的程序演示了这一过程。 /***************************************************************** 文件名        : WssHookPE.c 描述          : 拦截内核函数 作者          : sinister 最后修改日期  : 2002-11-02 *****************************************************************/ #include "ntddk.h" #include "windef.h" typedef enum _SYSTEM_INFORMATION_CLASS {     SystemBasicInformation,     SystemProcessorInformation,     SystemPerformanceInformation,     SystemTimeOfDayInformation,     SystemNotImplemented1,     SystemProcessesAndThreadsInformation,     SystemCallCounts,     SystemConfigurationInformation,     SystemProcessorTimes,     SystemGlobalFlag,     SystemNotImplemented2,     SystemModuleInformation,     SystemLockInformation,     SystemNotImplemented3,     SystemNotImplemented4,     SystemNotImplemented5,     SystemHandleInformation,     SystemObjectInformation,     SystemPagefileInformation,     SystemInstructionEmulationCounts,     SystemInvalidInfoClass1,     SystemCacheInformation,     SystemPoolTagInformation,     SystemProcessorStatistics,     SystemDpcInformation,     SystemNotImplemented6,     SystemLoadImage,     SystemUnloadImage,     SystemTimeAdjustment,     SystemNotImplemented7,     SystemNotImplemented8,     SystemNotImplemented9,     SystemCrashDumpInformation,     SystemExceptionInformation,     SystemCrashDumpStateInformation,     SystemKernelDebuggerInformation,     SystemContextSwitchInformation,     SystemRegistryQuotaInformation,     SystemLoadAndCallImage,     SystemPrioritySeparation,     SystemNotImplemented10,     SystemNotImplemented11,     SystemInvalidInfoClass2,     SystemInvalidInfoClass3,     SystemTimeZoneInformation,     SystemLookasideInformation,     SystemSetTimeSlipEvent,     SystemCreateSession,     SystemDeleteSession,     SystemInvalidInfoClass4,     SystemRangeStartInformation,     SystemVerifierInformation,     SystemAddVerifier,     SystemSessionProcessesInformation } SYSTEM_INFORMATION_CLASS; typedef struct tagSYSTEM_MODULE_INFORMATION {     ULONG Reserved[2];     PVOID Base;     ULONG Size;     ULONG Flags;     USHORT Index;     USHORT Unknown;     USHORT LoadCount;     USHORT ModuleNameOffset;     CHAR ImageName[256]; } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; #define IMAGE_DOS_SIGNATURE        0x5A4D      // MZ #define IMAGE_NT_SIGNATURE      0x50450000  // PE00 #define IMAGE_NT_SIGNATURE1        0x00004550    // 00EP typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header     WORD   e_magic;                     // Magic number     WORD   e_cblp;                      // Bytes on last page of file     WORD   e_cp;                        // Pages in file     WORD   e_crlc;                      // Relocations     WORD   e_cparhdr;                   // Size of header in paragraphs     WORD   e_minalloc;                  // Minimum extra paragraphs needed     WORD   e_maxalloc;                  // Maximum extra paragraphs needed     WORD   e_ss;                        // Initial (relative) SS value     WORD   e_sp;                        // Initial SP value     WORD   e_csum;                      // Checksum     WORD   e_ip;                        // Initial IP value     WORD   e_cs;                        // Initial (relative) CS value     WORD   e_lfarlc;                    // File address of relocation table     WORD   e_ovno;                      // Overlay number     WORD   e_res[4];                    // Reserved words     WORD   e_oemid;                     // OEM identifier (for e_oeminfo)     WORD   e_oeminfo;                   // OEM information; e_oemid specific     WORD   e_res2[10];                  // Reserved words     LONG   e_lfanew;                    // File address of new exe header   } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; typedef struct _IMAGE_FILE_HEADER {     WORD    Machine;     WORD    NumberOfSections;     DWORD   TimeDateStamp;     DWORD   PointerToSymbolTable;     DWORD   NumberOfSymbols;     WORD    SizeOfOptionalHeader;     WORD    Characteristics; } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; typedef struct _IMAGE_DATA_DIRECTORY {     DWORD   VirtualAddress;     DWORD   Size; } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16 // // Optional header format. // typedef struct _IMAGE_OPTIONAL_HEADER {     //     // Standard fields.     //     WORD    Magic;     BYTE    MajorLinkerVersion;     BYTE    MinorLinkerVersion;     DWORD   SizeOfCode;     DWORD   SizeOfInitializedData;     DWORD   SizeOfUninitializedData;     DWORD   AddressOfEntryPoint;     DWORD   BaseOfCode;     DWORD   BaseOfData;     //     // NT additional fields.     //     DWORD   ImageBase;     DWORD   SectionAlignment;     DWORD   FileAlignment;     WORD    MajorOperatingSystemVersion;     WORD    MinorOperatingSystemVersion;     WORD    MajorImageVersion;     WORD    MinorImageVersion;     WORD    MajorSubsystemVersion;     WORD    MinorSubsystemVersion;     DWORD   Win32VersionValue;     DWORD   SizeOfImage;     DWORD   SizeOfHeaders;     DWORD   CheckSum;     WORD    Subsystem;     WORD    DllCharacteristics;     DWORD   SizeOfStackReserve;     DWORD   SizeOfStackCommit;     DWORD   SizeOfHeapReserve;     DWORD   SizeOfHeapCommit;     DWORD   LoaderFlags;     DWORD   NumberOfRvaAndSizes;     IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; typedef struct _IMAGE_NT_HEADERS {     DWORD Signature;     IMAGE_FILE_HEADER FileHeader;     IMAGE_OPTIONAL_HEADER32 OptionalHeader; } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; typedef IMAGE_NT_HEADERS32                  IMAGE_NT_HEADERS; typedef PIMAGE_NT_HEADERS32                 PIMAGE_NT_HEADERS; // // Section header format. // #define IMAGE_SIZEOF_SHORT_NAME              8 typedef struct _IMAGE_SECTION_HEADER {     BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];     union {             DWORD   PhysicalAddress;             DWORD   VirtualSize;     } Misc;     DWORD   VirtualAddress;     DWORD   SizeOfRawData;     DWORD   PointerToRawData;     DWORD   PointerToRelocations;     DWORD   PointerToLinenumbers;     WORD    NumberOfRelocations;     WORD    NumberOfLinenumbers;     DWORD   Characteristics; } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; #define IMAGE_SIZEOF_SECTION_HEADER          40 // // Export Format // typedef struct _IMAGE_EXPORT_DIRECTORY {     DWORD   Characteristics;     DWORD   TimeDateStamp;     WORD    MajorVersion;     WORD    MinorVersion;     DWORD   Name;     DWORD   Base;     DWORD   NumberOfFunctions;     DWORD   NumberOfNames;     DWORD   AddressOfFunctions;     // RVA from base of image     DWORD   AddressOfNames;         // RVA from base of image     DWORD   AddressOfNameOrdinals;  // RVA from base of image } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; #define BASEADDRLEN 10 NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(     IN SYSTEM_INFORMATION_CLASS SystemInformationClass,     IN OUT PVOID SystemInformation,     IN ULONG SystemInformationLength,     OUT PULONG ReturnLength OPTIONAL     ); typedef NTSTATUS (* ZWCREATEFILE)(   OUT PHANDLE FileHandle,   IN ACCESS_MASK DesiredAccess,   IN POBJECT_ATTRIBUTES ObjectAttributes,   OUT PIO_STATUS_BLOCK IoStatusBlock,   IN PLARGE_INTEGER AllocationSize  OPTIONAL,   IN ULONG FileAttributes,   IN ULONG ShareAccess,   IN ULONG CreateDisposition,   IN ULONG CreateOptions,   IN PVOID EaBuffer  OPTIONAL,   IN ULONG EaLength   ); ZWCREATEFILE    OldZwCreateFile; static NTSTATUS  MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject); VOID DisableWriteProtect( PULONG pOldAttr); VOID EnableWriteProtect( ULONG ulOldAttr ); FARPROC HookFunction(    PCHAR pModuleBase, PCHAR pHookName, FARPROC pHookFunc ); NTSTATUS   HookNtCreateFile(   OUT PHANDLE FileHandle,   IN ACCESS_MASK DesiredAccess,   IN POBJECT_ATTRIBUTES ObjectAttributes,   OUT PIO_STATUS_BLOCK IoStatusBlock,   IN PLARGE_INTEGER AllocationSize  OPTIONAL,   IN ULONG FileAttributes,   IN ULONG ShareAccess,   IN ULONG CreateDisposition,   IN ULONG CreateOptions,   IN PVOID EaBuffer  OPTIONAL,   IN ULONG EaLength   ); PCHAR MyGetModuleBaseAddress( PCHAR pModuleName )  {     PSYSTEM_MODULE_INFORMATION    pSysModule;         ULONG            uReturn;     ULONG            uCount;     PCHAR            pBuffer = NULL;     PCHAR            pName    = NULL;     NTSTATUS        status;     UINT            ui;     CHAR            szBuffer[BASEADDRLEN];     PCHAR            pBaseAddress;          status = ZwQuerySystemInformation( SystemModuleInformation, szBuffer, BASEADDRLEN, &uReturn );     pBuffer = ( PCHAR )ExAllocatePool( NonPagedPool, uReturn );     if ( pBuffer )     {         status = ZwQuerySystemInformation( SystemModuleInformation, pBuffer, uReturn, &uReturn );         if( status == STATUS_SUCCESS )         {             uCount = ( ULONG )*( ( ULONG * )pBuffer );             pSysModule = ( PSYSTEM_MODULE_INFORMATION )( pBuffer + sizeof( ULONG ) );             for ( ui = 0; ui < uCount; ui++ )             {                 pName = MyStrchr( pSysModule->ImageName, ‘//’ );                 if ( !pName )                  {                     pName = pSysModule->ImageName;                 }                 else {                     pName++;                 }                 if( !_stricmp( pName, pModuleName ) )                 {                     pBaseAddress = ( PCHAR )pSysModule->Base;                     ExFreePool( pBuffer );                     return pBaseAddress;                 }                 pSysModule ++;             }         }         ExFreePool( pBuffer );     }     return NULL; } FARPROC HookFunction( PCHAR pModuleBase, PCHAR HookFunName, FARPROC HookFun ) {     PIMAGE_DOS_HEADER         pDosHdr;     PIMAGE_NT_HEADERS         pNtHdr;     PIMAGE_SECTION_HEADER     pSecHdr;     PIMAGE_EXPORT_DIRECTORY  pExtDir;     UINT                    ui,uj;     PCHAR                    FunName;     DWORD                    *dwAddrName;     DWORD                    *dwAddrFun;     FARPROC                    pOldFun;     ULONG                    uAttrib;     pDosHdr = ( PIMAGE_DOS_HEADER )pModuleBase;     if ( IMAGE_DOS_SIGNATURE == pDosHdr->e_magic )     {         pNtHdr = ( PIMAGE_NT_HEADERS )( pModuleBase + pDosHdr->e_lfanew );         if( IMAGE_NT_SIGNATURE  == pNtHdr->Signature ||    IMAGE_NT_SIGNATURE1 == pNtHdr->Signature )         {             pSecHdr = ( PIMAGE_SECTION_HEADER )( pModuleBase + pDosHdr->e_lfanew + sizeof( IMAGE_NT_HEADERS ) );             for ( ui = 0; ui < (UINT)pNtHdr->FileHeader.NumberOfSections; ui++ )             {                 if ( !strcmp( pSecHdr->Name, ".edata" ) )                 {                                     pExtDir = ( PIMAGE_EXPORT_DIRECTORY )( pModuleBase + pSecHdr->VirtualAddress );                     dwAddrName = ( PDWORD )(pModuleBase + pExtDir->AddressOfNames );                     dwAddrFun = ( PDWORD )(pModuleBase + pExtDir->AddressOfFunctions );                     for ( uj = 0; uj < (UINT)pExtDir->NumberOfFunctions; uj++ )                     {                         FunName = pModuleBase + *dwAddrName;                         if( !strcmp( FunName, HookFunName ) )                         {                             DbgPrint(" HOOK  %s()/n",FunName);                             DisableWriteProtect( &uAttrib );                             pOldFun = ( FARPROC )( pModuleBase + *dwAddrFun );                             *dwAddrFun = ( PCHAR )HookFun - pModuleBase;                             EnableWriteProtect( uAttrib );                             return pOldFun;                         }                       dwAddrName ++;                       dwAddrFun ++;                     }                 }                 pSecHdr++;             }         }     }     return NULL; } // 驱动入口 NTSTATUS  DriverEntry( IN PDRIVER_OBJECT DriverObject,  IN PUNICODE_STRING RegistryPath )  {          UNICODE_STRING  nameString, linkString;     PDEVICE_OBJECT  deviceObject;     NTSTATUS        status;     HANDLE          hHandle;     PCHAR            pModuleAddress;     int                i;          //卸载驱动     DriverObject->DriverUnload = DriverUnload;     //建立设备     RtlInitUnicodeString( &nameString, L"//Device//WssHookPE" );          status = IoCreateDevice( DriverObject,                              0,                              &nameString,                              FILE_DEVICE_UNKNOWN,                              0,                              TRUE,                              &deviceObject                            );                                 if (!NT_SUCCESS( status ))         return status;          RtlInitUnicodeString( &linkString, L"//DosDevices//WssHookPE" );     status = IoCreateSymbolicLink (&linkString, &nameString);     if (!NT_SUCCESS( status ))     {         IoDeleteDevice (DriverObject->DeviceObject);         return status;     }              pModuleAddress = MyGetModuleBaseAddress("ntoskrnl.exe");     if ( pModuleAddress == NULL)     {         DbgPrint(" MyGetModuleBaseAddress()/n");         return 0;     }     OldZwCreateFile = (ZWCREATEFILE)HookFunction( pModuleAddress, "ZwCreateFile",(ZWCREATEFILE)HookNtCreateFile);     if ( OldZwCreateFile == NULL)     {         DbgPrint(" HOOK FAILED/n");         return 0;     }     DbgPrint("HOOK SUCCEED/n");     for ( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)    {           DriverObject->MajorFunction[i] = MydrvDispatch;     }       DriverObject->DriverUnload = DriverUnload;         return STATUS_SUCCESS;  }  //处理设备对象操作 static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {      Irp->IoStatus.Status = STATUS_SUCCESS;     Irp->IoStatus.Information = 0L;     IoCompleteRequest( Irp, 0 );     return Irp->IoStatus.Status;      } VOID DriverUnload (IN PDRIVER_OBJECT    pDriverObject) {     UNICODE_STRING  nameString;     PCHAR            pModuleAddress;     pModuleAddress = MyGetModuleBaseAddress("ntoskrnl.exe");     if ( pModuleAddress == NULL)     {         DbgPrint("MyGetModuleBaseAddress()/n");         return ;     }     OldZwCreateFile = (ZWCREATEFILE)HookFunction( pModuleAddress, "ZwCreateFile",(ZWCREATEFILE)OldZwCreateFile);     if ( OldZwCreateFile == NULL)     {         DbgPrint(" UNHOOK FAILED!/n");         return ;     }     DbgPrint("UNHOOK SUCCEED/n");     RtlInitUnicodeString( &nameString, L"//DosDevices//WssHookPE" );         IoDeleteSymbolicLink(&nameString);     IoDeleteDevice(pDriverObject->DeviceObject);     return; } NTSTATUS   HookNtCreateFile(   OUT PHANDLE FileHandle,   IN ACCESS_MASK DesiredAccess,   IN POBJECT_ATTRIBUTES ObjectAttributes,   OUT PIO_STATUS_BLOCK IoStatusBlock,   IN PLARGE_INTEGER AllocationSize  OPTIONAL,   IN ULONG FileAttributes,   IN ULONG ShareAccess,   IN ULONG CreateDisposition,   IN ULONG CreateOptions,   IN PVOID EaBuffer  OPTIONAL,   IN ULONG EaLength   ) {     NTSTATUS    status;     DbgPrint("Hook ZwCreateFile()/n");     status = ((ZWCREATEFILE)(OldZwCreateFile))(                FileHandle,                DesiredAccess,                ObjectAttributes,                IoStatusBlock,                AllocationSize,                FileAttributes,                ShareAccess,                CreateDisposition,                CreateOptions,                EaBuffer,                EaLength               );     return status; } VOID DisableWriteProtect( PULONG pOldAttr) {      ULONG uAttr;      _asm     {           push eax;           mov  eax, cr0;           mov  uAttr, eax;           and  eax, 0FFFEFFFFh; // CR0 16 BIT = 0           mov  cr0, eax;           pop  eax;     };      *pOldAttr = uAttr; //保存原有的 CRO 属性 } VOID EnableWriteProtect( ULONG uOldAttr ) {   _asm   {        push eax;        mov  eax, uOldAttr; //恢复原有 CR0 属性        mov  cr0, eax;        pop  eax;   }; }

关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    107766博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0568s