Skip to content

Commit f898376

Browse files
committed
Fix exception handling registration.
- Only compile on 64bit, 32bit exception handling works differently. - Unregister table when module is unloaded. - Handle empty tables. - Fix wrong number of entries being passed to "RtlAddFunctionTable".
1 parent 18ace52 commit f898376

1 file changed

Lines changed: 36 additions & 4 deletions

File tree

MemoryModule.c

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -438,10 +438,39 @@ PerformBaseRelocation(PMEMORYMODULE module, ptrdiff_t delta)
438438
static BOOL
439439
RegisterExceptionHandling(PMEMORYMODULE module)
440440
{
441-
PIMAGE_DATA_DIRECTORY pDir = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_EXCEPTION);
442-
PIMAGE_RUNTIME_FUNCTION_ENTRY pEntry = (PIMAGE_RUNTIME_FUNCTION_ENTRY)(module->codeBase + pDir->VirtualAddress);
443-
UINT count = (pDir->Size / sizeof(IMAGE_RUNTIME_FUNCTION_ENTRY)) - 1;
444-
return RtlAddFunctionTable(pEntry, count, (DWORD64)module->codeBase);
441+
#ifdef _WIN64
442+
PRUNTIME_FUNCTION pEntry;
443+
DWORD count;
444+
PIMAGE_DATA_DIRECTORY pDir = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_EXCEPTION);
445+
if (pDir->Size == 0) {
446+
return TRUE;
447+
}
448+
449+
pEntry = (PRUNTIME_FUNCTION)(module->codeBase + pDir->VirtualAddress);
450+
count = (pDir->Size / sizeof(RUNTIME_FUNCTION));
451+
return RtlAddFunctionTable(pEntry, count, (DWORD64) module->codeBase);
452+
#else
453+
// TODO(fancycode): Support 32bit exception handling.
454+
return TRUE;
455+
#endif
456+
}
457+
458+
static BOOL
459+
UnregisterExceptionHandling(PMEMORYMODULE module)
460+
{
461+
#ifdef _WIN64
462+
PRUNTIME_FUNCTION pEntry;
463+
PIMAGE_DATA_DIRECTORY pDir = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_EXCEPTION);
464+
if (pDir->Size == 0) {
465+
return TRUE;
466+
}
467+
468+
pEntry = (PRUNTIME_FUNCTION)(module->codeBase + pDir->VirtualAddress);
469+
return RtlDeleteFunctionTable(pEntry);
470+
#else
471+
// TODO(fancycode): Support 32bit exception handling.
472+
return TRUE;
473+
#endif
445474
}
446475

447476
static BOOL
@@ -734,6 +763,7 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
734763
goto error;
735764
}
736765

766+
// register exception handling table so "try { } catch ( ) { }"" works
737767
if (!RegisterExceptionHandling(result)) {
738768
goto error;
739769
}
@@ -880,6 +910,8 @@ void MemoryFreeLibrary(HMEMORYMODULE mod)
880910
(*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0);
881911
}
882912

913+
UnregisterExceptionHandling(module);
914+
883915
free(module->nameExportsTable);
884916
if (module->modules != NULL) {
885917
// free previously opened libraries

0 commit comments

Comments
 (0)