首页 电脑 电脑学堂 查看内容

内核级HOOK的几种实现与应用

2004-9-29 20:05 725 0

摘要: 实现内核级 HOOK 对于拦截、分析、跟踪系统内核起着致关重要的作用。实现的方法不同意味着应用侧重点的不同。如想要拦截 NATIVE API 那么可能常用的就是 HOOK SERVICE TABLE ...
关键词: DWORD status ULONG IMAGE WORD HEADER return define nameString Information

实现内核级 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描述 : 系统调用跟踪*****************************************************************/#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))) #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{pushadpushfdpush fsmov bx,0x30mov fs,bxpush dspush essticall NativeApiCall; // 调用记录函数clipop espop dspop fspopfdpopadjmp 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 {clilea 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 //装入新的 IDTsti}}VOID UninstallNewInt2e(){IDTR idtr;PIDTENTRY OIdt;PIDTENTRY NIdt;__asm {sidt idtr;}OIdt = (PIDTENTRY)MAKELONG(idtr.LowIDTbase,idtr.HiIDTbase); NIdt = &(OIdt[SYSTEMCALL]);_asm {clilea eax,OldInt2eService;mov ebx, NIdt;mov [ebx],ax;shr eax,16mov [ebx+6],ax;lidt idtrsti}}// 驱动入口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 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 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 // 00EPtypedef struct _IMAGE_DOS_HEADER { // DOS .EXE headerWORD e_magic; // Magic numberWORD e_cblp; // Bytes on last page of fileWORD e_cp; // Pages in fileWORD e_crlc; // RelocationsWORD e_cparhdr; // Size of header in paragraphsWORD e_minalloc; // Minimum extra paragraphs neededWORD e_maxalloc; // Maximum extra paragraphs neededWORD e_ss; // Initial (relative) SS valueWORD e_sp; // Initial SP valueWORD e_csum; // ChecksumWORD e_ip; // Initial IP valueWORD e_cs; // Initial (relative) CS valueWORD e_lfarlc; // File address of relocation tableWORD e_ovno; // Overlay numberWORD e_res[4]; // Reserved wordsWORD e_oemid; // OEM identifier (for e_oeminfo)WORD e_oeminfo; // OEM information; e_oemid specificWORD e_res2[10]; // Reserved wordsLONG 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 8typedef 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 imageDWORD AddressOfNames; // RVA from base of imageDWORD AddressOfNameOrdinals; // RVA from base of image} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;#define BASEADDRLEN 10NTSYSAPINTSTATUSNTAPIZwQuerySystemInformation(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 {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 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 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 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 = 0mov cr0, eax;pop eax;};*pOldAttr = uAttr; //保存原有的 CRO 属性}VOID EnableWriteProtect( ULONG uOldAttr ){_asm{push eax;mov eax, uOldAttr; //恢复原有 CR0 属性mov cr0, eax;pop eax;};}
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部