0

How can i access the exception chain (SEH) using masm64?

Using masm32, I get the first exception looking into fs:[0]

But when I checked in Windbg if fs:[0] still pointed at the first exception in x64, I figured that it wasn't.

I'd like to set an exception in x64 the same way I did in x86. Is it feasible (maybe looking at gs register)?

ginko
  • 47
  • 5
  • The Windows x64 ABI uses unwind codes for exception handling. Use RtlLookupFunctionEntry to look up the unwind info for a particular function. – Raymond Chen Oct 17 '22 at 02:51

1 Answers1

0

If this is coding related then you use

ml64seh PROC FRAME:ExceptionFilter 

this adds your exception handler to .PDATA section RUNTIME_FUNCTION

if this is how to find this exception handler in windbg when the exception has been raised

use !exchain command

or if you want to find it before executing a specific function use .fnent command

a sample for x64 seh and finding it in windbg is as follows

;assemble and link with 
;ml64 /Zi ml64seh.asm /link /debug /entry:ml64seh /subsystem:console

.data
safeplace DWORD ?

.code

ExceptionFilter PROC 
    jmp Handler 
ExceptionFilter ENDP

PUBLIC ml64seh

ml64seh PROC FRAME:ExceptionFilter
.ENDPROLOG
    mov rax, 0
    mov [rax], rax ;access violation
    jmp exit
Handler::
    lea rax, safeplace
    mov [r8+078h], rax ; replacing rax in exception handler so access is possible
    mov rax, 0
    ret
Exit:
    ret 
ml64seh ENDP
 
END

run without stopping in windbg

:\>cdb -g ml64seh.exe
(2aa0.3024): Access violation - code c0000005 (first chance)
ml64seh!ml64seh+0x7:
00007ff7`0e3b1029 488900          mov     qword ptr [rax],rax ds:00000000`00000000=????????????????
0:000>

it crashed and broke now locating exception handlers

0:000> .fnent .
Debugger function entry 0000020b`e36c47a8 for:
(00007ff7`0e3b1022)   ml64seh!ml64seh+0x7   |  (00007ff7`0e3b32b0)   ml64seh!$xdatasym

BeginAddress      = 00000000`00001022
EndAddress        = 00000000`00001042
UnwindInfoAddress = 00000000`000032b0

Unwind info at 00007ff7`0e3b32b0, c bytes
  version 1, flags 3, prolog 0, codes 0
  handler routine: ml64seh!ILT+0(ExceptionFilter) (00007ff7`0e3b1005), data 0 <<<<<<<<<
  
  
0:000> !exchain
3 stack frames, scanning for handlers...
Frame 0x00: ml64seh!ml64seh+0x7 (00007ff7`0e3b1029)
  ehandler ml64seh!ILT+0(ExceptionFilter) (00007ff7`0e3b1005) <<<<<<<<<<<<
Frame 0x02: ntdll!RtlUserThreadStart+0x21 (00007ffe`213c26a1)
  ehandler ntdll!_C_specific_handler (00007ffe`213fc720)
0:000>

lets see if we go to the handler and return back to re access the faulting place

0:000> bp . 
0:000> bp 00007ff7`0e3b1005
0:000> bl
 0 e 00007ff7`0e3b1029     0001 (0001)  0:**** ml64seh!ml64seh+0x7
 1 e 00007ff7`0e3b1005     0001 (0001)  0:**** ml64seh!ILT+0(ExceptionFilter)
 
 
0:000> g
Breakpoint 1 hit
ml64seh!ILT+0(ExceptionFilter):
00007ff7`0e3b1005 e916000000      jmp     ml64seh!ExceptionFilter (00007ff7`0e3b1020)


0:000> g
Breakpoint 0 hit
ml64seh!ml64seh+0x7:  is accessible now
00007ff7`0e3b1029 488900          mov     qword ptr [rax],rax ds:00007ff7`0e3b4000=0000000000000000 
0:000>

btw you can use dumpbin or linker to spit out all the unwindinfos in a specific binary using -unwindinfo switch

:\>dumpbin /unwindinfo ml64seh.exe
Microsoft (R) COFF/PE Dumper Version 14.29.30146.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file ml64seh.exe

File Type: EXECUTABLE IMAGE

Function Table (1)

           Begin    End      Info      Function Name

  00000000 00001022 00001042 000032B0  ml64seh
    Unwind version: 1
    Unwind flags: EHANDLER UHANDLER
    Size of prologue: 0x00
    Count of codes: 0
    Handler: 00001005 @ILT+0(ExceptionFilter)
blabb
  • 8,674
  • 1
  • 18
  • 27