summaryrefslogtreecommitdiff
path: root/src/linker
diff options
context:
space:
mode:
authorJari Vetoniemi <mailroxas@gmail.com>2018-02-19 15:51:56 +0200
committerJari Vetoniemi <mailroxas@gmail.com>2018-02-19 15:51:56 +0200
commitda200d3ac0204abadd5992820486321970d689b8 (patch)
tree31b559749ff7487a420cd7f1b1b7a67aa0a9d021 /src/linker
parent09fc4ea761b6b774a6423bdfd92049be78e32a49 (diff)
refactoring, fixing and implementing
messy commits yay
Diffstat (limited to 'src/linker')
-rw-r--r--src/linker/dlfcn.c49
-rw-r--r--src/linker/linker.c87
2 files changed, 28 insertions, 108 deletions
diff --git a/src/linker/dlfcn.c b/src/linker/dlfcn.c
index 3f76e92..a044094 100644
--- a/src/linker/dlfcn.c
+++ b/src/linker/dlfcn.c
@@ -21,12 +21,7 @@
#include "linker.h"
#include "linker_format.h"
-/* for apkenv_get_hooked_symbol */
-// #include "../compat/hooks.h"
-
-/* for create_wrapper */
-// #include "../debug/wrappers.h"
-
+#include "wrapper/wrapper.h"
#include "linker_debug.h"
#ifdef APKENV_DEBUG
@@ -66,7 +61,7 @@ static void set_dlerror(int err)
dl_err_str = (const char *)&dl_err_buf[0];
}
-void *apkenv_android_dlopen(const char *filename, int flag)
+void *bionic_dlopen(const char *filename, int flag)
{
soinfo *ret;
@@ -83,18 +78,7 @@ void *apkenv_android_dlopen(const char *filename, int flag)
return ret;
}
-static void *apkenv_android_dlopen_wrap(const char *filename, int flag)
-{
-#if 0
- void *ret = get_builtin_lib_handle(filename);
- if (ret)
- return ret;
-#endif
-
- return apkenv_android_dlopen(filename, flag);
-}
-
-const char *apkenv_android_dlerror(void)
+const char *bionic_dlerror(void)
{
const char *tmp = dl_err_str;
dl_err_str = NULL;
@@ -105,7 +89,7 @@ enum {
WRAPPER_DYNHOOK,
};
-void *apkenv_android_dlsym(void *handle, const char *symbol)
+void *bionic_dlsym(void *handle, const char *symbol)
{
soinfo *found;
Elf32_Sym *sym;
@@ -159,7 +143,7 @@ void *apkenv_android_dlsym(void *handle, const char *symbol)
if(likely((bind == STB_GLOBAL) && (sym->st_shndx != 0))) {
unsigned ret = sym->st_value + found->base;
pthread_mutex_unlock(&apkenv_dl_lock);
- return create_wrapper((char*)symbol, (void*)ret, WRAPPER_DYNHOOK);
+ return wrapper_create((char*)symbol, (void*)ret);
}
set_dlerror(DL_ERR_SYMBOL_NOT_GLOBAL);
@@ -173,7 +157,7 @@ err:
return 0;
}
-int apkenv_android_dladdr(const void *addr, Dl_info *info)
+int bionic_dladdr(const void *addr, Dl_info *info)
{
int ret = 0;
@@ -204,7 +188,7 @@ int apkenv_android_dladdr(const void *addr, Dl_info *info)
return ret;
}
-int apkenv_android_dlclose(void *handle)
+int bionic_dlclose(void *handle)
{
#if 0
if (is_builtin_lib_handle(handle))
@@ -224,7 +208,7 @@ int apkenv_android_dlclose(void *handle)
#define ANDROID_LIBDL_STRTAB \
"dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0dl_unwind_find_exidx\0"
-_Unwind_Ptr apkenv_android_dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount);
+_Unwind_Ptr bionic_dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount);
#elif defined(ANDROID_X86_LINKER)
// 0000000 00011111 111112 22222222 2333333 3333444444444455
@@ -232,8 +216,7 @@ _Unwind_Ptr apkenv_android_dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount);
#define ANDROID_LIBDL_STRTAB \
"dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0dl_iterate_phdr\0"
int
-apkenv_android_dl_iterate_phdr(int (*cb)(struct dl_phdr_info *info, size_t size, void *data),
- void *data);
+bionic_dl_iterate_phdr(int (*cb)(struct dl_phdr_info *info, size_t size, void *data), void *data);
#else
#error Unsupported architecture. Only ARM and x86 are presently supported.
@@ -289,41 +272,41 @@ construct(void)
.st_name = sizeof(ANDROID_LIBDL_STRTAB) - 1,
}, {
.st_name = 0, // starting index of the name in apkenv_libdl_info.strtab
- .st_value = (Elf32_Addr)(uintptr_t)apkenv_android_dlopen_wrap,
+ .st_value = (Elf32_Addr)(uintptr_t)bionic_dlopen,
.st_info = STB_GLOBAL << 4,
.st_shndx = 1,
}, {
.st_name = 7,
- .st_value = (Elf32_Addr)(uintptr_t)apkenv_android_dlclose,
+ .st_value = (Elf32_Addr)(uintptr_t)bionic_dlclose,
.st_info = STB_GLOBAL << 4,
.st_shndx = 1,
}, {
.st_name = 15,
- .st_value = (Elf32_Addr)(uintptr_t)apkenv_android_dlsym,
+ .st_value = (Elf32_Addr)(uintptr_t)bionic_dlsym,
.st_info = STB_GLOBAL << 4,
.st_shndx = 1,
}, {
.st_name = 21,
- .st_value = (Elf32_Addr)(uintptr_t)apkenv_android_dlerror,
+ .st_value = (Elf32_Addr)(uintptr_t)bionic_dlerror,
.st_info = STB_GLOBAL << 4,
.st_shndx = 1,
}, {
.st_name = 29,
- .st_value = (Elf32_Addr)(uintptr_t)apkenv_android_dladdr,
+ .st_value = (Elf32_Addr)(uintptr_t)bionic_dladdr,
.st_info = STB_GLOBAL << 4,
.st_shndx = 1,
},
#ifdef ANDROID_ARM_LINKER
{
.st_name = 36,
- .st_value = (Elf32_Addr)(uintptr_t)apkenv_android_dl_unwind_find_exidx,
+ .st_value = (Elf32_Addr)(uintptr_t)bionic_dl_unwind_find_exidx,
.st_info = STB_GLOBAL << 4,
.st_shndx = 1,
},
#elif defined(ANDROID_X86_LINKER)
{
.st_name = 36,
- .st_value = (Elf32_Addr)(uintptr_t)apkenv_android_dl_iterate_phdr,
+ .st_value = (Elf32_Addr)(uintptr_t)bionic_dl_iterate_phdr,
.st_info = STB_GLOBAL << 4,
.st_shndx = 1,
},
diff --git a/src/linker/linker.c b/src/linker/linker.c
index 09ebf8f..e5e1095 100644
--- a/src/linker/linker.c
+++ b/src/linker/linker.c
@@ -54,10 +54,7 @@
#include "strlcpy.h"
-/* for apkenv_get_hooked_symbol */
-// #include "../compat/hooks.h"
-/* for create_wrapper */
-// #include "../debug/wrappers.h"
+#include "wrapper/wrapper.h"
#include "linker.h"
#include "linker_debug.h"
@@ -163,50 +160,6 @@ enum {
WRAPPER_ARM_INJECTION,
};
-static char* (*__cxa_demangle)(const char *mangled_name, char *output_buffer, size_t *length, int *status);
-
-static void
-trace(const char *const symbol)
-{
- if (__cxa_demangle) {
- // >If output_buffer is not long enough, it is expanded using realloc
- // Holy fuck gcc what the fuck? Guess we don't use stack then, thanks
- int status;
- char *demangled;
- if ((demangled = __cxa_demangle(symbol, NULL, NULL, &status))) {
- printf("trace: %s\n", demangled);
- free(demangled); // so pointless...
- return;
- }
- }
-
- printf("trace: %s\n", symbol);
-}
-
-__asm__(
- "wrapper_start: nop\n"
- "wrapper_symbol: pushl $0xFAFBFCFD\n"
- "wrapper_trace: movl $0xFAFBFCFD, %eax\ncall *%eax\npop %eax\n"
- "wrapper_call: movl $0xFAFBFCFD, %eax\njmp *%eax\n"
- "wrapper_end: nop\n"
-);
-
-extern char wrapper_start, wrapper_symbol, wrapper_trace, wrapper_call, wrapper_end;
-
-void*
-create_wrapper(const char *const symbol, void *function, int wrapper_type)
-{
- const size_t sz = &wrapper_end - &wrapper_start;
- unsigned char *fun = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- assert(fun != MAP_FAILED);
- memcpy(fun, &wrapper_start, sz);
- memcpy(fun + (&wrapper_symbol - &wrapper_start) + 1, &symbol, sizeof(symbol));
- memcpy(fun + (&wrapper_trace - &wrapper_start) + 1, (uintptr_t[]){ (uintptr_t)trace }, sizeof(uintptr_t));
- memcpy(fun + (&wrapper_call - &wrapper_start) + 1, &function, sizeof(function));
- mprotect(fun, sz, PROT_READ | PROT_EXEC);
- return fun;
-}
-
/*
* This function is an empty stub where GDB locates a breakpoint to get notified
* about linker activity.
@@ -388,19 +341,6 @@ static void apkenv_free_info(soinfo *si)
apkenv_freelist = si;
}
-static const char *apkenv_addr_to_name(unsigned addr)
-{
- soinfo *si;
-
- for(si = apkenv_solist; si != 0; si = si->next){
- if((addr >= si->base) && (addr < (si->base + si->size))) {
- return si->name;
- }
- }
-
- return "";
-}
-
/* For a given PC, find the .so that it belongs to.
* Returns the base address of the .ARM.exidx section
* for that .so, and the number of 8-byte entries
@@ -411,7 +351,7 @@ static const char *apkenv_addr_to_name(unsigned addr)
* This function is exposed via dlfcn.c and libdl.so.
*/
#ifdef ANDROID_ARM_LINKER
-_Unwind_Ptr apkenv_android_dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount)
+_Unwind_Ptr bionic_dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount)
{
soinfo *si;
unsigned addr = (unsigned)pc;
@@ -428,7 +368,7 @@ _Unwind_Ptr apkenv_android_dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount)
/* Here, we only have to provide a callback to iterate across all the
* loaded libraries. gcc_eh does the rest. */
int
-apkenv_android_dl_iterate_phdr(int (*cb)(struct dl_phdr_info *info, size_t size, void *data),
+bionic_dl_iterate_phdr(int (*cb)(struct dl_phdr_info *info, size_t size, void *data),
void *data)
{
soinfo *si;
@@ -1427,7 +1367,7 @@ static int apkenv_reloc_library(soinfo *si, Elf32_Rel *rel, unsigned count)
if (!strcmp(sym_name, "dl_iterate_phdr")) {
// FIXME: hack, move to libc.so
- sym_addr = apkenv_android_dl_iterate_phdr;
+ sym_addr = bionic_dl_iterate_phdr;
} else if ((sym_addr = dlsym(RTLD_DEFAULT, wrap_sym_name))) {
LINKER_DEBUG_PRINTF("%s hooked symbol %s to %x\n", si->name, wrap_sym_name, sym_addr);
} else if ((sym_addr = dlsym(RTLD_DEFAULT, sym_name))) {
@@ -1444,7 +1384,7 @@ static int apkenv_reloc_library(soinfo *si, Elf32_Rel *rel, unsigned count)
}
if(sym_addr != 0)
{
- sym_addr = (unsigned)create_wrapper(sym_name, (void*)sym_addr, WRAPPER_UNHOOKED);
+ sym_addr = (unsigned)wrapper_create(sym_name, (void*)sym_addr);
} else
if(s == NULL) {
/* We only allow an undefined symbol if this is a weak
@@ -1515,7 +1455,7 @@ static int apkenv_reloc_library(soinfo *si, Elf32_Rel *rel, unsigned count)
sym_addr = (unsigned)(s->st_value + base);
LINKER_DEBUG_PRINTF("%s symbol (from %s) %s to %x\n", si->name, apkenv_last_library_used, sym_name, sym_addr);
if(ELF32_ST_TYPE(s->st_info) == STT_FUNC) {
- sym_addr = (unsigned)create_wrapper(sym_name, (void*)sym_addr, WRAPPER_UNHOOKED);
+ sym_addr = (unsigned)wrapper_create(sym_name, (void*)sym_addr);
}
}
@@ -1834,7 +1774,7 @@ static void apkenv_wrap_function(void *sym_addr, char *sym_name, int is_thumb, s
{
DEBUG("HOOKING INTERNAL (ARM) FUNCTION %s@%x (in %s) TO: %x\n",sym_name,sym_addr,si->name,hook);
((int32_t*)sym_addr)[0] = 0xe51ff004; // ldr pc, [pc, -#4] (load the hooks address into pc)
- ((int32_t*)sym_addr)[1] = (uint32_t)create_wrapper(sym_name, hook, WRAPPER_LATEHOOK);
+ ((int32_t*)sym_addr)[1] = (uint32_t)wrapper_create(sym_name, hook);
__clear_cache((int32_t*)sym_addr, (int32_t*)sym_addr + 2);
}
@@ -1850,7 +1790,7 @@ static void apkenv_wrap_function(void *sym_addr, char *sym_name, int is_thumb, s
((int16_t*)sym_addr)[4] = 0xBC01; /* pop {r0} */
((int16_t*)sym_addr)[5] = 0x4760; /* bx ip */
- void *wrp = create_wrapper(sym_name, hook, WRAPPER_LATEHOOK);
+ void *wrp = wrapper_create(sym_name, hook);
// store the hooks address
((int16_t*)sym_addr)[6] = (uint32_t)wrp & 0x0000FFFF;
@@ -1867,7 +1807,7 @@ static void apkenv_wrap_function(void *sym_addr, char *sym_name, int is_thumb, s
{
DEBUG("CREATING ARM WRAPPER FOR: %s@%x (in %s)\n", sym_name, (unsigned)sym_addr, si->name);
- create_wrapper(sym_name, sym_addr, WRAPPER_ARM_INJECTION);
+ wrapper_create(sym_name, sym_addr);
}
// TODO: this will fail if the first 2-5 instructions do something pc related
// (this DOES happen very often)
@@ -1875,7 +1815,7 @@ static void apkenv_wrap_function(void *sym_addr, char *sym_name, int is_thumb, s
{
DEBUG("CREATING THUMB WRAPPER FOR: %s@%x (in %s)\n",sym_name, (unsigned)sym_addr,si->name);
- create_wrapper(sym_name, sym_addr, WRAPPER_THUMB_INJECTION);
+ wrapper_create(sym_name, sym_addr);
}
}
@@ -2133,9 +2073,6 @@ static int apkenv_link_image(soinfo *si, unsigned wr_offset)
lsi = apkenv_find_library(si->strtab + d[1]);
if (!lsi && dlopen(si->strtab + d[1], RTLD_NOW | RTLD_GLOBAL)) {
DEBUG("Loaded %s with glibc dlopen\n", si->strtab + d[1]);
-
- if (!__cxa_demangle)
- __cxa_demangle = dlsym(RTLD_DEFAULT, "__cxa_demangle");
}
#endif
if(lsi == 0) {
@@ -2234,7 +2171,7 @@ fail:
return -1;
}
-void apkenv_parse_library_path(const char *path, char *delim)
+void dl_parse_library_path(const char *path, char *delim)
{
size_t len;
char *apkenv_ldpaths_bufp = apkenv_ldpaths_buf;
@@ -2428,7 +2365,7 @@ sanitize:
/* Use LD_LIBRARY_PATH if we aren't setuid/setgid */
if (ldpath_env)
- apkenv_parse_library_path(ldpath_env, ":");
+ dl_parse_library_path(ldpath_env, ":");
if (ldpreload_env) {
apkenv_parse_apkenv_preloads(ldpreload_env, " :");