Mac QQ 消息防撤回的尝试
Doveccl
本文距离上次更新已过去 0 天,部分内容可能已经过时,请注意甄别。

在 MAS 版本的 QQ 更新到版本 5.5.1 之后,终于支持撤回消息了(当然也就不能防撤回了)

image

通过万能的 Google 查找了一下防撤回方法,没想到还真的找到了

尝试一:反编译二进制文件(参考:美女驱动型程序猿

  1. 安装 Hopper Disassembler

  2. 用 Hopper Disassembler 打开 /Applications/QQ.app/Contents/MacOS/QQ

    需要注意的是,当二进制文件被打开之后不要急于操作,要等待右下角 Working 消失,这个时间会非常长

  3. 在左边 Labels 一栏搜索 handleRecallNotify 关键词,得到如下结果

    image

  4. 选中 push rbp 这一行,按住 Option + A 并输入 ret,之后再点击 Assembler and Go Next 并按 ESC 结束编辑,大概意思是,直接让这个函数返回,不做任何操作(为啥每次都把 rbp 看成 rbq 呢?捂脸……)

    image

  5. 按住 Shift + Command + E 来输出新的二进制文件,会提示是否移除原有的签名,确认即可,这个时候把新的二进制文件复制到 /Applications/QQ.app/Contents/MacOS/ 把原来的替换掉就行

P.S. 经过参考链接评论区提醒,在测试发现修后的 QQ 把缓存全都放到了 ~/Documents/,本来好好的文档目录多出了一堆乱七八糟的文件,对于强迫症患者而言是绝对不能忍的

尝试二:动态库注入 hook(参考:0xBBC

  1. 新建 OC 源文件 QQUnrecall.m

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #import <Foundation/Foundation.h>
    #import <objc/runtime.h>

    void handleRecallNotifyIsOnline(id _i, SEL _s, void * _p, BOOL _b) {
    NSLog(@"已经阻止 QQ 撤回一条消息");
    }

    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wundeclared-selector"

    static void __attribute__((constructor)) initialize(void) {
    method_setImplementation(
    class_getInstanceMethod(
    NSClassFromString(@"QQMessageRevokeEngine"),
    @selector(handleRecallNotify:isOnline:)
    ),
    (IMP)&handleRecallNotifyIsOnline
    );
    }

    #pragma clang diagnostic pop
  2. 编译成动态库文件 clang -dynamiclib -framework Foundation QQUnrecall.m -o libQQUnrecall.dylib

  3. 使用 export DYLD_INSERT_LIBRARIES=libQQUnrecall.dylib 后运行 /Applications/QQ.app/Contents/MacOS/QQ 得到如下测试结果

    image

  4. 简单包装一下避免每次通过终端启动 QQ

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #define QPATH "/Applications/QQ.app/Contents/MacOS/"
    #define LIBENV "DYLD_INSERT_LIBRARIES"
    #define LIBNAME "libQQUnrecall.dylib"

    #define HOOK "export " LIBENV "=%s" LIBNAME
    #define RUN QPATH "QQ"
    #define AND " && "

    #define CMD HOOK AND RUN

    #define M 1024

    char path[M], buff[M];
    unsigned long len, i;

    int main(int argc, char **argv) {
    strcpy(path, argv[0]);
    len = strlen(path);
    for (i = len - 1; i; i--) {
    if (path[i] == '/')
    break ;
    path[i] = 0;
    }
    sprintf(buff, CMD, path);
    system(buff);
    return 0;
    }

P.S. 点击 这里 下载成品(macOS 10.12 以下版本最好自行编译,否则可能会出现问题),理论上只要撤回函数名称和参数不改,对于所有版本 QQ 都可用此方法

 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
总字数 24.2k 访客数 访问量