diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2022-03-01 23:39:01 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2022-03-01 23:39:01 +0100 |
| commit | 8b1f55aff0201549279684dc3f1d59f42a8fb0d4 (patch) | |
| tree | 2c4480443e86913bd870fff033865dc2e8e38a49 /src | |
| parent | b00764d658fbf3a9068a57cfe1fe41e2283ad5cb (diff) | |
| download | box64-8b1f55aff0201549279684dc3f1d59f42a8fb0d4.tar.gz box64-8b1f55aff0201549279684dc3f1d59f42a8fb0d4.zip | |
More work on readlinkat and clone syscall
Diffstat (limited to 'src')
| -rwxr-xr-x | src/box64context.c | 3 | ||||
| -rwxr-xr-x | src/elfs/elfloader.c | 13 | ||||
| -rwxr-xr-x | src/emu/x64int3.c | 2 | ||||
| -rwxr-xr-x | src/emu/x64syscall.c | 134 | ||||
| -rwxr-xr-x | src/include/box64context.h | 2 | ||||
| -rwxr-xr-x | src/include/elfloader.h | 2 | ||||
| -rwxr-xr-x | src/main.c | 29 | ||||
| -rw-r--r-- | src/wrapped/generated/functions_list.txt | 6 | ||||
| -rw-r--r-- | src/wrapped/generated/wrappedlibctypes.h | 2 | ||||
| -rw-r--r-- | src/wrapped/generated/wrappedlibdltypes.h | 4 | ||||
| -rw-r--r-- | src/wrapped/generated/wrapper.c | 4 | ||||
| -rw-r--r-- | src/wrapped/generated/wrapper.h | 2 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibc.c | 14 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibc_private.h | 7 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibdl.c | 23 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibdl_private.h | 2 |
16 files changed, 211 insertions, 38 deletions
diff --git a/src/box64context.c b/src/box64context.c index ee56ce5a..9d8e5d5d 100755 --- a/src/box64context.c +++ b/src/box64context.c @@ -259,6 +259,9 @@ void FreeBox64Context(box64context_t** context) freeGLProcWrapper(ctx); freeALProcWrapper(ctx); + if(ctx->stack_clone) + free(ctx->stack_clone); + void* ptr; if ((ptr = pthread_getspecific(ctx->tlskey)) != NULL) { diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index 761d2ee4..afd9002d 100755 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -147,6 +147,12 @@ const char* ElfName(elfheader_t* head) return "(noelf)"; return head->name; } +const char* ElfPath(elfheader_t* head) +{ + if(!head) + return NULL; + return head->path; +} int AllocElfMemory(box64context_t* context, elfheader_t* head, int mainbin) { uintptr_t offs = 0; @@ -1368,6 +1374,13 @@ void* GetTLSPointer(box64context_t* context, elfheader_t* h) return ptr->tlsdata+(ptr->tlssize+h->tlsbase); } +void* GetDynamicSection(elfheader_t* h) +{ + if(!h) + return NULL; + return h->Dynamic; +} + #ifdef DYNAREC dynablocklist_t* GetDynablocksFromAddress(box64context_t *context, uintptr_t addr) { diff --git a/src/emu/x64int3.c b/src/emu/x64int3.c index 86f1f0af..f7bb6291 100755 --- a/src/emu/x64int3.c +++ b/src/emu/x64int3.c @@ -97,7 +97,7 @@ void x64Int3(x64emu_t* emu) s = GetNativeName((void*)addr); if(addr==(uintptr_t)PltResolver) { snprintf(buff, 256, "%s", " ... "); - } else if (!strcmp(s, "__open") || !strcmp(s, "open") || !strcmp(s, "open ")) { + } else if (!strcmp(s, "__open") || !strcmp(s, "open") || !strcmp(s, "open ") || !strcmp(s, "open64")) { tmp = (char*)(R_RDI); snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", %d (,%d))", tid, *(void**)(R_RSP), s, (tmp)?tmp:"(nil)", (int)(R_ESI), (int)(R_EDX)); perr = 1; diff --git a/src/emu/x64syscall.c b/src/emu/x64syscall.c index 2a4e65d6..edcbfff4 100755 --- a/src/emu/x64syscall.c +++ b/src/emu/x64syscall.c @@ -106,12 +106,13 @@ scwrap_t syscallwrap[] = { { 46, __NR_sendmsg, 3}, { 47, __NR_recvmsg, 3}, { 53, __NR_socketpair, 4}, - #ifdef __NR_vfork - {56, __NR_vfork, 0}, - #endif + //{56, __NR_clone, 5}, #ifdef __NR_fork { 57, __NR_fork, 0 }, // should wrap this one, because of the struct pt_regs (the only arg)? #endif + #ifdef __NR_vfork + {58, __NR_vfork, 0}, + #endif { 61, __NR_wait4, 4}, //{ 63, __NR_uname, 1}, // Needs wrapping, use old_utsname { 66, __NR_semctl, 4}, @@ -253,15 +254,16 @@ typedef struct old_utsname_s { // int xss; //}; -//int clone_fn(void* arg) -//{ -// x64emu_t *emu = (x64emu_t*)arg; -// R_RAX = 0; -// DynaRun(emu); -// int ret = R_EAX; -// FreeX64Emu(&emu); -// return ret; -//} +int clone_fn(void* arg) +{ + x64emu_t *emu = (x64emu_t*)arg; + R_RAX = 0; + DynaRun(emu); + int ret = R_EAX; + FreeX64Emu(&emu); + my_context->stack_clone_used = 0; + return ret; +} void EXPORT x64Syscall(x64emu_t *emu) { @@ -344,19 +346,63 @@ void EXPORT x64Syscall(x64emu_t *emu) case 25: // sys_mremap R_RAX = (uintptr_t)my_mremap(emu, (void*)R_RDI, R_RSI, R_RDX, R_R10d, (void*)R_R8); break; - #ifndef __NR_vfork - case 56: // vfork + case 56: // sys_clone + if(R_RSI) { - int64_t r = vfork(); - R_RAX = r; + void* stack_base = (void*)R_RSI; + int stack_size = 0; + if(!R_RSI) { + // allocate a new stack... + int currstack = 0; + if((R_RSP>=(uintptr_t)emu->init_stack) && (R_RSP<=((uintptr_t)emu->init_stack+emu->size_stack))) + currstack = 1; + stack_size = (currstack)?emu->size_stack:(1024*1024); + stack_base = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0); + // copy value from old stack to new stack + if(currstack) + memcpy(stack_base, emu->init_stack, stack_size); + else { + int size_to_copy = (uintptr_t)emu->init_stack + emu->size_stack - (R_RSP); + memcpy(stack_base+stack_size-size_to_copy, (void*)R_RSP, size_to_copy); + } + } + x64emu_t * newemu = NewX64Emu(emu->context, R_RIP, (uintptr_t)stack_base, stack_size, (R_RSI)?0:1); + SetupX64Emu(newemu); + CloneEmu(newemu, emu); + SetRSP(newemu, (uintptr_t)stack_base); + void* mystack = NULL; + if(my_context->stack_clone_used) { + mystack = malloc(1024*1024); // stack for own process... memory leak, but no practical way to remove it + } else { + if(!my_context->stack_clone) + my_context->stack_clone = malloc(1024*1024); + mystack = my_context->stack_clone; + my_context->stack_clone_used = 1; + } + // x86_64 raw clone is long clone(unsigned long flags, void *stack, int *parent_tid, int *child_tid, unsigned long tls); + int64_t ret = clone(clone_fn, (void*)((uintptr_t)mystack+1024*1024), R_RDI, newemu, R_R10, R_R9, R_R8); + R_RAX = ret; } + else + #ifdef NOALIGN + return syscall(__NR_clone, R_RSI, R_RDX, R_R10, R_R8, R_R9); + #else + return syscall(__NR_clone, R_RSI, R_RDX, R_R10, R_R9, R_R8); // invert R_R8/R_R9 on Aarch64 and most other + #endif break; - #endif #ifndef __NR_fork case 57: R_RAX = fork(); break; #endif + #ifndef __NR_vfork + case 58: // vfork + { + int64_t r = vfork(); + R_RAX = r; + } + break; + #endif case 63: //uname { old_utsname_t *old = (old_utsname_t*)R_RDI; @@ -493,14 +539,60 @@ uintptr_t EXPORT my_syscall(x64emu_t *emu) #endif case 25: // sys_mremap return (uintptr_t)my_mremap(emu, (void*)R_RSI, R_RDX, R_RCX, R_R8d, (void*)R_R9); - #ifndef __NR_vfork - case 56: // vfork - return vfork(); - #endif + case 56: // sys_clone + if(R_RDX) + { + void* stack_base = (void*)R_RDX; + int stack_size = 0; + if(!stack_base) { + // allocate a new stack... + int currstack = 0; + if((R_RSP>=(uintptr_t)emu->init_stack) && (R_RSP<=((uintptr_t)emu->init_stack+emu->size_stack))) + currstack = 1; + stack_size = (currstack)?emu->size_stack:(1024*1024); + stack_base = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0); + // copy value from old stack to new stack + if(currstack) + memcpy(stack_base, emu->init_stack, stack_size); + else { + int size_to_copy = (uintptr_t)emu->init_stack + emu->size_stack - (R_RSP); + memcpy(stack_base+stack_size-size_to_copy, (void*)R_RSP, size_to_copy); + } + } + x64emu_t * newemu = NewX64Emu(emu->context, R_RIP, (uintptr_t)stack_base, stack_size, (R_RDX)?0:1); + SetupX64Emu(newemu); + CloneEmu(newemu, emu); + Push64(newemu, 0); + PushExit(newemu); + SetRSP(newemu, (uintptr_t)stack_base); + void* mystack = NULL; + if(my_context->stack_clone_used) { + mystack = malloc(1024*1024); // stack for own process... memory leak, but no practical way to remove it + } else { + if(!my_context->stack_clone) + my_context->stack_clone = malloc(1024*1024); + mystack = my_context->stack_clone; + my_context->stack_clone_used = 1; + } + // x86_64 raw clone is long clone(unsigned long flags, void *stack, int *parent_tid, int *child_tid, unsigned long tls); + int64_t ret = clone(clone_fn, (void*)((uintptr_t)mystack+1024*1024), R_ESI, newemu, R_RCX, R_R9, R_R8); + return ret; + } + else + #ifdef NOALIGN + return syscall(__NR_clone, R_RSI, R_RDX, R_RCX, R_R8, R_R9); + #else + return syscall(__NR_clone, R_RSI, R_RDX, R_RCX, R_R9, R_R8); // invert R_R8/R_R9 on Aarch64 and most other + #endif + break; #ifndef __NR_fork case 57: return fork(); #endif + #ifndef __NR_vfork + case 58: // vfork + return vfork(); + #endif case 63: //uname { old_utsname_t *old = (old_utsname_t*)R_RSI; diff --git a/src/include/box64context.h b/src/include/box64context.h index ecb00c3e..9d660664 100755 --- a/src/include/box64context.h +++ b/src/include/box64context.h @@ -188,6 +188,8 @@ typedef struct box64context_s { x64emu_t *emu_sig; // the emu with stack used for signal handling (must be separated from main ones) int no_sigsegv; int no_sigill; + void* stack_clone; + int stack_clone_used; } box64context_t; diff --git a/src/include/elfloader.h b/src/include/elfloader.h index c1b4ce89..4e06546b 100755 --- a/src/include/elfloader.h +++ b/src/include/elfloader.h @@ -16,6 +16,7 @@ typedef struct dynablocklist_s dynablocklist_t; elfheader_t* LoadAndCheckElfHeader(FILE* f, const char* name, int exec); // exec : 0 = lib, 1 = exec void FreeElfHeader(elfheader_t** head); const char* ElfName(elfheader_t* head); +const char* ElfPath(elfheader_t* head); void ElfAttachLib(elfheader_t* head, library_t* lib); // return 0 if OK @@ -52,6 +53,7 @@ dynablocklist_t* GetDynablocksFromElf(elfheader_t* h); #endif void ResetSpecialCaseMainElf(elfheader_t* h); void CreateMemorymapFile(box64context_t* context, int fd); +void* GetDynamicSection(elfheader_t* h); int ElfCheckIfUseTCMallocMinimal(elfheader_t* h); // return 1 if tcmalloc is used diff --git a/src/main.c b/src/main.c index 48c8f99e..388fea7d 100755 --- a/src/main.c +++ b/src/main.c @@ -956,6 +956,18 @@ int main(int argc, const char **argv, const char **env) { //wine_preloaded = 1; } } + #if 0 + // pre-check for pressure-vessel-wrap + if(strstr(prog, "pressure-vessel-wrap")==(prog+strlen(prog)-strlen("pressure-vessel-wrap"))) { + // pressure-vessel-wrap detecter, skipping it and all -- args until "--" if needed + ++nextarg; + if(argv[nextarg][0]=='-' && argv[nextarg][1]=='-') + while(argv[nextarg][0]=='-' && argv[nextarg][1]=='-') + ++nextarg; + prog = argv[nextarg]; + printf_log(LOG_INFO, "BOX64: pressure-vessel-wrap detected, loading \"%s\" directly\n", prog); + } + #endif // check if this is wine if(!strcmp(prog, "wine64") || !strcmp(prog, "wine64-development") @@ -990,9 +1002,9 @@ int main(int argc, const char **argv, const char **env) { // allocate extra space for new environment variables such as BOX64_PATH my_context->envv = (char**)calloc(my_context->envc+4, sizeof(char*)); GatherEnv(&my_context->envv, environ?environ:env, my_context->box64path); - if(box64_dump) { + if(box64_dump || 1) { for (int i=0; i<my_context->envc; ++i) - printf_dump(LOG_NEVER, " Env[%02d]: %s\n", i, my_context->envv[i]); + printf_dump(/*LOG_NEVER*/LOG_INFO, " Env[%02d]: %s\n", i, my_context->envv[i]); } path_collection_t ld_preload = {0}; @@ -1117,16 +1129,19 @@ int main(int argc, const char **argv, const char **env) { free_contextargv(); FreeCollection(&ld_preload); if(x86) { - // duplicate the array to change 1st arg as box86 - const char** newargv = (const char**)calloc(argc+1, sizeof(char*)); + // duplicate the array and insert 1st arg as box86 + const char** newargv = (const char**)calloc(my_context->argc+2, sizeof(char*)); newargv[0] = my_context->box86path; + for(int i=0; i<my_context->argc; ++i) + newargv[i+1] = my_context->argv[i]; FreeBox64Context(&my_context); - for(int i=1; i<argc; ++i) - newargv[i] = argv[i]; return execvp(newargv[0], (char * const*)newargv); } else { + const char** newargv = (const char**)calloc(my_context->argc+1, sizeof(char*)); + for(int i=0; i<my_context->argc; ++i) + newargv[i] = my_context->argv[i]; FreeBox64Context(&my_context); - return execvp(argv[1], (char * const*)(argv+1)); + return execvp(newargv[0], (char * const*)newargv); } printf_log(LOG_NONE, "Failed to execvp: error is %s\n", strerror(errno)); } diff --git a/src/wrapped/generated/functions_list.txt b/src/wrapped/generated/functions_list.txt index 8550ed82..25f672bb 100644 --- a/src/wrapped/generated/functions_list.txt +++ b/src/wrapped/generated/functions_list.txt @@ -1046,6 +1046,7 @@ #() vFppppp #() iFEiipp #() iFEiipV +#() iFEippL #() iFEippp #() iFEpiii #() iFEpipi @@ -1060,6 +1061,7 @@ #() iFEppiV #() iFEppiA #() iFEpplp +#() iFEpppi #() iFEpppp #() iFEpppV #() iFiiipu @@ -2757,6 +2759,8 @@ wrappedlibc: - semctl - iFipii: - epoll_wait +- iFippL: + - readlinkat - iFpipp: - __vasprintf_chk - glob @@ -2832,6 +2836,8 @@ wrappedlibdl: - dlmopen - pFppp: - dlvsym +- iFpppi: + - dladdr1 wrappedlibdrm: wrappedlibform: wrappedlibformw: diff --git a/src/wrapped/generated/wrappedlibctypes.h b/src/wrapped/generated/wrappedlibctypes.h index 2e0d5a12..688beb6c 100644 --- a/src/wrapped/generated/wrappedlibctypes.h +++ b/src/wrapped/generated/wrappedlibctypes.h @@ -55,6 +55,7 @@ typedef void (*vFpLLp_t)(void*, uintptr_t, uintptr_t, void*); typedef int64_t (*iFiiip_t)(int64_t, int64_t, int64_t, void*); typedef int64_t (*iFiiiN_t)(int64_t, int64_t, int64_t, ...); typedef int64_t (*iFipii_t)(int64_t, void*, int64_t, int64_t); +typedef int64_t (*iFippL_t)(int64_t, void*, void*, uintptr_t); typedef int64_t (*iFpipp_t)(void*, int64_t, void*, void*); typedef int64_t (*iFpipV_t)(void*, int64_t, void*, ...); typedef int64_t (*iFpLpp_t)(void*, uintptr_t, void*, void*); @@ -183,6 +184,7 @@ typedef int64_t (*iFpippppp_t)(void*, int64_t, void*, void*, void*, void*, void* GO(epoll_ctl, iFiiip_t) \ GO(semctl, iFiiiN_t) \ GO(epoll_wait, iFipii_t) \ + GO(readlinkat, iFippL_t) \ GO(__vasprintf_chk, iFpipp_t) \ GO(glob, iFpipp_t) \ GO(glob64, iFpipp_t) \ diff --git a/src/wrapped/generated/wrappedlibdltypes.h b/src/wrapped/generated/wrappedlibdltypes.h index 4f3e67b2..0c448396 100644 --- a/src/wrapped/generated/wrappedlibdltypes.h +++ b/src/wrapped/generated/wrappedlibdltypes.h @@ -19,6 +19,7 @@ typedef void* (*pFpp_t)(void*, void*); typedef int64_t (*iFpip_t)(void*, int64_t, void*); typedef void* (*pFppi_t)(void*, void*, int64_t); typedef void* (*pFppp_t)(void*, void*, void*); +typedef int64_t (*iFpppi_t)(void*, void*, void*, int64_t); #define SUPER() ADDED_FUNCTIONS() \ GO(dlclose, iFp_t) \ @@ -28,6 +29,7 @@ typedef void* (*pFppp_t)(void*, void*, void*); GO(dlsym, pFpp_t) \ GO(dlinfo, iFpip_t) \ GO(dlmopen, pFppi_t) \ - GO(dlvsym, pFppp_t) + GO(dlvsym, pFppp_t) \ + GO(dladdr1, iFpppi_t) #endif // __wrappedlibdlTYPES_H_ diff --git a/src/wrapped/generated/wrapper.c b/src/wrapped/generated/wrapper.c index 693f0388..0afca20a 100644 --- a/src/wrapped/generated/wrapper.c +++ b/src/wrapped/generated/wrapper.c @@ -1080,6 +1080,7 @@ typedef void (*vFppppL_t)(void*, void*, void*, void*, uintptr_t); typedef void (*vFppppp_t)(void*, void*, void*, void*, void*); typedef int64_t (*iFEiipp_t)(x64emu_t*, int64_t, int64_t, void*, void*); typedef int64_t (*iFEiipV_t)(x64emu_t*, int64_t, int64_t, void*, void*); +typedef int64_t (*iFEippL_t)(x64emu_t*, int64_t, void*, void*, uintptr_t); typedef int64_t (*iFEippp_t)(x64emu_t*, int64_t, void*, void*, void*); typedef int64_t (*iFEpiii_t)(x64emu_t*, void*, int64_t, int64_t, int64_t); typedef int64_t (*iFEpipi_t)(x64emu_t*, void*, int64_t, void*, int64_t); @@ -1094,6 +1095,7 @@ typedef int64_t (*iFEppip_t)(x64emu_t*, void*, void*, int64_t, void*); typedef int64_t (*iFEppiV_t)(x64emu_t*, void*, void*, int64_t, void*); typedef int64_t (*iFEppiA_t)(x64emu_t*, void*, void*, int64_t, void*); typedef int64_t (*iFEpplp_t)(x64emu_t*, void*, void*, intptr_t, void*); +typedef int64_t (*iFEpppi_t)(x64emu_t*, void*, void*, void*, int64_t); typedef int64_t (*iFEpppp_t)(x64emu_t*, void*, void*, void*, void*); typedef int64_t (*iFEpppV_t)(x64emu_t*, void*, void*, void*, void*); typedef int64_t (*iFiiipu_t)(int64_t, int64_t, int64_t, void*, uint64_t); @@ -3124,6 +3126,7 @@ void vFppppL(x64emu_t *emu, uintptr_t fcn) { vFppppL_t fn = (vFppppL_t)fcn; fn(( void vFppppp(x64emu_t *emu, uintptr_t fcn) { vFppppp_t fn = (vFppppp_t)fcn; fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8); } void iFEiipp(x64emu_t *emu, uintptr_t fcn) { iFEiipp_t fn = (iFEiipp_t)fcn; R_RAX=(int64_t)fn(emu, (int64_t)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (void*)R_RCX); } void iFEiipV(x64emu_t *emu, uintptr_t fcn) { iFEiipV_t fn = (iFEiipV_t)fcn; R_RAX=(int64_t)fn(emu, (int64_t)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (void*)(R_RSP + 8)); } +void iFEippL(x64emu_t *emu, uintptr_t fcn) { iFEippL_t fn = (iFEippL_t)fcn; R_RAX=(int64_t)fn(emu, (int64_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX); } void iFEippp(x64emu_t *emu, uintptr_t fcn) { iFEippp_t fn = (iFEippp_t)fcn; R_RAX=(int64_t)fn(emu, (int64_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX); } void iFEpiii(x64emu_t *emu, uintptr_t fcn) { iFEpiii_t fn = (iFEpiii_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX); } void iFEpipi(x64emu_t *emu, uintptr_t fcn) { iFEpipi_t fn = (iFEpipi_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (int64_t)R_RCX); } @@ -3138,6 +3141,7 @@ void iFEppip(x64emu_t *emu, uintptr_t fcn) { iFEppip_t fn = (iFEppip_t)fcn; R_RA void iFEppiV(x64emu_t *emu, uintptr_t fcn) { iFEppiV_t fn = (iFEppiV_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (int64_t)R_RDX, (void*)(R_RSP + 8)); } void iFEppiA(x64emu_t *emu, uintptr_t fcn) { iFEppiA_t fn = (iFEppiA_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (int64_t)R_RDX, (void*)R_RCX); } void iFEpplp(x64emu_t *emu, uintptr_t fcn) { iFEpplp_t fn = (iFEpplp_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (intptr_t)R_RDX, (void*)R_RCX); } +void iFEpppi(x64emu_t *emu, uintptr_t fcn) { iFEpppi_t fn = (iFEpppi_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int64_t)R_RCX); } void iFEpppp(x64emu_t *emu, uintptr_t fcn) { iFEpppp_t fn = (iFEpppp_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX); } void iFEpppV(x64emu_t *emu, uintptr_t fcn) { iFEpppV_t fn = (iFEpppV_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)(R_RSP + 8)); } void iFiiipu(x64emu_t *emu, uintptr_t fcn) { iFiiipu_t fn = (iFiiipu_t)fcn; R_RAX=(int64_t)fn((int64_t)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX, (void*)R_RCX, (uint64_t)R_R8); } diff --git a/src/wrapped/generated/wrapper.h b/src/wrapped/generated/wrapper.h index 8ac3a7de..360bc132 100644 --- a/src/wrapped/generated/wrapper.h +++ b/src/wrapped/generated/wrapper.h @@ -1079,6 +1079,7 @@ void vFppppL(x64emu_t *emu, uintptr_t fnc); void vFppppp(x64emu_t *emu, uintptr_t fnc); void iFEiipp(x64emu_t *emu, uintptr_t fnc); void iFEiipV(x64emu_t *emu, uintptr_t fnc); +void iFEippL(x64emu_t *emu, uintptr_t fnc); void iFEippp(x64emu_t *emu, uintptr_t fnc); void iFEpiii(x64emu_t *emu, uintptr_t fnc); void iFEpipi(x64emu_t *emu, uintptr_t fnc); @@ -1093,6 +1094,7 @@ void iFEppip(x64emu_t *emu, uintptr_t fnc); void iFEppiV(x64emu_t *emu, uintptr_t fnc); void iFEppiA(x64emu_t *emu, uintptr_t fnc); void iFEpplp(x64emu_t *emu, uintptr_t fnc); +void iFEpppi(x64emu_t *emu, uintptr_t fnc); void iFEpppp(x64emu_t *emu, uintptr_t fnc); void iFEpppV(x64emu_t *emu, uintptr_t fnc); void iFiiipu(x64emu_t *emu, uintptr_t fnc); diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index f0b7933e..e2ae9c76 100755 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -2101,13 +2101,23 @@ EXPORT void my___explicit_bzero_chk(x64emu_t* emu, void* dst, uint32_t len, uint EXPORT void* my_realpath(x64emu_t* emu, void* path, void* resolved_path) { - if(isProcSelf(path, "exe")) { return realpath(emu->context->fullpath, resolved_path); } - return realpath(path, resolved_path); + return realpath(path, resolved_path); } +EXPORT int my_readlinkat(x64emu_t* emu, int fd, void* path, void* buf, size_t bufsize) +{ + if(isProcSelf(path, "exe")) { + strncpy(buf, emu->context->fullpath, bufsize); + size_t l = strlen(emu->context->fullpath); + return (l>bufsize)?bufsize:(l+1); + } + return readlinkat(fd, path, buf, bufsize); +} + + EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot, int flags, int fd, int64_t offset) { (void)emu; diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h index 2dae6e29..36ef89b4 100755 --- a/src/wrapped/wrappedlibc_private.h +++ b/src/wrapped/wrappedlibc_private.h @@ -4,6 +4,7 @@ //socklen_t is u32 // typedef unsigned long int nfds_t; +// pid_t is S32 // key_t is S32 // uid_t is u32 // gid_t is u32 @@ -99,8 +100,8 @@ GOW(calloc, pFLL) //GO(callrpc, iFpLLL@p@p) //GO(__call_tls_dtors, vFv) GOW(canonicalize_file_name, pFp) -//GO(capget, -//GO(capset, +GO(capget, iFpp) +GO(capset, iFpp) GO(catclose, iFp) GO(catgets, pFpiip) GO(catopen, pFpi) @@ -1466,7 +1467,7 @@ GOW(readdir64, pFp) GOW(readdir64_r, iFppp) GOW(readdir_r, iFppp) GOWM(readlink, lFEppL) -GO(readlinkat, lFippL) +GOM(readlinkat, iFEippL) //GO(__readlinkat_chk, //GO(__readlink_chk, //GO(__read_nocancel, diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c index 53566797..dffc9fa9 100755 --- a/src/wrapped/wrappedlibdl.c +++ b/src/wrapped/wrappedlibdl.c @@ -4,6 +4,7 @@ #include <string.h> #include <dlfcn.h> #include <elf.h> +#include <link.h> #include "wrappedlibs.h" @@ -42,6 +43,7 @@ char* my_dlerror(x64emu_t* emu) EXPORT; void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) EXPORT; int my_dlclose(x64emu_t* emu, void *handle) EXPORT; int my_dladdr(x64emu_t* emu, void *addr, void *info) EXPORT; +int my_dladdr1(x64emu_t* emu, void *addr, void *info, void** extra_info, int flags) EXPORT; void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername) EXPORT; int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info) EXPORT; @@ -338,21 +340,38 @@ int my_dlclose(x64emu_t* emu, void *handle) } return 0; } -int my_dladdr(x64emu_t* emu, void *addr, void *i) +int my_dladdr1(x64emu_t* emu, void *addr, void *i, void** extra_info, int flags) { //int dladdr(void *addr, Dl_info *info); dlprivate_t *dl = emu->context->dlprivate; CLEARERR Dl_info *info = (Dl_info*)i; - printf_log(LOG_DEBUG, "Warning: partially unimplement call to dladdr(%p, %p)\n", addr, info); + printf_log(LOG_DEBUG, "Warning: partially unimplement call to dladdr/dladdr1(%p, %p, %p, %d)\n", addr, info, extra_info, flags); //emu->quit = 1; info->dli_saddr = NULL; info->dli_fname = NULL; info->dli_sname = FindSymbolName(emu->context->maplib, addr, &info->dli_saddr, NULL, &info->dli_fname, &info->dli_fbase); printf_log(LOG_DEBUG, " dladdr return saddr=%p, fname=\"%s\", sname=\"%s\"\n", info->dli_saddr, info->dli_sname?info->dli_sname:"", info->dli_fname?info->dli_fname:""); + if(flags==RTLD_DL_SYMENT) { + printf_log(LOG_INFO, "Warning, unimplement call to dladdr1 with RTLD_DL_SYMENT flags\n"); + } else if (flags==RTLD_DL_LINKMAP) { + printf_log(LOG_INFO, "Warning, partially unimplement call to dladdr1 with RTLD_DL_LINKMAP flags\n"); + static struct link_map my_map = {0}; + elfheader_t* elf = FindElfAddress(my_context, (uintptr_t)addr); + if(elf) { + my_map.l_addr = (uintptr_t)GetElfDelta(elf); + my_map.l_name = (char*)ElfPath(elf); + my_map.l_ld = GetDynamicSection(elf); + } + *extra_info = &my_map; + } return (info->dli_sname)?1:0; // success is non-null here... } +int my_dladdr(x64emu_t* emu, void *addr, void *i) +{ + return my_dladdr1(emu, addr, i, NULL, 0); +} void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername) { dlprivate_t *dl = emu->context->dlprivate; diff --git a/src/wrapped/wrappedlibdl_private.h b/src/wrapped/wrappedlibdl_private.h index 58064bca..4753af0b 100755 --- a/src/wrapped/wrappedlibdl_private.h +++ b/src/wrapped/wrappedlibdl_private.h @@ -1,7 +1,7 @@ #if defined(GO) && defined(GOM) && defined(GO2) && defined(DATA) GOM(dladdr, iFEpp) -// dladdr1 +GOM(dladdr1, iFEpppi) GOM(dlclose, iFEp) GOM(dlerror, pFEv) DATAB(_dlfcn_hook, 8) |