@@ -362,8 +362,9 @@ void msvc_eh_terminate() nothrow
362362 cmp RAX , 1 ;
363363 jle L_term;
364364
365- // update stack and IP so we just continue in __FrameUnwindHandler
366- // TODO: check DLL versions of MS runtime
365+ // update stack and IP so we just continue in __FrameUnwindHandler
366+ // NOTE: these checks can fail if you have breakpoints set at
367+ // the respective code locations
367368 mov RAX ,[RSP + 8 ]; // get return address
368369 cmp byte ptr[RAX ], 0xEB ; // jmp?
369370 jne noJump;
@@ -373,52 +374,64 @@ void msvc_eh_terminate() nothrow
373374 cmp byte ptr[RAX ], 0xE8 ; // call abort?
374375 jne L_term;
375376 add RAX ,5 ;
376- mov EDX ,[RAX ];
377+ mov EDX ,[RAX ];
377378 mov RBX , 0xFFFFFF ;
378379 and RDX , RBX ;
379380 cmp RDX , 0xC48348 ; // add ESP,nn
380- je L_addESP_found;
381- cmp DX , 0xCC90 ; // nop; int3;
382- jne L_term;
383- mov RDX , 0x28 ; // release build of vcruntimelib
384- jmp L_retTerminate;
385-
381+ je L_addESP_found;
382+ cmp DX , 0xCC90 ; // nop; int3;
383+ jne L_term;
384+ mov RDX , 0x28 ; // release build of vcruntimelib
385+ jmp L_retTerminate;
386+
386387 L_addESP_found:
387388 movzx RDX ,byte ptr[RAX + 3 ]; // read nn
388389
389390 cmp byte ptr [RAX + 4 ], 0xC3 ; // ret?
390391 jne L_term;
391-
392+
392393 L_retTerminate:
393394 lea RDX ,[RSP + RDX + 0x10 ]; // RSP before returning from terminate()
394395
395- mov RAX ,[RDX ]; // return address inside __FrameUnwindHandler
396+ mov RAX ,[RDX ]; // return address inside __FrameUnwindHandler
396397
397- cmp byte ptr [RAX - 19 ], 0xEB ; // skip back to default jump inside "switch" (debug build)
398- je L_switchFound;
399-
400- mov RBX , 0xc48348c0333048ff ; // dec [rax+30h]; xor eax,eax; add rsp,nn
398+ cmp byte ptr [RAX - 19 ], 0xEB ; // skip back to default jump inside "switch" (libvcruntimed.lib)
399+ je L_switchFound;
400+
401+ cmp byte ptr [RAX - 20 ], 0xEB ; // skip back to default jump inside "switch" (vcruntime140d.dll)
402+ je L_switchFound2;
403+
404+ mov RBX , 0xc48348c0333048ff ; // dec [rax+30h]; xor eax,eax; add rsp,nn (libvcruntime.lib)
401405 cmp RBX ,[RAX - 0x18 ];
406+ je L_retFound;
407+
408+ cmp RBX ,[RAX + 0x29 ]; // dec [rax+30h]; xor eax,eax; add rsp,nn (vcruntime140.dll)
402409 jne L_term;
403-
404- lea RAX , [RAX - 19 ];
405- jmp L_xorSkipped;
406-
410+
411+ lea RAX , [RAX + 0x2F ];
412+ jmp L_xorSkipped;
413+
414+ L_retFound:
415+ lea RAX , [RAX - 19 ];
416+ jmp L_xorSkipped;
417+
418+ L_switchFound2:
419+ dec RAX ;
407420 L_switchFound:
408421 movsx RBX , byte ptr [RAX - 18 ]; // follow jump
409422 lea RAX , [RAX + RBX - 17 ];
410423
411424 cmp word ptr[RAX ],0xC033 ; // xor EAX,EAX?
412425 jne L_term;
413426
414- add RAX ,2 ;
427+ add RAX ,2 ;
415428 L_xorSkipped:
416- pop RBX ;
429+ mov RBX ,[ RDX - 8 ]; // restore RBX (pushed inside terminate())
417430 lea RSP ,[RDX + 8 ];
418431 push RAX ; // new return after setting return value in __frameUnwindHandler
419-
420- call __processing_throw;
421- mov [RAX ], 1 ;
432+
433+ call __processing_throw;
434+ mov [RAX ], 1 ;
422435
423436 // add RSP,0x68; // TODO: needs to be verified for different CRT builds
424437 mov RAX ,1 ; // return EXCEPTION_EXECUTE_HANDLER
0 commit comments