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
This commit is contained in:
jp9000 2022-07-27 20:20:58 -07:00
parent 4e4afcd6d1
commit f6e349f033

View file

@ -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