阅读:1514回复:5
kernel mode SEH 是不是不再好用了??
我写一个驱动里面需要从80000000开始暴力搜索2G内存寻找ntoskrnl.exe的基址,因为可能出现指针无效的内存访问异常,加载了一个seh来处理,绝大部分的情况都可以处理,也好几天运行的很好,但是最近一加载就出现PAGE_FAULT_IN_NONPAGED_AREA错误并且蓝屏,在调试器里强行从KeBugCheckEx iret回去看到了出错现场也是一个内存访问地址不存在,但是这次seh却没有反应直接PAGE_FAULT_IN_NONPAGED_AREA蓝屏了,高手们说说这是为什么呀!!谢谢了
|
|
|
沙发#
发布于:2005-07-12 11:43
__declspec(naked)//self-reloc,rawmem searcher
void* __stdcall searchkmod(char* modname){ __asm{ push ebp mov ebp,esp sub esp,4//reloc base push ebx push esi push edi /// mov al,0 mov ecx,256 mov edi,modname cld repnz scasb mov edx,256 sub edx,ecx//edx:strlen /// call to to: pop ebx sub ebx,offset to mov [ebp-4],ebx add ebx,offset sehfilter push ebx push fs:0 mov fs:0,esp mov ebx,0x80000000 looper: cmp ebx,0 jz final mov ax,[ebx] cmp ax,'ZM'//不能只判断了是MZ后就开始认为符合格式,如果有块内存也是MZ开头,会异常 jnz goon mov esi,[ebx+60]//PEheaderRVA add esi,ebx//PEheader mov eax,[esi] cmp eax,00004550h//'PE\0\0' jnz goon add esi,78h//datadirectory,no.1 is exporttable mov eax,[esi]//exptable RVA add eax,ebx mov esi,eax//exptable add esi,12//nNameRVA mov esi,[esi] add esi,ebx//nName mov edi,modname cld mov ecx,edx repz cmpsb//注意区分大小写 jz final jnz goon goon: add ebx,1000h jmp looper final: mov eax,ebx pop dword ptr fs:0 //不知为何该死的ddk会编译成word ptr???? add esp,4 pop edi pop esi pop ebx add esp,4 pop ebp ret 4 sehfilter: MOV EAX, [ESP + 0CH] //;载入 CONTEXT 结构指针 add dword ptr [eax+164], 1000h //;将 CONTEXT 指定的 EBX 寄存器加1000H mov edx,dword ptr [eax+164] mov dword ptr [eax+160],edx //;设置esi=ebx,免得如果有块内存也是MZ开头会异常 XOR EAX, EAX //;设置返回值为 0,即重新执行异常处的代码 RET 10H } } |
|
|
板凳#
发布于:2005-07-12 12:01
因为错误根本断不下来,不知道当时的irql是多少,但是在driverentry里应该是passive了。
|
|
|
地板#
发布于:2005-07-13 16:55
是会不太好用的
|
|
|
地下室#
发布于:2005-07-13 20:09
恩,请教了各位高手,的确kernelmode SEH是有问题的。如果处理的非法地址是non-paged区域里的,会发生page_fault_in_nonpaged_area的KeBugCheckEx,代码到不了SEH里。在此帖出改进过的不用SEH的版本。
//rewrite 7.13.2005 __declspec(naked)//self-reloc,rawmem searcher,search 80000000-ffffffff for /3GB (???untested) //signiture:kdbg,<1000 but>0 size,3 qb. KDDEBUGGER_DATA64* __stdcall searchKdDebuggerDataBlock(){ __asm{ push ebp mov ebp,esp sub esp,8//reloc base,KDBG push ebx push esi push edi call to to: pop ebx sub ebx,offset to mov [ebp-4],ebx mov dword ptr [ebp-8],'GBDK' mov ebx,0x80000000 looper: cmp ebx,0x80000000 jae noring xor eax,eax jmp endsearch noring: push ebx call mmaddrvalid cmp eax,0 jz roundnext push 4 mov edx,1000h mov eax,ebx and eax,000000fffh sub edx,eax push edx//长度是到该页的结尾 lea eax,[ebp-8] push eax push ebx call memmem cmp eax,0//no kdbg??j jz roundnext mov ebx,eax add ebx,4 push ebx call mmaddrvalid cmp eax,0 jz roundnext cmp dword ptr [ebx],1000h ja looper//more than 1000h fail cmp dword ptr [ebx],0 jz looper//must be more than 0 add ebx,8 push ebx call mmaddrvalid cmp eax,0 jz roundnext cmp dword ptr [ebx],0 jnz looper//must be 0,qb in ia32 add ebx,8 push ebx call mmaddrvalid cmp eax,0 jz roundnext cmp dword ptr [ebx],0 jnz looper//must be 0,qb in ia32 add ebx,8 push ebx call mmaddrvalid cmp eax,0 jz roundnext cmp dword ptr [ebx],0 jnz looper//must be 0,qb in ia32 sub ebx,24+4+16//ok,passed the check. mov eax,ebx jmp endsearch roundnext: and ebx,0fffff000h add ebx,1000h//rounded to next page jmp looper endsearch: pop edi pop esi pop ebx add esp,8 pop ebp ret } } |
|
|
5楼#
发布于:2005-07-15 09:11
可能是你企图访问莫个虚拟地址,但是对应该地址的PTE不存在,这样会导致一个Page Fault,这种情况下SEH 是不管用的。最好用MmIsAddressValid检查后,才访问!
OSR有两篇文章:《So What is A Page Fault?》《Bugchecks Explained :PAGE_FAULT_IN_NONPAGED_AREA》说的很明白的 |
|
|