diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-02-16 13:44:54 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-02-16 13:44:54 +0100 |
| commit | 65f75b0cc0ead29db622afc790b6167c476e4960 (patch) | |
| tree | f4a2ab63e4f12ba67995a25c029468807d5e83fe /src | |
| parent | c50b0ef9e8342b634af873134a52ec3b7b889f42 (diff) | |
| download | box64-65f75b0cc0ead29db622afc790b6167c476e4960.tar.gz box64-65f75b0cc0ead29db622afc790b6167c476e4960.zip | |
[ELFLOADER] Better handling of STB_GNU_UNIQUE binded symbol (prevent dlclose)
Diffstat (limited to 'src')
| -rw-r--r-- | src/elfs/elfloader.c | 15 | ||||
| -rw-r--r-- | src/elfs/elfloader_private.h | 1 | ||||
| -rw-r--r-- | src/wrapped/wrappedlibdl.c | 6 |
3 files changed, 21 insertions, 1 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index 9f01f75b..f68658d7 100644 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -499,6 +499,21 @@ void GrabX64CopyMainElfReloc(elfheader_t* head) } } } +void CheckGNUUniqueBindings(elfheader_t* head) +{ + if(head->rela) { + int cnt = head->relasz / head->relaent; + Elf64_Rela* rela = (Elf64_Rela *)(head->rela + head->delta); + printf_dump(LOG_DEBUG, "Checking for symbol with STB_GNU_UNIQUE bindingsfor %s\n", head->name); + for (int i=0; i<cnt; ++i) { + int bind = ELF64_ST_BIND(rela[i].r_info); + if(bind == STB_GNU_UNIQUE) { + head->gnuunique = 1; + return; // can stop searching + } + } + } +} static elfheader_t* checkElfLib(elfheader_t* h, library_t* lib) { diff --git a/src/elfs/elfloader_private.h b/src/elfs/elfloader_private.h index 4487e972..91b3b510 100644 --- a/src/elfs/elfloader_private.h +++ b/src/elfs/elfloader_private.h @@ -102,6 +102,7 @@ typedef struct elfheader_s { int fini_done; int refcnt; // ref count for the elf int malloc_hook_2; // this elf hook malloc, hacking it + int gnuunique; // set if contains some STB_GNU_UNIQUE binding, preventing dlclose to unload the lib char* memory; // char* and not void* to allow math on memory pointer multiblock_t* multiblocks; diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c index f85b007d..b781b9cb 100644 --- a/src/wrapped/wrappedlibdl.c +++ b/src/wrapped/wrappedlibdl.c @@ -386,6 +386,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) pthread_mutex_unlock(&mutex); return (void*)start; } +static int actualy_closing = 0; int my_dlclose(x64emu_t* emu, void *handle) { (void)emu; @@ -410,7 +411,9 @@ int my_dlclose(x64emu_t* emu, void *handle) return -1; } --dl->dllibs[nlib].count; - DecRefCount(&dl->dllibs[nlib].lib, emu); + elfheader_t* h = GetElf(dl->dllibs[nlib].lib); + if(!h || !h->gnuunique || actualy_closing) + DecRefCount(&dl->dllibs[nlib].lib, emu); return 0; } #ifdef ANDROID @@ -597,6 +600,7 @@ EXPORT int my__dl_find_object(x64emu_t* emu, void* addr, my_dl_find_object_t* re void closeAllDLOpenned() { dlprivate_t *dl = my_context->dlprivate; + actualy_closing = 1; if(dl) { x64emu_t* emu = thread_get_emu(); for(size_t i=0; i<dl->lib_sz; ++i) |