[SDK:RTL] Add one validity check + comment documentation for RtlDispatchException().

- RtlDispatchException(): Check for invalid stack in ExceptionContinueSearch handler
  and bail out if so.
- Update few comments and fix a typo.
- Add a documenting comment about SafeSEH functionality support.
  See e.g. the following articles:
  https://www.optiv.com/blog/old-meets-new-microsoft-windows-safeseh-incompatibility
  https://msrc-blog.microsoft.com/2012/01/10/more-information-on-the-impact-of-ms12-001/
This commit is contained in:
Hermès Bélusca-Maïto 2019-11-16 22:47:05 +01:00
parent 872fc17d0d
commit a4b6e0d929
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0

View file

@ -113,11 +113,18 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
continue; continue;
} }
/* Set invalid stack and return false */ /* Set invalid stack and bail out */
ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID; ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
return FALSE; return FALSE;
} }
//
// TODO: Implement and call here RtlIsValidHandler(RegistrationFrame->Handler)
// for supporting SafeSEH functionality, see the following articles:
// https://www.optiv.com/blog/old-meets-new-microsoft-windows-safeseh-incompatibility
// https://msrc-blog.microsoft.com/2012/01/10/more-information-on-the-impact-of-ms12-001/
//
/* Check if logging is enabled */ /* Check if logging is enabled */
RtlpCheckLogException(ExceptionRecord, RtlpCheckLogException(ExceptionRecord,
Context, Context,
@ -144,7 +151,7 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
{ {
/* Continue execution */ /* Continue execution */
case ExceptionContinueExecution: case ExceptionContinueExecution:
{
/* Check if it was non-continuable */ /* Check if it was non-continuable */
if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
{ {
@ -161,20 +168,25 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
else else
{ {
/* In user mode, call any registered vectored continue handlers */ /* In user mode, call any registered vectored continue handlers */
RtlCallVectoredContinueHandlers(ExceptionRecord, RtlCallVectoredContinueHandlers(ExceptionRecord, Context);
Context);
/* Execution continues */ /* Execution continues */
return TRUE; return TRUE;
} }
}
/* Continue searching */ /* Continue searching */
case ExceptionContinueSearch: case ExceptionContinueSearch:
if (ExceptionRecord->ExceptionFlags & EXCEPTION_STACK_INVALID)
{
/* We have an invalid stack, bail out */
return FALSE;
}
break; break;
/* Nested exception */ /* Nested exception */
case ExceptionNestedException: case ExceptionNestedException:
{
/* Turn the nested flag on */ /* Turn the nested flag on */
ExceptionRecord->ExceptionFlags |= EXCEPTION_NESTED_CALL; ExceptionRecord->ExceptionFlags |= EXCEPTION_NESTED_CALL;
@ -185,10 +197,11 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
NestedFrame = DispatcherContext.RegistrationPointer; NestedFrame = DispatcherContext.RegistrationPointer;
} }
break; break;
}
/* Anything else */ /* Anything else */
default: default:
{
/* Set up the exception record */ /* Set up the exception record */
ExceptionRecord2.ExceptionRecord = ExceptionRecord; ExceptionRecord2.ExceptionRecord = ExceptionRecord;
ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION; ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION;
@ -198,13 +211,14 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
/* Raise the exception */ /* Raise the exception */
RtlRaiseException(&ExceptionRecord2); RtlRaiseException(&ExceptionRecord2);
break; break;
}
} }
/* Go to the next frame */ /* Go to the next frame */
RegistrationFrame = RegistrationFrame->Next; RegistrationFrame = RegistrationFrame->Next;
} }
/* Unhandled, return false */ /* Unhandled, bail out */
return FALSE; return FALSE;
} }
@ -335,22 +349,24 @@ RtlUnwind(IN PVOID TargetFrame OPTIONAL,
Context, Context,
&DispatcherContext, &DispatcherContext,
RegistrationFrame->Handler); RegistrationFrame->Handler);
switch(Disposition) switch(Disposition)
{ {
/* Continue searching */ /* Continue searching */
case ExceptionContinueSearch: case ExceptionContinueSearch:
break; break;
/* Collission */ /* Collision */
case ExceptionCollidedUnwind : case ExceptionCollidedUnwind:
{
/* Get the original frame */ /* Get the original frame */
RegistrationFrame = DispatcherContext.RegistrationPointer; RegistrationFrame = DispatcherContext.RegistrationPointer;
break; break;
}
/* Anything else */ /* Anything else */
default: default:
{
/* Set up the exception record */ /* Set up the exception record */
ExceptionRecord2.ExceptionRecord = ExceptionRecord; ExceptionRecord2.ExceptionRecord = ExceptionRecord;
ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION; ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION;
@ -360,6 +376,7 @@ RtlUnwind(IN PVOID TargetFrame OPTIONAL,
/* Raise the exception */ /* Raise the exception */
RtlRaiseException(&ExceptionRecord2); RtlRaiseException(&ExceptionRecord2);
break; break;
}
} }
/* Go to the next frame */ /* Go to the next frame */