diff options
Diffstat (limited to 'src/elfs/elfloader.c')
| -rw-r--r-- | src/elfs/elfloader.c | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index 37de9dc2..5a0890cf 100644 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -37,6 +37,7 @@ #include "dynablock.h" #endif #include "../emu/x64emu_private.h" +#include "../emu/x64run_private.h" #include "x64tls.h" void* my__IO_2_1_stderr_ = NULL; @@ -258,7 +259,7 @@ int AllocElfMemory(box64context_t* context, elfheader_t* head, int mainbin) } else { // vaddr is 0, load everything has a One block uintptr_t old_offs = offs; - if(!offs && box64_wine) + if(!offs /*&& box64_wine*/) offs = (uintptr_t)find47bitBlock(head->memsz); // limit to 47bits... printf_log(log_level, "Allocating 0x%zx memory @%p for Elf \"%s\"\n", head->memsz, (void*)offs, head->name); void* p = mmap((void*)offs, head->memsz @@ -373,6 +374,23 @@ int LoadElfMemory(FILE* f, box64context_t* context, elfheader_t* head) return 0; } +int isElfHasNeededVer(elfheader_t* head, const char* libname, elfheader_t* verneeded) +{ + if(!verneeded || !head) + return 1; + if(!head->VerDef || !verneeded->VerNeed) + return 1; + int cnt = GetNeededVersionCnt(verneeded, libname); + for (int i=0; i<cnt; ++i) { + const char* vername = GetNeededVersionString(verneeded, libname, i); + if(vername && !GetVersionIndice(head, vername)) { + printf_log(/*LOG_DEBUG*/LOG_INFO, "Discarding %s for missing version %s\n", head->path, vername); + return 0; // missing version + } + } + return 1; +} + int ReloadElfMemory(FILE* f, box64context_t* context, elfheader_t* head) { (void)context; @@ -502,7 +520,8 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* if(sym->st_size && offs) { printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) size=%ld on sym=%s \n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)(offs + head->delta), (void*)globoffs, sym->st_size, symname); memmove((void*)globoffs, (void*)offs, sym->st_size); // preapply to copy part from lib to main elf - AddUniqueSymbol(GetGlobalData(maplib), symname, offs + head->delta, sym->st_size, version, vername); + AddUniqueSymbol(GetGlobalData(maplib), symname, globoffs, sym->st_size, version, vername); + AddUniqueSymbol(my_context->globdata, symname, offs + head->delta, sym->st_size, version, vername); } else { printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) null sized on sym=%s \n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, symname); } @@ -527,7 +546,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* uintptr_t old_offs = offs; uintptr_t old_end = end; offs = 0; - GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, globdefver); // try globaldata symbols first + GetSizedSymbolStartEnd(my_context->globdata, symname, &offs, &end, size, version, vername, 1, globdefver); // try globaldata symbols first if(offs==0) { GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername, globdefver, weakdefver); // get original copy if any if(!offs && local_maplib) @@ -711,7 +730,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t globoffs = offs; globend = end; offs = end = 0; - GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, globdefver); // try globaldata symbols first + GetSizedSymbolStartEnd(my_context->globdata, symname, &offs, &end, size, version, vername, 1, globdefver); // try globaldata symbols first if(!offs && local_maplib) GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername, globdefver, weakdefver); if(!offs) @@ -736,7 +755,8 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, sym->st_size, symname, version, vername?vername:"(none)"); //memmove((void*)globoffs, (void*)offs, sym->st_size); // preapply to copy part from lib to main elf - AddUniqueSymbol(GetGlobalData(maplib), symname, offs, sym->st_size, version, vername); + AddUniqueSymbol(GetGlobalData(maplib), symname, globoffs, sym->st_size, version, vername); + AddUniqueSymbol(my_context->globdata, symname, offs, sym->st_size, version, vername); } else { printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) null sized on sym=%s (ver=%d/%s)\n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), @@ -890,7 +910,6 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t } return bindnow?ret_ok:0; } -void checkHookedSymbols(lib_t *maplib, elfheader_t* h); // in mallochook.c int RelocateElf(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* head) { if((head->flags&DF_BIND_NOW) && !bindnow) { @@ -911,7 +930,6 @@ int RelocateElf(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* he if(RelocateElfRELA(maplib, local_maplib, bindnow, head, cnt, (Elf64_Rela *)(head->rela + head->delta), NULL)) return -1; } - checkHookedSymbols(maplib, head); return 0; } @@ -1020,6 +1038,7 @@ uintptr_t GetLastByte(elfheader_t* h) return (uintptr_t)h->memory/* + h->delta*/ + h->memsz; } +void checkHookedSymbols(elfheader_t* h); // in mallochook.c void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* weaksymbols, kh_mapsymbols_t* localsymbols, elfheader_t* h) { if(box64_dump && h->DynSym) DumpDynSym(h); @@ -1104,6 +1123,7 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea } } } + checkHookedSymbols(h); } /* @@ -1184,9 +1204,13 @@ int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, box64c DumpDynamicNeeded(h); int cnt = 0; - for (int i=0; i<h->numDynamic; ++i) + // count the number of needed libs, and also grab soname + for (int i=0; i<h->numDynamic; ++i) { if(h->Dynamic[i].d_tag==DT_NEEDED) ++cnt; + if(h->Dynamic[i].d_tag==DT_SONAME) + h->soname = h->DynStrTab+h->delta+h->Dynamic[i].d_un.d_val; + } h->needed = new_neededlib(cnt); if(h == my_context->elfs[0]) my_context->neededlibs = h->needed; @@ -1196,7 +1220,7 @@ int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, box64c h->needed->names[j++] = h->DynStrTab+h->delta+h->Dynamic[i].d_un.d_val; // TODO: Add LD_LIBRARY_PATH and RPATH handling - if(AddNeededLib(maplib, local, bindnow, h->needed, box64, emu)) { + if(AddNeededLib(maplib, local, bindnow, h->needed, h, box64, emu)) { printf_log(LOG_INFO, "Error loading one of needed lib\n"); if(!allow_missing_libs) return 1; //error... @@ -1241,6 +1265,7 @@ void MarkElfInitDone(elfheader_t* h) if(h) h->init_done = 1; } +void startMallocHook(); void RunElfInitPltResolver(elfheader_t* h, x64emu_t *emu) { if(!h || h->init_done) @@ -1255,17 +1280,20 @@ void RunElfInitPltResolver(elfheader_t* h, x64emu_t *emu) } printf_dump(LOG_DEBUG, "Calling Init for %s @%p\n", ElfName(h), (void*)p); if(h->initentry) - RunSafeFunction(my_context, p, 3, my_context->argc, my_context->argv, my_context->envv); + RunSafeFunction(p, 3, my_context->argc, my_context->argv, my_context->envv); printf_dump(LOG_DEBUG, "Done Init for %s\n", ElfName(h)); // and check init array now Elf64_Addr *addr = (Elf64_Addr*)(h->initarray + h->delta); for (size_t i=0; i<h->initarray_sz; ++i) { if(addr[i]) { printf_dump(LOG_DEBUG, "Calling Init[%zu] for %s @%p\n", i, ElfName(h), (void*)addr[i]); - RunSafeFunction(my_context, (uintptr_t)addr[i], 3, my_context->argc, my_context->argv, my_context->envv); + RunSafeFunction((uintptr_t)addr[i], 3, my_context->argc, my_context->argv, my_context->envv); } } + if(h->malloc_hook_2) + startMallocHook(); + h->fini_done = 0; // can be fini'd now (in case it was re-inited) printf_dump(LOG_DEBUG, "All Init Done for %s\n", ElfName(h)); return; @@ -1310,6 +1338,9 @@ void RunElfInit(elfheader_t* h, x64emu_t *emu) } } + if(h->malloc_hook_2) + startMallocHook(); + h->fini_done = 0; // can be fini'd now (in case it was re-inited) printf_dump(LOG_DEBUG, "All Init Done for %s\n", ElfName(h)); return; @@ -1582,7 +1613,7 @@ static int my_dl_iterate_phdr_##A(struct dl_phdr_info* a, size_t b, void* c) return 0; \ if(!a->dlpi_name[0]) /*don't send informations about box64 itself*/ \ return 0; \ - return (int)RunFunction(my_context, my_dl_iterate_phdr_fct_##A, 3, a, b, c); \ + return (int)RunFunction(my_dl_iterate_phdr_fct_##A, 3, a, b, c); \ } SUPER() #undef GO @@ -1855,6 +1886,7 @@ EXPORT void PltResolver(x64emu_t* emu) printf_dump(LOG_DEBUG, "symbol %s from %s but elf not initialized yet, run Init now (from %s)\n", symname, ElfName(sym_elf), ElfName(h)); RunElfInitPltResolver(sym_elf, emu); } + offs = (uintptr_t)getAlternate((void*)offs); if(p) { printf_dump(LOG_DEBUG, " Apply %s R_X86_64_JUMP_SLOT %p with sym=%s(ver %d: %s%s%s) (%p -> %p / %s)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, version, symname, vername?"@":"", vername?vername:"",*(void**)p, (void*)offs, ElfName(sym_elf)); |