Monday, March 23, 2009

Annotated 0x86 Assembly -- VC++ Exception

Armed with the knowledge learned from the article by Matt Pietrek -- A Crash Course on the Depths of Win32™ Structured Exception Handling, and the article by Vishal Kochhar -- How a C++ compiler implements exception handling, below I list the annotated 0x86 assembly for a C++ program containing the nested exception handling and built on VS2008.

Recall the standard exception frame generated by VC++ is as following,

EBP-18 Standard ESP in frame
EBP-14 GetExceptionPointers
EBP-10 previous EXCEPTION_REGISTRATION
EBP-0C handler function address
EBP-08 scopetable pointer
EBP-04 trylevel
EBP-00 _ebp

The annotated assembly is as following,

52 00401000 push ebp ; _ebp
52 00401001 mov ebp,esp
52 00401003 push 0FFFFFFFEh ; initial value for trylevel
52 00401005 push offset ExceptionSample!_TI1H+0x10 (004027c8) ; scopetable pointer
52 0040100a push offset ExceptionSample!_except_handler4 (00401b75) ; handler address
52 0040100f mov eax,dword ptr fs:[00000000h]
52 00401015 push eax ; previous EXCEPTION_REGISTRATION
52 00401016 sub esp,8 ; reserve space for ExceptionPointer and ESP
52 00401019 push ebx
52 0040101a push esi
52 0040101b push edi
52 0040101c mov eax,dword ptr [ExceptionSample!__security_cookie (00403018)]
52 00401021 xor dword ptr [ebp-8],eax
52 00401024 xor eax,ebp
52 00401026 push eax
52 00401027 lea eax,[ebp-10h] ; eax = ebp-10h
52 0040102a mov dword ptr fs:[00000000h],eax ; point fs:[0] to the beginning of EXCEPTION_REGISTRATION on the stack
52 00401030 mov dword ptr [ebp-18h],esp
53 00401033 mov dword ptr [ebp-4],0 ; first try block
55 0040103a mov eax,1
55 0040103f mov dword ptr [ebp-4],eax ; second try block
57 00401042 mov dword ptr [ebp-4],2 ; third try block
59 00401049 mov dword ptr ds:[0],0
64 00401053 mov dword ptr [ebp-4],eax ; back to second try block
66 00401056 mov dword ptr [ebp-4],0 ; back to first try block
66 0040105d call ExceptionSample!try_except_finally+0x88 (00401088)
66 00401062 jmp ExceptionSample!try_except_finally+0xa8 (004010a8)
74 004010a8 mov eax,0FFFFFFFEh
74 004010ad mov dword ptr [ebp-4],eax ; out of try block
75 004010b0 mov dword ptr [ebp-4],3 ; fourth try block
77 004010b7 mov dword ptr ds:[0],0
78 004010c1 mov dword ptr [ebp-4],eax ; out of try block
84 004010c4 mov ecx,dword ptr [ebp-10h]
84 004010c7 mov dword ptr fs:[0],ecx ; point fs:[0] to previous EXCEPTION_REGISTRATION
84 004010ce pop ecx
84 004010cf pop edi
84 004010d0 pop esi
84 004010d1 pop ebx
84 004010d2 mov esp,ebp
84 004010d4 pop ebp
84 004010d5 ret

The following is the source code,

void try_except_finally()
{
__try
{
__try
{
__try
{
*((int *) 0) = 0;
}
__except(EXCEPTION_EXECUTE_HANDLER) { global = 1; }
}
__finally { global = 2; }
}
__except(EXCEPTION_EXECUTE_HANDLER) { global = 3; }

__try
{
*((int *) 0) = 0;
}
__except(EXCEPTION_EXECUTE_HANDLER) { global = 4; }
}

0 comments:

Post a Comment