2929#pragma warning( disable : 4311 4312 )
3030#endif
3131
32+ #include <stdio.h>
33+
3234#include <windows.h>
3335#include <winnt.h>
3436#include <stddef.h>
4244#define IMAGE_SIZEOF_BASE_RELOCATION (sizeof(IMAGE_BASE_RELOCATION))
4345#endif
4446
47+ #ifdef _WIN64
48+ // Support for SEH is currently only available for Win64
49+ #define WITH_SEH
50+ #endif
51+
4552#include "MemoryModule.h"
4653
4754typedef BOOL (WINAPI * DllEntryProc )(HINSTANCE hinstDLL , DWORD fdwReason , LPVOID lpReserved );
@@ -55,6 +62,9 @@ typedef struct {
5562 BOOL initialized ;
5663 BOOL isDLL ;
5764 BOOL isRelocated ;
65+ #ifdef WITH_SEH
66+ BOOL hasSEH ;
67+ #endif
5868 CustomLoadLibraryFunc loadLibrary ;
5969 CustomGetProcAddressFunc getProcAddress ;
6070 CustomFreeLibraryFunc freeLibrary ;
@@ -411,6 +421,50 @@ BuildImportTable(PMEMORYMODULE module)
411421 return result ;
412422}
413423
424+ #ifdef WITH_SEH
425+
426+ static BOOL
427+ SetupSEH (PMEMORYMODULE module )
428+ {
429+ PIMAGE_RUNTIME_FUNCTION_ENTRY exceptionDesc ;
430+ unsigned char * codeBase = module -> codeBase ;
431+
432+ PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY (module , IMAGE_DIRECTORY_ENTRY_EXCEPTION );
433+ if (directory -> Size == 0 ) {
434+ return TRUE;
435+ }
436+
437+ exceptionDesc = (PIMAGE_RUNTIME_FUNCTION_ENTRY ) (codeBase + directory -> VirtualAddress );
438+ if (!RtlAddFunctionTable ((PRUNTIME_FUNCTION ) (exceptionDesc ), directory -> Size / sizeof (IMAGE_RUNTIME_FUNCTION_ENTRY ), (DWORD64 ) codeBase )) {
439+ return FALSE;
440+ }
441+
442+ module -> hasSEH = TRUE;
443+ return TRUE;
444+ }
445+
446+ static BOOL
447+ CleanupSEH (PMEMORYMODULE module )
448+ {
449+ PIMAGE_RUNTIME_FUNCTION_ENTRY exceptionDesc ;
450+ unsigned char * codeBase = module -> codeBase ;
451+
452+ PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY (module , IMAGE_DIRECTORY_ENTRY_EXCEPTION );
453+ if (directory -> Size == 0 ) {
454+ return TRUE;
455+ }
456+
457+ exceptionDesc = (PIMAGE_RUNTIME_FUNCTION_ENTRY ) (codeBase + directory -> VirtualAddress );
458+ if (!RtlDeleteFunctionTable ((PRUNTIME_FUNCTION ) (exceptionDesc ))) {
459+ return FALSE;
460+ }
461+
462+ module -> hasSEH = FALSE;
463+ return TRUE;
464+ }
465+
466+ #endif // WITH_SEH
467+
414468static HCUSTOMMODULE _LoadLibrary (LPCSTR filename , void * userdata )
415469{
416470 HMODULE result = LoadLibraryA (filename );
@@ -508,6 +562,9 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data,
508562 result -> modules = NULL ;
509563 result -> initialized = FALSE;
510564 result -> isDLL = (old_header -> FileHeader .Characteristics & IMAGE_FILE_DLL ) != 0 ;
565+ #ifdef WITH_SEH
566+ result -> hasSEH = FALSE;
567+ #endif
511568 result -> loadLibrary = loadLibrary ;
512569 result -> getProcAddress = getProcAddress ;
513570 result -> freeLibrary = freeLibrary ;
@@ -558,6 +615,12 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data,
558615 goto error ;
559616 }
560617
618+ #ifdef WITH_SEH
619+ if (!SetupSEH (result )) {
620+ goto error ;
621+ }
622+ #endif
623+
561624 // get entry point of loaded library
562625 if (result -> headers -> OptionalHeader .AddressOfEntryPoint != 0 ) {
563626 if (result -> isDLL ) {
@@ -638,6 +701,13 @@ void MemoryFreeLibrary(HMEMORYMODULE mod)
638701 if (module == NULL ) {
639702 return ;
640703 }
704+
705+ #ifdef WITH_SEH
706+ if (module -> hasSEH ) {
707+ CleanupSEH (module );
708+ }
709+ #endif
710+
641711 if (module -> initialized ) {
642712 // notify library about detaching from process
643713 DllEntryProc DllEntry = (DllEntryProc ) (module -> codeBase + module -> headers -> OptionalHeader .AddressOfEntryPoint );
0 commit comments