-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
您这个和Aspects的instance hook有什么不同吗😂 #1
Comments
在开源这份代码之前我并未了解和使用过aspect,发表完https://mp.weixin.qq.com/s/wxigL1Clem1dR8Nkt8LLMw 这篇技术文章之后看到有些留言提到了aspect然后我去github大概看了一下基本思路都是基于类似kvo的isa替换,但是从api设计以及实现上也有明确的区别。具体区别或者异同我最近先研究下aspect源码,随后会给出答案。 |
还包括了统一hook时替换imp为objc_msgForward,hook forwardInvocation: 这种细节; |
在开源这份代码之前我并未了解和使用过aspects,发表完https://mp.weixin.qq.com/s/wxigL1Clem1dR8Nkt8LLMw 这篇技术文章之后看到有些留言提到了aspects然后我去github大概看了一下基本思路都是基于类似kvo的isa替换,但是从api设计以及实现上也有明确的区别,我们通过以下示例简要介绍下: 假设有这样一个自定义类Test,在其内部定义了一个求和的方法,接收四个int类型的参数。 @implementation Test
- (int)sumWithA:(int)a b:(int)b c:(int)c d:(int)d {
return a + b + c + d;
}
@end 现在要求将四个参数分别平方然后再求和。 使用aspects实现如下: Test *testObj = [Test new];
[testObj aspect_hookSelector:@selector(sumWithA:b:c:d:) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> info, int a, int b, int c, int d) {
int aa = a * a;
int bb = b * b;
int cc = c * c;
int dd = d * d;
[info.originalInvocation setArgument:&aa atIndex:2];
[info.originalInvocation setArgument:&bb atIndex:3];
[info.originalInvocation setArgument:&cc atIndex:4];
[info.originalInvocation setArgument:&dd atIndex:5];
} error:NULL];
int sum = [testObj sumWithA:1 b:2 c:3 d:4];
NSLog(@">>>> %d", sum); // >>>> 30 使用SDMagicHook实现如下: Test *testObj = [Test new];
[testObj hookMethod:@selector(sumWithA:b:c:d:) impBlock:^(typeof(testObj) this, int a, int b, int c, int d) {
__block int res;
[this callOriginalMethodInBlock:^{
res = [this sumWithA:a * a b:b * b c:c * c d:d * d];
}];
return res;
}];
int sum = [testObj sumWithA:1 b:2 c:3 d:4];
NSLog(@">>>> %d", sum); // >>>> 30 由以上demo可以看出: 2.aspects将原始方法封装在NSInvocation里面,如果想要修改 |
其实触发方法转发走 forwardInvocation、替换 isa 指针、对象级别 Hook 等等这些都是老生常谈的Hook 技术,很多组件都基于这套方案来 Hook,在长时间使用后也暴露了很多已知的缺陷。我之前写的节流限频组件也是用到了这些技术,文章大部分都是介绍 Aspects 没有处理好的场景: 不过凡是基于方法转发的 Hook 方案都有一个无法解决的致命问题,就是父子类都 Hook 了同一个方法,然后子类调用父类 super 的时候会死循环。这也是为何这个方案在多年之后 Aspects 的作者终于声明它不再适用于生产环境。 而此问题需要吴子奇基于桥的 Hook 在汇编层面来解决。 想问下除了原理基本相同,API 略有不同之外,有没有解决 Aspects 相关技术带来的这些通病呢? |
关于你提到的第一个问题: 关于你提到的Aspects本身遇到但是尚未解决的问题:在aspects的readme中看到了他们介绍到有“KVO works if observers are created after your calls aspect_hookSelector: It most likely will crash the other way around. Still looking for workarounds here - any help appreciated.”这样一个问题。SDMagicHook测试了一下同样遇到了,但是我们已经有了相关解决方案,大概会在下周一前后同步到github上。 还有其他问题的话欢迎持续交流反馈 @yulingtianxia |
兼容系统KVO已经实现,欢迎更新&反馈 |
关于这个问题,我相信 https://github.com/623637646/SwiftHook 很好的解决了这个问题。 |
No description provided.
The text was updated successfully, but these errors were encountered: