1. A previous misunderstanding
In ring3, the FS segment points to Teb.
There has been a misunderstanding in the past. FS: [0] and fs: [1] record prediction_registration
Otherwise, FS: [0] records the pointer of prediction_registration.
2. Data Structure, which can form a linked list. The first address of the linked list is recorded in FS: [0], where handle is an exception handling function.
_ Prediction_registration struc
Prev dd?
Handler dd?
_ Prediction_registration ends
3. The exception handling function is executed twice.
For the first time, the system uses the linked list to find the handler for this exception.
The second is unwind, which is used for recycling. For example, the C ++ destructor executes the _ Finally block.
After the execution is complete, the system will return to the initial error state and delete the useless prediction_registration chain.
4. _ Try _ partition t nested blocks use only one exception_registration, but not multiple
5. The VC compiler extends the prediction_registration data structure to support _ Try _ excetp.
; Struct _ exception_registration {
; Struct _ prediction_registration * Prev;
; Void (* Handler) (pexception_record,
; Pexception_registration,
; Pcontext,
; Pexception_record );
; Struct scopetable_entry * scopetable;
; Int trylevel;
; Int _ EBP;
; Pexception_pointers xpointers;
;};
6.
Stack of functions with _ Try Blocks
EBP-00 _ EBP
Trylevel EBP-04
EBP-08 scopetable pointer
EBP-0C handler function address
EBP-10 previous prediction_registration
EBP-14 getexceptionpointers
EBP-18 standard ESP in Frame
Here we will explain the role of standard ESP in frame.
Save the old EBP and run ESP => EBP to access the local variables in the stack.
A function generally uses add ESP (negative) To open up local variables in the stack.
At this time, if you push or pop again, it is above the stack. In this case, esp needs to be remembered. If an exception occurs, this value needs to be restored. It is recorded in the position of the EBP-18.
For example:
# Include <stdio. h>
# Include <windows. h>
Int main (INT argc, char * argv [])
{
_ Try
{
* (Puchar) null) = 0;
} _ Limit T (1) // The ESP value must be restored here.
{
}
Return 0;
}