Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom SEH handler with /SAFESEH

I am currently trying to create a compiler in C++, which generates machine code at run time. However, I am currently trying to enable safe exception handling (compiling with /SAFESEH). My custom exception handler is working in the debug mode, but when I run the same code in release mode, my process is just terminated.

I am quite certain the problem is that I fail to register my custom exception handler as such, because when I compile my code with /SAFESEH:NO, everything works fine even in release mode.

My custom exception handler is written in my other C++-code, and I have tried to register it as an exception handler by adding a .asm-file to my project with the content:

.386
.model flat
_MyExceptionHandler@16 proto
.safeseh _MyExceptionHandler@16
end

as described here. The asm-file was then assembled with the /safeseh option (among others).

My handler function currently has the following declaration:

extern "C" EXCEPTION_DISPOSITION __stdcall MyExceptionHandler(struct
_EXCEPTION_RECORD *ExceptionRecord, void * EstablisherFrame, struct 
_CONTEXT *ContextRecord, void * DispatcherContext);

What would the correct way to register this function as an exception handler be?

Thanks for any suggestions!

like image 753
Filip Avatar asked Aug 18 '12 15:08

Filip


1 Answers

I finally found a page describing the problem: here. However, the code sample in the page did not work without modification.

The problem seems to be that registering external procedures as exception handler does not work as intended, so you have to register a local assembly procedure as an exception handler instead.

Based on the example given on the previously mentioned page, this is what I ended up with:

.386
.model flat, stdcall
option casemap :none

extern MyExceptionHandler@16:near

MyExceptionHandlerAsm proto
.SAFESEH MyExceptionHandlerAsm

.code
MyExceptionHandlerAsm proc
    jmp MyExceptionHandler@16
MyExceptionHandlerAsm endp
end

This seems to work, but it is most probably not the most elegant solution. For example: to avoid linking errors when referencing MyExceptionHandlerAsm from C/C++, I had to declare it as:

extern "C" int __stdcall MyExceptionHandlerAsm();

Which would crash if anyone tried to call MyExceptionHandlerAsm from C/C++, since the number of parameters does not match the ones of MyExceptionHandler.

like image 168
Filip Avatar answered Sep 28 '22 04:09

Filip