Skip to content
This repository was archived by the owner on Feb 8, 2024. It is now read-only.

Commit e332492

Browse files
committed
fix restoring RBX
adjust for other vcruntime lib/dll versions
1 parent 162f29f commit e332492

File tree

1 file changed

+37
-24
lines changed

1 file changed

+37
-24
lines changed

src/ldc/eh/win32.d

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)