From 7a6a41b4d8db829cd3c1f3da677575b4db845215 Mon Sep 17 00:00:00 2001 From: cocay Date: Wed, 3 Jan 2024 22:12:10 +0700 Subject: [PATCH] First big update b.cc (gnu coreutils) --- research/custom_loader/b.cc | 64 ++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/research/custom_loader/b.cc b/research/custom_loader/b.cc index 1b66cfe..f6cbce5 100644 --- a/research/custom_loader/b.cc +++ b/research/custom_loader/b.cc @@ -127,8 +127,8 @@ uint32_t calculate_libname_hash(const libcache *cache, const char *name) { char* p = realpath(rpath, 0); hash = hash_func(p); hash = fnv_hash_extend(&name[6], hash); - for (size_t i = 0; i < cache->size; i++) { - if (cache->libs[i].hash == hash) { + for (size_t j = 0; j < cache->size; j++) { + if (cache->libs[j].hash == hash) { free(p); return hash; } @@ -389,12 +389,29 @@ void *get_export_trie(const void *header, uint32_t &size) { const uint32_t offset = *((uint32_t *)ptr + 2); size = *((uint32_t *)ptr + 3); uint64_t offset_in_linkedit = (uint64_t)offset - linkedit_fileoffset; + + printf("trie: %p\n",linkedit_vmaddr + slice + offset_in_linkedit ); + if (linkedit_vmaddr + slice + offset_in_linkedit == 0x7ff888187f78) { + FILE* f = fopen("../scripts/libsystem_c.dylib", "wb"); + // fwrite(header, size + linkedit_vmaddr + slice + offset_in_linkedit, 1, f); + // fwrite((char*)linkedit_vmaddr + slice + offset_in_linkedit, size, 1, f); + fclose(f); + } + return (void *)(linkedit_vmaddr + slice + offset_in_linkedit); } if (cmd == LC_DYLD_INFO_ONLY) { const uint32_t offset = *((uint32_t *)ptr + 10); size = *((uint32_t *)ptr + 11); uint64_t offset_in_linkedit = (uint64_t)offset - linkedit_fileoffset; + + printf("trie: %p\n",linkedit_vmaddr + slice + offset_in_linkedit ); + if (linkedit_vmaddr + slice + offset_in_linkedit == 0x7ff888187f78) { + FILE* f = fopen("../scripts/libsystem_c.bin", "wb"); + fwrite((char*)linkedit_vmaddr + slice + offset_in_linkedit, size, 1, f); + fclose(f); + } + return (void *)(linkedit_vmaddr + slice + offset_in_linkedit); } if (cmd == LC_SEGMENT_64) { @@ -448,7 +465,7 @@ uint32_t should_follow_symbol(char *&buffer, char *&_find) { return is_prefix; } -void *find_in_export_trie(const void *header, void *trie, const char *symbol) { +void *find_in_export_trie(const void *header, void *trie, char *& symbol) { uint32_t func = 0; char *ptr = (char *)trie; @@ -485,17 +502,23 @@ void *find_in_export_trie(const void *header, void *trie, const char *symbol) { } char count = *(ptr - 1); - ptr++; // flags + uint8_t flag = *ptr++; // flags // uleb128 offset decode_uleb128(ptr, &func); + + if (flag == 0x8 /*re-export*/) { + symbol = ptr; + printf("re-export %s\n", symbol); + return 0; + } return (void *)((char *)header + func); } void *find_in_lib(struct libcache *cache, struct libcache_item *lib, - const char *symbol); + char *& symbol); void *find_in_reexport(struct libcache *cache, struct libcache_item *lib, - const char *symbol) { + char *& symbol) { void *header = lib->header; const uint32_t magic = *(uint32_t *)header; char *ptr = (char *)header; @@ -531,12 +554,13 @@ void *find_in_reexport(struct libcache *cache, struct libcache_item *lib, } void *find_in_lib(struct libcache *cache, struct libcache_item *lib, - const char *symbol) { + char *& symbol) { void *direct = find_in_export_trie(lib->header, lib->trie, symbol); if (direct) { return direct; } // cannot find in directly exported trie, loop through all reexport libs + // printf("looking for symbol: %s\n", symbol); return find_in_reexport(cache, lib, symbol); } @@ -544,7 +568,16 @@ void *custom_dlsym(struct libcache *cache, uint32_t hash, const char *symbol) { for (size_t i = 0; i < cache->size; i++) { struct libcache_item *cache_lib = &cache->libs[i]; if (cache_lib->hash == hash) { - return find_in_lib(cache, cache_lib, symbol); + // if (custom_strcmp(symbol, "_strlen") == 0) { + // return find_in_lib(cache, cache_lib, "__platform_strlen"); + // } + char** symbol_copy = (char**)&symbol; + void* func = find_in_lib(cache, cache_lib, *symbol_copy); + if (*symbol_copy != symbol) { + printf("symbol found %p %s %s\n", func, *symbol_copy, symbol); + func = find_in_lib(cache, cache_lib, *symbol_copy); + } + return func; } } return 0; @@ -864,14 +897,20 @@ void build_cache(struct libcache &cache, void *main) { typedef int (*dyld_image_count_t)(void); typedef char *(*dyld_get_image_name_t)(int); typedef void *(*dyld_get_image_header_t)(int); + + char* dyld_image_count_s = "__dyld_image_count"; int (*dyld_image_count_func)(void) = (dyld_image_count_t)find_in_export_trie( - libdyld, libdyld_export_trie, "__dyld_image_count"); + libdyld, libdyld_export_trie, dyld_image_count_s); + + char* dyld_get_image_header_s = "__dyld_get_image_header"; void *(*dyld_get_image_header_func)(int) = (dyld_get_image_header_t)find_in_export_trie(libdyld, libdyld_export_trie, - "__dyld_get_image_header"); + dyld_get_image_header_s); + + char* dyld_get_image_name_s = "__dyld_get_image_name"; char *(*dyld_get_image_name_func)(int) = (dyld_get_image_name_t)find_in_export_trie(libdyld, libdyld_export_trie, - "__dyld_get_image_name"); + dyld_get_image_name_s); cache.size = dyld_image_count_func(); cache.libs = @@ -881,7 +920,7 @@ void build_cache(struct libcache &cache, void *main) { char *name = dyld_get_image_name_func(i); bootstrap_libcache_item(&cache.libs[i], header, name); cache.libs[i].hash = calculate_libname_hash(&cache, name); - // printf("%p %s\n", header, name); + printf("%p %s\n", header, name); } } @@ -1212,6 +1251,7 @@ void volatile custom_initializer(int argc, const char *const argv[], free(custom_initializer_i->constructors); } + printf("initializers completed\n"); free(custom_initializer_i); }