美文网首页
好奇下 WeChatICU-ForMac 插件

好奇下 WeChatICU-ForMac 插件

作者: 天空中的球 | 来源:发表于2021-02-23 14:50 被阅读0次

    在看到 Mac 微信插件 的时候,看到可以防撤回,群消息统计之类的功能,超赞,于是想着去了解下。
    哦,先从 简单的 Mac 企业微信插件 了解下,功能相对简单些只有 消息防撤回和去掉会话水印的。

    企业微信插件功能

    项目很简单,从下面几个类就可以看出:

    WeChatICU

    先总的归纳下,感觉可以注意的几个点:

    • __attribute__((constructor)) 函数
    • fishhook
    • 如何找到要替换的方法

    一、__attribute__((constructor)) 函数理解

    在 main 函数中执行

    static void __attribute__((constructor)) initialize(void) {
        [NSObject hook];
    }
    

    简单的说,__attribute__((constructor)) 方便我们在main函数之前,执行函数方法,便于我们做一些准备工作。

    二、fishhook 了解

    Facebook 提供的 fishhook 是一个非常牛的Mach-O二进制库,原因是因为它可以动态重新绑定Mach-O符号, 最大功能就是可以干涉系统函数。
    它利用MachO文件加载原理,原理是通过修改懒加载和非懒加载两个表的指针达到C函数HOOK的目的,所以不能修改自己定义的函数,只能修改系统库函数。

    // 1、创建函数指针,用保存原始的函数的地址
    static NSString *(*original_NSHomeDirectory)(void);
    
    // 2、创建新的函数
    NSString *swizzled_NSHomeDirectory(void) {
        return [NSString stringWithFormat:@"%@-->标记OK了", original_NSHomeDirectory()];
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        /*
        struct rebinding {
          const char *name;//需要HOOK的函数名称,字符串
          void *replacement;//替换到那个新的函数上(函数指针,也就是函数的名称)
          void **replaced;//保存原始函数指针变量的指针(它是一个二级指针!)
        };
         
        rebind_symbols (
         arg1 : 存放rebinding结构体的数组
         arg2 : 数组的长度
        )
         */
        // 3、执行符号重绑定
        rebind_symbols((struct rebinding[1]) {
            {"NSHomeDirectory", swizzled_NSHomeDirectory, (void *) &original_NSHomeDirectory}
        }, 1);
    }
    

    以上就是替换 NSHomeDirectory 地址的 Demo 展示。

    至于具体的分析 fishhook ,可以参考这个 分析 fishhook

    三、如何找到要替换的方法 好奇

    + (void)hook {
        // 水印
        hookMethod(objc_getClass("WEWConversation"), @selector(isConversationSupportWaterMark), [self class], @selector(hook_isConversationSupportWaterMark));
       // 撤回
        hookMethod(objc_getClass("WEWMessage"), @selector(isRevoke), [self class], @selector(hook_isRevoke));
        hookMethod(objc_getClass("NSBundle"), @selector(executablePath), [self class], @selector(hook_executablePath));
    }
    

    对于这个 hookMethod 我们是很熟悉的

    void hookMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector) {
        Method originalMethod = class_getInstanceMethod(originalClass, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector);
        if (originalMethod && swizzledMethod) {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    }
    

    但是如何找到WEWConversation 中的 isConversationSupportWaterMarkWEWMessage 中的 isRevoke 才是关键的。

    这是逆向相关的,对这个如何的, 通过 Hopper 来找的,打开分析了下我们可以看到:


    hopper isRevoke

    但是如何确定是哪个类,哪个方法的呢?

    • 1、猜,通过 UI Reveal 获取视图层次信息去猜测的,以及相关动词方法名猜。
    • 2、获取方法的 IMP ,将地址翻译成 Selector

    参考 如何在逆向工程中 Hook 得更准 - 微信屏蔽好友&群消息实战,还是去实战一个 Mac App 再说的。

    相关文章

      网友评论

          本文标题:好奇下 WeChatICU-ForMac 插件

          本文链接:https://www.haomeiwen.com/subject/meuxzktx.html