c++ 反汇编 异常处理

c++异常处理

int main(){
     try
     {
         throw 1;
     }
     catch ( int e )
     {
         printf("catch int
");
     }
     catch ( float e)
     {
         printf("catch float
");
     }
}

函数开始,注册异常处理函数

008C8660 55                   push        ebp  
008C8661 8B EC                mov         ebp,esp  
008C8663 6A FF                push        0FFFFFFFFh  
008C8665 68 C0 83 97 00       push        9783C0h //异常处理函数 
008C866A 64 A1 00 00 00 00    mov         eax,dword ptr fs:[00000000h] //eax中存放SEH中的next*指针 
008C8670 50                   push        eax //next*入栈(相当于seh新节点的next*) 
008C8671 51                   push        ecx  
008C8672 81 EC E4 00 00 00    sub         esp,0E4h  
008C8678 53                   push        ebx  
008C8679 56                   push        esi  
008C867A 57                   push        edi  
008C867B 8D BD 0C FF FF FF    lea         edi,[ebp-0F4h]  
008C8681 B9 39 00 00 00       mov         ecx,39h  
008C8686 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
008C868B F3 AB                rep stos    dword ptr es:[edi]  
008C868D A1 04 20 9A 00       mov         eax,dword ptr [__security_cookie (09A2004h)]  
008C8692 33 C5                xor         eax,ebp  
008C8694 50                   push        eax  
008C8695 8D 45 F4             lea         eax,[ebp-0Ch] //取next*地址 
008C8698 64 A3 00 00 00 00    mov         dword ptr fs:[00000000h],eax//相当于seh链表插入新节点的next*,指向的是原来的next*指针  
008C869E 89 65 F0             mov         dword ptr [ebp-10h],esp

9783C0h

__ehhandler$_main:
009783C0 8B 54 24 08          mov         edx,dword ptr [esp+8]  
009783C4 8D 42 0C             lea         eax,[edx+0Ch]  
009783C7 8B 8A 08 FF FF FF    mov         ecx,dword ptr [edx-0F8h]  
009783CD 33 C8                xor         ecx,eax  
009783CF E8 3A AB F4 FF       call        @__security_check_cookie@4 (08C2F0Eh)  
009783D4 B8 0C 03 9A 00       mov         eax,9A030Ch  //EAX=FuncInfo   *pFuncInfo,          // Static information for this frame
009783D9 E9 AF 9A F4 FF       jmp         ___CxxFrameHandler3 (08C1E8Dh)

__CxxFrameHandler

EXCEPTION_DISPOSITION __CxxFrameHandler(
      EHExceptionRecord  *pExcept,
      EHRegistrationNode *pRN,
      void               *pContext,
      DispatcherContext  *pDC
   )

Parameters

pExcept
Exception record that is passed to the possible catch statements.

pRN
Dynamic information about the stack frame that is used to handle the exception. For more information, see ehdata.h.

pContext
Context. (Not used on Intel processors.)

pDC
Additional information about the function entry and stack frame.

Return Value

One of the filter expression values used by the try-except Statement.

br

  • pContext
 名称类型
  pContext 0x00cff468 void *
  pDC 0x00cff3a4 void *
pExcept 0x00cff418 {ExceptionCode=0xe06d7363 ExceptionFlags=0x00000001 ExceptionRecord=0x00000000 <NULL> ...} EHExceptionRecord *
pFuncInfo Excepction.exe!0x009a030c {magicNumber=0x19930522 bbtFlags=0x00000000 maxState=0x00000002 ...} const _s_FuncInfo *
pRN 0x00cffa00 {pNext=0x00cffa6c {pNext=0x00cffae8 {pNext=0x00cffb00 {pNext=0xffffffff {pNext=??? frameHandler=...} ...} ...} ...} ...} EHRegistrationNode *
  • pExcept
 名称类型
pExcept 0x00cff418 {ExceptionCode=0xe06d7363 ExceptionFlags=0x00000001 ExceptionRecord=0x00000000 <NULL> ...} EHExceptionRecord *
  ExceptionCode 0xe06d7363 unsigned long
  ExceptionFlags 0x00000001 unsigned long
  ▶ ExceptionRecord 0x00000000 <NULL> _EXCEPTION_RECORD *
  ExceptionAddress KernelBase.dll!0x74cfb022 (加载符号以获取其他信息) void *
  NumberParameters 0x00000003 unsigned long
  ▶ params {magicNumber=0x19930520 pExceptionObject=0x00cff91c pThrowInfo=0x009a0428 {Excepction.exe!__TI1H} {attributes=...} } EHExceptionRecord::EHParameters

  • pFuncInfo
 名称类型
pFuncInfo Excepction.exe!0x009a030c {magicNumber=0x19930522 bbtFlags=0x00000000 maxState=0x00000002 ...} const _s_FuncInfo *
  magicNumber 0x19930522 unsigned int
  bbtFlags 0x00000000 unsigned int
  maxState 0x00000002 int
  ▶ pUnwindMap Excepction.exe!0x009a02c8 {toState=0xffffffff action=0x00000000 } const _s_UnwindMapEntry *
  nTryBlocks 0x00000001 unsigned int
  ▶ pTryBlockMap Excepction.exe!0x009a02d8 {tryLow=0x00000000 tryHigh=0x00000000 catchHigh=0x00000001 ...} const _s_TryBlockMapEntry *
  nIPMapEntries 0x00000000 unsigned int
  pIPtoStateMap 0x00000000 void *
  ▶ pESTypeList 0x00000000 <NULL> const _s_ESTypeList *
  EHFlags 0x00000001 int

  • pRN
 名称类型
pRN 0x00cffa00 {pNext=0x00cffa6c {pNext=0x00cffae8 {pNext=0x00cffb00 {pNext=0xffffffff {pNext=??? frameHandler=...} ...} ...} ...} ...} EHRegistrationNode *
  ◢ pNext 0x00cffa6c {pNext=0x00cffae8 {pNext=0x00cffb00 {pNext=0xffffffff {pNext=??? frameHandler=??? state=??? } ...} ...} ...} EHRegistrationNode *
  ◢ pNext 0x00cffae8 {pNext=0x00cffb00 {pNext=0xffffffff {pNext=??? frameHandler=??? state=??? } frameHandler=...} ...} EHRegistrationNode *
  ◢ pNext 0x00cffb00 {pNext=0xffffffff {pNext=??? frameHandler=??? state=??? } frameHandler=ntdll.dll!0x772051a0 ...} EHRegistrationNode *
  ▶ pNext 0xffffffff {pNext=??? frameHandler=??? state=??? } EHRegistrationNode *
  frameHandler ntdll.dll!0x772051a0 (加载符号以获取其他信息) void *
  state 0x00000000 int
  frameHandler ntdll.dll!0x771f86d0 (加载符号以获取其他信息) void *
  state 0x86f8a54a int
  frameHandler 0x008cc890 {Excepction.exe!_except_handler4(_EXCEPTION_RECORD *, _EXCEPTION_REGISTRATION_RECORD *, _CONTEXT *, void *)} void *
  state 0xcb1e6901 int
  frameHandler 0x009783c0 {内部 Excepction.exe!_wcschr()} void *
  state 0x00000000 int

__CxxFrameHandler3


//
// __CxxFrameHandler3 - Real entry point to the runtime // __CxxFrameHandler2 is an alias for __CxxFrameHandler3 // since they are compatible in VC version of CRT // These function should be separated out if a change makes // __CxxFrameHandler3 incompatible with __CxxFrameHandler2 // extern "C" _VCRTIMP __declspec(naked) DECLSPEC_GUARD_SUPPRESS EXCEPTION_DISPOSITION __cdecl __CxxFrameHandler3( /* EAX=FuncInfo *pFuncInfo, // Static information for this frame */ EHExceptionRecord *pExcept, // Information for this exception EHRegistrationNode *pRN, // Dynamic information for this frame void *pContext, // Context info (we don't care what's in it) DispatcherContext *pDC // More dynamic info for this frame (ignored on Intel) ) { FuncInfo *pFuncInfo; EXCEPTION_DISPOSITION result; __asm { // // Standard function prolog // push ebp mov ebp, esp sub esp, __LOCAL_SIZE push ebx push esi push edi cld // A bit of paranoia -- Our code-gen assumes this // // Save the extra parameter // mov pFuncInfo, eax } EHTRACE_ENTER_FMT1("pRN = 0x%p", pRN); result = __InternalCxxFrameHandler<RENAME_EH_EXTERN(__FrameHandler3)>( pExcept, pRN, (PCONTEXT)pContext, pDC, pFuncInfo, 0, nullptr, FALSE ); EHTRACE_HANDLER_EXIT(result); __asm { pop edi pop esi pop ebx mov eax, result mov esp, ebp pop ebp ret 0 } }

__InternalCxxFrameHandler函数主要完成了标记检查、展开、查找和派发等工作

  1 ////////////////////////////////////////////////////////////////////////////////
  2 //
  3 // __InternalCxxFrameHandler - the frame handler for all functions with C++ EH
  4 // information.
  5 //
  6 // If exception is handled, this doesn't return; otherwise, it returns
  7 // ExceptionContinueSearch.
  8 //
  9 // Note that this is called three ways:
 10 //     From __CxxFrameHandler: primary usage, called to inspect whole function.
 11 //         CatchDepth == 0, pMarkerRN == nullptr
 12 //     From CatchGuardHandler: If an exception occurred within a catch, this is
 13 //         called to check for try blocks within that catch only, and does not
 14 //         handle unwinds.
 15 //     From TranslatorGuardHandler: Called to handle the translation of a
 16 //         non-C++ EH exception.  Context considered is that of parent.
 17 
 18 template <class T>
 19 EXCEPTION_DISPOSITION __InternalCxxFrameHandler(
 20     EHExceptionRecord  *pExcept,        // Information for this exception
 21     EHRegistrationNode *pRN,            // Dynamic information for this frame
 22     CONTEXT *pContext,                  // Context info
 23     DispatcherContext *pDC,             // Context within subject frame
 24     typename T::FuncInfo *pFuncInfo,    // Static information for this frame
 25     int CatchDepth,                     // How deeply nested are we?
 26     EHRegistrationNode *pMarkerRN,      // Marker node for when checking inside
 27                                         //  catch block
 28     BOOLEAN recursive                   // Are we handling a translation?
 29 ) {
 30 
 31 #if defined(_M_HYBRID_X86_ARM64) && !defined(_CHPE_X86_ARM64_EH_)
 32     _HybridGenerateThunks(__InternalCxxFrameHandler<T>, 1);
 33 #endif
 34 
 35     EHTRACE_ENTER_FMT2("%s, pRN = 0x%p",
 36                        IS_UNWINDING(PER_FLAGS(pExcept)) ? "Unwinding" : "Searching",
 37                        pRN);
 38 
 39     __except_validate_context_record(pContext);
 40 
 41     if ((cxxReThrow == false) && (PER_CODE(pExcept) != EH_EXCEPTION_NUMBER) &&
 42 #if defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID)
 43         /* On the 64 bit/ARM platforms, ExceptionCode maybe set to STATUS_UNWIND_CONSOLIDATE
 44            when called from _UnwindNestedFrames during Logical Unwind. _UnwindNestedFrames
 45            will also set EH_MAGIC_NUMBER1 in the 8 element */
 46         (!((PER_CODE(pExcept) == STATUS_UNWIND_CONSOLIDATE) && (PER_NPARAMS(pExcept) == 15) && (PER_EXCEPTINFO(pExcept)[8] == EH_MAGIC_NUMBER1))) &&
 47 #endif
 48         (PER_CODE(pExcept) != STATUS_LONGJUMP) &&
 49         (T::getMagicNum(pFuncInfo) >= EH_MAGIC_NUMBER3) &&
 50         (T::isEHs(pFuncInfo)))
 51     {
 52         /*
 53          * This function was compiled /EHs so we don't need to do anything in
 54          * this handler.
 55          */
 56         return ExceptionContinueSearch;
 57     }
 58 
 59     if (IS_UNWINDING(PER_FLAGS(pExcept)))
 60     {
 61         // We're at the unwinding stage of things.  Don't care about the
 62         // exception itself.  (Check this first because it's easier)
 63 
 64         if (T::GetMaxState(pDC, pFuncInfo) != 0 && CatchDepth == 0)
 65         {
 66             // Only unwind if there's something to unwind
 67             // AND we're being called through the primary RN.
 68 
 69 #if defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_)
 70 
 71             if (IS_TARGET_UNWIND(PER_FLAGS(pExcept)) && PER_CODE(pExcept) == STATUS_LONGJUMP) {
 72                     __ehstate_t target_state = T::StateFromIp(
 73                                                              pFuncInfo,
 74                                                              pDC,
 75 #if defined(_M_X64)
 76                                                              pDC->TargetIp
 77 #elif defined(_M_ARM) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_)
 78                                                              pDC->TargetPc
 79 #endif
 80                                                              );
 81 
 82                     DASSERT(target_state >= EH_EMPTY_STATE
 83                             && target_state < T::GetMaxState(pDC, pFuncInfo));
 84 
 85                     T::FrameUnwindToState(pRN, pDC, pFuncInfo, target_state);
 86                     EHTRACE_HANDLER_EXIT(ExceptionContinueSearch);
 87                     return ExceptionContinueSearch;
 88             } else if(IS_TARGET_UNWIND(PER_FLAGS(pExcept)) &&
 89                       PER_CODE(pExcept) == STATUS_UNWIND_CONSOLIDATE)
 90             {
 91                 PEXCEPTION_RECORD pSehExcept = (PEXCEPTION_RECORD)pExcept;
 92                 __ehstate_t target_state = (__ehstate_t)pSehExcept->ExceptionInformation[3];
 93 
 94                 DASSERT(target_state >= EH_EMPTY_STATE
 95                         && target_state < T::GetMaxState(pDC, pFuncInfo));
 96                 T::FrameUnwindToState((EHRegistrationNode *)pSehExcept->ExceptionInformation[1],
 97                                    pDC,
 98                                    pFuncInfo,
 99                                    target_state);
100                 EHTRACE_HANDLER_EXIT(ExceptionContinueSearch);
101                 return ExceptionContinueSearch;
102             }
103 #endif // defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_)
104             T::FrameUnwindToEmptyState(pRN, pDC, pFuncInfo);
105         }
106         EHTRACE_HANDLER_EXIT(ExceptionContinueSearch);
107         return ExceptionContinueSearch;     // I don't think this value matters
108 
109     }
110     else
111     {
112         auto tryBlockMap = T::TryBlockMap(pFuncInfo, pDC);
113         if (tryBlockMap.getNumTryBlocks() != 0
114             //
115             // If the function has no try block, we still want to call the
116             // frame handler if there is an exception specification
117             //
118             || (T::getMagicNum(pFuncInfo) >= EH_MAGIC_NUMBER2 && (T::getESTypes(pFuncInfo) != nullptr))
119             || (T::getMagicNum(pFuncInfo) >= EH_MAGIC_NUMBER3 && (T::isNoExcept(pFuncInfo) != 0)))
120         {
121 
122             // NT is looking for handlers.  We've got handlers.
123             // Let's check this puppy out.  Do we recognize it?
124 
125             int(__cdecl *pfn)(...);
126 
127             if (PER_CODE(pExcept) == EH_EXCEPTION_NUMBER
128                 && PER_NPARAMS(pExcept) >= 3
129                 && PER_MAGICNUM(pExcept) > EH_MAGIC_NUMBER3
130                 && (pfn = THROW_FORWARDCOMPAT(*PER_PTHROW(pExcept))) != nullptr) {
131 
132                 // Forward compatibility:  The thrown object appears to have been
133                 // created by a newer version of our compiler.  Let that version's
134                 // frame handler do the work (if one was specified).
135 
136 #if defined(_DEBUG)
137                 if (_ValidateExecute((FARPROC)(PVOID)pfn)) {
138 #endif
139                     EXCEPTION_DISPOSITION result =
140                         (EXCEPTION_DISPOSITION)pfn(pExcept, pRN, pContext, pDC,
141                             pFuncInfo, CatchDepth,
142                             pMarkerRN, recursive);
143                     EHTRACE_HANDLER_EXIT(result);
144                     return result;
145 #if defined(_DEBUG)
146                 }
147                 else {
148                     terminate(); // Does not return; TKB
149                 }
150 #endif
151 
152             }
153             else {
154 
155                 // Anything else: we'll handle it here.
156                 FindHandler<T>(pExcept, pRN, pContext, pDC, pFuncInfo, recursive, CatchDepth, pMarkerRN);
157             }
158 
159             // If it returned, we didn't have any matches.
160 
161         } // NT was looking for a handler
162     }
163 
164     // We had nothing to do with it or it was rethrown.  Keep searching.
165     EHTRACE_HANDLER_EXIT(ExceptionContinueSearch);
166     return ExceptionContinueSearch;
167 
168 } // __InternalCxxFrameHandler
View Code

汇编:

008CEC70 55                   push        ebp  
008CEC71 8B EC                mov         ebp,esp  
008CEC73 83 EC 14             sub         esp,14h  
008CEC76 8B 45 10             mov         eax,dword ptr [pContext]  
008CEC79 50                   push        eax  
008CEC7A E8 50 36 FF FF       call        ___except_validate_context_record (08C22CFh)  
008CEC7F 83 C4 04             add         esp,4  
008CEC82 E8 FD 49 FF FF       call        ___vcrt_getptd (08C3684h)  
008CEC87 83 78 20 00          cmp         dword ptr [eax+20h],0  
008CEC8B 75 46                jne         __InternalCxxFrameHandler<__FrameHandler3>+63h (08CECD3h)  
008CEC8D 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CEC90 81 39 63 73 6D E0    cmp         dword ptr [ecx],0E06D7363h  
008CEC96 74 3B                je          __InternalCxxFrameHandler<__FrameHandler3>+63h (08CECD3h)  
008CEC98 8B 55 08             mov         edx,dword ptr [pExcept]  
008CEC9B 81 3A 26 00 00 80    cmp         dword ptr [edx],80000026h  
008CECA1 74 30                je          __InternalCxxFrameHandler<__FrameHandler3>+63h (08CECD3h)  
008CECA3 8B 45 18             mov         eax,dword ptr [pFuncInfo]  
008CECA6 50                   push        eax  
008CECA7 E8 88 35 FF FF       call        __FrameHandler3::getMagicNum (08C2234h)  
008CECAC 83 C4 04             add         esp,4  
008CECAF 3D 22 05 93 19       cmp         eax,19930522h  
008CECB4 72 1D                jb          __InternalCxxFrameHandler<__FrameHandler3>+63h (08CECD3h)  
008CECB6 8B 4D 18             mov         ecx,dword ptr [pFuncInfo]  
008CECB9 51                   push        ecx  
008CECBA E8 55 23 FF FF       call        __FrameHandler3::isEHs (08C1014h)  
008CECBF 83 C4 04             add         esp,4  
008CECC2 0F B6 D0             movzx       edx,al  
008CECC5 85 D2                test        edx,edx  
008CECC7 74 0A                je          __InternalCxxFrameHandler<__FrameHandler3>+63h (08CECD3h)  
008CECC9 B8 01 00 00 00       mov         eax,1  
008CECCE E9 73 01 00 00       jmp         __InternalCxxFrameHandler<__FrameHandler3>+1D6h (08CEE46h)  
008CECD3 8B 45 08             mov         eax,dword ptr [pExcept]  
008CECD6 8B 48 04             mov         ecx,dword ptr [eax+4]  
008CECD9 83 E1 66             and         ecx,66h  
008CECDC 74 3D                je          __InternalCxxFrameHandler<__FrameHandler3>+0ABh (08CED1Bh)  
008CECDE 8B 55 18             mov         edx,dword ptr [pFuncInfo]  
008CECE1 52                   push        edx  
008CECE2 8B 45 14             mov         eax,dword ptr [pDC]  
008CECE5 50                   push        eax  
008CECE6 E8 52 27 FF FF       call        __FrameHandler3::GetMaxState (08C143Dh)  
008CECEB 83 C4 08             add         esp,8  
008CECEE 85 C0                test        eax,eax  
008CECF0 74 1A                je          __InternalCxxFrameHandler<__FrameHandler3>+9Ch (08CED0Ch)  
008CECF2 83 7D 1C 00          cmp         dword ptr [CatchDepth],0  
008CECF6 75 14                jne         __InternalCxxFrameHandler<__FrameHandler3>+9Ch (08CED0Ch)  
008CECF8 8B 4D 18             mov         ecx,dword ptr [pFuncInfo]  
008CECFB 51                   push        ecx  
008CECFC 8B 55 14             mov         edx,dword ptr [pDC]  
008CECFF 52                   push        edx  
008CED00 8B 45 0C             mov         eax,dword ptr [pRN]  
008CED03 50                   push        eax  
008CED04 E8 4D 59 FF FF       call        __FrameHandler3::FrameUnwindToEmptyState (08C4656h)  
008CED09 83 C4 0C             add         esp,0Ch  
008CED0C B8 01 00 00 00       mov         eax,1  
008CED11 E9 30 01 00 00       jmp         __InternalCxxFrameHandler<__FrameHandler3>+1D6h (08CEE46h)  
008CED16 E9 26 01 00 00       jmp         __InternalCxxFrameHandler<__FrameHandler3>+1D1h (08CEE41h)  
008CED1B 8B 4D 14             mov         ecx,dword ptr [pDC]  
008CED1E 51                   push        ecx  
008CED1F 8B 55 18             mov         edx,dword ptr [pFuncInfo]  
008CED22 52                   push        edx  
008CED23 8D 4D EC             lea         ecx,[ebp-14h]  
008CED26 E8 8B 58 FF FF       call        __FrameHandler3::TryBlockMap::TryBlockMap (08C45B6h)  
008CED2B 8D 4D EC             lea         ecx,[ebp-14h]  
008CED2E E8 46 31 FF FF       call        __FrameHandler3::TryBlockMap::getNumTryBlocks (08C1E79h)  
008CED33 85 C0                test        eax,eax  
008CED35 75 51                jne         __InternalCxxFrameHandler<__FrameHandler3>+118h (08CED88h)  
008CED37 8B 45 18             mov         eax,dword ptr [pFuncInfo]  
008CED3A 50                   push        eax  
008CED3B E8 F4 34 FF FF       call        __FrameHandler3::getMagicNum (08C2234h)  
008CED40 83 C4 04             add         esp,4  
008CED43 3D 21 05 93 19       cmp         eax,19930521h  
008CED48 72 10                jb          __InternalCxxFrameHandler<__FrameHandler3>+0EAh (08CED5Ah)  
008CED4A 8B 4D 18             mov         ecx,dword ptr [pFuncInfo]  
008CED4D 51                   push        ecx  
008CED4E E8 FE 26 FF FF       call        __FrameHandler3::getESTypes (08C1451h)  
008CED53 83 C4 04             add         esp,4  
008CED56 85 C0                test        eax,eax  
008CED58 75 2E                jne         __InternalCxxFrameHandler<__FrameHandler3>+118h (08CED88h)  
008CED5A 8B 55 18             mov         edx,dword ptr [pFuncInfo]  
008CED5D 52                   push        edx  
008CED5E E8 D1 34 FF FF       call        __FrameHandler3::getMagicNum (08C2234h)  
008CED63 83 C4 04             add         esp,4  
008CED66 3D 22 05 93 19       cmp         eax,19930522h  
008CED6B 0F 82 D0 00 00 00    jb          __InternalCxxFrameHandler<__FrameHandler3>+1D1h (08CEE41h)  
008CED71 8B 45 18             mov         eax,dword ptr [pFuncInfo]  
008CED74 50                   push        eax  
008CED75 E8 61 51 FF FF       call        __FrameHandler3::isNoExcept (08C3EDBh)  
008CED7A 83 C4 04             add         esp,4  
008CED7D 0F B6 C8             movzx       ecx,al  
008CED80 85 C9                test        ecx,ecx  
008CED82 0F 84 B9 00 00 00    je          __InternalCxxFrameHandler<__FrameHandler3>+1D1h (08CEE41h)  
008CED88 8B 55 08             mov         edx,dword ptr [pExcept]  
008CED8B 81 3A 63 73 6D E0    cmp         dword ptr [edx],0E06D7363h  
008CED91 0F 85 81 00 00 00    jne         __InternalCxxFrameHandler<__FrameHandler3>+1A8h (08CEE18h)  
008CED97 8B 45 08             mov         eax,dword ptr [pExcept]  
008CED9A 83 78 10 03          cmp         dword ptr [eax+10h],3  
008CED9E 72 78                jb          __InternalCxxFrameHandler<__FrameHandler3>+1A8h (08CEE18h)  
008CEDA0 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CEDA3 81 79 14 22 05 93 19 cmp         dword ptr [ecx+14h],19930522h  
008CEDAA 76 6C                jbe         __InternalCxxFrameHandler<__FrameHandler3>+1A8h (08CEE18h)  
008CEDAC 8B 55 08             mov         edx,dword ptr [pExcept]  
008CEDAF 8B 42 1C             mov         eax,dword ptr [edx+1Ch]  
008CEDB2 8B 48 08             mov         ecx,dword ptr [eax+8]  
008CEDB5 89 4D FC             mov         dword ptr [ebp-4],ecx  
008CEDB8 83 7D FC 00          cmp         dword ptr [ebp-4],0  
008CEDBC 74 5A                je          __InternalCxxFrameHandler<__FrameHandler3>+1A8h (08CEE18h)  
008CEDBE 8B 55 FC             mov         edx,dword ptr [ebp-4]  
008CEDC1 52                   push        edx  
008CEDC2 E8 EC 50 FF FF       call        _ValidateExecute (08C3EB3h)  
008CEDC7 83 C4 04             add         esp,4  
008CEDCA 0F B6 C0             movzx       eax,al  
008CEDCD 85 C0                test        eax,eax  
008CEDCF 74 40                je          __InternalCxxFrameHandler<__FrameHandler3>+1A1h (08CEE11h)  
008CEDD1 0F B6 4D 24          movzx       ecx,byte ptr [recursive]  
008CEDD5 51                   push        ecx  
008CEDD6 8B 55 20             mov         edx,dword ptr [pMarkerRN]  
008CEDD9 52                   push        edx  
008CEDDA 8B 45 1C             mov         eax,dword ptr [CatchDepth]  
008CEDDD 50                   push        eax  
008CEDDE 8B 4D 18             mov         ecx,dword ptr [pFuncInfo]  
008CEDE1 51                   push        ecx  
008CEDE2 8B 55 14             mov         edx,dword ptr [pDC]  
008CEDE5 52                   push        edx  
008CEDE6 8B 45 10             mov         eax,dword ptr [pContext]  
008CEDE9 50                   push        eax  
008CEDEA 8B 4D 0C             mov         ecx,dword ptr [pRN]  
008CEDED 51                   push        ecx  
008CEDEE 8B 55 08             mov         edx,dword ptr [pExcept]  
008CEDF1 52                   push        edx  
008CEDF2 8B 45 FC             mov         eax,dword ptr [ebp-4]  
008CEDF5 89 45 F8             mov         dword ptr [ebp-8],eax  
008CEDF8 8B 4D F8             mov         ecx,dword ptr [ebp-8]  
008CEDFB FF 15 00 60 9A 00    call        dword ptr [__guard_check_icall_fptr (09A6000h)]  
008CEE01 FF 55 F8             call        dword ptr [ebp-8]  
008CEE04 83 C4 20             add         esp,20h  
008CEE07 89 45 F4             mov         dword ptr [ebp-0Ch],eax  
008CEE0A 8B 45 F4             mov         eax,dword ptr [ebp-0Ch]  
008CEE0D EB 37                jmp         __InternalCxxFrameHandler<__FrameHandler3>+1D6h (08CEE46h)  
008CEE0F EB 05                jmp         __InternalCxxFrameHandler<__FrameHandler3>+1A6h (08CEE16h)  
008CEE11 E8 5D 27 FF FF       call        _terminate (08C1573h)  
008CEE16 EB 29                jmp         __InternalCxxFrameHandler<__FrameHandler3>+1D1h (08CEE41h)  
008CEE18 8B 4D 20             mov         ecx,dword ptr [pMarkerRN]  
008CEE1B 51                   push        ecx  
008CEE1C 8B 55 1C             mov         edx,dword ptr [CatchDepth]  
008CEE1F 52                   push        edx  
008CEE20 0F B6 45 24          movzx       eax,byte ptr [recursive]  
008CEE24 50                   push        eax  
008CEE25 8B 4D 18             mov         ecx,dword ptr [pFuncInfo]  
008CEE28 51                   push        ecx  
008CEE29 8B 55 14             mov         edx,dword ptr [pDC]  
008CEE2C 52                   push        edx  
008CEE2D 8B 45 10             mov         eax,dword ptr [pContext]  
008CEE30 50                   push        eax  
008CEE31 8B 4D 0C             mov         ecx,dword ptr [pRN]  
008CEE34 51                   push        ecx  
008CEE35 8B 55 08             mov         edx,dword ptr [pExcept]  
008CEE38 52                   push        edx  
008CEE39 E8 C2 F4 FF FF       call        FindHandler<__FrameHandler3> (08CE300h)  //
008CEE3E 83 C4 20             add         esp,20h  
008CEE41 B8 01 00 00 00       mov         eax,1  
008CEE46 8B E5                mov         esp,ebp  
008CEE48 5D                   pop         ebp  
008CEE49 C3                   ret 

FindHandler<__FrameHandler3>(EHExceptionRecord *, EHRegistrationNode *, _CONTEXT *, void *, const _s_FuncInfo *, unsigned char, int, EHRegistrationNode *)

  1 template <class T>
  2 static void FindHandler(
  3     EHExceptionRecord *pExcept,         // Information for this (logical)
  4                                         //   exception
  5     EHRegistrationNode *pRN,            // Dynamic information for subject frame
  6     CONTEXT *pContext,                  // Context info
  7     DispatcherContext *pDC,             // Context within subject frame
  8     typename T::FuncInfo *pFuncInfo,    // Static information for subject frame
  9     BOOLEAN recursive,                  // TRUE if we're handling the
 10                                         //   translation
 11     int CatchDepth,                     // Level of nested catch that is being
 12                                         //   checked
 13     EHRegistrationNode *pMarkerRN       // Extra marker RN for nested catch
 14                                         //   handling
 15 )
 16 {
 17 
 18 #if defined(_M_HYBRID_X86_ARM64) && !defined(_CHPE_X86_ARM64_EH_)
 19     _HybridGenerateThunks(FindHandler<T>, 1);
 20 #endif
 21 
 22     EHTRACE_ENTER;
 23 
 24     BOOLEAN IsRethrow = FALSE;
 25     BOOLEAN gotMatch = FALSE;
 26 
 27     // Get the current state (machine-dependent)
 28     __ehstate_t curState = EH_EMPTY_STATE;
 29 #if defined(_M_X64) || defined(_M_ARM_NT) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_)
 30     curState = T::GetHandlerSearchState(pRN, pDC, pFuncInfo);
 31 #else
 32     curState = T::GetCurrentState(pRN, pDC, pFuncInfo);
 33 #endif
 34     DASSERT(curState >= EH_EMPTY_STATE && curState < T::GetMaxState(pDC, pFuncInfo));
 35 
 36     // Check if it's a re-throw.  Use the exception we stashed away if it is.
 37     if (PER_IS_MSVC_EH(pExcept) && PER_PTHROW(pExcept) == nullptr) {
 38 
 39         if (_pCurrentException == nullptr) {
 40             // Oops!  User re-threw a non-existent exception!  Let it propagate.
 41             EHTRACE_EXIT;
 42             return;
 43         }
 44 
 45         pExcept = _pCurrentException;
 46         pContext = _pCurrentExContext;
 47         IsRethrow = TRUE;
 48 #if _EH_RELATIVE_TYPEINFO
 49         _SetThrowImageBase((ptrdiff_t)pExcept->params.pThrowImageBase);
 50 #endif
 51 
 52         DASSERT(_ValidateRead(pExcept));
 53         DASSERT(!PER_IS_MSVC_EH(pExcept) || PER_PTHROW(pExcept) != nullptr);
 54 
 55         //
 56         // We know it is a rethrow -- did we come here as a result of an
 57         // exception re-thrown from CallUnexpected() ?
 58         //
 59         if( _pCurrentFuncInfo != nullptr )
 60         {
 61             ESTypeList* pCurrentFuncInfo = _pCurrentFuncInfo;   // remember it in a local variable
 62             _pCurrentFuncInfo = nullptr;   // and reset it immediately -- so we don't forget to do it later
 63 
 64             // Does the exception thrown by CallUnexpected belong to the exception specification?
 65 
 66             if( IsInExceptionSpec(pExcept, pCurrentFuncInfo) )
 67             {
 68                 // Yes it does -- so "continue the search for another handler at the call of the function
 69                 // whose exception-specification was violated"
 70                 ;
 71             }
 72             else
 73             {
 74                 // Nope, it does not. Is std::bad_exception allowed by the spec?
 75 
 76                 if( Is_bad_exception_allowed(pCurrentFuncInfo) )
 77                 {
 78                     // yup -- so according to the standard, we need to replace the thrown
 79                     // exception by an implementation-defined object of the type std::bad_exception
 80                     // and continue the search for another handler at the call of the function
 81                     // whose exception-specification was violated.
 82 
 83                     // Just throw bad_exception -- we will then come into FindHandler for the third time --
 84                     // but make sure we will not get here again
 85 
 86                     __DestructExceptionObject(pExcept, TRUE);   // destroy the original object
 87 
 88                     throw std::bad_exception();
 89                 }
 90                 else
 91                 {
 92                     terminate();
 93                 }
 94             }
 95         }
 96     }
 97 
 98     auto tryBlockMap = T::TryBlockMap(pFuncInfo, pDC);
 99 
100     if (PER_IS_MSVC_EH(pExcept)) {
101         // Looks like it's ours.  Let's see if we have a match:
102         //
103         // First, determine range of try blocks to consider:
104         // Only try blocks which are at the current catch depth are of interest.
105 
106         if (tryBlockMap.getNumTryBlocks() > 0)
107         {
108             auto startStop = T::GetRangeOfTrysToCheck(tryBlockMap, curState, CatchDepth);
109             // Scan the try blocks in the function:
110             for (auto iter = startStop.first; iter < startStop.second; ++iter) {
111                 auto tryBlock = *iter;
112 
113 #if _EH_RELATIVE_TYPEINFO
114                 __int32 const *ppCatchable;
115 #else
116                 CatchableType * const *ppCatchable;
117 #endif
118                 CatchableType *pCatchable;
119 
120                 if (tryBlock->tryLow > curState || curState > tryBlock->tryHigh) {
121                     continue;
122                 }
123 
124                 // Try block was in scope for current state.  Scan catches for this
125                 // try:
126                 T::HandlerMap handlerMap = T::HandlerMap(tryBlock, pDC);
127                 for (auto handler : handlerMap)
128                 {
129                     // Scan all types that thrown object can be converted to:
130                     ppCatchable = THROW_CTLIST(*PER_PTHROW(pExcept));
131                     for (int catchables = THROW_COUNT(*PER_PTHROW(pExcept));
132                         catchables > 0; catchables--, ppCatchable++) {
133 
134 #if _EH_RELATIVE_TYPEINFO
135                         pCatchable = (CatchableType *)(_GetThrowImageBase() + *ppCatchable);
136 #else
137                         pCatchable = *ppCatchable;
138 #endif
139 
140                         if (!T::TypeMatch(handler, pCatchable, PER_PTHROW(pExcept))) {
141                             continue;
142                         }
143 
144                         // OK.  We finally found a match.  Activate the catch.  If
145                         // control gets back here, the catch did a re-throw, so
146                         // keep searching.
147 
148                         gotMatch = TRUE;
149 
150                         CatchIt<T>(pExcept,
151                                    pRN,
152                                    pContext,
153                                    pDC,
154                                    pFuncInfo,
155                                    handler,
156                                    pCatchable,
157                                    tryBlock,
158                                    CatchDepth,
159                                    pMarkerRN,
160                                    IsRethrow
161 #if defined (_M_X64) || defined(_M_ARM_NT) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_)
162                                    , recursive
163 #endif
164                                    );
165                         goto NextTryBlock;
166 
167                     } // Scan posible conversions
168                 } // Scan catch clauses
169     NextTryBlock: ;
170             } // Scan try blocks
171         } // if FUNC_NTRYBLOCKS( pFuncInfo ) > 0
172 #if defined(_DEBUG)
173         else
174         {
175             //
176             // This can only happen if the function has an exception specification
177             // but no try/catch blocks
178             //
179             DASSERT(T::getMagicNum(pFuncInfo) >= EH_MAGIC_NUMBER2);
180             DASSERT(T::getESTypes(pFuncInfo) != nullptr);
181         }
182 #endif
183 
184 #if defined(_M_IX86) && !defined(_CHPE_X86_ARM64_EH_)
185         if (recursive) {
186             //
187             // A translation was provided, but this frame didn't catch it.
188             // Destruct the translated object before returning; if destruction
189             // raises an exception, terminate.
190             //
191             // This is not done for Win64 platforms.  On those, the translated
192             // object is destructed in __CxxCallCatchBlock.
193             //
194             __DestructExceptionObject(pExcept, TRUE);
195         }
196 #endif
197 
198         // FH4 doesn't support Exception Specifications aside from NoExcept
199         if constexpr (std::is_same_v<T, RENAME_EH_EXTERN(__FrameHandler4)>)
200         {
201             if (!gotMatch && T::isNoExcept(pFuncInfo) &&
202 #if defined(_M_IX86) && !defined(_CHPE_X86_ARM64_EH_)
203                 CatchDepth == 0
204 #else
205                 !T::ExecutionInCatch(pDC, pFuncInfo)
206 #endif
207                 )
208             {
209                 terminate();
210             }
211         }
212         else
213         {
214             //
215             // We haven't found the match -- let's look at the exception spec and see if our try
216             // matches one of the listed types.
217             //
218             // This block also handles noexcept termination if the current function is noexcept and
219             // we are not handling a nested throw or re-throw. e.g.:
220             //
221             // try {
222             //   try { throw 1; } (1)
223             //   catch(int) { throw; /* or throw <something new>; */ } (2)
224             // } catch(int) {} (3)
225             //
226             // During the initial search for a handler when throwing the original exception (1)
227             // we find and execute catch handler (2). This throws, which re-enters this function
228             // while in the context of a catch, but which cannot find a handler. We cannot terminate here,
229             // we're in a recursive context. Just let it go, and we'll return back to the original search
230             // from (1) and find (3). If we fail to find a handler, e.g. (3) didn't match, we would
231             // then terminate at this point as we are not in a catch block.
232             //
233             // Catch block detection uses CatchDepth on X86, or _ExecutionInCatch on other platforms. On
234             // these platforms CatchDepth is always 0 - we don't maintain a stack of entered try/catch
235             // states.
236             if (!gotMatch && FUNC_MAGICNUM(*pFuncInfo) >= EH_MAGIC_HAS_ES &&
237                 (T::getESTypes(pFuncInfo) != nullptr || (T::isNoExcept(pFuncInfo) &&
238 #if defined(_M_IX86) && !defined(_CHPE_X86_ARM64_EH_)
239                     CatchDepth == 0
240 #else
241                     !T::ExecutionInCatch(pDC, pFuncInfo)
242 #endif
243                     )))
244             {
245                 // Are we noexcept?
246                 if (T::isNoExcept(pFuncInfo))
247                 {
248                     terminate();
249                 }
250 
251                 if (!IsInExceptionSpec(pExcept, T::getESTypes(pFuncInfo)))
252                 {
253                     // Nope, it does not. Call unexpected
254 
255                     //
256                     // We must unwind the stack before calling unexpected -- this makes it work
257                     // as if it were inside catch(...) clause
258                     //
259 #if defined (_M_X64) || defined(_M_ARM_NT) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_)
260                     EHRegistrationNode *pEstablisher = pRN;
261                     EHRegistrationNode EstablisherFramePointers;
262                     pEstablisher = T::GetEstablisherFrame(pRN, pDC, pFuncInfo, &EstablisherFramePointers);
263                     T::UnwindNestedFrames(pRN,
264                         pExcept,
265                         pContext,
266                         pEstablisher,
267                         nullptr,
268                         pFuncInfo,
269                         EH_EMPTY_STATE,
270                         EH_EMPTY_STATE,
271                         nullptr,
272                         pDC,
273                         recursive
274                     );
275 #else
276 
277                     _pCurrentException = pExcept;
278                     _pCurrentExContext = pContext;
279 
280                     if (pMarkerRN == nullptr) {
281                         RENAME_EH_EXTERN(_UnwindNestedFrames)(pRN, pExcept);
282                     }
283                     else {
284                         RENAME_EH_EXTERN(_UnwindNestedFrames)(pMarkerRN, pExcept);
285                     }
286                     T::FrameUnwindToEmptyState(pRN, pDC, pFuncInfo);
287 
288                     CallUnexpected(T::getESTypes(pFuncInfo));
289                     _pCurrentException = pExcept;
290                     _pCurrentExContext = pContext;
291 #endif
292                 }
293             }
294         }
295     } // It was a C++ EH exception
296     else
297     {
298         // Not ours.  But maybe someone told us how to make it ours.
299         if (tryBlockMap.getNumTryBlocks() > 0)
300         {
301             if (!recursive) {
302                 FindHandlerForForeignException<T>(pExcept, pRN, pContext, pDC,
303                 pFuncInfo, curState, CatchDepth, pMarkerRN);
304             } else {
305                 // We're recursive, and the exception wasn't a C++ EH!
306                 // Translator threw something uninteligable.
307 
308                 // Two choices here: we could let the new exception take over, or we could abort. We abort.
309                 terminate();
310             }
311         }
312     } // It wasn't our exception
313 
314     DASSERT( _pCurrentFuncInfo == nullptr );   // never leave it initialized with something
315 
316     EHTRACE_EXIT;
317 }
View Code

函数_InternalCxxFrameHandler的主要功能是完成异常类型的检查,最终调用查找try块和catch块的函数FindHandler。这个函数是完成异常处理的关键部分,完成了查找try块中抛出的异常对应的catch语句块的过程。

008CE300 55                   push        ebp  
008CE301 8B EC                mov         ebp,esp  
008CE303 83 EC 68             sub         esp,68h  
008CE306 C6 45 FF 00          mov         byte ptr [IsRethrow],0  
008CE30A C6 45 FE 00          mov         byte ptr [gotMatch],0  
008CE30E C7 45 F8 FF FF FF FF mov         dword ptr [curState],0FFFFFFFFh  
008CE315 8B 45 18             mov         eax,dword ptr [pFuncInfo]  
008CE318 50                   push        eax  
008CE319 8B 4D 14             mov         ecx,dword ptr [pDC]  
008CE31C 51                   push        ecx  
008CE31D 8B 55 0C             mov         edx,dword ptr [pRN]  
008CE320 52                   push        edx  
008CE321 E8 DC 39 FF FF       call        __FrameHandler3::GetCurrentState (08C1D02h)  
008CE326 83 C4 0C             add         esp,0Ch  
008CE329 89 45 F8             mov         dword ptr [curState],eax  
008CE32C 83 7D F8 FF          cmp         dword ptr [curState],0FFFFFFFFh  
008CE330 7C 17                jl          FindHandler<__FrameHandler3>+49h (08CE349h)  
008CE332 8B 45 18             mov         eax,dword ptr [pFuncInfo]  
008CE335 50                   push        eax  
008CE336 8B 4D 14             mov         ecx,dword ptr [pDC]  
008CE339 51                   push        ecx  
008CE33A E8 FE 30 FF FF       call        __FrameHandler3::GetMaxState (08C143Dh)  
008CE33F 83 C4 08             add         esp,8  
008CE342 39 45 F8             cmp         dword ptr [curState],eax  
008CE345 7D 02                jge         FindHandler<__FrameHandler3>+49h (08CE349h)  
008CE347 EB 05                jmp         FindHandler<__FrameHandler3>+4Eh (08CE34Eh)  
008CE349 E8 25 32 FF FF       call        _terminate (08C1573h)  
008CE34E 8B 55 08             mov         edx,dword ptr [pExcept]  
008CE351 81 3A 63 73 6D E0    cmp         dword ptr [edx],0E06D7363h  
008CE357 0F 85 47 01 00 00    jne         FindHandler<__FrameHandler3>+1A4h (08CE4A4h)  
008CE35D 8B 45 08             mov         eax,dword ptr [pExcept]  
008CE360 83 78 10 03          cmp         dword ptr [eax+10h],3  
008CE364 0F 85 3A 01 00 00    jne         FindHandler<__FrameHandler3>+1A4h (08CE4A4h)  
008CE36A 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CE36D 81 79 14 20 05 93 19 cmp         dword ptr [ecx+14h],19930520h  
008CE374 74 1C                je          FindHandler<__FrameHandler3>+92h (08CE392h)  
008CE376 8B 55 08             mov         edx,dword ptr [pExcept]  
008CE379 81 7A 14 21 05 93 19 cmp         dword ptr [edx+14h],19930521h  
008CE380 74 10                je          FindHandler<__FrameHandler3>+92h (08CE392h)  
008CE382 8B 45 08             mov         eax,dword ptr [pExcept]  
008CE385 81 78 14 22 05 93 19 cmp         dword ptr [eax+14h],19930522h  
008CE38C 0F 85 12 01 00 00    jne         FindHandler<__FrameHandler3>+1A4h (08CE4A4h)  
008CE392 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CE395 83 79 1C 00          cmp         dword ptr [ecx+1Ch],0  
008CE399 0F 85 05 01 00 00    jne         FindHandler<__FrameHandler3>+1A4h (08CE4A4h)  
008CE39F E8 E0 52 FF FF       call        ___vcrt_getptd (08C3684h)  
008CE3A4 83 78 10 00          cmp         dword ptr [eax+10h],0  
008CE3A8 75 05                jne         FindHandler<__FrameHandler3>+0AFh (08CE3AFh)  
008CE3AA E9 60 04 00 00       jmp         NextTryBlock+1A6h (08CE80Fh)  
008CE3AF E8 D0 52 FF FF       call        ___vcrt_getptd (08C3684h)  
008CE3B4 8B 50 10             mov         edx,dword ptr [eax+10h]  
008CE3B7 89 55 08             mov         dword ptr [pExcept],edx  
008CE3BA E8 C5 52 FF FF       call        ___vcrt_getptd (08C3684h)  
008CE3BF 8B 40 14             mov         eax,dword ptr [eax+14h]  
008CE3C2 89 45 10             mov         dword ptr [pContext],eax  
008CE3C5 C6 45 FF 01          mov         byte ptr [IsRethrow],1  
008CE3C9 6A 01                push        1  
008CE3CB 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CE3CE 51                   push        ecx  
008CE3CF E8 4C 48 FF FF       call        _ValidateRead (08C2C20h)  
008CE3D4 83 C4 08             add         esp,8  
008CE3D7 0F B6 D0             movzx       edx,al  
008CE3DA 85 D2                test        edx,edx  
008CE3DC 74 02                je          FindHandler<__FrameHandler3>+0E0h (08CE3E0h)  
008CE3DE EB 05                jmp         FindHandler<__FrameHandler3>+0E5h (08CE3E5h)  
008CE3E0 E8 8E 31 FF FF       call        _terminate (08C1573h)  
008CE3E5 8B 45 08             mov         eax,dword ptr [pExcept]  
008CE3E8 81 38 63 73 6D E0    cmp         dword ptr [eax],0E06D7363h  
008CE3EE 75 3B                jne         FindHandler<__FrameHandler3>+12Bh (08CE42Bh)  
008CE3F0 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CE3F3 83 79 10 03          cmp         dword ptr [ecx+10h],3  
008CE3F7 75 32                jne         FindHandler<__FrameHandler3>+12Bh (08CE42Bh)  
008CE3F9 8B 55 08             mov         edx,dword ptr [pExcept]  
008CE3FC 81 7A 14 20 05 93 19 cmp         dword ptr [edx+14h],19930520h  
008CE403 74 18                je          FindHandler<__FrameHandler3>+11Dh (08CE41Dh)  
008CE405 8B 45 08             mov         eax,dword ptr [pExcept]  
008CE408 81 78 14 21 05 93 19 cmp         dword ptr [eax+14h],19930521h  
008CE40F 74 0C                je          FindHandler<__FrameHandler3>+11Dh (08CE41Dh)  
008CE411 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CE414 81 79 14 22 05 93 19 cmp         dword ptr [ecx+14h],19930522h  
008CE41B 75 0E                jne         FindHandler<__FrameHandler3>+12Bh (08CE42Bh)  
008CE41D 8B 55 08             mov         edx,dword ptr [pExcept]  
008CE420 83 7A 1C 00          cmp         dword ptr [edx+1Ch],0  
008CE424 75 05                jne         FindHandler<__FrameHandler3>+12Bh (08CE42Bh)  
008CE426 E8 48 31 FF FF       call        _terminate (08C1573h)  
008CE42B E8 54 52 FF FF       call        ___vcrt_getptd (08C3684h)  
008CE430 83 78 1C 00          cmp         dword ptr [eax+1Ch],0  
008CE434 74 6E                je          FindHandler<__FrameHandler3>+1A4h (08CE4A4h)  
008CE436 E8 49 52 FF FF       call        ___vcrt_getptd (08C3684h)  
008CE43B 8B 40 1C             mov         eax,dword ptr [eax+1Ch]  
008CE43E 89 45 E8             mov         dword ptr [ebp-18h],eax  
008CE441 E8 3E 52 FF FF       call        ___vcrt_getptd (08C3684h)  
008CE446 C7 40 1C 00 00 00 00 mov         dword ptr [eax+1Ch],0  
008CE44D 8B 4D E8             mov         ecx,dword ptr [ebp-18h]  
008CE450 51                   push        ecx  
008CE451 8B 55 08             mov         edx,dword ptr [pExcept]  
008CE454 52                   push        edx  
008CE455 E8 66 14 00 00       call        IsInExceptionSpec (08CF8C0h)  
008CE45A 83 C4 08             add         esp,8  
008CE45D 0F B6 C0             movzx       eax,al  
008CE460 85 C0                test        eax,eax  
008CE462 74 02                je          FindHandler<__FrameHandler3>+166h (08CE466h)  
008CE464 EB 3E                jmp         FindHandler<__FrameHandler3>+1A4h (08CE4A4h)  
008CE466 8B 4D E8             mov         ecx,dword ptr [ebp-18h]  
008CE469 51                   push        ecx  
008CE46A E8 31 15 00 00       call        Is_bad_exception_allowed (08CF9A0h)  
008CE46F 83 C4 04             add         esp,4  
008CE472 0F B6 D0             movzx       edx,al  
008CE475 85 D2                test        edx,edx  
008CE477 74 26                je          FindHandler<__FrameHandler3>+19Fh (08CE49Fh)  
008CE479 6A 01                push        1  
008CE47B 8B 45 08             mov         eax,dword ptr [pExcept]  
008CE47E 50                   push        eax  
008CE47F E8 FC 3C FF FF       call        ___DestructExceptionObject (08C2180h)  
008CE484 83 C4 08             add         esp,8  
008CE487 8D 4D A8             lea         ecx,[ebp-58h]  
008CE48A E8 D2 38 FF FF       call        std::bad_exception::bad_exception (08C1D61h)  
008CE48F 68 78 06 9A 00       push        offset __TI2?AVbad_exception@std@@ (09A0678h)  
008CE494 8D 4D A8             lea         ecx,[ebp-58h]  
008CE497 51                   push        ecx  
008CE498 E8 D1 62 FF FF       call        __CxxThrowException@8 (08C476Eh)  
008CE49D EB 05                jmp         FindHandler<__FrameHandler3>+1A4h (08CE4A4h)  
008CE49F E8 CF 30 FF FF       call        _terminate (08C1573h)  
008CE4A4 8B 55 14             mov         edx,dword ptr [pDC]  
008CE4A7 52                   push        edx  
008CE4A8 8B 45 18             mov         eax,dword ptr [pFuncInfo]  
008CE4AB 50                   push        eax  
008CE4AC 8D 4D C4             lea         ecx,[tryBlockMap]  
008CE4AF E8 02 61 FF FF       call        __FrameHandler3::TryBlockMap::TryBlockMap (08C45B6h)  
008CE4B4 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CE4B7 81 39 63 73 6D E0    cmp         dword ptr [ecx],0E06D7363h  
008CE4BD 0F 85 F7 02 00 00    jne         NextTryBlock+151h (08CE7BAh)  
008CE4C3 8B 55 08             mov         edx,dword ptr [pExcept]  
008CE4C6 83 7A 10 03          cmp         dword ptr [edx+10h],3  
008CE4CA 0F 85 EA 02 00 00    jne         NextTryBlock+151h (08CE7BAh)  
008CE4D0 8B 45 08             mov         eax,dword ptr [pExcept]  
008CE4D3 81 78 14 20 05 93 19 cmp         dword ptr [eax+14h],19930520h  
008CE4DA 74 1C                je          FindHandler<__FrameHandler3>+1F8h (08CE4F8h)  
008CE4DC 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CE4DF 81 79 14 21 05 93 19 cmp         dword ptr [ecx+14h],19930521h  
008CE4E6 74 10                je          FindHandler<__FrameHandler3>+1F8h (08CE4F8h)  
008CE4E8 8B 55 08             mov         edx,dword ptr [pExcept]  
008CE4EB 81 7A 14 22 05 93 19 cmp         dword ptr [edx+14h],19930522h  
008CE4F2 0F 85 C2 02 00 00    jne         NextTryBlock+151h (08CE7BAh)  
008CE4F8 8D 4D C4             lea         ecx,[tryBlockMap]  
008CE4FB E8 79 39 FF FF       call        __FrameHandler3::TryBlockMap::getNumTryBlocks (08C1E79h)  
008CE500 85 C0                test        eax,eax  
008CE502 0F 86 68 01 00 00    jbe         NextTryBlock+7h (08CE670h)  
008CE508 8B 45 20             mov         eax,dword ptr [CatchDepth]  
008CE50B 50                   push        eax  
008CE50C 8B 4D F8             mov         ecx,dword ptr [curState]  
008CE50F 51                   push        ecx  
008CE510 8D 55 C4             lea         edx,[tryBlockMap]  
008CE513 52                   push        edx  
008CE514 8D 45 98             lea         eax,[ebp-68h]  
008CE517 50                   push        eax  
008CE518 E8 7D 54 FF FF       call        __FrameHandler3::GetRangeOfTrysToCheck (08C399Ah)  
008CE51D 83 C4 10             add         esp,10h  
008CE520 8B 4D 98             mov         ecx,dword ptr [ebp-68h]  
008CE523 89 4D D4             mov         dword ptr [ebp-2Ch],ecx  
008CE526 8B 55 9C             mov         edx,dword ptr [ebp-64h]  
008CE529 89 55 D8             mov         dword ptr [ebp-28h],edx  
008CE52C EB 08                jmp         FindHandler<__FrameHandler3>+236h (08CE536h)  
008CE52E 8D 4D D4             lea         ecx,[ebp-2Ch]  
008CE531 E8 85 4C FF FF       call        __FrameHandler3::TryBlockMap::iterator::operator++ (08C31BBh)  
008CE536 8D 45 A0             lea         eax,[ebp-60h]  
008CE539 50                   push        eax  
008CE53A 8D 4D D4             lea         ecx,[ebp-2Ch]  
008CE53D E8 BE 2F FF FF       call        __FrameHandler3::TryBlockMap::iterator::operator< (08C1500h)  
008CE542 0F B6 C8             movzx       ecx,al  
008CE545 85 C9                test        ecx,ecx  
008CE547 0F 84 21 01 00 00    je          NextTryBlock+5h (08CE66Eh)  
008CE54D 8D 4D D4             lea         ecx,[ebp-2Ch]  
008CE550 E8 B7 3C FF FF       call        __FrameHandler3::TryBlockMap::iterator::operator* (08C220Ch)  
008CE555 89 45 F4             mov         dword ptr [ebp-0Ch],eax  
008CE558 8B 55 F4             mov         edx,dword ptr [ebp-0Ch]  
008CE55B 8B 02                mov         eax,dword ptr [edx]  
008CE55D 3B 45 F8             cmp         eax,dword ptr [curState]  
008CE560 7F 0B                jg          FindHandler<__FrameHandler3>+26Dh (08CE56Dh)  
008CE562 8B 4D F4             mov         ecx,dword ptr [ebp-0Ch]  
008CE565 8B 55 F8             mov         edx,dword ptr [curState]  
008CE568 3B 51 04             cmp         edx,dword ptr [ecx+4]  
008CE56B 7E 02                jle         FindHandler<__FrameHandler3>+26Fh (08CE56Fh)  
008CE56D EB BF                jmp         FindHandler<__FrameHandler3>+22Eh (08CE52Eh)  
008CE56F 8B 45 14             mov         eax,dword ptr [pDC]  
008CE572 50                   push        eax  
008CE573 8B 4D F4             mov         ecx,dword ptr [ebp-0Ch]  
008CE576 51                   push        ecx  
008CE577 8D 4D BC             lea         ecx,[ebp-44h]  
008CE57A E8 F1 4B FF FF       call        __FrameHandler3::HandlerMap::HandlerMap (08C3170h)  
008CE57F 8D 55 BC             lea         edx,[ebp-44h]  
008CE582 89 55 E4             mov         dword ptr [ebp-1Ch],edx  
008CE585 8D 45 CC             lea         eax,[ebp-34h]  
008CE588 50                   push        eax  
008CE589 8B 4D E4             mov         ecx,dword ptr [ebp-1Ch]  
008CE58C E8 84 42 FF FF       call        __FrameHandler3::HandlerMap::begin (08C2815h)  
008CE591 8D 4D B4             lea         ecx,[ebp-4Ch]  
008CE594 51                   push        ecx  
008CE595 8B 4D E4             mov         ecx,dword ptr [ebp-1Ch]  
008CE598 E8 E5 57 FF FF       call        __FrameHandler3::HandlerMap::end (08C3D82h)  
008CE59D EB 08                jmp         FindHandler<__FrameHandler3>+2A7h (08CE5A7h)  
008CE59F 8D 4D CC             lea         ecx,[ebp-34h]  
008CE5A2 E8 9E 3A FF FF       call        __FrameHandler3::HandlerMap::iterator::operator++ (08C2045h)  
008CE5A7 8D 55 B4             lea         edx,[ebp-4Ch]  
008CE5AA 52                   push        edx  
008CE5AB 8D 4D CC             lea         ecx,[ebp-34h]  
008CE5AE E8 76 4C FF FF       call        __FrameHandler3::HandlerMap::iterator::operator!= (08C3229h)  
008CE5B3 0F B6 C0             movzx       eax,al  
008CE5B6 85 C0                test        eax,eax  
008CE5B8 0F 84 AB 00 00 00    je          NextTryBlock (08CE669h)  
008CE5BE 8D 4D CC             lea         ecx,[ebp-34h]  
008CE5C1 E8 9D 58 FF FF       call        __FrameHandler3::HandlerMap::iterator::operator* (08C3E63h)  
008CE5C6 89 45 DC             mov         dword ptr [ebp-24h],eax  
008CE5C9 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CE5CC 8B 51 1C             mov         edx,dword ptr [ecx+1Ch]  
008CE5CF 8B 42 0C             mov         eax,dword ptr [edx+0Ch]  
008CE5D2 83 C0 04             add         eax,4  
008CE5D5 89 45 EC             mov         dword ptr [ebp-14h],eax  
008CE5D8 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CE5DB 8B 51 1C             mov         edx,dword ptr [ecx+1Ch]  
008CE5DE 8B 42 0C             mov         eax,dword ptr [edx+0Ch]  
008CE5E1 8B 08                mov         ecx,dword ptr [eax]  
008CE5E3 89 4D F0             mov         dword ptr [ebp-10h],ecx  
008CE5E6 EB 12                jmp         FindHandler<__FrameHandler3>+2FAh (08CE5FAh)  
008CE5E8 8B 55 F0             mov         edx,dword ptr [ebp-10h]  
008CE5EB 83 EA 01             sub         edx,1  
008CE5EE 89 55 F0             mov         dword ptr [ebp-10h],edx  
008CE5F1 8B 45 EC             mov         eax,dword ptr [ebp-14h]  
008CE5F4 83 C0 04             add         eax,4  
008CE5F7 89 45 EC             mov         dword ptr [ebp-14h],eax  
008CE5FA 83 7D F0 00          cmp         dword ptr [ebp-10h],0  
008CE5FE 7E 64                jle         FindHandler<__FrameHandler3>+364h (08CE664h)  
008CE600 8B 4D EC             mov         ecx,dword ptr [ebp-14h]  
008CE603 8B 11                mov         edx,dword ptr [ecx]  
008CE605 89 55 E0             mov         dword ptr [ebp-20h],edx  
008CE608 8B 45 08             mov         eax,dword ptr [pExcept]  
008CE60B 8B 48 1C             mov         ecx,dword ptr [eax+1Ch]  
008CE60E 51                   push        ecx  
008CE60F 8B 55 E0             mov         edx,dword ptr [ebp-20h]  
008CE612 52                   push        edx  
008CE613 8B 45 DC             mov         eax,dword ptr [ebp-24h]  
008CE616 50                   push        eax  
008CE617 E8 2C 50 FF FF       call        __FrameHandler3::TypeMatch (08C3648h)//异常匹配的判定  
008CE61C 83 C4 0C             add         esp,0Ch  
008CE61F 85 C0                test        eax,eax  
008CE621 75 02                jne         FindHandler<__FrameHandler3>+325h (08CE625h)  
008CE623 EB C3                jmp         FindHandler<__FrameHandler3>+2E8h (08CE5E8h)  
008CE625 C6 45 FE 01          mov         byte ptr [gotMatch],1  
008CE629 0F B6 4D FF          movzx       ecx,byte ptr [IsRethrow]  
008CE62D 51                   push        ecx  
008CE62E 8B 55 24             mov         edx,dword ptr [pMarkerRN]  
008CE631 52                   push        edx  
008CE632 8B 45 20             mov         eax,dword ptr [CatchDepth]  
008CE635 50                   push        eax  
008CE636 8B 4D F4             mov         ecx,dword ptr [ebp-0Ch]  
008CE639 51                   push        ecx  
008CE63A 8B 55 E0             mov         edx,dword ptr [ebp-20h]  
008CE63D 52                   push        edx  
008CE63E 8B 45 DC             mov         eax,dword ptr [ebp-24h]  
008CE641 50                   push        eax  
008CE642 8B 4D 18             mov         ecx,dword ptr [pFuncInfo]  
008CE645 51                   push        ecx  
008CE646 8B 55 14             mov         edx,dword ptr [pDC]  
008CE649 52                   push        edx  
008CE64A 8B 45 10             mov         eax,dword ptr [pContext]  
008CE64D 50                   push        eax  
008CE64E 8B 4D 0C             mov         ecx,dword ptr [pRN]  
008CE651 51                   push        ecx  
008CE652 8B 55 08             mov         edx,dword ptr [pExcept]  
008CE655 52                   push        edx  
008CE656 E8 A5 FB FF FF       call        CatchIt<__FrameHandler3> (08CE200h)  //catch对象的构造与析构过程,并跳转到catch结束地址
008CE65B 83 C4 2C             add         esp,2Ch  
008CE65E EB 09                jmp         NextTryBlock (08CE669h)  
008CE660 EB 07                jmp         NextTryBlock (08CE669h)  
008CE662 EB 84                jmp         FindHandler<__FrameHandler3>+2E8h (08CE5E8h)  
008CE664 E9 36 FF FF FF       jmp         FindHandler<__FrameHandler3>+29Fh (08CE59Fh)  
008CE669 E9 C0 FE FF FF       jmp         FindHandler<__FrameHandler3>+22Eh (08CE52Eh)  
008CE66E EB 31                jmp         NextTryBlock+38h (08CE6A1h)  
008CE670 8B 45 18             mov         eax,dword ptr [pFuncInfo]  
008CE673 50                   push        eax  
008CE674 E8 BB 3B FF FF       call        __FrameHandler3::getMagicNum (08C2234h)  
008CE679 83 C4 04             add         esp,4  
008CE67C 3D 21 05 93 19       cmp         eax,19930521h  
008CE681 72 02                jb          NextTryBlock+1Ch (08CE685h)  
008CE683 EB 05                jmp         NextTryBlock+21h (08CE68Ah)  
008CE685 E8 E9 2E FF FF       call        _terminate (08C1573h)  
008CE68A 8B 4D 18             mov         ecx,dword ptr [pFuncInfo]  
008CE68D 51                   push        ecx  
008CE68E E8 BE 2D FF FF       call        __FrameHandler3::getESTypes (08C1451h)  
008CE693 83 C4 04             add         esp,4  
008CE696 85 C0                test        eax,eax  
008CE698 74 02                je          NextTryBlock+33h (08CE69Ch)  
008CE69A EB 05                jmp         NextTryBlock+38h (08CE6A1h)  
008CE69C E8 D2 2E FF FF       call        _terminate (08C1573h)  
008CE6A1 0F B6 55 1C          movzx       edx,byte ptr [recursive]  
008CE6A5 85 D2                test        edx,edx  
008CE6A7 74 0E                je          NextTryBlock+4Eh (08CE6B7h)  
008CE6A9 6A 01                push        1  
008CE6AB 8B 45 08             mov         eax,dword ptr [pExcept]  
008CE6AE 50                   push        eax  
008CE6AF E8 CC 3A FF FF       call        ___DestructExceptionObject (08C2180h)  
008CE6B4 83 C4 08             add         esp,8  
008CE6B7 0F B6 4D FE          movzx       ecx,byte ptr [gotMatch]  
008CE6BB 85 C9                test        ecx,ecx  
008CE6BD 0F 85 F5 00 00 00    jne         NextTryBlock+14Fh (08CE7B8h)  
008CE6C3 8B 55 18             mov         edx,dword ptr [pFuncInfo]  
008CE6C6 8B 02                mov         eax,dword ptr [edx]  
008CE6C8 25 FF FF FF 1F       and         eax,1FFFFFFFh  
008CE6CD 3D 21 05 93 19       cmp         eax,19930521h  
008CE6D2 0F 82 E0 00 00 00    jb          NextTryBlock+14Fh (08CE7B8h)  
008CE6D8 8B 4D 18             mov         ecx,dword ptr [pFuncInfo]  
008CE6DB 51                   push        ecx  
008CE6DC E8 70 2D FF FF       call        __FrameHandler3::getESTypes (08C1451h)  
008CE6E1 83 C4 04             add         esp,4  
008CE6E4 85 C0                test        eax,eax  
008CE6E6 75 21                jne         NextTryBlock+0A0h (08CE709h)  
008CE6E8 8B 55 18             mov         edx,dword ptr [pFuncInfo]  
008CE6EB 52                   push        edx  
008CE6EC E8 EA 57 FF FF       call        __FrameHandler3::isNoExcept (08C3EDBh)  
008CE6F1 83 C4 04             add         esp,4  
008CE6F4 0F B6 C0             movzx       eax,al  
008CE6F7 85 C0                test        eax,eax  
008CE6F9 0F 84 B9 00 00 00    je          NextTryBlock+14Fh (08CE7B8h)  
008CE6FF 83 7D 20 00          cmp         dword ptr [CatchDepth],0  
008CE703 0F 85 AF 00 00 00    jne         NextTryBlock+14Fh (08CE7B8h)  
008CE709 8B 4D 18             mov         ecx,dword ptr [pFuncInfo]  
008CE70C 51                   push        ecx  
008CE70D E8 C9 57 FF FF       call        __FrameHandler3::isNoExcept (08C3EDBh)  
008CE712 83 C4 04             add         esp,4  
008CE715 0F B6 D0             movzx       edx,al  
008CE718 85 D2                test        edx,edx  
008CE71A 74 05                je          NextTryBlock+0B8h (08CE721h)  
008CE71C E8 52 2E FF FF       call        _terminate (08C1573h)  
008CE721 8B 45 18             mov         eax,dword ptr [pFuncInfo]  
008CE724 50                   push        eax  
008CE725 E8 27 2D FF FF       call        __FrameHandler3::getESTypes (08C1451h)  
008CE72A 83 C4 04             add         esp,4  
008CE72D 50                   push        eax  
008CE72E 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CE731 51                   push        ecx  
008CE732 E8 89 11 00 00       call        IsInExceptionSpec (08CF8C0h)  
008CE737 83 C4 08             add         esp,8  
008CE73A 0F B6 D0             movzx       edx,al  
008CE73D 85 D2                test        edx,edx  
008CE73F 75 77                jne         NextTryBlock+14Fh (08CE7B8h)  
008CE741 E8 3E 4F FF FF       call        ___vcrt_getptd (08C3684h)  
008CE746 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CE749 89 48 10             mov         dword ptr [eax+10h],ecx  
008CE74C E8 33 4F FF FF       call        ___vcrt_getptd (08C3684h)  
008CE751 8B 55 10             mov         edx,dword ptr [pContext]  
008CE754 89 50 14             mov         dword ptr [eax+14h],edx  
008CE757 83 7D 24 00          cmp         dword ptr [pMarkerRN],0  
008CE75B 75 0F                jne         NextTryBlock+103h (08CE76Ch)  
008CE75D 8B 45 08             mov         eax,dword ptr [pExcept]  
008CE760 50                   push        eax  
008CE761 8B 4D 0C             mov         ecx,dword ptr [pRN]  
008CE764 51                   push        ecx  
008CE765 E8 32 32 FF FF       call        _UnwindNestedFrames (08C199Ch)  
008CE76A EB 0D                jmp         NextTryBlock+110h (08CE779h)  
008CE76C 8B 55 08             mov         edx,dword ptr [pExcept]  
008CE76F 52                   push        edx  
008CE770 8B 45 24             mov         eax,dword ptr [pMarkerRN]  
008CE773 50                   push        eax  
008CE774 E8 23 32 FF FF       call        _UnwindNestedFrames (08C199Ch)  
008CE779 8B 4D 18             mov         ecx,dword ptr [pFuncInfo]  
008CE77C 51                   push        ecx  
008CE77D 8B 55 14             mov         edx,dword ptr [pDC]  
008CE780 52                   push        edx  
008CE781 8B 45 0C             mov         eax,dword ptr [pRN]  
008CE784 50                   push        eax  
008CE785 E8 CC 5E FF FF       call        __FrameHandler3::FrameUnwindToEmptyState (08C4656h)  
008CE78A 83 C4 0C             add         esp,0Ch  
008CE78D 8B 4D 18             mov         ecx,dword ptr [pFuncInfo]  
008CE790 51                   push        ecx  
008CE791 E8 BB 2C FF FF       call        __FrameHandler3::getESTypes (08C1451h)  
008CE796 83 C4 04             add         esp,4  
008CE799 50                   push        eax  
008CE79A E8 C1 0D 00 00       call        CallUnexpected (08CF560h)  
008CE79F 83 C4 04             add         esp,4  
008CE7A2 E8 DD 4E FF FF       call        ___vcrt_getptd (08C3684h)  
008CE7A7 8B 55 08             mov         edx,dword ptr [pExcept]  
008CE7AA 89 50 10             mov         dword ptr [eax+10h],edx  
008CE7AD E8 D2 4E FF FF       call        ___vcrt_getptd (08C3684h)  
008CE7B2 8B 4D 10             mov         ecx,dword ptr [pContext]  
008CE7B5 89 48 14             mov         dword ptr [eax+14h],ecx  
008CE7B8 EB 43                jmp         NextTryBlock+194h (08CE7FDh)  
008CE7BA 8D 4D C4             lea         ecx,[tryBlockMap]  
008CE7BD E8 B7 36 FF FF       call        __FrameHandler3::TryBlockMap::getNumTryBlocks (08C1E79h)  
008CE7C2 85 C0                test        eax,eax  
008CE7C4 76 37                jbe         NextTryBlock+194h (08CE7FDh)  
008CE7C6 0F B6 55 1C          movzx       edx,byte ptr [recursive]  
008CE7CA 85 D2                test        edx,edx  
008CE7CC 75 2A                jne         NextTryBlock+18Fh (08CE7F8h)  
008CE7CE 8B 45 24             mov         eax,dword ptr [pMarkerRN]  
008CE7D1 50                   push        eax  
008CE7D2 8B 4D 20             mov         ecx,dword ptr [CatchDepth]  
008CE7D5 51                   push        ecx  
008CE7D6 8B 55 F8             mov         edx,dword ptr [curState]  
008CE7D9 52                   push        edx  
008CE7DA 8B 45 18             mov         eax,dword ptr [pFuncInfo]  
008CE7DD 50                   push        eax  
008CE7DE 8B 4D 14             mov         ecx,dword ptr [pDC]  
008CE7E1 51                   push        ecx  
008CE7E2 8B 55 10             mov         edx,dword ptr [pContext]  
008CE7E5 52                   push        edx  
008CE7E6 8B 45 0C             mov         eax,dword ptr [pRN]  
008CE7E9 50                   push        eax  
008CE7EA 8B 4D 08             mov         ecx,dword ptr [pExcept]  
008CE7ED 51                   push        ecx  
008CE7EE E8 6D 01 00 00       call        FindHandlerForForeignException<__FrameHandler3> (08CE960h)  
008CE7F3 83 C4 20             add         esp,20h  
008CE7F6 EB 05                jmp         NextTryBlock+194h (08CE7FDh)  
008CE7F8 E8 76 2D FF FF       call        _terminate (08C1573h)  
008CE7FD E8 82 4E FF FF       call        ___vcrt_getptd (08C3684h)  
008CE802 83 78 1C 00          cmp         dword ptr [eax+1Ch],0  
008CE806 75 02                jne         NextTryBlock+1A1h (08CE80Ah)  
008CE808 EB 05                jmp         NextTryBlock+1A6h (08CE80Fh)  
008CE80A E8 64 2D FF FF       call        _terminate (08C1573h)  
008CE80F 8B E5                mov         esp,ebp  
008CE811 5D                   pop         ebp  
008CE812 C3                   ret  
int RENAME_EH_EXTERN(__FrameHandler3)::TypeMatch(
    HandlerType   *pCatch,
    CatchableType *pCatchable,
    ThrowInfo     *pThrow
)
TypeMatch函数完成了对异常匹配的判定
int RENAME_EH_EXTERN(__FrameHandler3)::TypeMatch(
    HandlerType   *pCatch,
    CatchableType *pCatchable,
    ThrowInfo     *pThrow
)
{
    return TypeMatchHelper<HandlerType>(pCatch, pCatchable, pThrow);
};
View Code
 1 template <class T>
 2 int TypeMatchHelper(
 3     T *pCatch,                  // Type of the 'catch' clause
 4     CatchableType *pCatchable,  // Type conversion under consideration
 5     ThrowInfo *pThrow           // General information about the thrown
 6                                 //   type.
 7 ) {
 8     // First, check for match with ellipsis:
 9     if (HT_IS_TYPE_ELLIPSIS(*pCatch)) {
10         return TRUE;
11     }
12 
13     if (HT_ISBADALLOCCOMPAT(*pCatch) && CT_ISSTDBADALLOC(*pCatchable))
14     {
15         return true;
16     }
17 
18     // Not ellipsis; the basic types match if it's the same record *or* the
19     // names are identical.
20     if (HT_PTD(*pCatch) != CT_PTD(*pCatchable)
21         && strcmp(HT_NAME(*pCatch), CT_NAME(*pCatchable)) != 0) {
22         return FALSE;
23     }
24 
25     // Basic types match.  The actual conversion is valid if:
26     //   caught by ref if ref required *and*
27     //   the qualifiers are compatible *and*
28     //   the alignments match *and*
29     //   the volatility matches
30 
31     return (!CT_BYREFONLY(*pCatchable) || HT_ISREFERENCE(*pCatch))
32         && (!THROW_ISCONST(*pThrow) || HT_ISCONST(*pCatch))
33 #if defined(_M_X64) || defined(_M_ARM_NT) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_)
34         && (!THROW_ISUNALIGNED(*pThrow) || HT_ISUNALIGNED(*pCatch))
35 #endif
36         && (!THROW_ISVOLATILE(*pThrow) || HT_ISVOLATILE(*pCatch));
37 }
View Code

CatchIt<__FrameHandler3>(EHExceptionRecord *, EHRegistrationNode *, _CONTEXT *, void *, const _s_FuncInfo *, const _s_HandlerType *, const _s_CatchableType *, const _s_TryBlockMapEntry *, int, EHRegistrationNode *, unsigned char)
函数主要由四部分组成:异常对象的产生,析构try中的对象,跳转到对应的catch地址,返回到异常catch块的结尾地址。
  1 ////////////////////////////////////////////////////////////////////////////////
  2 //
  3 // CatchIt - A handler has been found for the thrown type.  Do the work to
  4 //   transfer control.
  5 //
  6 // Description:
  7 //     Builds the catch object
  8 //     Unwinds the stack to the point of the try
  9 //     Calls the address of the handler (funclet) with the frame set up for that
 10 //       function but without resetting the stack.
 11 //     Handler funclet returns address to continue execution, or nullptr if the
 12 //       handler re-threw ("throw;" lexically in handler)
 13 //     If the handler throws an EH exception whose exception info is nullptr, then
 14 //       it's a re-throw from a dynamicly enclosed scope.
 15 //
 16 // It is an open question whether the catch object is built before or after the local unwind.
 17 //
 18 // Returns:
 19 //     No return value.  Returns iff handler re-throws.
 20 template <class T>
 21 static void CatchIt(
 22     EHExceptionRecord *pExcept,           // The exception thrown
 23     EHRegistrationNode *pRN,              // Dynamic info of function with catch
 24     CONTEXT *pContext,                    // Context info
 25     DispatcherContext *pDC,               // Context within subject frame
 26     typename T::FuncInfo *pFuncInfo,      // Static info of function with catch
 27     typename T::HandlerType *pCatch,      // The catch clause selected
 28     CatchableType *pConv,                 // The rules for making the conversion
 29     typename T::TryBlockMapEntry *pEntry, // Description of the try block
 30     int CatchDepth,                       // How many catches are we nested in?
 31     EHRegistrationNode *pMarkerRN,        // Special node if nested in catch
 32     BOOLEAN IsRethrow                     // Is this a rethrow ?
 33 #if defined(_M_X64) || defined(_M_ARM_NT) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_)
 34     , BOOLEAN recursive
 35 #endif // defined(_POWERPC)
 36 ) {
 37 
 38     // These parameters are not used in some compilations
 39     UNREFERENCED_PARAMETER(CatchDepth);
 40     UNREFERENCED_PARAMETER(pMarkerRN);
 41     UNREFERENCED_PARAMETER(IsRethrow);
 42 
 43     EHTRACE_ENTER_FMT1("Catching object @ 0x%p", PER_PEXCEPTOBJ(pExcept));
 44 
 45     EHRegistrationNode *pEstablisher = pRN;
 46 
 47 #if defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_)
 48     EHRegistrationNode EstablisherFramePointers;
 49     pEstablisher = T::GetEstablisherFrame(pRN, pDC, pFuncInfo, &EstablisherFramePointers);
 50 #else
 51     void *continuationAddress;
 52 #endif // defined(_POWERPC)
 53 
 54     // Copy the thrown object into a buffer in the handler's stack frame,
 55     // unless the catch was by elipsis (no conversion) OR the catch was by
 56     // type without an actual 'catch object'.
 57 
 58     if (pConv != nullptr) {
 59         T::BuildCatchObject(pExcept, pEstablisher, pCatch, pConv);
 60     }
 61 
 62     // Unwind stack objects to the entry of the try that caught this exception.
 63 
 64 #if defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_)
 65     // This call will never return. This call will end up calling CxxCallCatchBlock
 66     // through RtlUnwind (STATUS_CONSULIDATE_FRAMES) mechanism.
 67     T::UnwindNestedFrames(
 68         pRN,
 69         pExcept,
 70         pContext,
 71         pEstablisher,
 72         __GetAddress(HT_HANDLER(*pCatch), pDC),
 73         pFuncInfo,
 74         pEntry->tryLow,
 75         pEntry->catchHigh,
 76         pCatch,
 77         pDC,
 78         recursive
 79         );
 80 
 81 #else
 82 
 83     if constexpr (std::is_same_v<T, RENAME_EH_EXTERN(__FrameHandler4)>)
 84     {
 85         // TODO: x86
 86         DASSERT(!"NYI");
 87     }
 88     else
 89     {
 90         if (pMarkerRN == nullptr) {
 91             RENAME_EH_EXTERN(_UnwindNestedFrames)(pRN, pExcept);
 92         }
 93         else {
 94             RENAME_EH_EXTERN(_UnwindNestedFrames)(pMarkerRN, pExcept);
 95         }
 96 
 97 
 98         T::FrameUnwindToState(pEstablisher, pDC, pFuncInfo, TBME_LOW(*pEntry));
 99 
100         // Call the catch.  Separated out because it introduces a new registration
101         // node.
102 
103         EHTRACE_FMT2("Move from state %d to state %d", T::GetCurrentState(pRN, pDC, pFuncInfo), TBME_HIGH(*pEntry) + 1);
104         T::SetState(pRN, pFuncInfo, TBME_HIGH(*pEntry) + 1);
105 
106         continuationAddress = CallCatchBlock(pExcept,
107             pEstablisher,
108             pContext,
109             pFuncInfo,
110             __GetAddress(HT_HANDLER(*pCatch), pDC),
111             CatchDepth,
112             0x100);
113 
114         // Transfer control to the continuation address.  If no continuation then
115         // it's a re-throw, so return.
116 
117         if (continuationAddress != nullptr) {
118 
119             _JumpToContinuation(continuationAddress, pRN);
120             // No return.
121 
122         }
123         EHTRACE_EXIT;
124     }
125 #endif
126 }
View Code
 
00B4E200 55                   push        ebp  
00B4E201 8B EC                mov         ebp,esp  
00B4E203 83 EC 08             sub         esp,8  
00B4E206 8B 45 0C             mov         eax,dword ptr [pRN]  
00B4E209 89 45 FC             mov         dword ptr [pEstablisher],eax  
00B4E20C 83 7D 20 00          cmp         dword ptr [pConv],0  
00B4E210 74 18                je          CatchIt<__FrameHandler3>+2Ah (0B4E22Ah)  
00B4E212 8B 4D 20             mov         ecx,dword ptr [pConv]  
00B4E215 51                   push        ecx  
00B4E216 8B 55 1C             mov         edx,dword ptr [pCatch]  
00B4E219 52                   push        edx  
00B4E21A 8B 45 FC             mov         eax,dword ptr [pEstablisher]  
00B4E21D 50                   push        eax  
00B4E21E 8B 4D 08             mov         ecx,dword ptr [pExcept]  
00B4E221 51                   push        ecx  
00B4E222 E8 D5 59 FF FF       call        __FrameHandler3::BuildCatchObject (0B43BFCh)  //使用BuildCatchObject函数对抛出的异常对象进行处理
00B4E227 83 C4 10             add         esp,10h  
00B4E22A 83 7D 2C 00          cmp         dword ptr [pMarkerRN],0  
00B4E22E 75 0F                jne         CatchIt<__FrameHandler3>+3Fh (0B4E23Fh)  
00B4E230 8B 55 08             mov         edx,dword ptr [pExcept]  
00B4E233 52                   push        edx  
00B4E234 8B 45 0C             mov         eax,dword ptr [pRN]  
00B4E237 50                   push        eax  
00B4E238 E8 5F 37 FF FF       call        _UnwindNestedFrames (0B4199Ch)  
00B4E23D EB 0D                jmp         CatchIt<__FrameHandler3>+4Ch (0B4E24Ch)  
00B4E23F 8B 4D 08             mov         ecx,dword ptr [pExcept]  
00B4E242 51                   push        ecx  
00B4E243 8B 55 2C             mov         edx,dword ptr [pMarkerRN]  
00B4E246 52                   push        edx  
00B4E247 E8 50 37 FF FF       call        _UnwindNestedFrames (0B4199Ch)  
00B4E24C 8B 45 24             mov         eax,dword ptr [pEntry]  
00B4E24F 8B 08                mov         ecx,dword ptr [eax]  
00B4E251 51                   push        ecx  
00B4E252 8B 55 18             mov         edx,dword ptr [pFuncInfo]  
00B4E255 52                   push        edx  
00B4E256 8B 45 14             mov         eax,dword ptr [pDC]  
00B4E259 50                   push        eax  
00B4E25A 8B 4D FC             mov         ecx,dword ptr [pEstablisher]  
00B4E25D 51                   push        ecx  
00B4E25E E8 94 40 FF FF       call        __FrameHandler3::FrameUnwindToState (0B422F7h)//处理展开流程  
00B4E263 83 C4 10             add         esp,10h  
00B4E266 8B 55 24             mov         edx,dword ptr [pEntry]  
00B4E269 8B 42 04             mov         eax,dword ptr [edx+4]  
00B4E26C 83 C0 01             add         eax,1  
00B4E26F 50                   push        eax  
00B4E270 8B 4D 18             mov         ecx,dword ptr [pFuncInfo]  
00B4E273 51                   push        ecx  
00B4E274 8B 55 0C             mov         edx,dword ptr [pRN]  
00B4E277 52                   push        edx  
00B4E278 E8 B9 3D FF FF       call        __FrameHandler3::SetState (0B42036h)  
00B4E27D 83 C4 0C             add         esp,0Ch  
00B4E280 68 00 01 00 00       push        100h  
00B4E285 8B 45 28             mov         eax,dword ptr [CatchDepth]  
00B4E288 50                   push        eax  
00B4E289 8B 4D 1C             mov         ecx,dword ptr [pCatch]  
00B4E28C 8B 51 0C             mov         edx,dword ptr [ecx+0Ch]  
00B4E28F 52                   push        edx  
00B4E290 8B 45 18             mov         eax,dword ptr [pFuncInfo]  
00B4E293 50                   push        eax  
00B4E294 8B 4D 10             mov         ecx,dword ptr [pContext]  
00B4E297 51                   push        ecx  
00B4E298 8B 55 FC             mov         edx,dword ptr [pEstablisher]  
00B4E29B 52                   push        edx  
00B4E29C 8B 45 08             mov         eax,dword ptr [pExcept]  
00B4E29F 50                   push        eax  
00B4E2A0 E8 AB 0F 00 00       call        CallCatchBlock (0B4F250h) //进入catch块进行处理,返回catch结束地址 
00B4E2A5 83 C4 1C             add         esp,1Ch  
00B4E2A8 89 45 F8             mov         dword ptr [continuationAddress],eax  
00B4E2AB 83 7D F8 00          cmp         dword ptr [continuationAddress],0  
00B4E2AF 74 0D                je          CatchIt<__FrameHandler3>+0BEh (0B4E2BEh)  
00B4E2B1 8B 4D 0C             mov         ecx,dword ptr [pRN]  
00B4E2B4 51                   push        ecx  
00B4E2B5 8B 55 F8             mov         edx,dword ptr [continuationAddress]  
00B4E2B8 52                   push        edx  
00B4E2B9 E8 0D 4E FF FF       call        _JumpToContinuation (0B430CBh) //跳转到catch块的结束 
00B4E2BE 8B E5                mov         esp,ebp  
00B4E2C0 5D                   pop         ebp  
00B4E2C1 C3                   ret  

CallCatchBlock(EHExceptionRecord *, EHRegistrationNode *, _CONTEXT *, const _s_FuncInfo *, void *, int, unsigned long)

  1 ////////////////////////////////////////////////////////////////////////////////
  2 //
  3 // CallCatchBlock - continuation of CatchIt.
  4 //
  5 // This is separated from CatchIt because it needs to introduce an SEH/EH frame
  6 //   in case the catch block throws.  This frame cannot be added until unwind of
  7 //   nested frames has been completed (otherwise this frame would be the first
  8 //   to go).
  9 
 10 static __declspec(guard(ignore)) void *CallCatchBlock(
 11     EHExceptionRecord *pExcept,         // The exception thrown
 12     EHRegistrationNode *pRN,            // Dynamic info of function with catch
 13     CONTEXT *pContext,                  // Context info
 14     FuncInfo *pFuncInfo,                // Static info of function with catch
 15     void *handlerAddress,               // Code address of handler
 16     int CatchDepth,                     // How deeply nested in catch blocks
 17                                         //   are we?
 18     unsigned long NLGCode               // NLG destination code
 19 ) {
 20     EHTRACE_ENTER;
 21 
 22     // Address where execution resumes after exception handling completed.
 23     // Initialized to non-nullptr (value doesn't matter) to distinguish from
 24     // re-throw in __finally.
 25     void *continuationAddress = handlerAddress;
 26 
 27     BOOL ExceptionObjectDestroyed = FALSE;
 28 
 29     // The stack pointer at entry to the try must be saved, in case there is
 30     // another try inside this catch.  We'll restore it on our way out.
 31     void *saveESP = PRN_STACK(pRN);
 32 
 33     // Push this catch block's frame info on a linked list
 34     FRAMEINFO FrameInfo;
 35     FRAMEINFO *pFrameInfo = RENAME_EH_EXTERN(_CreateFrameInfo)(&FrameInfo, PER_PEXCEPTOBJ(pExcept));
 36 
 37     // Save the current exception in case of a rethrow.  Save the previous value
 38     // on the stack, to be restored when the catch exits.
 39     EHExceptionRecord *pSaveException = _pCurrentException;
 40     CONTEXT *pSaveExContext = _pCurrentExContext;
 41 
 42     _pCurrentException = pExcept;
 43     _pCurrentExContext = pContext;
 44 
 45     __try {
 46         __try {
 47             // Execute the handler as a funclet, whose return value is the
 48             // address to resume execution.
 49             continuationAddress = _CallCatchBlock2(pRN, pFuncInfo,
 50                 handlerAddress, CatchDepth, NLGCode);
 51         } __except(EHTRACE_EXCEPT(ExFilterRethrow(exception_info()))) {
 52             cxxReThrow=false;
 53             // Here we are exiting the catch block on rethrow out of this
 54             // catch block. To keep the order of destruction and construction
 55             // same when the the rethrow was from function or was inline, here
 56             // we unwind to the parent state for this catch.
 57             UnwindMapEntry *pUnwindMap = pFuncInfo->pUnwindMap;
 58             int cState = RENAME_EH_EXTERN(__FrameHandler3)::GetCurrentState(pRN, handlerAddress, pFuncInfo);
 59             TryBlockMapEntry *pTryBlockMap = pFuncInfo->pTryBlockMap;
 60             unsigned int i;
 61             for (i = 0; i < pFuncInfo->nTryBlocks; i++) {
 62                 if (cState > pTryBlockMap[i].tryHigh &&
 63                     cState <= pTryBlockMap[i].catchHigh) {
 64                     cState = pTryBlockMap[i].tryHigh +1;
 65                     cState = pUnwindMap[cState].toState;
 66                     break;
 67                 }
 68             }
 69             RENAME_EH_EXTERN(__FrameHandler3)::FrameUnwindToState(pRN, nullptr, pFuncInfo, cState);
 70             // If the handler threw a typed exception without exception info or
 71             // exception object, then it's a re-throw, so return.  Otherwise
 72             // it's a new exception, which takes precedence over this one.
 73             continuationAddress = nullptr;
 74         }
 75     } __finally {
 76         EHTRACE_SAVE_LEVEL;
 77         EHTRACE_FMT1("Executing __finally, %snormal termination", _abnormal_termination() ? "ab" : "");
 78 
 79         // Restore the saved stack pointer, so the stack can be reset when
 80         // we're done.
 81         PRN_STACK(pRN) = saveESP;
 82 
 83         // Pop this catch block's frame info
 84         RENAME_EH_EXTERN(_FindAndUnlinkFrame)(pFrameInfo);
 85 
 86         // Restore the 'current exception' for a possibly enclosing catch
 87         _pCurrentException = pSaveException;
 88         _pCurrentExContext = pSaveExContext;
 89 
 90         // Destroy the original exception object if we're not exiting on a
 91         // re-throw and the object isn't also in use by a more deeply nested
 92         // catch.  Note that the catch handles destruction of its parameter.
 93 
 94         if (PER_IS_MSVC_EH(pExcept) && !ExceptionObjectDestroyed
 95             && continuationAddress != nullptr
 96             && _IsExceptionObjectToBeDestroyed(PER_PEXCEPTOBJ(pExcept)))
 97         {
 98             __DestructExceptionObject(pExcept, abnormal_termination() != FALSE);
 99         }
100 
101         EHTRACE_RESTORE_LEVEL(!!_abnormal_termination());
102     }
103     EHTRACE_EXIT;
104     return continuationAddress;
105 }
View Code
00B4F250 55                   push        ebp  
00B4F251 8B EC                mov         ebp,esp  
00B4F253 6A FE                push        0FFFFFFFEh  
00B4F255 68 A8 05 C2 00       push        0C205A8h  
00B4F25A 68 90 C8 B4 00       push        offset _except_handler4 (0B4C890h)  
00B4F25F 64 A1 00 00 00 00    mov         eax,dword ptr fs:[00000000h]  
00B4F265 50                   push        eax  
00B4F266 83 C4 C0             add         esp,0FFFFFFC0h  
00B4F269 53                   push        ebx  
00B4F26A 56                   push        esi  
00B4F26B 57                   push        edi  
00B4F26C A1 04 20 C2 00       mov         eax,dword ptr [__security_cookie (0C22004h)]  
00B4F271 31 45 F8             xor         dword ptr [ebp-8],eax  
00B4F274 33 C5                xor         eax,ebp  
00B4F276 50                   push        eax  
00B4F277 8D 45 F0             lea         eax,[ebp-10h]  
00B4F27A 64 A3 00 00 00 00    mov         dword ptr fs:[00000000h],eax  
00B4F280 89 65 E8             mov         dword ptr [ebp-18h],esp  
00B4F283 8B 45 18             mov         eax,dword ptr [handlerAddress]  
00B4F286 89 45 D8             mov         dword ptr [continuationAddress],eax  
00B4F289 C7 45 BC 00 00 00 00 mov         dword ptr [ExceptionObjectDestroyed],0  
00B4F290 B9 04 00 00 00       mov         ecx,4  
00B4F295 6B D1 FF             imul        edx,ecx,0FFFFFFFFh  
00B4F298 8B 45 0C             mov         eax,dword ptr [pRN]  
00B4F29B 8B 0C 10             mov         ecx,dword ptr [eax+edx]  
00B4F29E 89 4D CC             mov         dword ptr [saveESP],ecx  
00B4F2A1 8B 55 08             mov         edx,dword ptr [pExcept]  
00B4F2A4 8B 42 18             mov         eax,dword ptr [edx+18h]  
00B4F2A7 50                   push        eax  
00B4F2A8 8D 4D B0             lea         ecx,[FrameInfo]  
00B4F2AB 51                   push        ecx  
00B4F2AC E8 C8 26 FF FF       call        __CreateFrameInfo (0B41979h)  
00B4F2B1 83 C4 08             add         esp,8  
00B4F2B4 89 45 C8             mov         dword ptr [pFrameInfo],eax  
00B4F2B7 E8 C8 43 FF FF       call        ___vcrt_getptd (0B43684h)  
00B4F2BC 8B 50 10             mov         edx,dword ptr [eax+10h]  
00B4F2BF 89 55 C4             mov         dword ptr [pSaveException],edx  
00B4F2C2 E8 BD 43 FF FF       call        ___vcrt_getptd (0B43684h)  
00B4F2C7 8B 40 14             mov         eax,dword ptr [eax+14h]  
00B4F2CA 89 45 C0             mov         dword ptr [pSaveExContext],eax  
00B4F2CD E8 B2 43 FF FF       call        ___vcrt_getptd (0B43684h)  
00B4F2D2 8B 4D 08             mov         ecx,dword ptr [pExcept]  
00B4F2D5 89 48 10             mov         dword ptr [eax+10h],ecx  
00B4F2D8 E8 A7 43 FF FF       call        ___vcrt_getptd (0B43684h)  
00B4F2DD 8B 55 10             mov         edx,dword ptr [pContext]  
00B4F2E0 89 50 14             mov         dword ptr [eax+14h],edx  
00B4F2E3 C7 45 FC 00 00 00 00 mov         dword ptr [ebp-4],0  
00B4F2EA C7 45 B8 01 00 00 00 mov         dword ptr [ebp-48h],1  
00B4F2F1 C7 45 FC 01 00 00 00 mov         dword ptr [ebp-4],1  
00B4F2F8 8B 45 20             mov         eax,dword ptr [NLGCode]  
00B4F2FB 50                   push        eax  
00B4F2FC 8B 4D 1C             mov         ecx,dword ptr [CatchDepth]  
00B4F2FF 51                   push        ecx  
00B4F300 8B 55 18             mov         edx,dword ptr [handlerAddress]  
00B4F303 52                   push        edx  
00B4F304 8B 45 14             mov         eax,dword ptr [pFuncInfo]  
00B4F307 50                   push        eax  
00B4F308 8B 4D 0C             mov         ecx,dword ptr [pRN]  
00B4F30B 51                   push        ecx  
00B4F30C E8 79 2E FF FF       call        _CallCatchBlock2 (0B4218Ah)  
00B4F311 83 C4 14             add         esp,14h  
00B4F314 89 45 D8             mov         dword ptr [continuationAddress],eax  
00B4F317 C7 45 FC 00 00 00 00 mov         dword ptr [ebp-4],0  
00B4F31E E9 C7 00 00 00       jmp         CallCatchBlock+19Ah (0B4F3EAh)  
$LN24:
00B4F323 8B 55 EC             mov         edx,dword ptr [ebp-14h]  
00B4F326 52                   push        edx  
00B4F327 E8 E4 02 00 00       call        ExFilterRethrow (0B4F610h)  
00B4F32C 83 C4 04             add         esp,4  
$LN22:
00B4F32F C3                   ret  
$LN19:
00B4F330 8B 65 E8             mov         esp,dword ptr [ebp-18h]  
00B4F333 E8 4C 43 FF FF       call        ___vcrt_getptd (0B43684h)  
00B4F338 C7 40 20 00 00 00 00 mov         dword ptr [eax+20h],0  
00B4F33F 8B 45 14             mov         eax,dword ptr [pFuncInfo]  
00B4F342 8B 48 08             mov         ecx,dword ptr [eax+8]  
00B4F345 89 4D D0             mov         dword ptr [ebp-30h],ecx  
00B4F348 8B 55 14             mov         edx,dword ptr [pFuncInfo]  
00B4F34B 52                   push        edx  
00B4F34C 8B 45 18             mov         eax,dword ptr [handlerAddress]  
00B4F34F 50                   push        eax  
00B4F350 8B 4D 0C             mov         ecx,dword ptr [pRN]  
00B4F353 51                   push        ecx  
00B4F354 E8 A9 29 FF FF       call        __FrameHandler3::GetCurrentState (0B41D02h)  
00B4F359 83 C4 0C             add         esp,0Ch  
00B4F35C 89 45 DC             mov         dword ptr [ebp-24h],eax  
00B4F35F 8B 55 14             mov         edx,dword ptr [pFuncInfo]  
00B4F362 8B 42 10             mov         eax,dword ptr [edx+10h]  
00B4F365 89 45 D4             mov         dword ptr [ebp-2Ch],eax  
00B4F368 C7 45 E0 00 00 00 00 mov         dword ptr [ebp-20h],0  
00B4F36F EB 09                jmp         CallCatchBlock+12Ah (0B4F37Ah)  
00B4F371 8B 4D E0             mov         ecx,dword ptr [ebp-20h]  
00B4F374 83 C1 01             add         ecx,1  
00B4F377 89 4D E0             mov         dword ptr [ebp-20h],ecx  
00B4F37A 8B 55 14             mov         edx,dword ptr [pFuncInfo]  
00B4F37D 8B 45 E0             mov         eax,dword ptr [ebp-20h]  
00B4F380 3B 42 0C             cmp         eax,dword ptr [edx+0Ch]  
00B4F383 73 41                jae         CallCatchBlock+176h (0B4F3C6h)  
00B4F385 6B 4D E0 14          imul        ecx,dword ptr [ebp-20h],14h  
00B4F389 8B 55 D4             mov         edx,dword ptr [ebp-2Ch]  
00B4F38C 8B 45 DC             mov         eax,dword ptr [ebp-24h]  
00B4F38F 3B 44 0A 04          cmp         eax,dword ptr [edx+ecx+4]  
00B4F393 7E 2F                jle         CallCatchBlock+174h (0B4F3C4h)  
00B4F395 6B 4D E0 14          imul        ecx,dword ptr [ebp-20h],14h  
00B4F399 8B 55 D4             mov         edx,dword ptr [ebp-2Ch]  
00B4F39C 8B 45 DC             mov         eax,dword ptr [ebp-24h]  
00B4F39F 3B 44 0A 08          cmp         eax,dword ptr [edx+ecx+8]  
00B4F3A3 7F 1F                jg          CallCatchBlock+174h (0B4F3C4h)  
00B4F3A5 6B 4D E0 14          imul        ecx,dword ptr [ebp-20h],14h  
00B4F3A9 8B 55 D4             mov         edx,dword ptr [ebp-2Ch]  
00B4F3AC 8B 44 0A 04          mov         eax,dword ptr [edx+ecx+4]  
00B4F3B0 83 C0 01             add         eax,1  
00B4F3B3 89 45 DC             mov         dword ptr [ebp-24h],eax  
00B4F3B6 8B 4D DC             mov         ecx,dword ptr [ebp-24h]  
00B4F3B9 8B 55 D0             mov         edx,dword ptr [ebp-30h]  
00B4F3BC 8B 04 CA             mov         eax,dword ptr [edx+ecx*8]  
00B4F3BF 89 45 DC             mov         dword ptr [ebp-24h],eax  
00B4F3C2 EB 02                jmp         CallCatchBlock+176h (0B4F3C6h)  
00B4F3C4 EB AB                jmp         CallCatchBlock+121h (0B4F371h)  
00B4F3C6 8B 4D DC             mov         ecx,dword ptr [ebp-24h]  
00B4F3C9 51                   push        ecx  
00B4F3CA 8B 55 14             mov         edx,dword ptr [pFuncInfo]  
00B4F3CD 52                   push        edx  
00B4F3CE 6A 00                push        0  
00B4F3D0 8B 45 0C             mov         eax,dword ptr [pRN]  
00B4F3D3 50                   push        eax  
00B4F3D4 E8 1E 2F FF FF       call        __FrameHandler3::FrameUnwindToState (0B422F7h)  
00B4F3D9 83 C4 10             add         esp,10h  
00B4F3DC C7 45 D8 00 00 00 00 mov         dword ptr [continuationAddress],0  
00B4F3E3 C7 45 FC 00 00 00 00 mov         dword ptr [ebp-4],0  
00B4F3EA C7 45 FC FE FF FF FF mov         dword ptr [ebp-4],0FFFFFFFEh  
00B4F3F1 C7 45 B8 00 00 00 00 mov         dword ptr [ebp-48h],0  
00B4F3F8 E8 05 00 00 00       call        CallCatchBlock+1B2h (0B4F402h)  
00B4F3FD E9 AC 00 00 00       jmp         $LN17 (0B4F4AEh)  
00B4F402 B9 04 00 00 00       mov         ecx,4  
00B4F407 6B D1 FF             imul        edx,ecx,0FFFFFFFFh  
00B4F40A 8B 45 0C             mov         eax,dword ptr [pRN]  
00B4F40D 8B 4D CC             mov         ecx,dword ptr [saveESP]  
00B4F410 89 0C 10             mov         dword ptr [eax+edx],ecx  
00B4F413 8B 55 C8             mov         edx,dword ptr [pFrameInfo]  
00B4F416 52                   push        edx  
00B4F417 E8 F2 49 FF FF       call        __FindAndUnlinkFrame (0B43E0Eh)  
00B4F41C 83 C4 04             add         esp,4  
00B4F41F E8 60 42 FF FF       call        ___vcrt_getptd (0B43684h)  
00B4F424 8B 4D C4             mov         ecx,dword ptr [pSaveException]  
00B4F427 89 48 10             mov         dword ptr [eax+10h],ecx  
00B4F42A E8 55 42 FF FF       call        ___vcrt_getptd (0B43684h)  
00B4F42F 8B 55 C0             mov         edx,dword ptr [pSaveExContext]  
00B4F432 89 50 14             mov         dword ptr [eax+14h],edx  
00B4F435 8B 45 08             mov         eax,dword ptr [pExcept]  
00B4F438 81 38 63 73 6D E0    cmp         dword ptr [eax],0E06D7363h  
00B4F43E 75 6D                jne         CallCatchBlock+25Dh (0B4F4ADh)  
00B4F440 8B 4D 08             mov         ecx,dword ptr [pExcept]  
00B4F443 83 79 10 03          cmp         dword ptr [ecx+10h],3  
00B4F447 75 64                jne         CallCatchBlock+25Dh (0B4F4ADh)  
00B4F449 8B 55 08             mov         edx,dword ptr [pExcept]  
00B4F44C 81 7A 14 20 05 93 19 cmp         dword ptr [edx+14h],19930520h  
00B4F453 74 18                je          CallCatchBlock+21Dh (0B4F46Dh)  
00B4F455 8B 45 08             mov         eax,dword ptr [pExcept]  
00B4F458 81 78 14 21 05 93 19 cmp         dword ptr [eax+14h],19930521h  
00B4F45F 74 0C                je          CallCatchBlock+21Dh (0B4F46Dh)  
00B4F461 8B 4D 08             mov         ecx,dword ptr [pExcept]  
00B4F464 81 79 14 22 05 93 19 cmp         dword ptr [ecx+14h],19930522h  
00B4F46B 75 40                jne         CallCatchBlock+25Dh (0B4F4ADh)  
00B4F46D 83 7D BC 00          cmp         dword ptr [ExceptionObjectDestroyed],0  
00B4F471 75 3A                jne         CallCatchBlock+25Dh (0B4F4ADh)  
00B4F473 83 7D D8 00          cmp         dword ptr [continuationAddress],0  
00B4F477 74 34                je          CallCatchBlock+25Dh (0B4F4ADh)  
00B4F479 8B 55 08             mov         edx,dword ptr [pExcept]  
00B4F47C 8B 42 18             mov         eax,dword ptr [edx+18h]  
00B4F47F 50                   push        eax  
00B4F480 E8 45 38 FF FF       call        __IsExceptionObjectToBeDestroyed (0B42CCAh)  
00B4F485 83 C4 04             add         esp,4  
00B4F488 85 C0                test        eax,eax  
00B4F48A 74 21                je          CallCatchBlock+25Dh (0B4F4ADh)  
00B4F48C 83 7D B8 00          cmp         dword ptr [ebp-48h],0  
00B4F490 74 06                je          CallCatchBlock+248h (0B4F498h)  
00B4F492 C6 45 E7 01          mov         byte ptr [ebp-19h],1  
00B4F496 EB 04                jmp         CallCatchBlock+24Ch (0B4F49Ch)  
00B4F498 C6 45 E7 00          mov         byte ptr [ebp-19h],0  
00B4F49C 0F B6 4D E7          movzx       ecx,byte ptr [ebp-19h]  
00B4F4A0 51                   push        ecx  
00B4F4A1 8B 55 08             mov         edx,dword ptr [pExcept]  
00B4F4A4 52                   push        edx  
00B4F4A5 E8 D6 2C FF FF       call        ___DestructExceptionObject (0B42180h)  
00B4F4AA 83 C4 08             add         esp,8  
$LN23:
00B4F4AD C3                   ret  
00B4F4AE 8B 45 D8             mov         eax,dword ptr [continuationAddress]  
00B4F4B1 8B 4D F0             mov         ecx,dword ptr [ebp-10h]  
00B4F4B4 64 89 0D 00 00 00 00 mov         dword ptr fs:[0],ecx  
00B4F4BB 59                   pop         ecx  
00B4F4BC 5F                   pop         edi  
00B4F4BD 5E                   pop         esi  
00B4F4BE 5B                   pop         ebx  
00B4F4BF 8B E5                mov         esp,ebp  
00B4F4C1 5D                   pop         ebp  
00B4F4C2 C3                   ret 

抛出异常(throw)

ThrowInfo
//
// ThrowInfo - information describing the thrown object, statically built
// at the throw site.
//
// pExceptionObject (the dynamic part of the throw; see below) is always a
// reference, whether or not it is logically one.  If 'isSimpleType' is true,
// it is a reference to the simple type, which is 'size' bytes long.  If
// 'isReference' and 'isSimpleType' are both false, then it's a UDT or
// a pointer to any type (i.e. pExceptionObject points to a pointer).  If it's
// a pointer, copyFunction is NULL, otherwise it is a pointer to a copy
// constructor or copy constructor closure.
//
// The pForwardCompat function pointer is intended to be filled in by future
// versions, so that if say a DLL built with a newer version (say C10) throws,
// and a C9 frame attempts a catch, the frame handler attempting the catch (C9)
// can let the version that knows all the latest stuff do the work.
//
typedef const struct _s_ThrowInfo {
    unsigned int    attributes;                            // Throw Info attributes (Bit field)
    PMFN            pmfnUnwind;                            // Destructor to call when exception has been handled or aborted
#if _EH_RELATIVE_TYPEINFO && !defined(BUILDING_C1XX_FORCEINCLUDE)
    int                pForwardCompat;                        // Image relative offset of Forward compatibility frame handler
    int                pCatchableTypeArray;                // Image relative offset of CatchableTypeArray
#else
    int    (__cdecl * pForwardCompat)(...);                // Forward compatibility frame handler
    CatchableTypeArray* pCatchableTypeArray;            // Pointer to list of pointers to types
#endif
} ThrowInfo;

_CxxThrowException

// _CxxThrowException - implementation of 'throw'
//
// Description:
//      Builds the NT Exception record, and calls the NT runtime to initiate
//      exception processing.
//
//      Why is pThrowInfo defined as _ThrowInfo?  Because _ThrowInfo is secretly
//      snuck into the compiler, as is the prototype for _CxxThrowException, so
//      we have to use the same type to keep the compiler happy.
//
//      Another result of this is that _CRTIMP can't be used here.  Instead, we
//      synthesisze the -export directive below.
//
// Returns:
//      NEVER.  (until we implement resumable exceptions, that is)
//
extern "C" __declspec(noreturn) void __stdcall
_CxxThrowException(
        void*           pExceptionObject,   // The object thrown
        _ThrowInfo*     pThrowInfo          // Everything we need to know about it
) {
        EHTRACE_ENTER_FMT1("Throwing object @ 0x%p", pExceptionObject);

        static const EHExceptionRecord ExceptionTemplate = { // A generic exception record
            EH_EXCEPTION_NUMBER,            // Exception number
            EXCEPTION_NONCONTINUABLE,       // Exception flags (we don't do resume)
            nullptr,                           // Additional record (none)
            nullptr,                           // Address of exception (OS fills in)
            EH_EXCEPTION_PARAMETERS,        // Number of parameters
            {   EH_MAGIC_NUMBER1,           // Our version control magic number
                nullptr,                       // pExceptionObject
                nullptr,
#if EH_EXCEPTION_PARAMETERS == 4
                nullptr                        // Image base of thrown object
#endif
            }                      // pThrowInfo
        };
        EHExceptionRecord ThisException = ExceptionTemplate;    // This exception

        ThrowInfo* pTI = (ThrowInfo*)pThrowInfo;
        if (pTI && (THROW_ISWINRT( (*pTI) ) ) )
        {
            ULONG_PTR *exceptionInfoPointer = *reinterpret_cast<ULONG_PTR**>(pExceptionObject);
            exceptionInfoPointer--; // The pointer to the ExceptionInfo structure is stored sizeof(void*) infront of each WinRT Exception Info.

            WINRTEXCEPTIONINFO** ppWei = reinterpret_cast<WINRTEXCEPTIONINFO**>(exceptionInfoPointer);
            pTI = (*ppWei)->throwInfo;

            (*ppWei)->PrepareThrow( ppWei );
        }

        //
        // Fill in the blanks:
        //
        ThisException.params.pExceptionObject = pExceptionObject;
        ThisException.params.pThrowInfo = pTI;
#if _EH_RELATIVE_TYPEINFO
        PVOID ThrowImageBase = RtlPcToFileHeader((PVOID)pTI, &ThrowImageBase);
        ThisException.params.pThrowImageBase = ThrowImageBase;
#endif

        //
        // If the throw info indicates this throw is from a pure region,
        // set the magic number to the Pure one, so only a pure-region
        // catch will see it.
        //
        // Also use the Pure magic number on Win64 if we were unable to
        // determine an image base, since that was the old way to determine
        // a pure throw, before the TI_IsPure bit was added to the FuncInfo
        // attributes field.
        //
        if (pTI != nullptr)
        {
            if (THROW_ISPURE(*pTI))
            {
                ThisException.params.magicNumber = EH_PURE_MAGIC_NUMBER1;
            }
#if _EH_RELATIVE_TYPEINFO
            else if (ThrowImageBase == nullptr)
            {
                ThisException.params.magicNumber = EH_PURE_MAGIC_NUMBER1;
            }
#endif
        }

        //
        // Hand it off to the OS:
        //

        EHTRACE_EXIT;
        RaiseException( ThisException.ExceptionCode,
                        ThisException.ExceptionFlags,
                        ThisException.NumberParameters,
                        (PULONG_PTR)&ThisException.params );
}

 

函数_InternalCxxFrameHandler的主要功能是完成异常类型的检查,最终调用查找try块和catch块的函数FindHandler。这个函数是完成异常处理的关键部分,完成了查找try块中抛出的异常对应的catch语句块的过程

原文地址:https://www.cnblogs.com/DirWang/p/12208665.html