美文网首页
减少crash的方法hook

减少crash的方法hook

作者: 哥只是个菜鸟 | 来源:发表于2021-06-18 11:38 被阅读0次
  • 这种方法可能不够严谨,会出现找不到originalSelector方法的情况
- (void)hookInstanceMethod:(SEL)originalSelector AndSelector:(SEL)swizzledSelector {
    Method originMethod = class_getInstanceMethod(self.class, originalSelector);
    Method newMethod = class_getInstanceMethod(self.class, swizzledSelector);
    method_exchangeImplementations(originMethod, newMethod);
}
+ (void)SwizzledMethod:(Class)class OriginalSelector:(SEL)originalSelector newSelector:(SEL)newSelector {
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method newMethod = class_getInstanceMethod(class, newSelector);
//    if (originMethod && newMethod) {
//        method_exchangeImplementations(originMethod, newMethod);
//    }
    
    //class_addMethod 添加的SEL是 originalSelector ,IMP 是 method_getImplementation(originalMethod),我称他们为原配,
       //如果本类中,已经有 originalSelector,再添加 originalSelector, 肯定返回NO,添加失败,那就直接交换了,跟第一版hook流程一模一样了,
       //如果本类中,没有此SEL,那就会去父类里找,返回的就是父类里的信息,然后将父类的信息,添加到本类中,就相当于,本类完全的继承了父类的方法,
       BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
       if (didAddMethod) {
           //添加成功后,本类中,已经有一个originalSelector方法了
           //我们第一次获得originalMethod是返回父类的originalMethod
           //我们需要再重新获得一下originalMethod,这次返回的不是父类的originalMethod
           //而是我们刚刚class_addMethod添加的到本类的originalMethod
           
           originalMethod = class_getInstanceMethod(class, originalSelector);
       }
       
       //走到这,就证明了,本类中肯定已经有这两个方法了,那就这样直接交换吧。
       method_exchangeImplementations(newMethod, originalMethod);
}
  • 这里只贴避免数组越界的例子,(其他字典,字符串类似),这里注意替换方法的class不能是[NSArray class],之前一直方法替换不成功,问题出在这里
 swizzling_exchangeMethod([NSArray class], @selector(objectAtIndex:), 
swizzling_exchangeMethod(objc_getClass("__NSArray0"), @selector(objectAtIndex:), 
image.png

+ (void)load {
    //__NSArrayI:不可变,2个或2以上元素  __NSArray0:空数组  __NSArrayM:可变  __NSSingleObjectArrayI:只有单个元素
//    [array objectAtIndex:8]
    [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayI") OriginalSelector:@selector(objectAtIndex:) newSelector:@selector(array_objectAtIndex:)];
    [SwizzledHelper SwizzledMethod:objc_getClass("__NSArray0") OriginalSelector:@selector(objectAtIndex:) newSelector:@selector(empty_objectAtIndex:)];
    [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayM") OriginalSelector:@selector(objectAtIndex:) newSelector:@selector(arrayM_objectAtIndex:)];
    [SwizzledHelper SwizzledMethod:objc_getClass("__NSSingleObjectArrayI") OriginalSelector:@selector(objectAtIndex:) newSelector:@selector(singleArray_objectAtIndex:)];

    //array[8]
    [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayI") OriginalSelector:@selector(objectAtIndexedSubscript:) newSelector:@selector(array_objectAtIndexedSubscript:)];
    [SwizzledHelper SwizzledMethod:objc_getClass("__NSArray0") OriginalSelector:@selector(objectAtIndexedSubscript:) newSelector:@selector(empty_objectAtIndexedSubscript:)];
    [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayM") OriginalSelector:@selector(objectAtIndexedSubscript:) newSelector:@selector(arrayM_objectAtIndexedSubscript:)];
    [SwizzledHelper SwizzledMethod:objc_getClass("__NSSingleObjectArrayI") OriginalSelector:@selector(objectAtIndexedSubscript:) newSelector:@selector(singleArray_objectAtIndexedSubscript:)];

    [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayM") OriginalSelector:@selector(removeObjectAtIndex:) newSelector:@selector(arrayM_removeObjectAtIndex:)];
    [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayM") OriginalSelector:@selector(replaceObjectAtIndex:withObject:) newSelector:@selector(arrayM_replaceObjectAtIndex:withObject:)];
    [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayM") OriginalSelector:@selector(insertObject:atIndex:) newSelector:@selector(arrayM_insertObject:atIndex:)];
}

- (id)array_objectAtIndex:(NSUInteger)index {
    if (index < self.count) {
        return [self array_objectAtIndex:index];
    } else {
        return nil;
    }
}

- (id)empty_objectAtIndex:(NSUInteger)index {
    if (index < self.count) {
        return [self empty_objectAtIndex:index];
    } else {
        return nil;
    }
}

- (id)arrayM_objectAtIndex:(NSUInteger)index {
    if (index < self.count) {
        return [self arrayM_objectAtIndex:index];
    } else {
        return nil;
    }
}

- (id)singleArray_objectAtIndex:(NSUInteger)index {
    if (index < self.count) {
        return [self singleArray_objectAtIndex:index];
    } else {
        return nil;
    }
}

- (id)array_objectAtIndexedSubscript:(NSUInteger)index {
    if (index < self.count) {
        return [self array_objectAtIndexedSubscript:index];
    } else {
        return nil;
    }
}

- (id)empty_objectAtIndexedSubscript:(NSUInteger)index {
    if (index < self.count) {
        return [self empty_objectAtIndexedSubscript:index];
    } else {
        return nil;
    }
}

- (id)arrayM_objectAtIndexedSubscript:(NSUInteger)index {
    if (index < self.count) {
        return [self arrayM_objectAtIndexedSubscript:index];
    } else {
        return nil;
    }
}

- (id)singleArray_objectAtIndexedSubscript:(NSUInteger)index {
    if (index < self.count) {
        return [self singleArray_objectAtIndexedSubscript:index];
    } else {
        return nil;
    }
}

- (void)arrayM_insertObject:(id)object atIndex:(NSUInteger)index {
    if (object && index <= self.count) {
        [self arrayM_insertObject:object atIndex:index];
    }
}

- (void)arrayM_removeObjectAtIndex:(NSUInteger)index {
    if (index < self.count) {
         [self arrayM_removeObjectAtIndex:index];
    }
}

- (void)arrayM_replaceObjectAtIndex:(NSUInteger)index withObject:(id)object {
    if (object && index < self.count) {
         [self arrayM_replaceObjectAtIndex:index withObject:object];
    }
}


@end

相关文章

  • 减少crash的方法hook

    这种方法可能不够严谨,会出现找不到originalSelector方法的情况 推荐第二种,借鉴https://ww...

  • hook delegate 正确姿势

    核心hook方法:网上有类似hook方式,但没考虑继承和子类的问题,会导致循环调用crash。 使用 案例:(XX...

  • 记录Xposed常用的使用方法

    一、hook方法 在方法调用前HOOK (beforeHookedMethod) 在方法调用后HOOK (afte...

  • 遍历hook Dex中的类

    创建DexFile 遍历拿出所有类名 找到类对象,进行hook hook构造函数 hook方法 打印hook方法中的日志

  • Aspects 源码分析

    需求 hook 实例对象的方法(仅该对象的方法被hook) hook 类对象的方法(该类所有对象调用该方法的时候,...

  • KSCrash源码学习

    KSCrash监控的crash有以下几种类型: 分别通过不同的KSCrashMonitor类绑定: 主要hook以...

  • allhookinone

    java hook思路 在hook之前需要准备的信息 需要知道被hook方法的名字以及被hook方法定义所在的类 ...

  • Linux kill & Java shutdownhook

    shutdown-hook 建议加上shutdown的钩子如果程序出现了内存溢出crash 则现在代码是没有任何保...

  • WKWebView POST请求body丢失问题处理方案

    HOOK 方案 一 hook initWithFrame:configuration: 方法,进行JS注入,使用...

  • iOS逆向 ---- Hook方法及原理OC篇

    iOS逆向 ---- Hook方法及原理OC篇[iOS逆向 ---- Hook方法及原理OC篇](阅读原文

网友评论

      本文标题:减少crash的方法hook

      本文链接:https://www.haomeiwen.com/subject/xxbmdktx.html