flat assembler
Message board for the users of flat assembler.

Index > Windows > Win64 SEH implementation

Author
Thread Post new topic Reply to topic
QQ2976501934



Joined: 06 Jul 2021
Posts: 3
QQ2976501934 06 Jul 2021, 12:35
Code:
UNW_FLAG_NHANDLER = 0
UNW_FLAG_EHANDLER = 1
UNW_FLAG_UHANDLER = 2
UNW_FLAG_CHAININFO = 4

__SEH64_REG.rax = 0
__SEH64_REG.rcx = 1
__SEH64_REG.rdx = 2
__SEH64_REG.rbx = 3
__SEH64_REG.rsp = 4
__SEH64_REG.rbp = 5
__SEH64_REG.rsi = 6
__SEH64_REG.rdi = 7
__SEH64_REG.r8  = 8
__SEH64_REG.r9  = 9
__SEH64_REG.r10 = 10
__SEH64_REG.r11 = 11
__SEH64_REG.r12 = 12
__SEH64_REG.r13 = 13
__SEH64_REG.r14 = 14
__SEH64_REG.r15 = 15

virtual at -510
  __SEH64_UNWIND_CODE::
        dw 255 dup(?)
        assert ($ = 0)
end virtual

; The UNWIND_INFO structure tells how the portion of code should be handled. Here's the declaration I found on MSDN:
; typedef union _UNWIND_CODE {
;     struct {
;         UBYTE CodeOffset;
;         UBYTE UnwindOp : 4;
;         UBYTE OpInfo   : 4;
;     };
;     USHORT FrameOffset;
; } UNWIND_CODE, *PUNWIND_CODE;
;
; typedef struct _UNWIND_INFO {
;     UBYTE Version       : 3;
;     UBYTE Flags         : 5;
;     UBYTE SizeOfProlog;
;     UBYTE CountOfCodes;
;     UBYTE FrameRegister : 4;
;     UBYTE FrameOffset   : 4;
;     UNWIND_CODE UnwindCode[1];
; /*  UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1];
;  *  union {
;  *      OPTIONAL ULONG ExceptionHandler;
;  *      OPTIONAL ULONG FunctionEntry;
;  *  };
;  *  OPTIONAL ULONG ExceptionData[];
;  */

macro .seh_proc func {
        local ..func, ..flags, ..frameptr, ..funcptr, ..funclabel, ..ucodes
        ..flags = 0
        ..frameptr = 0
        ..ucodes = 0
        macro .seh_handler handler, flags \{
                ..flags = flags
                ..funcptr = rva handler
        \}
        macro .seh_pushreg reg \{
                ; UWOP_PUSH_NONVOL
                \local ..label
          ..label:
                ..ucodes = ..ucodes + 1
                store byte (..label - ..func) at __SEH64_UNWIND_CODE:(-2*..ucodes)
                store byte (__SEH64_REG.\#reg * 16) at __SEH64_UNWIND_CODE:(-2*..ucodes+1)
        \}
        macro .seh_stackalloc size \{
                \local ..label
          ..label:
                if size <= 128
                        ; UWOP_ALLOC_SMALL
                        ..ucodes = ..ucodes + 1
                        store byte (..label - ..func) at __SEH64_UNWIND_CODE:(-2*..ucodes)
                        store byte ((size) * 2 - 14) at __SEH64_UNWIND_CODE:(-2*..ucodes+1)
                else if size < 524288
                        ; UWOP_ALLOC_LARGE (OpInfo = 0)
                        ..ucodes = ..ucodes + 2
                        store byte (..label - ..func) at __SEH64_UNWIND_CODE:(-2*..ucodes)
                        store byte 1 at __SEH64_UNWIND_CODE:(-2*..ucodes+1)
                        store word ((size) / 8) at __SEH64_UNWIND_CODE:(-2*..ucodes+2)
                else
                        ; UWOP_ALLOC_LARGE (OpInfo = 1)
                        ..ucodes = ..ucodes + 3
                        store byte (..label - ..func) at __SEH64_UNWIND_CODE:(-2*..ucodes)
                        store byte 17 at __SEH64_UNWIND_CODE:(-2*..ucodes+1)
                        store dword (size) at __SEH64_UNWIND_CODE:(-2*..ucodes+2)
                end if
        \}
        macro .seh_setframe reg, offset \{
                ; UWOP_SET_FPREG
                \local ..label
          ..label:
                ..ucodes = ..ucodes + 1
                ..frameptr = __SEH64_REG.\#reg + offset
                store byte (..label - ..func) at __SEH64_UNWIND_CODE:(-2*..ucodes)
                store byte (__SEH64_REG.\#reg * 16 + 3) at __SEH64_UNWIND_CODE:(-2*..ucodes+1)
        \}
        macro .seh_endprologue \{
                \local ..endp, ..tmp
          ..endp:
                virtual at 0
                  ..funclabel#.uinfo::
                        db 1 + (..flags * 8)
                        db ..endp - ..func
                        db ..ucodes
                        db ..frameptr
                        repeat ..ucodes
                                load ..tmp word from __SEH64_UNWIND_CODE:((-..ucodes + % - 1) * 2)
                                dw ..tmp
                        end repeat
                        align 4
                        if ..flags <> UNW_FLAG_NHANDLER
                                dd ..funcptr
                        end if

                  ..funclabel#.uinfo.size = $
                end virtual
        \}
        macro .seh_endproc \{
                \local ..endp
                purge .seh_handler
                purge .seh_pushreg
                purge .seh_stackalloc
                purge .seh_setframe
                purge .seh_endprologue
                purge .seh_endproc
          ..endp:
                virtual at 0
                  ..funclabel::
                        dd rva ..func, rva ..endp, rva ..funclabel#.uinfo.ptr
                end virtual
                __SEH64_FUNCTABL equ ..funclabel
        \}
  ..func:
        match any, func \{
          func:
        \}
}

macro .seh_fixup {
        local sym, cmd, mem, i, t
        data 3
        irpv sym, __SEH64_FUNCTABL \{
                irp mem, sym \\{
                        load t dword from mem:0
                        dd t
                        load t dword from mem:4
                        dd t
                        load t dword from mem:8
                        dd t
                \\}
        \}
        end data
        irpv sym, __SEH64_FUNCTABL \{
                irp mem, sym \\{
                        i = 0
                  mem\\#.uinfo.ptr:
                        while i < mem\\#.uinfo.size
                                load t dword from mem\\#.uinfo:i
                                dd t
                                i = i + 4
                        end while
                \\}
        \}
}
    


Last edited by QQ2976501934 on 15 Sep 2021, 13:37; edited 2 times in total
Post 06 Jul 2021, 12:35
View user's profile Send private message Reply with quote
Feryno



Joined: 23 Mar 2005
Posts: 514
Location: Czech republic, Slovak republic
Feryno 06 Jul 2021, 18:27
Hi QQ2976501934 and welcome to the forum. We were discussing exception handling using Exception Directory here:
https://board.flatassembler.net/topic.php?t=11266
Your macros are very helpful. Well done. Thank you for posting them.
Post 06 Jul 2021, 18:27
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.