Skip to content

Commit f1d0537

Browse files
committed
Register function table (required for SEH support).
1 parent dc173ca commit f1d0537

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

MemoryModule.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
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>
@@ -42,6 +44,11 @@
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

4754
typedef 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+
414468
static 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

Comments
 (0)