c++ 反汇编 异常处理

 

 

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

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

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

c++ 反汇编 异常处理

 

 

 

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

c++ 反汇编 异常处理

 

 

  • 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

c++ 反汇编 异常处理

 

 

  • 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

c++ 反汇编 异常处理

 

 

 

__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

相关文章:

  • 2021-08-14
  • 2021-10-05
  • 2021-10-23
猜你喜欢
  • 2021-08-14
  • 2022-01-29
  • 2022-01-04
  • 2022-12-23
  • 2021-06-22
  • 2021-12-22
  • 2021-09-21
相关资源
相似解决方案