
I've found a bug in Olly leads to crash SEH/VEH-based programs during tracing.
(an example-pack could be found at: http://nezumi.org.ru/olly-bug-776.zip,
it includes two SEH/VEH programs and requests XP or latter to run VEH,
while SEH works everywhere).
Load an example into Olly and start tracing [F7]
/* we can skip the first call by pressing [F8] (Step Over),
since it has nothing interesting for us */
xor eax,eax/mov eax,[eax] generates an exceptions,
catching by OS kernel. the kernel saves registry context
(including TF-bit, set by Olly to "1") and passes control to
NTDLL.DLL!KiUserExceptionDispatcher function - the first
user-land function executes after an exception.
it calls SEH/VEH handler (if there is at lest one).
if the handler returns control to the code,
where the exception was raised, registry context
(including TF-bit) is restored by OS kernel.
everything is fine, yes? hell, no!!!
Olly catches NTDLL.DLL!KiUserExceptionDispatcher
and offers us to press Shift?F7/F8/F9.
Olly allows to trace KiUserExceptionDispatcher,
but totally forgets to clean TF-bit.
as result - when control is passed the to original code
(to the command follows mov eax,[eax] in our case,
since handler adds 2 bytes /* size of mov eax,[eax] */ to EIP),
TF-bit is set!!! so, a new exception occurs and SEH/VEH handled
is called again and over again, coz, Olly passes this exception
to the program, coz it forgets who "owns" this exception!!!
since, SEH/VEH handler doesn't expect to handle trace exaction,
we have an undefined behavior (a crash).
it's definitely a bug!!!
and how we can to fix it?!
well, it's very simple. look at the prototype of
KiUserExceptionDispatcher(EXCPT_REC *pExcptRec, CONTEXT *pContext).
everything we need - is just to take pContext and clear TF-bit manually.
pContext is the next DWORD on the stack and EFlags has C0h offset,
while TF-bit is the first bit of the next word (1 << 8).
just clean it and enjoy! press [F9] to Run the program
or do whatever you want!
of course, we can create plug-in, doing it automatically,
or set-up a conditional breakpoint on KiUserExceptionDispatcher.
I've checked the latest 2.00e version (April 19, 2008) and...
the bug is still there, damn it!