Hi,
it seems we have a little bug in KiFastCallEntry. It is initialized a trap frame on the stack. It is a trap frame without the v86 segment registers. ESP points to TSS->ESP0 - sizeof(KTRAP_FRAME) + 16. 16 for the missing v86 segment register. ESP is compared with KTHREAD->InitialStack - 0x29c. 0x29c is equal to sizeof(FX_SAVE_AREA) + sizeof(KTRAP_FRAME). If the compare operation fails, it is called BadStack which results in a v86 invalid opcode exception. To bypass this bug, there is added a value of 0x10 to TSS->ESP0 in Ke386InitThreadWithContext. A friend of me has looked to WinXp. He has found a piece of code which is an exact copy of BadStack and he has found a piece of code which looks like this:
_KiFastCallEntry: ... /* Use the thread's stack */ mov ebp, [esi+KTHREAD_INITIAL_STACK] ... /* Make space for us on the stack */ sub ebp, 0x29C
/* Write the previous mode */ mov byte ptr [esi+KTHREAD_PREVIOUS_MODE], UserMode
/* Sanity check */ cmp ebp, esp jnz BadStack ...
- Hartmut