diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-03 17:32:24 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-03 17:32:24 +0100 |
| commit | be17349a5d8e2ea323a793384b43653e3e9c22a6 (patch) | |
| tree | 4b856b728da01c04f6d822887a2ce1e602730b1f /src | |
| parent | 9aabe9c97fecb77f70361e0e0df8380f1489fc81 (diff) | |
| download | box64-be17349a5d8e2ea323a793384b43653e3e9c22a6.tar.gz box64-be17349a5d8e2ea323a793384b43653e3e9c22a6.zip | |
Added some X86_64 RelocA and a few wrapped function (wrapper still not correct anyway)
Diffstat (limited to 'src')
| -rwxr-xr-x | src/elfs/elfloader.c | 32 | ||||
| -rwxr-xr-x | src/emu/x64emu.c | 50 | ||||
| -rwxr-xr-x | src/main.c | 7 | ||||
| -rw-r--r-- | src/wrapped/generated/functions_list.txt | 4 | ||||
| -rw-r--r-- | src/wrapped/generated/wrapper.c | 8 | ||||
| -rw-r--r-- | src/wrapped/generated/wrapper.h | 4 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibc.c | 8 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibc_private.h | 8 |
8 files changed, 89 insertions, 32 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index bf90c9e1..6c30018e 100755 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -520,15 +520,22 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int c { for (int i=0; i<cnt; ++i) { Elf64_Sym *sym = &head->DynSym[ELF64_R_SYM(rela[i].r_info)]; + int bind = ELF64_ST_BIND(sym->st_info); const char* symname = SymName(head, sym); - uint32_t *p = (uint32_t*)(rela[i].r_offset + head->delta); + uint64_t *p = (uint64_t*)(rela[i].r_offset + head->delta); uintptr_t offs = 0; uintptr_t end = 0; + uintptr_t globoffs, globend; + uint64_t* globp; switch(ELF64_R_TYPE(rela[i].r_info)) { case R_X86_64_NONE: case R_X86_64_PC32: // can be ignored break; + case R_X86_64_RELATIVE: + printf_log(LOG_DUMP, "Apply %s R_X86_64_RELATIVE @%p (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, *(void**)p, (void*)((*p)+head->delta)); + *p += head->delta; + break; case R_X86_64_COPY: if(local_maplib) GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head); @@ -542,6 +549,29 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int c printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply RELA R_X86_64_COPY @%p (%p) in %s\n", symname, p, *(void**)p, head->name); } break; + case R_X86_64_GLOB_DAT: + if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp)) { + // set global offs / size for the symbol + offs = sym->st_value + head->delta; + end = offs + sym->st_size; + printf_log(LOG_DUMP, "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, (void*)globoffs, sym->st_size, symname); + *p = globoffs + rela[i].r_addend; + AddWeakSymbol(GetGlobalData(maplib), symname, offs, end-offs+1); + } else { + // Look for same symbol already loaded but not in self (so no need for local_maplib here) + if (GetGlobalNoWeakSymbolStartEnd(maplib, symname, &globoffs, &globend)) { + offs = globoffs; + end = globend; + } + if (!offs) { + if(strcmp(symname, "__gmon_start__")) + printf_log(LOG_NONE, "Error: Global Symbol %s not found, cannot apply R_X86_64_GLOB_DAT @%p (%p) in %s\n", symname, p, *(void**)p, head->name); + } else { + printf_log(LOG_DUMP, "Apply %s R_X86_64_GLOB_DAT @%p (%p -> %p) on sym=%s\n", (bind==STB_LOCAL)?"Local":"Global", p, (void*)(p?(*p):0), (void*)offs, symname); + *p = offs + rela[i].r_addend; + } + } + break; default: printf_log(LOG_INFO, "Warning, don't know of to handle rela #%d %s on %s\n", i, DumpRelType(ELF64_R_TYPE(rela[i].r_info)), symname); } diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index ea3cc138..b501334d 100755 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -143,32 +143,32 @@ void AddCleanup1Arg(x64emu_t *emu, void *p, void* a) my_context->cleanups[my_context->clean_sz++].f = p; } -//void CallCleanup(x64emu_t *emu, void* p) -//{ -// printf_log(LOG_DEBUG, "Calling atexit registered functions for %p mask\n", p); -// for(int i=my_context->clean_sz-1; i>=0; --i) { -// if(p==my_context->cleanups[i].f) { -// printf_log(LOG_DEBUG, "Call cleanup #%d\n", i); -// RunFunctionWithEmu(emu, 0, (uintptr_t)(my_context->cleanups[i].f), my_context->cleanups[i].arg, my_context->cleanups[i].a ); -// // now remove the cleanup -// if(i!=my_context->clean_sz-1) -// memmove(my_context->cleanups+i, my_context->cleanups+i+1, (my_context->clean_sz-i-1)*sizeof(cleanup_t)); -// --my_context->clean_sz; -// } -// } -//} +void CallCleanup(x64emu_t *emu, void* p) +{ + printf_log(LOG_DEBUG, "Calling atexit registered functions for %p mask\n", p); + for(int i=my_context->clean_sz-1; i>=0; --i) { + if(p==my_context->cleanups[i].f) { + printf_log(LOG_DEBUG, "Call cleanup #%d\n", i); + RunFunctionWithEmu(emu, 0, (uintptr_t)(my_context->cleanups[i].f), my_context->cleanups[i].arg, my_context->cleanups[i].a ); + // now remove the cleanup + if(i!=my_context->clean_sz-1) + memmove(my_context->cleanups+i, my_context->cleanups+i+1, (my_context->clean_sz-i-1)*sizeof(cleanup_t)); + --my_context->clean_sz; + } + } +} -//void CallAllCleanup(x64emu_t *emu) -//{ -// printf_log(LOG_DEBUG, "Calling atexit registered functions\n"); -// for(int i=my_context->clean_sz-1; i>=0; --i) { -// printf_log(LOG_DEBUG, "Call cleanup #%d\n", i); -// RunFunctionWithEmu(emu, 0, (uintptr_t)(my_context->cleanups[i].f), my_context->cleanups[i].arg, my_context->cleanups[i].a ); -// } -// my_context->clean_sz = 0; -// free(my_context->cleanups); -// my_context->cleanups = NULL; -//} +void CallAllCleanup(x64emu_t *emu) +{ + printf_log(LOG_DEBUG, "Calling atexit registered functions\n"); + for(int i=my_context->clean_sz-1; i>=0; --i) { + printf_log(LOG_DEBUG, "Call cleanup #%d\n", i); + RunFunctionWithEmu(emu, 0, (uintptr_t)(my_context->cleanups[i].f), my_context->cleanups[i].arg, my_context->cleanups[i].a ); + } + my_context->clean_sz = 0; + free(my_context->cleanups); + my_context->cleanups = NULL; +} static void internalFreeX64(x64emu_t* emu) { diff --git a/src/main.c b/src/main.c index b67b9789..8495aca5 100755 --- a/src/main.c +++ b/src/main.c @@ -864,6 +864,13 @@ int main(int argc, const char **argv, const char **env) { FreeBox64Context(&my_context); return -1; } + // reloc... + printf_log(LOG_DEBUG, "And now export symbols / relocation for %s...\n", ElfName(elf_header)); + if(RelocateElf(my_context->maplib, NULL, elf_header)) { + printf_log(LOG_NONE, "Error: relocating symbols in elf %s\n", my_context->argv[0]); + FreeBox64Context(&my_context); + return -1; + } return 0; } diff --git a/src/wrapped/generated/functions_list.txt b/src/wrapped/generated/functions_list.txt index 357ab0bd..69ac3d89 100644 --- a/src/wrapped/generated/functions_list.txt +++ b/src/wrapped/generated/functions_list.txt @@ -5,15 +5,18 @@ #() lFp #() pFE #() pFp +#() vFEp #() vFpp #() iFEp #() iFip #() iFup #() pFEp +#() vFEpu #() iFEpp #() iFpiu #() pFEpi #() pFEpp +#() vFEpup #() iFEupp #() iFEpip #() iFEppp @@ -21,4 +24,5 @@ #() pFEppi #() pFEppp #() iFipppi +#() iFEpippppp #() pFEv -> pFE diff --git a/src/wrapped/generated/wrapper.c b/src/wrapped/generated/wrapper.c index 1b34a0d7..d24d62c8 100644 --- a/src/wrapped/generated/wrapper.c +++ b/src/wrapped/generated/wrapper.c @@ -76,15 +76,18 @@ typedef int32_t (*iFp_t)(void*); typedef intptr_t (*lFp_t)(void*); typedef void* (*pFE_t)(x64emu_t*); typedef void* (*pFp_t)(void*); +typedef void (*vFEp_t)(x64emu_t*, void*); typedef void (*vFpp_t)(void*, void*); typedef int32_t (*iFEp_t)(x64emu_t*, void*); typedef int32_t (*iFip_t)(int32_t, void*); typedef int32_t (*iFup_t)(uint32_t, void*); typedef void* (*pFEp_t)(x64emu_t*, void*); +typedef void (*vFEpu_t)(x64emu_t*, void*, uint32_t); typedef int32_t (*iFEpp_t)(x64emu_t*, void*, void*); typedef int32_t (*iFpiu_t)(void*, int32_t, uint32_t); typedef void* (*pFEpi_t)(x64emu_t*, void*, int32_t); typedef void* (*pFEpp_t)(x64emu_t*, void*, void*); +typedef void (*vFEpup_t)(x64emu_t*, void*, uint32_t, void*); typedef int32_t (*iFEupp_t)(x64emu_t*, uint32_t, void*, void*); typedef int32_t (*iFEpip_t)(x64emu_t*, void*, int32_t, void*); typedef int32_t (*iFEppp_t)(x64emu_t*, void*, void*, void*); @@ -92,6 +95,7 @@ typedef int32_t (*iFuipp_t)(uint32_t, int32_t, void*, void*); typedef void* (*pFEppi_t)(x64emu_t*, void*, void*, int32_t); typedef void* (*pFEppp_t)(x64emu_t*, void*, void*, void*); typedef int32_t (*iFipppi_t)(int32_t, void*, void*, void*, int32_t); +typedef int32_t (*iFEpippppp_t)(x64emu_t*, void*, int32_t, void*, void*, void*, void*, void*); void vFE(x64emu_t *emu, uintptr_t fcn) { vFE_t fn = (vFE_t)fcn; fn(emu); } void vFv(x64emu_t *emu, uintptr_t fcn) { vFv_t fn = (vFv_t)fcn; fn(); } @@ -100,15 +104,18 @@ void iFp(x64emu_t *emu, uintptr_t fcn) { iFp_t fn = (iFp_t)fcn; R_RAX=fn(*(void* void lFp(x64emu_t *emu, uintptr_t fcn) { lFp_t fn = (lFp_t)fcn; R_RAX=(intptr_t)fn(*(void**)(R_RSP + 4)); } void pFE(x64emu_t *emu, uintptr_t fcn) { pFE_t fn = (pFE_t)fcn; R_RAX=(uintptr_t)fn(emu); } void pFp(x64emu_t *emu, uintptr_t fcn) { pFp_t fn = (pFp_t)fcn; R_RAX=(uintptr_t)fn(*(void**)(R_RSP + 4)); } +void vFEp(x64emu_t *emu, uintptr_t fcn) { vFEp_t fn = (vFEp_t)fcn; fn(emu, *(void**)(R_RSP + 4)); } void vFpp(x64emu_t *emu, uintptr_t fcn) { vFpp_t fn = (vFpp_t)fcn; fn(*(void**)(R_RSP + 4), *(void**)(R_RSP + 12)); } void iFEp(x64emu_t *emu, uintptr_t fcn) { iFEp_t fn = (iFEp_t)fcn; R_RAX=fn(emu, *(void**)(R_RSP + 4)); } void iFip(x64emu_t *emu, uintptr_t fcn) { iFip_t fn = (iFip_t)fcn; R_RAX=fn(*(int32_t*)(R_RSP + 4), *(void**)(R_RSP + 8)); } void iFup(x64emu_t *emu, uintptr_t fcn) { iFup_t fn = (iFup_t)fcn; R_RAX=fn(*(uint32_t*)(R_RSP + 4), *(void**)(R_RSP + 8)); } void pFEp(x64emu_t *emu, uintptr_t fcn) { pFEp_t fn = (pFEp_t)fcn; R_RAX=(uintptr_t)fn(emu, *(void**)(R_RSP + 4)); } +void vFEpu(x64emu_t *emu, uintptr_t fcn) { vFEpu_t fn = (vFEpu_t)fcn; fn(emu, *(void**)(R_RSP + 4), *(uint32_t*)(R_RSP + 12)); } void iFEpp(x64emu_t *emu, uintptr_t fcn) { iFEpp_t fn = (iFEpp_t)fcn; R_RAX=fn(emu, *(void**)(R_RSP + 4), *(void**)(R_RSP + 12)); } void iFpiu(x64emu_t *emu, uintptr_t fcn) { iFpiu_t fn = (iFpiu_t)fcn; R_RAX=fn(*(void**)(R_RSP + 4), *(int32_t*)(R_RSP + 12), *(uint32_t*)(R_RSP + 16)); } void pFEpi(x64emu_t *emu, uintptr_t fcn) { pFEpi_t fn = (pFEpi_t)fcn; R_RAX=(uintptr_t)fn(emu, *(void**)(R_RSP + 4), *(int32_t*)(R_RSP + 12)); } void pFEpp(x64emu_t *emu, uintptr_t fcn) { pFEpp_t fn = (pFEpp_t)fcn; R_RAX=(uintptr_t)fn(emu, *(void**)(R_RSP + 4), *(void**)(R_RSP + 12)); } +void vFEpup(x64emu_t *emu, uintptr_t fcn) { vFEpup_t fn = (vFEpup_t)fcn; fn(emu, *(void**)(R_RSP + 4), *(uint32_t*)(R_RSP + 12), *(void**)(R_RSP + 16)); } void iFEupp(x64emu_t *emu, uintptr_t fcn) { iFEupp_t fn = (iFEupp_t)fcn; R_RAX=fn(emu, *(uint32_t*)(R_RSP + 4), *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); } void iFEpip(x64emu_t *emu, uintptr_t fcn) { iFEpip_t fn = (iFEpip_t)fcn; R_RAX=fn(emu, *(void**)(R_RSP + 4), *(int32_t*)(R_RSP + 12), *(void**)(R_RSP + 16)); } void iFEppp(x64emu_t *emu, uintptr_t fcn) { iFEppp_t fn = (iFEppp_t)fcn; R_RAX=fn(emu, *(void**)(R_RSP + 4), *(void**)(R_RSP + 12), *(void**)(R_RSP + 20)); } @@ -116,5 +123,6 @@ void iFuipp(x64emu_t *emu, uintptr_t fcn) { iFuipp_t fn = (iFuipp_t)fcn; R_RAX=f void pFEppi(x64emu_t *emu, uintptr_t fcn) { pFEppi_t fn = (pFEppi_t)fcn; R_RAX=(uintptr_t)fn(emu, *(void**)(R_RSP + 4), *(void**)(R_RSP + 12), *(int32_t*)(R_RSP + 20)); } void pFEppp(x64emu_t *emu, uintptr_t fcn) { pFEppp_t fn = (pFEppp_t)fcn; R_RAX=(uintptr_t)fn(emu, *(void**)(R_RSP + 4), *(void**)(R_RSP + 12), *(void**)(R_RSP + 20)); } void iFipppi(x64emu_t *emu, uintptr_t fcn) { iFipppi_t fn = (iFipppi_t)fcn; R_RAX=fn(*(int32_t*)(R_RSP + 4), *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(int32_t*)(R_RSP + 32)); } +void iFEpippppp(x64emu_t *emu, uintptr_t fcn) { iFEpippppp_t fn = (iFEpippppp_t)fcn; R_RAX=fn(emu, *(void**)(R_RSP + 4), *(int32_t*)(R_RSP + 12), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48)); } void pFEv(x64emu_t *emu, uintptr_t fcn) { pFE_t fn = (pFE_t)fcn; R_RAX=(uintptr_t)fn(emu); } diff --git a/src/wrapped/generated/wrapper.h b/src/wrapped/generated/wrapper.h index 4700b365..6feb7f67 100644 --- a/src/wrapped/generated/wrapper.h +++ b/src/wrapped/generated/wrapper.h @@ -37,15 +37,18 @@ void iFp(x64emu_t *emu, uintptr_t fnc); void lFp(x64emu_t *emu, uintptr_t fnc); void pFE(x64emu_t *emu, uintptr_t fnc); void pFp(x64emu_t *emu, uintptr_t fnc); +void vFEp(x64emu_t *emu, uintptr_t fnc); void vFpp(x64emu_t *emu, uintptr_t fnc); void iFEp(x64emu_t *emu, uintptr_t fnc); void iFip(x64emu_t *emu, uintptr_t fnc); void iFup(x64emu_t *emu, uintptr_t fnc); void pFEp(x64emu_t *emu, uintptr_t fnc); +void vFEpu(x64emu_t *emu, uintptr_t fnc); void iFEpp(x64emu_t *emu, uintptr_t fnc); void iFpiu(x64emu_t *emu, uintptr_t fnc); void pFEpi(x64emu_t *emu, uintptr_t fnc); void pFEpp(x64emu_t *emu, uintptr_t fnc); +void vFEpup(x64emu_t *emu, uintptr_t fnc); void iFEupp(x64emu_t *emu, uintptr_t fnc); void iFEpip(x64emu_t *emu, uintptr_t fnc); void iFEppp(x64emu_t *emu, uintptr_t fnc); @@ -53,6 +56,7 @@ void iFuipp(x64emu_t *emu, uintptr_t fnc); void pFEppi(x64emu_t *emu, uintptr_t fnc); void pFEppp(x64emu_t *emu, uintptr_t fnc); void iFipppi(x64emu_t *emu, uintptr_t fnc); +void iFEpippppp(x64emu_t *emu, uintptr_t fnc); void pFEv(x64emu_t *emu, uintptr_t fnc); diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index dce09009..dbd79dcc 100755 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -393,7 +393,7 @@ void EXPORT my___gmon_start__(x64emu_t *emu) { printf_log(LOG_DEBUG, "__gmon_start__ called (dummy call)\n"); } -#if 0 + int EXPORT my___cxa_atexit(x64emu_t* emu, void* p, void* a, void* d) { AddCleanup1Arg(emu, p, a); @@ -413,7 +413,7 @@ int EXPORT my_atexit(x64emu_t* emu, void *p) AddCleanup(emu, p); return 0; } - +#if 0 int my_getcontext(x64emu_t* emu, void* ucp); int my_setcontext(x64emu_t* emu, void* ucp); int my_makecontext(x64emu_t* emu, void* ucp, void* fnc, int32_t argc, void* argv); @@ -935,7 +935,7 @@ EXPORT int my_swprintf(x64emu_t* emu, void* s, uint32_t n, void* fmt, void *b) return r; #endif } - +#endif EXPORT void my__ITM_addUserCommitAction(x64emu_t* emu, void* cb, uint32_t b, void* c) { // disabled for now... Are all this _ITM_ stuff really mendatory? @@ -952,7 +952,7 @@ EXPORT void my__ITM_addUserCommitAction(x64emu_t* emu, void* cb, uint32_t b, voi EXPORT void my__ITM_registerTMCloneTable(x64emu_t* emu, void* p, uint32_t s) {} EXPORT void my__ITM_deregisterTMCloneTable(x64emu_t* emu, void* p) {} - +#if 0 struct i386_stat { uint64_t st_dev; uint32_t __pad1; diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h index 4efac07b..bdeddf0d 100755 --- a/src/wrapped/wrappedlibc_private.h +++ b/src/wrapped/wrappedlibc_private.h @@ -178,7 +178,7 @@ //GO(cuserid, //GO(__cxa_atexit, //GO(__cxa_at_quick_exit, -//GO(__cxa_finalize, +GOM(__cxa_finalize, vFEp) //GO(__cxa_thread_atexit_impl, //GO(__cyg_profile_func_enter, //GO(__cyg_profile_func_exit, @@ -1049,7 +1049,7 @@ //GO(__libc_scratch_buffer_set_array_size, //GOW(__libc_secure_getenv, //GO(__libc_siglongjmp, -//GO(__libc_start_main, +GOM(__libc_start_main, iFEpippppp) //GO(__libc_system, //GO(__libc_thread_freeres, //GO(__libc_valloc, @@ -2234,5 +2234,9 @@ GOW(tzset, vFv) //GO(__xstat, //GO(__xstat64, +GOM(_ITM_addUserCommitAction, vFEpup) +GOM(_ITM_registerTMCloneTable, vFEpu) +GOM(_ITM_deregisterTMCloneTable, vFEp) + GOM(__register_frame_info, vFpp) // faked function GOM(__deregister_frame_info, pFp) |