【求助】通过fishhook,hook'_NSDictionaryOfVariableBindings'函数编译不过

code

static id ori__NSDictionaryOfVariableBindings(NSString *commaSeparatedKeysString, __nullable id firstValue, ...);

static id new__NSDictionaryOfVariableBindings(NSString *commaSeparatedKeysString, __nullable id firstValue, ...){
    va_list args;
    va_start(args, firstValue);
    
    va_end(args);
    return nil;
}
__attribute__((constructor)) static void _wsApplicationConstructorCallback() {
    rebind_symbols((struct rebinding[1]){{"__NSDictionaryOfVariableBindings", new__NSDictionaryOfVariableBindings, (void*)&ori__NSDictionaryOfVariableBindings}},1);
  
}

编译错误提示如下:

_ori__NSDictionaryOfVariableBindings
Undefined symbols for architecture arm64:
  "_ori__NSDictionaryOfVariableBindings", referenced from:
      l_constinit in WSLaunchDetector.o
ld: symbol(s) not found for architecture arm64

这种问题有哪位大佬了解么?
如果去掉rebind_symbols((struct rebinding[1]){{"__NSDictionaryOfVariableBindings", new__NSDictionaryOfVariableBindings, (void*)&ori__NSDictionaryOfVariableBindings}},1);这句,也就是不用fishhook就可以编译过。

你要声明成函数指针啊大兄弟

嗯嗯,是的,验证没问题,感谢。

代码改成这样,可以编译过:

static NSDictionary * (*ori__NSDictionaryOfVariableBindings)(NSString *commaSeparatedKeysString, __nullable id firstValue, ...);

static NSDictionary * new__NSDictionaryOfVariableBindings(NSString *commaSeparatedKeysString, __nullable id firstValue, ...){
    va_list args;
    va_start(args, firstValue);
    
    va_end(args);
    return nil;
}

...

rebind_symbols((struct rebinding[1]){{"__NSDictionaryOfVariableBindings", new__NSDictionaryOfVariableBindings, (void*)&ori__NSDictionaryOfVariableBindings}},1);

但是还是hook不到这个函数
UIKIT_EXTERN NSDictionary *_NSDictionaryOfVariableBindings(NSString *commaSeparatedKeysString, __nullable id firstValue, ...) NS_AVAILABLE_IOS(6_0);

内部函数是这个

为什么会这样捏?

你确定这个函数被直接调用了吗

fishhook只能hook被直接调用的外部函数

如果你要hook _NSDictionaryOfVariableBindings ,那就在代码里写这个名称而不是__NSDictionaryOfVariableBindings __NSDictionaryOfVariableBindings 这个名称是经过 名字修饰(Name Mangling)(C只是在前缀加了个_)。

在fishhook源码里可以看到,查找符号比对的时候是比较Name Mangling之前的,&symbol_name[1]

if (symbol_name_longer_than_1 && strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) {
    kern_return_t err;

    if (cur->rebindings[j].replaced != NULL && indirect_symbol_bindings[i] != cur->rebindings[j].replacement)
        *(cur->rebindings[j].replaced) = indirect_symbol_bindings[i];
    err = vm_protect(mach_task_self(), (uintptr_t)indirect_symbol_bindings, section->size, 0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY);
    if (err == KERN_SUCCESS) {
        indirect_symbol_bindings[i] = cur->rebindings[j].replacement;
    }
    goto symbol_loop;
}