/* Get the current stack limits and registration frame */ RtlpGetStackLimits(&StackLow, &StackHigh); RegistrationFrame = RtlpGetExceptionList();
/* Now loop every frame */ while (RegistrationFrame != EXCEPTION_CHAIN_END) { /* Find out where it ends */ RegistrationFrameEnd = (ULONG_PTR)RegistrationFrame + sizeof(EXCEPTION_REGISTRATION_RECORD);
/* Make sure the registration frame is located within the stack */ if ((RegistrationFrameEnd > StackHigh) || ((ULONG_PTR)RegistrationFrame < StackLow) || ((ULONG_PTR)RegistrationFrame & 0x3)) { /* Check if this happened in the DPC Stack */ if (RtlpHandleDpcStackException(RegistrationFrame, RegistrationFrameEnd, &StackLow, &StackHigh)) { /* Use DPC Stack Limits and restart */ continue; }
/* Set invalid stack and return false */ ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID; return FALSE; }
/* Check if logging is enabled */ RtlpCheckLogException(ExceptionRecord, Context, RegistrationFrame, sizeof(*RegistrationFrame));
/* Check if this is a nested frame */ if (RegistrationFrame == NestedFrame) { /* Mask out the flag and the nested frame */ ExceptionRecord->ExceptionFlags &= ~EXCEPTION_NESTED_CALL; NestedFrame = NULL; }
/* Handle the dispositions */ switch (Disposition) { /* Continue searching */ case ExceptionContinueExecution:
/* Check if it was non-continuable */ if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) { /* Set up the exception record */ ExceptionRecord2.ExceptionRecord = ExceptionRecord; ExceptionRecord2.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE; ExceptionRecord2.NumberParameters = 0;
/* Raise the exception */ RtlRaiseException(&ExceptionRecord2); } else { /* Return to caller */ return TRUE; }
/* Continue searching */ case ExceptionContinueSearch: break;
/* Nested exception */ case ExceptionNestedException:
/* Turn the nested flag on */ ExceptionRecord->ExceptionFlags |= EXCEPTION_NESTED_CALL;
/* Update the current nested frame */ if (DispatcherContext.RegistrationPointer > NestedFrame) { /* Get the frame from the dispatcher context */ NestedFrame = DispatcherContext.RegistrationPointer; } break;
/* Anything else */ default:
/* Set up the exception record */ ExceptionRecord2.ExceptionRecord = ExceptionRecord; ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION; ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE; ExceptionRecord2.NumberParameters = 0;
/* Raise the exception */ RtlRaiseException(&ExceptionRecord2); break; }
/* Go to the next frame */ RegistrationFrame = RegistrationFrame->Next; }
do { bRet=((DWORD)(pChain->pHandler)>=dwStackLimit)&&((DWORD)(pChain->pHandler)<=dwStackBase); pChain=pChain->pNext; }while(!bRet&&(pChain!=(SEHChain*)-1));
在检测到非安全的Handler时我为什么要用ExitThread呢,因为基于TIB的Seh Chain是线程相关的,它不是Final型的SEH Handler(不懂的参考一下Hume大侠的经典文章<<SEH in ASM>>),所以直接用ExitThread把可能出现危险的线程给退掉,如果是主线程则进程会退出,需要的话同时记录一下日志,以供管理员分析受攻击情况。