From dabbca767f9de4fc4cf68252037de3061592eae2 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sun, 9 Jul 2023 12:38:48 +0200 Subject: [ELFLOADER] Added a check if lib version is compatible with what the elf loading it wants (helps Linux games on Steam) --- src/elfs/elfloader.c | 19 ++++++++++++++++++- src/elfs/elfparser.c | 52 ++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 58 insertions(+), 13 deletions(-) (limited to 'src/elfs') diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index 4caa07ce..7977b592 100755 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -374,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; ipath, vername); + return 0; // missing version + } + } + return 1; +} + int ReloadElfMemory(FILE* f, box64context_t* context, elfheader_t* head) { (void)context; @@ -1201,7 +1218,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... diff --git a/src/elfs/elfparser.c b/src/elfs/elfparser.c index 7b83e07e..1701378f 100755 --- a/src/elfs/elfparser.c +++ b/src/elfs/elfparser.c @@ -416,18 +416,6 @@ int GetVersionIndice(elfheader_t* h, const char* vername) { if(!vername) return 0; - if(h->VerNeed) { - Elf64_Verneed *ver = (Elf64_Verneed*)((uintptr_t)h->VerNeed + h->delta); - while(ver) { - Elf64_Vernaux *aux = (Elf64_Vernaux*)((uintptr_t)ver + ver->vn_aux); - for(int j=0; jvn_cnt; ++j) { - if(!strcmp(h->DynStr+aux->vna_name, vername)) - return aux->vna_other; - aux = (Elf64_Vernaux*)((uintptr_t)aux + aux->vna_next); - } - ver = ver->vn_next?((Elf64_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL; - } - } if(h->VerDef) { Elf64_Verdef *def = (Elf64_Verdef*)((uintptr_t)h->VerDef + h->delta); while(def) { @@ -438,4 +426,44 @@ int GetVersionIndice(elfheader_t* h, const char* vername) } } return 0; +} + +int GetNeededVersionCnt(elfheader_t* h, const char* libname) +{ + if(!libname) + return 0; + if(h->VerNeed) { + Elf64_Verneed *ver = (Elf64_Verneed*)((uintptr_t)h->VerNeed + h->delta); + while(ver) { + char *filename = h->DynStr + ver->vn_file; + Elf64_Vernaux *aux = (Elf64_Vernaux*)((uintptr_t)ver + ver->vn_aux); + if(!strcmp(filename, libname)) + return ver->vn_cnt; + ver = ver->vn_next?((Elf64_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL; + } + } + return 0; +} + +const char* GetNeededVersionString(elfheader_t* h, const char* libname, int idx) +{ + if(!libname) + return 0; + if(h->VerNeed) { + Elf64_Verneed *ver = (Elf64_Verneed*)((uintptr_t)h->VerNeed + h->delta); + while(ver) { + char *filename = h->DynStr + ver->vn_file; + Elf64_Vernaux *aux = (Elf64_Vernaux*)((uintptr_t)ver + ver->vn_aux); + if(!strcmp(filename, libname)) { + for(int j=0; jvn_cnt; ++j) { + if(j==idx) + return h->DynStr+aux->vna_name; + aux = (Elf64_Vernaux*)((uintptr_t)aux + aux->vna_next); + } + return NULL; // idx out of bound, return NULL... + } + ver = ver->vn_next?((Elf64_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL; + } + } + return NULL; } \ No newline at end of file -- cgit 1.4.1