News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

my SEH doesn't work

Started by x64Core, December 02, 2012, 05:55:59 PM

Previous topic - Next topic

Antariy

You could easily use those macroses in AxEH.inc in your programs :t

MichaelW

I would be surprised if the method used here would not work under Windows Vista/7.

;==============================================================================
; try.asm
;==============================================================================

LPEXCEPTION_POINTERS TYPEDEF PTR EXCEPTION_POINTERS

;-----------------------------------------------------------------
; This macro sets the top-level exception filter for the calling
; process to our try_filter procedure, so when an unhandled
; exception reaches the UnhandledExceptionFilter function, and
; the process is not being debugged, the function will call our
; procedure. The return_address parameter specifies the address
; of a label were execution will continue if an exception occurs.
; Use this macro to begin a guarded section of code.
;-----------------------------------------------------------------

try_begin MACRO return_address
    push return_address
    pop _exception_return_address_
    invoke SetUnhandledExceptionFilter, try_filter
    mov _previous_exception_filter_, eax
ENDM

;----------------------------------------------------------------
; This macro sets the top-level exception filter for the calling
; process to what it was before the try_begin macro changed it.
; Use this macro to end a guarded section of code.
;----------------------------------------------------------------

try_end MACRO
    invoke SetUnhandledExceptionFilter, _previous_exception_filter_
ENDM

;==============================================================================
    .data
        _exception_return_address_  dd 0
        _previous_exception_filter_ dd 0
        exception_record            EXCEPTION_RECORD <>
    .code
;==============================================================================

PEXCEPTION_RECORD TYPEDEF PTR EXCEPTION_RECORD

;-----------------------------------
; These not defined in windows.inc.
;-----------------------------------

EXCEPTION_NONCONTINUABLE_EXCEPTION  equ 0C0000025h
EXCEPTION_STACK_OVERFLOW            equ 0C00000FDh
EXCEPTION_INVALID_DISPOSITION       equ 0C0000026h
EXCEPTION_GUARD_PAGE                equ 080000001h
EXCEPTION_INVALID_HANDLE            equ 0C0000008h

ShowException proc uses ebx per:PEXCEPTION_RECORD
    mov ebx, per
    SWITCH [ebx].EXCEPTION_RECORD.ExceptionCode
        CASE EXCEPTION_ACCESS_VIOLATION
            printf("EXCEPTION_ACCESS_VIOLATION")
        CASE EXCEPTION_DATATYPE_MISALIGNMENT
            printf("EXCEPTION_DATATYPE_MISALIGNMENT")
        CASE EXCEPTION_BREAKPOINT
            printf("EXCEPTION_BREAKPOINT")
        CASE EXCEPTION_SINGLE_STEP
            printf("EXCEPTION_SINGLE_STEP")
        CASE EXCEPTION_ARRAY_BOUNDS_EXCEEDED
            printf("EXCEPTION_ARRAY_BOUNDS_EXCEEDED")
        CASE EXCEPTION_FLT_DENORMAL_OPERAND
            printf("EXCEPTION_FLT_DENORMAL_OPERAND")
        CASE EXCEPTION_FLT_DIVIDE_BY_ZERO
            printf("EXCEPTION_FLT_DIVIDE_BY_ZERO")
        CASE EXCEPTION_FLT_INEXACT_RESULT
            printf("EXCEPTION_FLT_INEXACT_RESULT")
        CASE EXCEPTION_FLT_INVALID_OPERATION
            printf("EXCEPTION_FLT_INVALID_OPERATION")
        CASE EXCEPTION_FLT_OVERFLOW
            printf("EXCEPTION_FLT_OVERFLOW")
        CASE EXCEPTION_FLT_STACK_CHECK
            printf("EXCEPTION_FLT_STACK_CHECK")
        CASE EXCEPTION_FLT_UNDERFLOW
            printf("EXCEPTION_FLT_UNDERFLOW")
        CASE EXCEPTION_INT_DIVIDE_BY_ZERO
            printf("EXCEPTION_INT_DIVIDE_BY_ZERO")
        CASE EXCEPTION_INT_OVERFLOW
            printf("EXCEPTION_INT_OVERFLOW")
        CASE EXCEPTION_PRIV_INSTRUCTION
            printf("EXCEPTION_PRIV_INSTRUCTION")
        CASE EXCEPTION_IN_PAGE_ERROR
            printf("EXCEPTION_IN_PAGE_ERROR")
        CASE EXCEPTION_ILLEGAL_INSTRUCTION
            printf("EXCEPTION_ILLEGAL_INSTRUCTION")
        CASE EXCEPTION_NONCONTINUABLE_EXCEPTION
            printf("EXCEPTION_NONCONTINUABLE_EXCEPTION")
        CASE EXCEPTION_STACK_OVERFLOW
            printf("EXCEPTION_STACK_OVERFLOW")
        CASE EXCEPTION_INVALID_DISPOSITION
            printf("EXCEPTION_INVALID_DISPOSITION")
        CASE EXCEPTION_GUARD_PAGE
            printf("EXCEPTION_GUARD_PAGE")
        CASE EXCEPTION_INVALID_HANDLE
            printf("EXCEPTION_INVALID_HANDLE")
        DEFAULT
            printf("exception code ")
            printf("%X",[ebx].EXCEPTION_RECORD.ExceptionCode)
    ENDSW
    printf(" @ %Xh\n",[ebx].EXCEPTION_RECORD.ExceptionAddress)
    ret
ShowException endp

;==============================================================================

;---------------------------------------------------
; This procedure is our top-level exception filter.
;---------------------------------------------------

try_filter proc lpexception_pointers:LPEXCEPTION_POINTERS

    ;-------------------------------------------------------------------------
    ; Copy the entire EXCEPTION_RECORD structure (80 bytes) to global memory.
    ;-------------------------------------------------------------------------

    mov edx, lpexception_pointers
    mov ecx, [edx].EXCEPTION_POINTERS.pExceptionRecord
    mov edx, OFFSET exception_record
    DISP=0
    REPEAT (SIZEOF EXCEPTION_RECORD) / 4
        mov eax, [ecx+DISP]
        mov [edx+DISP], eax
        DISP=DISP+4
    ENDM

    ;------------------------------------------------------------------
    ; Modify the EIP member of the CONTEXT structure so execution will
    ; continue at the address passed to the try_begin macro, instead
    ; of continuing at the point of the exception (which would cause
    ; the exception to repeat).
    ;------------------------------------------------------------------

    mov edx, lpexception_pointers
    mov eax, [edx].EXCEPTION_POINTERS.ContextRecord
    push _exception_return_address_
    pop [eax].CONTEXT.regEip

    invoke ShowException, ADDR exception_record

    ;------------------------------------------------------------------------
    ; Returning EXCEPTION_CONTINUE_EXECUTION to the UnhandledExceptionFilter
    ; function will cause it to return and continue execution from the point
    ; specified in the EIP member of the CONTEXT structure.
    ;------------------------------------------------------------------------

    return EXCEPTION_CONTINUE_EXECUTION

try_filter endp

;==============================================================================


;==============================================================================
include \masm32\include\masm32rt.inc
.686
include try.asm
;==============================================================================
.data
.code
;==============================================================================
start:
;==============================================================================

    ;--------------------------------------------------------------
    ; The try_ labels and the printf statements were added here to
    ; to verify that ExceptionAddress is being reported correctly,
    ; and the error handlers were placed inline as a convenience.
    ;--------------------------------------------------------------


    try_begin eh0
  try0:
    int 3
  eh0:
    printf("%Xh\n",try0)
  @@:
    try_end

    try_begin eh1
    mov ecx, 1
    mov edx, 10
  try1:
    div ecx
    jmp @F
  eh1:
    printf("%Xh\n",try1)
  @@:
    try_end

    try_begin eh2
    xor ecx, ecx
  try2:
    div ecx
    jmp @F
  eh2:
    printf("%Xh\n",try2)
  @@:
    try_end

    try_begin eh3
  try3:
    mov cr0, eax
    div ecx
    jmp @F
  eh3:
    printf("%Xh\n",try3)
  @@:
    try_end

    try_begin eh4
    xor eax, eax
  try4:
    mov DWORD PTR [eax], 1
    jmp @F
  eh4:
    printf("%Xh\n\n",try4)
  @@:
    try_end

    inkey
    exit
;==============================================================================
end start

Well Microsoft, here's another nice mess you've gotten us into.

Antariy

Michael, I guess the C example you provided is "not working on Win7" just because it has some incompatibility with modern VC compilers that use many default flags which were not available at 1997, so it is not the flaws of the example/code but the build environemnt assumptions (LINK.EXE likes to make a choice instead of a programmer :biggrin:).

jj2007

Quote from: Antariy on December 03, 2012, 01:12:51 PM
Michael, I guess the C example you provided is "not working on Win7" just because it has some incompatibility with modern VC compilers that use many default flags which were not available at 1997, so it is not the flaws of the example/code but the build environemnt assumptions (LINK.EXE likes to make a choice instead of a programmer :biggrin:).

There are two SEH examples in the MasmBasic library (using plain old techniques) at
\Masm32\RichMasm\RES\SkelTryCatchDetailed.asc
\Masm32\RichMasm\RES\SkelTryCatch.asc
They both work fine on Win7-32 and Win7-64, with no particular linker settings, and tested with both polink and the old linker that comes with Masm32. So apparently, the problem is not Win7.

Gunther

Yes, Alex is right.

Good to see you back here, Alex.  :t

Gunther
You have to know the facts before you can distort them.

Antariy


Gunther

Alex, you're always welcome.

Gunther
You have to know the facts before you can distort them.

dedndave

yes - good to see you, Alex   :t
i had forgotten about your SEH macros   :P