Jeffrey&Lynny

一个温馨小家庭的.Net生活

导航

Testing SEH tips

I use the code snippet below to test some points of SEH:

 

#define WIN32_LEAN_AND_MEAN
#include
<stdio.h>
#include
<windows.h>

void main()
{
    
char *str="this is a local string";
    printf(
"Entering main function\n");
    
    __try
    
{
        
int dw=3;
        printf(
"Entering first __try block\n");
        __try
        
{
            printf(
"Entering second __try block\n");
            __try
            
{
                
*(DWORD *)0=1;
            }

            __finally
            
{
                printf(
"Clean in finally block\n");
            }

        }

        __except(EXCEPTION_EXECUTE_HANDLER)
        
{
            printf(
"We handled this exception %d, %s\n", dw, str);
        }

    }

    __except(EXCEPTION_CONTINUE_SEARCH)
    
{
        printf(
"We do not handle this exception\n");
    }

    printf(
"Exiting main function\n");
}


Outcome:
1. How does __except_handler3 call the __except block without returning back?
Before entering __except block, the compiler always generates the following statement:
mov         esp,dword ptr [ebp-18h]  
It will restore the esp register to the value of before executing any code.

2. Since the __except bock will restore the esp to the value of before executing any code, how does it use the local variables?
Since the local variables are accessed through the offset of ebp, although the esp does not point to the stack top anymore, compiler can still use ebp offset to use them. Take the local variables, "dw" and "str" for example, see below:

 char *str="this is a local string";
0041338B  mov         dword ptr [ebp-20h],424E70h
  int dw=3;
004133A6  mov         dword ptr [ebp-2Ch],3

the __except block will use them like this:
0041340A  mov         esp,dword ptr [ebp-18h]
  {
   printf("We handled this exception %d, %s\n", dw, str);
0041340D  mov         eax,dword ptr [ebp-20h]
00413410  push        eax 
00413411  mov         ecx,dword ptr [ebp-2Ch]
00413414  push        ecx 

Additionally, based on my test, once the SEH is used in the function, the VC optimizer will not omit Frame Pointer register(ebp) anyway, it will always save the ebp for offset usage.

3. 2 points of code in __except_handler3.
Before calling the __except code block, the __except_handler3 sets the ebp register to the original saved ebp value in the extended EXCEPTION_REGISTRATION so that when the __except block is executed, the ebp register can be used to lookup the function local variables that contains __except block.

Also, before calling the __except code block, the __except_handler3 sets the trylevel field in the EXCEPTION_REGISTRATION to the parent __try block trylevel value, so that it can handle any nested exception generated in __except code block.

posted on 2006-10-28 22:50  比尔盖房  阅读(216)  评论(0编辑  收藏  举报