1、场景分析

以微信抢红包为例
image.png
如果想要了解抢红包时调用了哪个方法,正常思路是先找到当前视图控制器,再找到对应方法。可以通过cycript或者Reveal来查看当前的视图控制器,以cycript为例:
cy# MJFrontVc()

  1. #"<BaseMsgContentViewController: 0x15b65c000>"

然后将微信脱壳,再使用class-dump导出头文件,可以看到这类中有很多个方法:截屏2022-07-29 17.09.16.png
按照之前的思路创建一个tweak项目,然后hook所有的方法,添加打印信息,来找到点击红包的方法:

  1. %hook BaseMsgContentViewController
  2. ...
  3. - (void)bindYReportSdkAndReportLiveExpose:(id)arg1 andViewId:(id)arg2 {
  4. %log; // 打印方法信息(调用者、方法名、参数)
  5. %orig; // 调用原始方法
  6. }
  7. - (void)registerYReportSdk {
  8. %log;
  9. %orig;
  10. }
  11. - (void)onSpeakStop {
  12. %log;
  13. %orig;
  14. }
  15. ...
  16. %end

但是这样手动添加很多方法打印,特别麻烦,这时就需要使用logify来处理了。

2、logify

logify.pl可以将一个头文件快速转换成已经包含打印信息的.x文件:
$ logify.pl xxx.h > xxx.xm
在tweak项目中新建src文件夹,将生成的的BaseMsgContentViewController.x和Tweak.x添加到src目录下,调整Makefile中的配置信息:

  1. tweak_redbag_FILES = $(wildcard src/*.x)

编译tweak代码:

  1. %hook BaseMsgContentViewController
  2. + (void)reload:(id)arg1 sections:(id)arg2 withRowAnimation:(long long)arg3 { %log; %orig; }
  3. - (void)setTableCellUpdateSeq:(unsigned long long )tableCellUpdateSeq { %log; %orig; }
  4. - (unsigned long long )tableCellUpdateSeq { %log; unsigned long long r = %orig; NSLog(@" = %llu", r); return r; }
  5. - (void)setTableReloadSeq:(unsigned long long )tableReloadSeq { %log; %orig; }
  6. - (unsigned long long )tableReloadSeq { %log; unsigned long long r = %orig; NSLog(@" = %llu", r); return r; }
  7. - (void)setChatroomBkgColor:(UIColor *)chatroomBkgColor { %log; %orig; }
  8. - (UIColor *)chatroomBkgColor { %log; UIColor * r = %orig; NSLog(@" = %@", r); return r; }
  9. - (void)setPopBackInteractivePopGesture:(UIScreenEdgePanGestureRecognizer *)popBackInteractivePopGesture { %log; %orig; }
  10. - (UIScreenEdgePanGestureRecognizer *)popBackInteractivePopGesture { %log; UIScreenEdgePanGestureRecognizer * r = %orig; NSLog(@" = %@", r); return r; }
  11. - (void)setMessageTipView:(MessageTipView *)messageTipView { %log; %orig; }
  12. - (MessageTipView *)messageTipView { %log; MessageTipView * r = %orig; NSLog(@" = %@", r); return r; }
  13. - (void)setDismissWithoutReset:(_Bool )dismissWithoutReset { %log; %orig; }
  14. ...
  15. %end

编译过程中可能会遇到一些报错,需要进行定义类、定义协议、删除__weak、删除inout、删除.cxx_destruct方法等操作

安装到iPhone后,打开聊天界面,点击红包时就可以通过控制台的打印信息来分析调用的方法了:
image.png

也可以通过替换%log;来添加自定义的打印信息,例如: NSLog(@"My WeChat Log %@", NSStringFromSelector(_cmd));

3、注意点

使用logify.pl生成.x文件,有很多时候是编译不通过的,需要进行一些处理,可能包括:
1、删掉__weak
2、删掉inout
3、删掉或者声明协议
4、删掉或者声明类,也可以使用void *替换XXClass *