erase objc method names

This commit is contained in:
2024-01-10 14:19:59 +07:00
parent 07f361d8ac
commit a68bbf2b8f
9 changed files with 212 additions and 13 deletions

View File

@ -1,4 +1,5 @@
#import <Foundation/Foundation.h>
#include <objc/message.h>
#include <stdio.h>
@interface Foo : NSObject
@ -6,7 +7,7 @@
@implementation Foo
- (void)bar {
NSLog(@"%@", self);
NSLog(@"[Foo bar]: %@", self);
}
@end
@ -44,9 +45,16 @@ hmmge(int argc, char** argv) {
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"Hello, World!");
NSLog(@"main()");
NSLog(@"selector for \"bar:\" %p", @selector(bar:));
Foo *foo = [[Foo alloc] init];
[foo bar];
NSLog(@"directly call \"bar\" %p through objc_msgSend %p with object foo %p\n", @selector(bar), objc_msgSend, foo);
typedef void (*barfunc)(id, SEL);
barfunc bar_ = &objc_msgSend;
bar_(foo, @selector(bar));
}
printf("argc=%d\n", argc);

View File

@ -1279,6 +1279,7 @@ void fix_objc(struct libcache_item *libfixing, struct libcache &cache) {
// "mov rcx, 123;"
// "call r12;");
printf("fixing objective-c\n");
void *header = libfixing->header;
const uint32_t magic = *(uint32_t *)header;
char *ptr = (char *)header;
@ -1305,6 +1306,48 @@ void fix_objc(struct libcache_item *libfixing, struct libcache &cache) {
printf("segment %s\n", name);
if (custom_strcmp(name, "__TEXT") == 0) {
slide = (uint64_t)header - vmaddr;
uint64_t nsect = *((uint32_t *)ptr + 8 * 2);
char *sections_ptr = (char *)((uint32_t *)ptr + 18);
for (int sec = 0; sec < nsect; sec++) {
char *secname = sections_ptr;
printf("section %s\n", secname);
if (custom_strncmp(secname, "__objc_methname", 16) == 0) {
uint64_t addr = *((uint64_t *)sections_ptr + 4);
uint64_t size = *((uint64_t *)sections_ptr + 5);
uint64_t *data_ptr = (uint64_t *)(addr + slide);
// printf("methname addr %p : %s\n", data_ptr, (char*)data_ptr);
break;
}
sections_ptr += 16 * 2 + 8 * 2 + 4 * 8;
}
} else if (custom_strcmp(name, "__DATA") == 0) {
uint64_t nsect = *((uint32_t *)ptr + 8 * 2);
char *sections_ptr = (char *)((uint32_t *)ptr + 18);
for (int sec = 0; sec < nsect; sec++) {
char *secname = sections_ptr;
printf("section %s\n", secname);
if (custom_strncmp(secname, "__objc_selrefs", 16) == 0) {
uint64_t addr = *((uint64_t *)sections_ptr + 4);
uint64_t size = *((uint64_t *)sections_ptr + 5);
uint64_t *data_ptr = (uint64_t *)(addr + slide);
uint32_t trie_size;
void* libdyld = cache.libdyld;
void *libdyld_export_trie = get_export_trie(libdyld, trie_size);
typedef void *(*dyld_get_objc_selector_t)(const char*);
dyld_get_objc_selector_t dyld_get_objc_selector_func = (dyld_get_objc_selector_t)find_in_export_trie(
libdyld, libdyld_export_trie, "__dyld_get_objc_selector");
// resolve method names that cached in the dyld
for (int i = 0; i < bshield_data::n_selectors; i++) {
uint32_t idx = bshield_data::special_selectors_idx[i];
char* name = bshield_data::special_selectors_name[i];
data_ptr[idx] = (uint64_t)dyld_get_objc_selector_func(name);
}
}
sections_ptr += 16 * 2 + 8 * 2 + 4 * 8;
}
} else if (custom_strcmp(name, "__DATA_CONST") == 0) {
uint64_t nsect = *((uint32_t *)ptr + 8 * 2);
char *sections_ptr = (char *)((uint32_t *)ptr + 18);

View File

@ -64,11 +64,11 @@ clang -fobjc-arc -ObjC -mmacosx-version-min=$VERSION -o $OUT/a -L"./out" -lb a.m
# extract symbols from a
# ../../macho-go/bin/ios-wrapper pepe -o $OUT/a-fixed -b $OUT/b.bcell --remove-imports --remove-exports --remove-symbol-table --keep-imports _printf $OUT/a
../../macho-go/bin/ios-wrapper pepe -o $OUT/a-fixed -b $OUT/b.bcell --remove-imports --remove-exports $OUT/a
../../macho-go/bin/ios-wrapper pepe -o $OUT/a-fixed -b $OUT/b.bcell --remove-imports --remove-exports --remove-symbol-table --remove-others $OUT/a
../../macho-go/bin/ios-wrapper bcell2header -b $OUT/b.bcell -o $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
# ../../macho-go/bin/ios-wrapper pepe -o $OUT/libb.dylib -b $OUT/libb.bcell --remove-imports --remove-exports --keep-imports _dyld_get_sdk_version --keep-imports _malloc --keep-imports _printf --keep-imports ___stack_chk_guard $OUT/libb.dylib
../../macho-go/bin/ios-wrapper pepe -o $OUT/libb.dylib -b $OUT/libb.bcell --remove-imports --remove-exports --remove-symbol-table --remove-others --keep-imports _dyld_get_sdk_version --keep-imports _malloc --keep-imports ___stack_chk_guard --keep-imports _printf $OUT/libb.dylib
# resign
codesign --force --deep -s - $OUT/a-fixed