From 887c53ed44b566e7894352da42b60f444b913e7f Mon Sep 17 00:00:00 2001 From: nganhkhoa Date: Wed, 7 Jun 2023 10:49:59 +0700 Subject: [PATCH] add test for objc --- research/custom_loader/a.mm | 8 ++++++++ research/custom_loader/b.cc | 20 ++++++++++++++++---- research/custom_loader/build.sh | 21 ++++++++++++++++++++- 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 research/custom_loader/a.mm diff --git a/research/custom_loader/a.mm b/research/custom_loader/a.mm new file mode 100644 index 0000000..029b87e --- /dev/null +++ b/research/custom_loader/a.mm @@ -0,0 +1,8 @@ +#import + +int main(int argc, const char * argv[]) { + @autoreleasepool { + NSLog(@"Hello, World!"); + } + return 0; +} diff --git a/research/custom_loader/b.cc b/research/custom_loader/b.cc index fd80703..30c7b25 100644 --- a/research/custom_loader/b.cc +++ b/research/custom_loader/b.cc @@ -31,7 +31,6 @@ void set_cwd(const char *const *envp) { pwd = (char *)(*envp + 4); for (; pwd[pwd_len] != 0; pwd_len++) ; - printf("%s\n", pwd); } const uint32_t magic64 = 0xfeedfacf; @@ -111,6 +110,7 @@ uint32_t calculate_libname_hash(const libcache *cache, const char *name) { // i don't know if dyld_stub_binder should be better // because if they are not familiar with dyld // they would not suspect dyld_stub_binder inside modern macho +// Added iOS 6, macOS 10.8 extern "C" uint32_t dyld_get_sdk_version(const mach_header *mh); void exported_from_c(); @@ -491,10 +491,17 @@ void bootstrap_libcache_item(struct libcache_item* item, const void* header, con } struct libcache_item* get_libcache_with_name(struct libcache* cache, const char* name) { + void* to_find = 0; + if (custom_strcmp(name, "main") == 0) { + to_find = cache->main; + } else if (custom_strcmp(name, "thislib") == 0) { + to_find = cache->thislib; + } uint32_t hash = calculate_libname_hash(cache, name); for (int i = 0; i < cache->size; i++) { struct libcache_item* cache_lib = &cache->libs[i]; - if (cache_lib->hash == hash) { + // search by hash or by pointer for special case + if (cache_lib->hash == hash || cache_lib->header == to_find) { return cache_lib; } } @@ -545,6 +552,7 @@ void test(struct libcache& cache); __attribute__((constructor)) static void bruh(int argc, const char *const argv[], const char *const envp[], const char *const apple[], const struct ProgramVars *vars) { + printf("=== manual symbol bind starts ===\n"); set_cwd(envp); // ProgramVars contains pointer to main executable (mapped) file @@ -572,6 +580,7 @@ bruh(int argc, const char *const argv[], const char *const envp[], free(cache.libs[i].segment); } free(cache.libs); + printf("=== manual symbol bind completes ===\n"); } void build_cache(struct libcache& cache, void* main) { @@ -708,7 +717,10 @@ void fix(struct libcache& cache) { #include "out/b.h" // think of a way to get what binary to fix // so we can iterate through them - struct libcache_item* libfixing = get_libcache_with_name(&cache, "./out/a"); + if (nimports == 0) { + printf("there is no imports to fix\n"); + } + struct libcache_item* libfixing = get_libcache_with_name(&cache, lib_to_resolve); // print_macho_summary(libfixing->header); for (int i = 0; i < nimports; i++) { struct imported_symbol symbol = imported_table[i]; @@ -742,7 +754,7 @@ void fix(struct libcache& cache) { symbol.name, fix_at); printf(" from=%s\n", symbol.lib); printf(" segment id=%d; offset=0x%llx;", symbol.segment_i, symbol.offset); - printf(" resolved=%p\n", resolved); + printf(" resolved=%llx(%p)\n", *(uint64_t*)fix_at, resolved); } for (int j = 0; j < npage_rw_fixed; j++) { diff --git a/research/custom_loader/build.sh b/research/custom_loader/build.sh index 442bf99..dd4018d 100755 --- a/research/custom_loader/build.sh +++ b/research/custom_loader/build.sh @@ -2,7 +2,7 @@ VERSION=${1:-14} OUT=./out -LOGIC=2 +LOGIC=3 mkdir -p $OUT @@ -48,6 +48,25 @@ clang++ -mmacosx-version-min=$VERSION -o $OUT/libb.dylib -shared -Wl,-reexport_l out/a +elif [[ $LOGIC -eq 3 ]] +then +# remove imports test + +# libc to test reexport custom lib +clang++ -mmacosx-version-min=$VERSION -o $OUT/libc.dylib -shared c.cc + +# create our dummy lib first +clang++ -mmacosx-version-min=$VERSION -o $OUT/libb.dylib -shared -Wl,-reexport_library out/libc.dylib dummy.cc +# build a references libb +clang -fobjc-arc -ObjC -mmacosx-version-min=$VERSION -o $OUT/a -L"./out" -lb a.mm + +# extract symbols from a +../../macho-go/bin/ios-wrapper remove-imports $OUT/a -o $OUT/a > $OUT/b.h +# build libb with symbols extracted from a +clang++ -mmacosx-version-min=$VERSION -o $OUT/libb.dylib -shared -Wl,-reexport_library out/libc.dylib b.cc + +out/a + else # dummy test build