Hookzz只打印部分方法

工具:MonkeyDev,Hookzz

本来使用lldb想去断点具体的方法,但是发现断不进去,然后用hookzz打印方法,发现启动的时候还打印一些方法,启动之后就完全不打印任何方法了。

启动的时候打印方法也只是部分方法,比如说,里面有个 LauncherAppDelegate,能打印出来 **[LauncherAppDelegate respondsToSelector: ]**和 [LauncherAppDelegate class ],但是打印不了[LauncherAppDelegate application:didFinishLaunchingWithOptions:],我断点能进入application:didFinishLaunchingWithOptions。

hookzz方法如下



#import <Foundation/Foundation.h>
#import <dlfcn.h>
#import <mach-o/dyld.h>
#import <objc/message.h>
#import <objc/runtime.h>


#include "hookzz.h"

#ifndef ZREG_MACRO
#define ZREG_MACRO
#if defined(__LP64__)
#define ZREG(n) general.regs.x##n
#else
#define ZREG(n) general.regs.r##n
#endif
#endif

char decollators[512]           = {0};

@interface OCMethodMonitor : NSObject

@end

@implementation OCMethodMonitor

+ (void)load {
    [self hook_objc_msgSend];
    OCMethodMonitor *z = [OCMethodMonitor new];
    [z log_for_test];
}

- (void)log_for_test {
    NSLog(@"catch by HookZz:OCMethodMonitor");
}

+ (void)hook_objc_msgSend {
     ZzHookGOT(NULL,"objc_msgSend", NULL, NULL, objc_msgSend_pre_call, objc_msgSend_post_call);
}

void objc_msgSend_pre_call(RegState *rs, ThreadStackPublic *ts, CallStackPublic *cs, const HookEntryInfo *info) {
    char *selector = (char *)rs->ZREG(1);
    id arg1 = (id)rs->ZREG(2);
    id tmpObject = (id)rs->ZREG(0);
    Class tmpClass  = object_getClass(tmpObject);
//    class_getClassMethod
    NSString *selStr = [NSString stringWithFormat:@"%s", selector];
    
  
    if (!tmpClass)
        return;

    const char *className               = class_getName(tmpClass);

    SEL selectter = NSSelectorFromString(selStr);
    if (!selectter) {
        return;
    }
    Method tempMethod = class_getInstanceMethod(tmpClass, selectter);
    
    if (!arg1) {
        return;
    }
    
    if (!tempMethod) {
        return;
    }
    
    const char *tempMethodStr = sel_getName(method_getName(tempMethod));
    
    const char *arg1Name = method_getTypeEncoding(tempMethod);
    
    if (strstr(className, "__")  ||  strstr(className, "YY") ||  strstr(className, "NS") ||  strstr(className, "MJ") || strstr(className, "UI") || strstr(className, "NS")|| strstr(className, "BLY") || strstr(className, "JS") || strstr(className, "SD") || strstr(className, "CQPageControl") ) {
        return;
    }

    memset(decollators, '-', 512);
    if (ts->size * 3 >= 512)
        return;
    decollators[ts->size * 3] = '\0';

    printf("-(%s) [%ld] %s [%s %s ]\n", arg1Name,ts->thread_id, decollators, className, selector);
    
}

@end

尝试过反调试, AntiAntiDebug并没有打印对应的反调试日志,自己写的反调试倒是进去了syscall


#import <sys/sysctl.h>
#import <sys/proc.h>
#import <substrate.h>

int (*old__sysctl)(int *name, u_int num, void* buffer, size_t *bufferSize, void *set0, size_t set1);
int new_sysctl(int *name, u_int num, void* buffer, size_t *bufferSize, void *set0, size_t set1)
{
    NSLog(@"========================new_sysctl");
    int result =  old__sysctl(name, num, buffer, bufferSize, set0, set1);
    size_t info_size = sizeof(struct kinfo_proc);
    if(info_size == *bufferSize){
    NSLog(@"info_size == buffer_size");
    int * flag = (int*)buffer+(0x20/sizeof(int));
        *flag = ~P_TRACED;
    }
    return result;
}
%ctor {
MSHookFunction((void *)sysctl, (void *)&new_sysctl, (void **)&old__sysctl);
}

还请大佬们指导下,跪谢~

  1. 这个是有一定的 filter 过滤的, 比如入 selector 地址, metaclass 地址的过滤
  2. libmainthreadchecker.dylib 对函数的 lr 进行 Validation check.

目前可以建议换个思路. 或者把 mainthreadchecker 关闭, 然后调整 filter.

嗯嗯,感谢,我去试试

请问下lldb断点是不是也有这种filter过滤的