阅读:2157回复:1
内核API Inline hook引发BSOD,大家看看是什么原因
目前在写一个inline hook api的demo,采用在NtQuerySystemInformation前10个字节写入跳转指令,跳转到自己定义的函数中,等执行完hook函数后,再恢复NtQuerySystemInformation前10字节的内容,继续程序执行,可是在调试的过程中出现BSOD,反馈的错误是:
Break Due to KeBugCheckEx(UnHandled kernel mode exception) Error = 7f (UNEXPECTED_KERNEL_MODE_TRAP) P1 = 8 P2= 80042000 P3=0 P4 = 0 完整代码如下: .386 .model flat, stdcall option casemap:none include w2k\ntstatus.inc include w2k\ntddk.inc include w2k\native.inc include w2k\ntoskrnl.inc include w2k\hal.inc includelib C:\RadASM\masm32\lib\w2k\ntoskrnl.lib includelib C:\RadASM\masm32\lib\w2k\hal.lib include C:\RadASM\masm32\macros\strings.mac hooksysapi.rar hooksysapi.rar ;---------------------------------------------------------------------------------------------------- ; D A T A ;---------------------------------------------------------------------------------------------------- .data ;保存地址 szcommand db 0EAh, 0AAh, 0AAh ,0AAh, 0AAh, 08h, 0h ,090h ,090h, 090h szOldCmd db 10 dup(0) NewNtQuerySystemInformationAddr dd ? ;---------------------------------------------------------------------------------------------------- ; C O N S T A N T S ;---------------------------------------------------------------------------------------------------- .const CCOUNTED_UNICODE_STRING "\\Device\\devHideprocess", g_usDeviceName, 4 CCOUNTED_UNICODE_STRING "\\??\\slHideprocess", g_usSymbolicLinkName, 4 CCOUNTED_UNICODE_STRING "explorer.exe", processname, 4 SetHookOn proto SetHookOff proto WpOn proto WpOff proto ;---------------------------------------------------------------------------------------------------- ; C O D E ;---------------------------------------------------------------------------------------------------- .code ;本例从第二个块开始遍历,因为第一个块通常是System Idle Process. NewNtQuerySystemInformation proc SysInfoClass,lpSysInfo,SysInfoL,Return pushad invoke SetHookOff invoke NtQuerySystemInformation,SysInfoClass,lpSysInfo,SysInfoL,Return ;调用原函数 test eax,eax ;判断调用是否成功 jnz exit .if SysInfoClass == SystemProcessesAndThreadsInformation ;5 mov esi,lpSysInfo mov ebx,esi ;ebx指向前一个块 add esi,[esi] ;esi指向后一个块 @@: add esi,38h ;在38h偏移处取得进程名字。 invoke RtlCompareUnicodeString,addr processname, esi, 1 .if eax== 0 ;找到进程块 invoke DbgPrint, $CTA0("\nsuccessful \n") .if dword ptr[esi-38h] == 0 ;是最后一个块 mov dword ptr[ebx],0 ;让前一个块作为最后的块 jmp exit ;退出循环 .else sub esi,38h ;回到块首 mov edx,[esi] ;edx --->NextEntryDelta add [ebx],edx ;让前一个块指向当前块的下一个块 add esi,[esi] ;遍历当前块的下一个块,继续查找下一个隐藏的进程 jmp @B ;继续循环 .endif .else sub esi,38h ;回到块首 cmp dword ptr[esi],0 ;判断是否到了最后一个块 jz exit ;是,退出循环 mov ebx,esi ;否则前一个块指针指向当前块 add esi,[esi] ;当前块指针指向下一个结构块 jmp @B ;继续循环 .endif .endif exit: invoke SetHookOn popad ret NewNtQuerySystemInformation endp ;---------------------------------------------------------------------------------------------------- ; H O O K F U N C ;---------------------------------------------------------------------------------------------------- SetHookOn proc ;保存原来NtQuerySystemInformation的开头10字节 pushad cld mov esi, 08060798Ah ;NtQuerySystemInformation的地址 lea edi, szOldCmd mov ecx, 10 rep movsb ;申请非分页内存,将新函数拷贝到其中。 invoke ExAllocatePool,NonPagedPool,256 mov NewNtQuerySystemInformationAddr,eax cld lea esi,NewNtQuerySystemInformation lea edi,NewNtQuerySystemInformationAddr mov ecx,081h rep movsb ;得到将非分页内存的首地址,添加到szcommand中 lea eax,NewNtQuerySystemInformationAddr lea edi,szcommand+1 stosd ;将szcommand写入原函数开头字节 invoke WpOff cld lea esi,szcommand mov edi,08060798Ah ;NtQuerySystemInformation mov ecx,10 rep movsb invoke WpOn popad ret SetHookOn endp SetHookOff proc pushad ;恢复原函数开头字节 invoke WpOff cld mov edi,08060798Ah;NtQuerySystemInformation lea esi,szOldCmd mov ecx,10 rep movsb invoke WpOn popad ret SetHookOff endp WpOn proc mov eax,cr0 ;move CR0 register into EAX or eax,10000H ;enable WP bit mov cr0, eax ;write register back sti ;enable interrupt WpOn endp WpOff proc cli ;dissable interrupt mov eax, cr0 ;move CR0 register into EAX and eax, not 10000H ;disable WP bit mov cr0, eax ;write register back WpOff endp ;---------------------------------------------------------------------------------------------------- ; DriverUnload ;---------------------------------------------------------------------------------------------------- DriverUnload proc pDriverObject:PDRIVER_OBJECT ;必须保存环境,否则后果很严重。在这个函数中恢复被修改的地址。 pushad invoke DbgPrint, $CTA0("\nEntry into DriverUnload \n") invoke SetHookOff invoke ExFreePool,NewNtQuerySystemInformationAddr invoke IoDeleteSymbolicLink, addr g_usSymbolicLinkName mov eax,pDriverObject invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject popad ret DriverUnload endp DriverEntry proc pDriverObject:PDRIVER_OBJECT,pusRegistryPath:PUNICODE_STRING LOCAL status:NTSTATUS local pDeviceObject:PDEVICE_OBJECT invoke DbgPrint, $CTA0("\nEntry into DriverEntry\n") mov status, STATUS_DEVICE_CONFIGURATION_ERROR invoke IoCreateDevice, pDriverObject, 0, addr g_usDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, addr pDeviceObject .if eax == STATUS_SUCCESS mov eax, pDriverObject assume eax:ptr DRIVER_OBJECT mov [eax].DriverUnload, offset DriverUnload assume eax:nothing invoke SetHookOn mov status, STATUS_SUCCESS .endif mov eax, status ret DriverEntry endp end DriverEntry |
|
沙发#
发布于:2008-10-02 20:22
建议在调用原函数时不要这么搞,改来改去,调用又频繁,不蓝才怪~
|
|