xp下hook IofCallDriver出错
先向将要帮助我的人表示感谢.
问题是这样的:我根据《天书夜读》上的思路做了一个xp下hook IofCallDriver的小程序,当总是出错,用WinDbg单步调试时,最终的蓝屏代码为DRIVER_IRQL_NOT_LESS_OR_EQUAL,另外当不调试直接在OS中运行时,最终蓝屏代码为PAGE_FAULT_IN_NONPAGED
下面是关键的代码
//driver.htypedef PCHAR PBYTE; //不想在一个一个替换了,so...typedef NTSTATUS (__fastcall *PIOFCALLDRIVER)(PDEVICE_OBJECT,PIRP);typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT pDevice; UNICODE_STRING ustrDeviceName; //设备名称 UNICODE_STRING ustrSymLinkName; //符号链接名 PIOFCALLDRIVER nativerIofCallDriver; //保存系统的IofCallDriver的地址} DEVICE_EXTENSION, *PDEVICE_EXTENSION;//driver.cpp#include "Driver.h"ULONG g_uCR0; //保存我们修改CRP寄存器之前的它的值KSPIN_LOCK SDTSpinLock;NTSTATUS FASTCALL MyIofCallDriver(IN PDEVICE_OBJECT,IN OUT PIRP); //我们的IofCallDriver;PIOFCALLDRIVER HookIofCallDriver(IN PIOFCALLDRIVER, IN BOOLEAN ); //Hook IofCallDriver or unhookVOID WPOFF(); //VOID WPON(); //#pragma PAGEDCODEVOID WPOFF(){ ULONG uAttr; _asm { push eax; mov eax, cr0; mov uAttr, eax; and eax, 0FFFEFFFFh; // CR0 16 BIT = 0 mov cr0, eax; pop eax; cli }; g_uCR0=uAttr;}VOID WPON(){ _asm { sti push eax; mov eax, g_uCR0; //恢復原有 CR0 屬性 mov cr0, eax; pop eax; }; }#pragma PAGEDCODE NTSTATUS FASTCALL MyIofCallDriver(IN PDEVICE_OBJECT pDevObj,IN OUT PIRP pIrp){ DbgPrint("HDM:This is MyIofCallDriver! You succeed!\n"); PDEVICE_EXTENSION pdx=(PDEVICE_EXTENSION)pDevObj->DeviceExtension; return (*(pdx->nativerIofCallDriver))(pDevObj,pIrp);}#pragma PAGEDCODE////当hookOrUnhook为TRUE时,IofCallDriver为我们的替换函数的地址//当hookOrUnhook为FALSE时,则为系统IofCallDriver的地址//无论是hook or unhook,当函数成功时,返回系统IofCallDriver的地址,否则返回NULLPIOFCALLDRIVER HookIofCallDriver(IN PIOFCALLDRIVER IofCallDriver, IN BOOLEAN hookOrUnhook){ DbgPrint("HDM:Enter HookIofCallDriver\n"); UNICODE_STRING functionName; PBYTE address=NULL; //通过调用MmGetSystemRoutineAddress得到的IofCallDriver的入口地址 PBYTE nativeIofCallDriver=NULL; //IofCallDriver执行体的地址 RtlInitUnicodeString(&functionName,L"IofCallDriver"); //得到IofCallDriver的入口地址 address=(PBYTE)MmGetSystemRoutineAddress(&functionName); if (address==NULL) { return NULL; } if (hookOrUnhook) { //通过反汇编可知,将上面得到的地址加两字节地址就是系统的IofCallDriver执行体的地址 nativeIofCallDriver=(PBYTE)(*(PLONG)(address+2)); KIRQL OldIrql; KeAcquireSpinLock( &SDTSpinLock, &OldIrql ); WPOFF(); InterlockedExchange((PLONG)(address+2),(LONG)IofCallDriver); WPON(); KeReleaseSpinLock( &SDTSpinLock, OldIrql ); } else { if (IofCallDriver) { KIRQL OldIrql; KeAcquireSpinLock( &SDTSpinLock, &OldIrql ); WPOFF(); InterlockedExchange((PLONG)(address+2),(LONG)IofCallDriver); WPON(); KeReleaseSpinLock( &SDTSpinLock, OldIrql ); nativeIofCallDriver=(PBYTE)IofCallDriver; } else { return NULL; } } DbgPrint("HDM:Leave HookIofCallDriver\n"); return (PIOFCALLDRIVER)nativeIofCallDriver;}#pragma INITCODENTSTATUS CreateDevice ( IN PDRIVER_OBJECT pDriverObject) { NTSTATUS status=STATUS_SUCCESS; PDEVICE_OBJECT pDevObj; PDEVICE_EXTENSION pDevExt; //创建设备名称 UNICODE_STRING devName; RtlInitUnicodeString(&devName,L"\\Device\\XPHookIofCallDriver"); //创建设备 status = IoCreateDevice( pDriverObject, sizeof(DEVICE_EXTENSION), &(UNICODE_STRING)devName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj ); if (!NT_SUCCESS(status)) return status; pDevObj->Flags |= DO_BUFFERED_IO; pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension; pDevExt->pDevice = pDevObj; pDevExt->ustrDeviceName = devName; //创建符号链接 UNICODE_STRING symLinkName; RtlInitUnicodeString(&symLinkName,L"\\??\\XPHookIofCallDriver"); pDevExt->ustrSymLinkName = symLinkName; status = IoCreateSymbolicLink( &symLinkName,&devName ); if (!NT_SUCCESS(status)) { IoDeleteDevice( pDevObj ); return status; } pDevExt->nativerIofCallDriver=HookIofCallDriver(MyIofCallDriver,TRUE); if (pDevExt->nativerIofCallDriver==NULL) { IoDeleteDevice(pDevObj); IoDeleteSymbolicLink(&symLinkName); status=STATUS_UNSUCCESSFUL; } return status;}