add test for objc

This commit is contained in:
nganhkhoa 2023-06-07 10:49:59 +07:00
parent 88bb0aa09d
commit 887c53ed44
3 changed files with 44 additions and 5 deletions

View File

@ -0,0 +1,8 @@
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"Hello, World!");
}
return 0;
}

View File

@ -31,7 +31,6 @@ void set_cwd(const char *const *envp) {
pwd = (char *)(*envp + 4); pwd = (char *)(*envp + 4);
for (; pwd[pwd_len] != 0; pwd_len++) for (; pwd[pwd_len] != 0; pwd_len++)
; ;
printf("%s\n", pwd);
} }
const uint32_t magic64 = 0xfeedfacf; 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 // i don't know if dyld_stub_binder should be better
// because if they are not familiar with dyld // because if they are not familiar with dyld
// they would not suspect dyld_stub_binder inside modern macho // 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); extern "C" uint32_t dyld_get_sdk_version(const mach_header *mh);
void exported_from_c(); 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) { 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); uint32_t hash = calculate_libname_hash(cache, name);
for (int i = 0; i < cache->size; i++) { for (int i = 0; i < cache->size; i++) {
struct libcache_item* cache_lib = &cache->libs[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; return cache_lib;
} }
} }
@ -545,6 +552,7 @@ void test(struct libcache& cache);
__attribute__((constructor)) static void __attribute__((constructor)) static void
bruh(int argc, const char *const argv[], const char *const envp[], bruh(int argc, const char *const argv[], const char *const envp[],
const char *const apple[], const struct ProgramVars *vars) { const char *const apple[], const struct ProgramVars *vars) {
printf("=== manual symbol bind starts ===\n");
set_cwd(envp); set_cwd(envp);
// ProgramVars contains pointer to main executable (mapped) file // 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[i].segment);
} }
free(cache.libs); free(cache.libs);
printf("=== manual symbol bind completes ===\n");
} }
void build_cache(struct libcache& cache, void* main) { void build_cache(struct libcache& cache, void* main) {
@ -708,7 +717,10 @@ void fix(struct libcache& cache) {
#include "out/b.h" #include "out/b.h"
// think of a way to get what binary to fix // think of a way to get what binary to fix
// so we can iterate through them // 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); // print_macho_summary(libfixing->header);
for (int i = 0; i < nimports; i++) { for (int i = 0; i < nimports; i++) {
struct imported_symbol symbol = imported_table[i]; struct imported_symbol symbol = imported_table[i];
@ -742,7 +754,7 @@ void fix(struct libcache& cache) {
symbol.name, fix_at); symbol.name, fix_at);
printf(" from=%s\n", symbol.lib); printf(" from=%s\n", symbol.lib);
printf(" segment id=%d; offset=0x%llx;", symbol.segment_i, symbol.offset); 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++) { for (int j = 0; j < npage_rw_fixed; j++) {

View File

@ -2,7 +2,7 @@
VERSION=${1:-14} VERSION=${1:-14}
OUT=./out OUT=./out
LOGIC=2 LOGIC=3
mkdir -p $OUT mkdir -p $OUT
@ -48,6 +48,25 @@ clang++ -mmacosx-version-min=$VERSION -o $OUT/libb.dylib -shared -Wl,-reexport_l
out/a 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 else
# dummy test build # dummy test build