iOS 常用的Hook方式

iOS 常用的Hook方式面向切面编程就是在不需要改变源代码逻辑的前提下,给系统的方法增加一些逻辑进去,并且这个逻辑是在整个程序的生命周期之内都能够应用.

Aspects 是iOS老牌的AOP库

Aspects主要是利用了forwardInvocation进行转发,Aspects其实利用和kvo类似的原理,通过动态创建子类的方式,把对应的对象isa指针指向创建的子类,然后把子类的forwardInvocation的IMP替成__ASPECTS_ARE_BEING_CALLED__,假设要hook的方法名XX,在子类中添加一个Aspects_XX的方法,然后将Aspects_XX的IMP指向原来的XX方法的IMP,这样方便后面调用原始的方法,再把要hook的方法XX的IMP指向_objc_msgForward,这样就进入了消息转发流程,而forwardInvocation的IMP被替换成了__ASPECTS_ARE_BEING_CALLED__,这样就会进入__ASPECTS_ARE_BEING_CALLED__进行拦截处理

消息转发流程图

image.png

AOP框架Aspects实现原理

Stinger 是饿了么开源的AOP库

没有使用手动消息转发。解析原方法签名,使用libffi中的ffi_closure_alloc构造与原方法参数一致的”函数” — _stingerIMP,以替换原方法函数指针;此外,生成了原方法和Block的调用的参数模板cif和blockCif。方法调用时,最终会调用到void _st_ffi_function(ffi_cif *cif, void *ret, void **args, void *userdata), 在该函数内,可获取到方法调用的所有参数、返回值位置,主要通过ffi_call根据cif调用原方法实现和切面block。

使用 libffi 实现 AOP

Method Swizzling

Method originalMethod = class_getInstanceMethod([self class], originalSelector);
    Method swizzledMethod = class_getInstanceMethod([self class], swizzledSelector);
    
    BOOL didAddMethod =
    class_addMethod([self class],
                    originalSelector,
                    method_getImplementation(swizzledMethod),
                    method_getTypeEncoding(swizzledMethod));
    
    if (didAddMethod) {
        class_replaceMethod([self class],
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }

fishhook

通过fishhook:除了可以hook c函数,fishhook+汇编还可以hook objc_msgSend实现全打点.

Cydia Substrate

Cydia Substrate是一个基于Hook的代码修改框架,可以在Android、iOS平台使用,并实现修改系统默认代码。

method swizzling/Aspects/Stinger对比

对比项 swizzling Aspects Stinger
速度 极快 非常快
Api友好度 非常差 非常好 非常好
类的hook 支持 支持 支持
实例对象的hook 不支持 支持 支持
调用原方法时改变selector 修改 修改 不修改
方法可能因命名冲突 不会 不会
兼容其他hook方式(RAC, JSPactch…) 兼容 不兼容 兼容
支持多线程增加hook 自己加锁 支持 支持
hook可预见性,可追溯性 非常差 非常好
修改父类方法实现 可能会 不会 不会

参考:Stinger到底能比Aspects快多少

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/21722.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注