阅读:1940回复:1
XP下Hook IofCallDriver后死循环
废话就不多说了,郁闷中,下面是关键代码
//driver.h typedef PCHAR PBYTE; //不想在一个一个替换了,so... typedef NTSTATUS (__fastcall *PIOFCALLDRIVER)(PDEVICE_OBJECT,PIRP); //driver.cpp ULONG g_uCR0; //保存我们修改CRP寄存器之前的它的值 KSPIN_LOCK SDTSpinLock; PIOFCALLDRIVER g_nativeIofCallDriver; //保存系统的IofCallDriver的地址 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 LOCKEDCODE NTSTATUS FASTCALL MyIofCallDriver(IN PDEVICE_OBJECT pDevObj,IN OUT PIRP pIrp) { DbgPrint("HDM:This is MyIofCallDriver! You succeed!\n"); NTSTATUS status=STATUS_SUCCESS; status=g_nativeIofCallDriver(pDevObj,pIrp); return status; } #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) { /* kd> u IofCallDriver nt!IofCallDriver: 804ef130 ff2580d25480 jmp dword ptr [nt!pIofCallDriver (8054d280)] 804ef136 cc int 3 804ef137 cc int 3 804ef138 cc int 3 804ef139 cc int 3 804ef13a cc int 3 804ef13b cc int 3 nt!IoCheckQuerySetFileInformation: 804ef13c 8bff mov edi,edi 注意,上面jmp指令的寻址方式为段间间接远转移,具体格式如下 格式:JMP DWORD PTR OPR 执行的操作: (EIP)←(EA) (CS)←(EA+4) 其中EA由OPR的寻址方式确定,根据寻址方式确定EA后,把指定存储单元的字内容送到 IP或EIP寄存器,并把下一个字的内容送到CS,这样就实现了段间跳转 */ nativeIofCallDriver=(PBYTE)(*(PLONG)(*(PLONG)(address+2))); KIRQL OldIrql; KeAcquireSpinLock( &SDTSpinLock, &OldIrql ); WPOFF(); InterlockedExchange((PLONG)(*(PLONG)(address+2)),(LONG)IofCallDriver); WPON(); KeReleaseSpinLock( &SDTSpinLock, OldIrql ); } else { if (IofCallDriver) { KIRQL OldIrql; KeAcquireSpinLock( &SDTSpinLock, &OldIrql ); WPOFF(); InterlockedExchange((PLONG)(*(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; } g_nativeIofCallDriver=HookIofCallDriver(MyIofCallDriver,TRUE); if (g_nativeIofCallDriver==NULL) { IoDeleteDevice(pDevObj); IoDeleteSymbolicLink(&symLinkName); status=STATUS_UNSUCCESSFUL; } return status; } 问题就是调用HookIofCallDriver成功后,接下来就会不停的进入MyIofCallDriver,电脑几乎不反应了, 先先向帮助我的人表示感谢了 |
|
沙发#
发布于:2011-10-24 08:29
OK,程序没什么问题,自己弄错了,有兴趣的可以帮忙再测试一下
|
|