盘一下method_exchangeImplementations使用的注意项

常用的HOOK方式

1、Method Swizzling:method_exchangeImplementations (三方可以使用RSSwizzle)
2、消息转发方案:Aspects
3、通过fishhook:除了可以hook c函数,fishhook+汇编还可以hook objc_msgSend实现全打点.#
4、Cydia Substrate
5、通过libffi:例如饿了么开源的Stinger

使用method_exchangeImplementations的⚠️注意项

  • 若父类和子类都没有原方法,有可能导致循环调用
  • 若父类有原方法,子类并没实现该方法,会导致父类的原方法被交换,导致其它子类的实现受到影响,比如找不到方法奔溃
  • 若原方法里有使用_cmd作为业务逻辑,方法交换后,会导致_cmd变成hook后的,影响原方法功能实现
  • 若原方法被偶数次调用了同一个swizzle方法,会导致方法交换成自身,等于没有hook
  • 若原方法被多个业务方进行多次swizzle,可能会产生一定的污染,比如要统计原方法的耗时时间,实际上包含了多个swizzle后函数的运行时间
  • 若使用method_exchangeImplementations进行hook,通常要在该类初始化之前实现,一般开发会放到+load 或是__attribute__((constructor))函数里dispatch_once里执行;+load 或是__attribute__((constructor))函数带来的问题是,会影响应用启动速度
  • 若使用method_exchangeImplementations进行hook,不在+load 或是__attribute__((constructor))函数里调用,延迟调用,不容易控制时机,导致还没hook,类对象或是实例就被创建
  • 父类、子类各种分类里做swizzle导致的一些问题
  • 另外命名冲突也会导致失效或是循环调用等问题
  • 另外,对于系统类的hook一定要小心,比如NSArray等类簇
  • 若因为hook出现bug,排查问题会增加一定的时间和难度:比如,之前我们应用内支付业务,使用了Method Swizzling进行AOP打点,测试时候发现应用内支付收不到苹果的返回。通过分析,因为项目里有使用facebook sdk以及firebase sdk(广告统计),发现它们都有对应用内支付做hook操作(开始是猜测,后续通过hopper印证),导致了该问题
总结:hook是风险与便利共存,以上部分问题是method_exchangeImplementations特有,有些是hook共性问题,使用的时候一定要当心。

另外,补充一篇hook大乱斗分析的文章:http://yulingtianxia.com/blog/2017/04/17/Objective-C-Method-Swizzling/

posted @ 2021-05-15 17:53  七夜i  阅读(528)  评论(0编辑  收藏  举报