From 6b2373af93e033019dd1ddd5683f2d866e253d8c Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Mon, 14 Apr 2025 19:34:43 +0800 Subject: [WOW64] Added non-functional PE build (#2532) --- src/os/os_linux.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'src/os/os_linux.c') diff --git a/src/os/os_linux.c b/src/os/os_linux.c index 6d9db214..556d4d9b 100644 --- a/src/os/os_linux.c +++ b/src/os/os_linux.c @@ -1,8 +1,11 @@ +#define _GNU_SOURCE #include #include #include #include #include +#include +#include #include "os.h" #include "signals.h" @@ -10,6 +13,9 @@ #include "bridge.h" #include "elfloader.h" #include "env.h" +#include "debug.h" +#include "x64tls.h" +#include "librarian.h" int GetTID(void) { @@ -51,6 +57,70 @@ void EmuX86Syscall(void* emu) x86Syscall((x64emu_t*)emu); } +extern int box64_is32bits; + +void* GetSeg43Base() +{ + tlsdatasize_t* ptr = getTLSData(my_context); + return ptr->data; +} + +void* GetSegmentBase(uint32_t desc) +{ + if (!desc) { + printf_log(LOG_NONE, "Warning, accessing segment NULL\n"); + return NULL; + } + int base = desc >> 3; + if (!box64_is32bits && base == 0x8 && !my_context->segtls[base].key_init) + return GetSeg43Base(); + if (box64_is32bits && (base == 0x6)) + return GetSeg43Base(); + if (base > 15) { + printf_log(LOG_NONE, "Warning, accessing segment unknown 0x%x or unset\n", desc); + return NULL; + } + if (my_context->segtls[base].key_init) { + void* ptr = pthread_getspecific(my_context->segtls[base].key); + return ptr; + } + + void* ptr = (void*)my_context->segtls[base].base; + return ptr; +} + +const char* GetNativeName(void* p) +{ + static char buff[500] = { 0 }; + { + const char* n = getBridgeName(p); + if (n) + return n; + } + Dl_info info; + if (dladdr(p, &info) == 0) { + const char* ret = GetNameOffset(my_context->maplib, p); + if (ret) + return ret; + sprintf(buff, "%s(%p)", "???", p); + return buff; + } else { + if (info.dli_sname) { + strcpy(buff, info.dli_sname); + if (info.dli_fname) { + strcat(buff, "("); + strcat(buff, info.dli_fname); + strcat(buff, ")"); + } + } else { + sprintf(buff, "%s(%s+%p)", "???", info.dli_fname, (void*)(p - info.dli_fbase)); + return buff; + } + } + return buff; +} + + void PersonalityAddrLimit32Bit(void) { personality(ADDR_LIMIT_32BIT); -- cgit 1.4.1