From f6e349f0330c3876ede6823c0be6eb2ed9b542ff Mon Sep 17 00:00:00 2001 From: jp9000 Date: Wed, 27 Jul 2022 20:20:58 -0700 Subject: [PATCH] libobs/util: Put module load detection in its own func Puts the detection of obs_module_load in Windows DLLs for the "is this an obs plugin" check into its own function --- libobs/util/platform-windows.c | 136 ++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 62 deletions(-) diff --git a/libobs/util/platform-windows.c b/libobs/util/platform-windows.c index c2078e5cb..54a4a1356 100644 --- a/libobs/util/platform-windows.c +++ b/libobs/util/platform-windows.c @@ -136,6 +136,79 @@ void os_dlclose(void *module) FreeLibrary(module); } +static bool has_obs_export(VOID *base, PIMAGE_NT_HEADERS nt_headers) +{ + __try { + PIMAGE_DATA_DIRECTORY data_dir; + data_dir = + &nt_headers->OptionalHeader + .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; + + if (data_dir->Size == 0) + return false; + + PIMAGE_SECTION_HEADER section, last_section; + section = IMAGE_FIRST_SECTION(nt_headers); + last_section = section; + + /* find the section that contains the export directory */ + int i; + for (i = 0; i < nt_headers->FileHeader.NumberOfSections; i++) { + if (section->VirtualAddress <= + data_dir->VirtualAddress) { + last_section = section; + section++; + continue; + } else { + break; + } + } + + /* double check in case we exited early */ + if (last_section->VirtualAddress > data_dir->VirtualAddress || + section->VirtualAddress <= data_dir->VirtualAddress) + return false; + + section = last_section; + + /* get a pointer to the export directory */ + PIMAGE_EXPORT_DIRECTORY export; + export = (PIMAGE_EXPORT_DIRECTORY)((byte *)base + + data_dir->VirtualAddress - + section->VirtualAddress + + section->PointerToRawData); + + if (export->NumberOfNames == 0) + return false; + + /* get a pointer to the export directory names */ + DWORD *names_ptr; + names_ptr = (DWORD *)((byte *)base + export->AddressOfNames - + section->VirtualAddress + + section->PointerToRawData); + + /* iterate through each name and see if its an obs plugin */ + CHAR *name; + size_t j; + for (j = 0; j < export->NumberOfNames; j++) { + + name = (CHAR *)base + names_ptr[j] - + section->VirtualAddress + + section->PointerToRawData; + + if (!strcmp(name, "obs_module_load")) { + return true; + } + } + } __except (EXCEPTION_EXECUTE_HANDLER) { + /* we failed somehow, for compatibility let's assume it + * was a valid plugin and let the loader deal with it */ + return true; + } + + return false; +} + bool os_is_obs_plugin(const char *path) { struct dstr dll_name; @@ -147,7 +220,6 @@ bool os_is_obs_plugin(const char *path) PIMAGE_DOS_HEADER dos_header; PIMAGE_NT_HEADERS nt_headers; - PIMAGE_SECTION_HEADER section, last_section; bool ret = false; @@ -193,67 +265,7 @@ bool os_is_obs_plugin(const char *path) if (nt_headers->Signature != IMAGE_NT_SIGNATURE) goto cleanup; - PIMAGE_DATA_DIRECTORY data_dir; - data_dir = - &nt_headers->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; - - if (data_dir->Size == 0) - goto cleanup; - - section = IMAGE_FIRST_SECTION(nt_headers); - last_section = section; - - /* find the section that contains the export directory */ - int i; - for (i = 0; i < nt_headers->FileHeader.NumberOfSections; i++) { - if (section->VirtualAddress <= - data_dir->VirtualAddress) { - last_section = section; - section++; - continue; - } else { - break; - } - } - - /* double check in case we exited early */ - if (last_section->VirtualAddress > data_dir->VirtualAddress || - section->VirtualAddress <= data_dir->VirtualAddress) - goto cleanup; - - section = last_section; - - /* get a pointer to the export directory */ - PIMAGE_EXPORT_DIRECTORY export; - export = (PIMAGE_EXPORT_DIRECTORY)((byte *)base + - data_dir->VirtualAddress - - section->VirtualAddress + - section->PointerToRawData); - - if (export->NumberOfNames == 0) - goto cleanup; - - /* get a pointer to the export directory names */ - DWORD *names_ptr; - names_ptr = (DWORD *)((byte *)base + export->AddressOfNames - - section->VirtualAddress + - section->PointerToRawData); - - /* iterate through each name and see if its an obs plugin */ - CHAR *name; - size_t j; - for (j = 0; j < export->NumberOfNames; j++) { - - name = (CHAR *)base + names_ptr[j] - - section->VirtualAddress + - section->PointerToRawData; - - if (!strcmp(name, "obs_module_load")) { - ret = true; - goto cleanup; - } - } + ret = has_obs_export(base, nt_headers); } __except (EXCEPTION_EXECUTE_HANDLER) { /* we failed somehow, for compatibility let's assume it