阅读:1722回复:0
xp下hook IofCallDriver出错
先向将要帮助我的人表示感谢.
问题是这样的:我根据《天书夜读》上的思路做了一个xp下hook IofCallDriver的小程序,当总是出错,用WinDbg单步调试时,最终的蓝屏代码为DRIVER_IRQL_NOT_LESS_OR_EQUAL,另外当不调试直接在OS中运行时,最终蓝屏代码为PAGE_FAULT_IN_NONPAGED 下面是关键的代码 //driver.h typedef 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 unhook VOID WPOFF(); // VOID WPON(); // #pragma PAGEDCODE VOID 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的地址,否则返回NULL PIOFCALLDRIVER 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 INITCODE NTSTATUS 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; } 也许我很菜,但please help me |
|